[
  {
    "path": ".github/workflows/build.yaml",
    "content": "name: Build\n\non: [ pull_request, workflow_dispatch ]\n\npermissions: read-all\n\nenv:\n  XCODE_PROJECT: \"approf.xcodeproj\"\n  XCODE_SCHEME: \"approf\"\n  CODE_SIGN_IDENTITY: \"-\"\n  BUILD_DIR: \"build\"\n  XCODE_ARCHIVE: \"approf.xcarchive\"\n  APP_NAME: \"approf.app\"\n  EXPORT_OPTIONS_PLIST: \"exportOptions.plist\"\n  DMG_NAME: \"approf\"\n  DMG_FILE_NAME: \"approf.dmg\"\n\njobs:\n  build:\n    runs-on: macos-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Set up Xcode\n        run: |\n          sudo xcode-select -s \"/Applications/Xcode_16.app\"\n          xcodebuild -version\n      - name: Allow macro\n        run: |\n          defaults write com.apple.dt.Xcode IDESkipMacroFingerprintValidation -bool YES\n      - name: Build\n        run: xcodebuild -project \"$XCODE_PROJECT\" -scheme \"$XCODE_SCHEME\" archive CODE_SIGN_IDENTITY=\"$CODE_SIGN_IDENTITY\" -archivePath \"$BUILD_DIR/$XCODE_ARCHIVE\"\n      - name: Export\n        run: |\n          plutil -convert xml1 - -o \"$EXPORT_OPTIONS_PLIST\" << EOF\n            {\n              \"destination\": \"export\",\n              \"method\": \"mac-application\"\n            }\n          EOF\n          \n          xcodebuild -exportArchive -archivePath \"$BUILD_DIR/$XCODE_ARCHIVE\" -exportPath \"$BUILD_DIR\" -exportOptionsPlist \"$EXPORT_OPTIONS_PLIST\"\n      - name: Resign App\n        run: codesign --force --deep -s \"$CODE_SIGN_IDENTITY\" \"$BUILD_DIR/$APP_NAME\"\n      - name: Make DMG\n        run: hdiutil create -srcdir \"$BUILD_DIR\" -volname \"$DMG_NAME\" \"$DMG_FILE_NAME\"\n      - name: Upload\n        uses: actions/upload-artifact@v4\n        with:\n          name: Build\n          path: ${{ env.DMG_FILE_NAME }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# 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## Playgrounds\ntimeline.xctimeline\nplayground.xcworkspace\n\n# Swift Package Manager\n#\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#\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#\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#\n# Pods/\n#\n# Add this line if you want to avoid checking in source code from the Xcode workspace\n# *.xcworkspace\n\n# Carthage\n#\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\nCarthage/Build/\n\n# Accio dependency management\nDependencies/\n.accio/\n\n# fastlane\n#\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#\n# After new code Injection tools there's a generated folder /iOSInjectionProject\n# https://github.com/johnno1962/injectionforxcode\n\niOSInjectionProject/\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2024 moderato.app\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 all\ncopies 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 THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "https://github.com/user-attachments/assets/d61cd45f-abd8-4fa1-9038-5f9968ce9c9c\n\n## A native macOS app for [pprof](https://github.com/google/pprof)\nOpen pprof profiles without command-line hassle ✨.\n\n## Install\n```bash\nbrew install approf\n```\n\nYou can also download the latest app from [release](https://github.com/moderato-app/approf/releases/latest).\n\n## Requirements\n* `Graphviz` installed\n* macOS **Sonoma 14.0** or later on a **M-series chip**\n\n_Translucent background is only availble on macOS **Sequoia 15.0** or later_\n\n\n## Features\n- [x] Drag and drop pprof files to open\n- [x] Compare pprof profiles using the [`-diff_base`](https://github.com/google/pprof/blob/main/doc/README.md#comparing-profiles) option\n- [x] Reorder / Add / Remove files in seconds\n- [x] Dark / Light mode\n- [x] Save sessions for later use\n\n## Screenshots\n<img width=\"100%\" alt=\"Screenshot\" src=\"https://github.com/user-attachments/assets/efff596b-302d-45c9-8795-1ff8633e7d0f\">\n<div align=\"center\">Command line under the hood</div>\n<br/>\n<br/>\n<img width=\"100%\" alt=\"Screenshot\" src=\"https://github.com/user-attachments/assets/d34f68fb-8aa6-46ad-9a34-7c97c1a3ae0b\">\n<div align=\"center\">WEB page in dark mode </div>\n\n## Implementation\n* SwiftUI and AppKit as the UI framework.\n* The Composable Architecture for state management.\n* Running [pprof](https://github.com/golang/go/tree/master/src/cmd/pprof) binay in a process.\n\n## Credits\n<a href=\"https://golangweekly.com/latest\" target=\"_blank\">\n  <img width=\"200\" alt=\"image\" src=\"https://github.com/user-attachments/assets/25490d69-576c-4d47-9f3a-6b8a1200e57b\">\n</a>\n\nThanks to [Golang Weekly](https://golangweekly.com/latest) for the shoutout!\n"
  },
  {
    "path": "approf/App/AppDataSource.swift",
    "content": "import ComposableArchitecture\n\nstruct DateSource{\n  @MainActor\n  static let store = Store(initialState: AppFeature.State()) {\n    AppFeature()\n//      ._printChanges()\n  }\n}\n"
  },
  {
    "path": "approf/App/AppDelegate.swift",
    "content": "import AppKit\nimport CoreSpotlight\nimport Logging\n\nvar log = Logger(label: \"approf\")\n\nclass AppDelegate: NSObject, NSApplicationDelegate {\n  var windowController: CustomWindowController?\n\n  func application(_ application: NSApplication, open urls: [URL]) {\n    log.info(\"application open urls: \\(urls)\")\n    DateSource.store.send(.drop(.onDropEnds(urls)))\n  }\n\n  func applicationDidFinishLaunching(_ notification: Notification) {\n    log.logLevel = .debug\n\n    if let window = NSApp.windows.first {\n      windowController = CustomWindowController(window: window)\n      windowController?.showWindow(self)\n    }\n\n    registerSpotlightSearch()\n    registerSpotlightSearch2()\n    registerSpotlightSearch3()\n//    showTrafficLights(window, false)\n  }\n\n  func applicationDidUpdate(_ notification: Notification) {\n//    guard let window = NSApp.keyWindow else { return }\n//    // avoid interfering with traffic lights in full screen mode to prevent glitches.\n//    if !window.styleMask.contains(.fullScreen) {\n//      showTrafficLights(window, UIState.shared.mouseInsideWindow)\n//    }\n  }\n\n  func applicationWillTerminate(_ notification: Notification) {\n    log.info(\"applicationWillTerminate\")\n    DateSource.store.send(.onAppTermination)\n  }\n}\n\nfunc showTrafficLights(_ window: NSWindow, _ show: Bool) {\n  NSAnimationContext.runAnimationGroup { context in\n    context.duration = 0.5 // Set the animation duration\n\n    if let closeButton = window.standardWindowButton(.closeButton) {\n      closeButton.animator().alphaValue = show ? 1.0 : 0.0\n    }\n    if let miniaturizeButton = window.standardWindowButton(.miniaturizeButton) {\n      miniaturizeButton.animator().alphaValue = show ? 1.0 : 0.0\n    }\n    if let zoomButton = window.standardWindowButton(.zoomButton) {\n      zoomButton.animator().alphaValue = show ? 1.0 : 0.0\n    }\n  }\n}\n\nprivate func registerSpotlightSearch() {\n  let userActivity = NSUserActivity(activityType: \"the.future.app.approf.approf.alternative\")\n  userActivity.title = \"approf\"\n  userActivity.keywords = [\"pprof\", \"go\", \"pp\"]\n  userActivity.isEligibleForSearch = true\n  userActivity.isEligibleForPublicIndexing = true\n  userActivity.becomeCurrent()\n}\n\nprivate func registerSpotlightSearch2() {\n  let attributeSet = CSSearchableItemAttributeSet(contentType: UTType.data)\n  attributeSet.title = \"approf\"\n  attributeSet.contentDescription = \"A native macOS app to view pprof profiles\"\n  attributeSet.keywords = [\"pprof\", \"go\", \"pp\"]\n  let item = CSSearchableItem(uniqueIdentifier: \"0\", domainIdentifier: \"the.future.app.approf.approf.alternative\", attributeSet: attributeSet)\n  CSSearchableIndex.default().indexSearchableItems([item])\n}\n\nprivate func registerSpotlightSearch3() {\n  let attributeSet = CSSearchableItemAttributeSet(itemContentType: \"application\")\n  attributeSet.title = \"approf\"\n  attributeSet.keywords = [\"pprof\", \"go\", \"pp\"]\n  attributeSet.contentDescription = \"A native macOS app to view pprof profiles\"\n\n  let item = CSSearchableItem(uniqueIdentifier: \"the.future.app.approf.approf.alternative3\", domainIdentifier: nil, attributeSet: attributeSet)\n  CSSearchableIndex.default().indexSearchableItems([item]) { err in\n    if let err = err {\n      log.error(\"CSSearchableIndex.default().indexSearchableItems err: \\(err)\")\n    }\n  }\n}\n"
  },
  {
    "path": "approf/App/AppShortcuts.swift",
    "content": "import SwiftUI\nimport UniformTypeIdentifiers\n\nstruct CMD: Commands {\n  @Environment(\\.openWindow) var openWindow\n\n  @ObservedObject var asm = AppStorageManager.shared\n\n  var body: some Commands {\n    CommandGroup(replacing: CommandGroupPlacement.appInfo) {\n      Button(\"About pprof\") {\n        self.openWindow(id: \"about\")\n      }\n    }\n    CommandGroup(after: .newItem) {\n      Button(\"Open\") {\n        let urls = selectMultiFiles(utTypes: allowedImportFileTypes)\n        DateSource.store.send(.drop(.onDropEnds(urls)))\n      }\n      .keyboardShortcut(\"o\", modifiers: [.command])\n    }\n    CommandGroup(replacing: CommandGroupPlacement.sidebar) {\n      Button(\"Show/Hide Sidebar\") {\n        NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)\n      }\n      .keyboardShortcut(\"l\", modifiers: [.command, .shift])\n      Button(\"Show/Hide Sidebar\") {\n        NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)\n      }\n      .keyboardShortcut(\"s\", modifiers: [.command])\n      Picker(selection: self.$asm.colorScheme, label: Text(\"Appearance\")) {\n        Text(\"Automatic\").tag(AppColorScheme.automatic)\n        Text(\"Light\").tag(AppColorScheme.light)\n        Text(\"Dark\").tag(AppColorScheme.dark)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/App.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\n@main\nstruct MyMain {\n  static func main() {\n    if #available(macOS 15.0, *) {\n      MacOS15App.main()\n    } else {\n      MacOS14App.main()\n    }\n  }\n}\n\n@available(macOS 15.0, *)\nstruct MacOS15App: App {\n  @ObservedObject var asm = AppStorageManager.shared\n  @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate\n\n  var body: some Scene {\n    Window(\"approf\", id: \"main\") {\n      if isTesting {\n        EmptyView()\n      } else {\n        ContentView(store: DateSource.store)\n          .toolbar(removing: .title)\n          .toolbarBackgroundVisibility(.hidden, for: .windowToolbar)\n          .containerBackground(asm.materialType.actualMaterial, for: .window)\n          .preferredColorScheme(asm.computedColorScheme)\n      }\n    }\n    .defaultWindowPlacement { _, context in\n      let displayBounds = context.defaultDisplay.visibleRect\n      let size = CGSize(width: displayBounds.width * 0.8, height: displayBounds.height)\n      return WindowPlacement(size: size)\n    }\n    .commands {\n      CMD()\n    }\n\n    Settings {\n      SettingsView()\n        .toolbar(removing: .title)\n        .toolbarBackgroundVisibility(.hidden, for: .windowToolbar)\n        .containerBackground(.ultraThinMaterial, for: .window)\n        .preferredColorScheme(asm.computedColorScheme)\n    }\n    .windowManagerRole(.associated)\n\n    Window(\"About approf\", id: \"about\") {\n      AboutView()\n        .toolbar(removing: .title)\n        .toolbarBackgroundVisibility(.hidden, for: .windowToolbar)\n        .containerBackground(.ultraThinMaterial, for: .window)\n        .windowMinimizeBehavior(.disabled)\n        .windowResizeBehavior(.disabled)\n        .preferredColorScheme(asm.computedColorScheme)\n    }\n    .windowResizability(.contentSize)\n    .restorationBehavior(.disabled)\n  }\n}\n\nstruct MacOS14App: App {\n  @ObservedObject var asm = AppStorageManager.shared\n  @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate\n\n  var body: some Scene {\n    Window(\"approf\", id: \"main\") {\n      if isTesting {\n        EmptyView()\n      } else {\n        ContentView(store: DateSource.store)\n          .preferredColorScheme(asm.computedColorScheme)\n      }\n    }\n    .handlesExternalEvents(matching: [\"*\"])\n    .commands {\n      CMD()\n    }\n\n    Settings {\n      SettingsView()\n        .preferredColorScheme(asm.computedColorScheme)\n    }\n\n    Window(\"About approf\", id: \"about\") {\n      AboutView()\n        .preferredColorScheme(asm.computedColorScheme)\n    }\n    .windowResizability(.contentSize)\n  }\n}\n\nfunc shrinkToFit(ideal: CGSize, bounds: CGRect) -> CGSize {\n  let widthRatio = bounds.width / ideal.width\n  let heightRatio = bounds.height / ideal.height\n\n  let scale = min(widthRatio, heightRatio)\n\n  return CGSize(width: ideal.width * scale, height: ideal.height * scale)\n}\n"
  },
  {
    "path": "approf/Assets.xcassets/About.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"AboutImage.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "approf/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "approf/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  },\n  \"images\" : [\n    {\n      \"scale\" : \"1x\",\n      \"filename\" : \"icon_1024.png\",\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"20x20\",\n      \"filename\" : \"icon_40.png\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"icon_60.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"scale\" : \"2x\",\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"icon_58.png\"\n    },\n    {\n      \"scale\" : \"3x\",\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"icon_87.png\"\n    },\n    {\n      \"scale\" : \"2x\",\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"icon_80.png\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"filename\" : \"icon_120.png\"\n    },\n    {\n      \"filename\" : \"icon_120.png\",\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"icon_180.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"16x16\",\n      \"filename\" : \"icon_16.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_32.png\",\n      \"size\" : \"16x16\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"filename\" : \"icon_32.png\",\n      \"scale\" : \"1x\",\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\"\n    },\n    {\n      \"scale\" : \"2x\",\n      \"filename\" : \"icon_64.png\",\n      \"idiom\" : \"mac\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"scale\" : \"1x\",\n      \"idiom\" : \"mac\",\n      \"size\" : \"128x128\",\n      \"filename\" : \"icon_128.png\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"filename\" : \"icon_256.png\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"icon_256.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"icon_512.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"filename\" : \"icon_512.png\",\n      \"size\" : \"512x512\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"size\" : \"512x512\",\n      \"scale\" : \"2x\",\n      \"filename\" : \"icon_1024.png\"\n    }\n  ]\n}"
  },
  {
    "path": "approf/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "approf/Assets.xcassets/DocIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"icon_1024.png\",\n      \"idiom\" : \"ios-marketing\",\n      \"scale\" : \"1x\",\n      \"size\" : \"1024x1024\"\n    },\n    {\n      \"filename\" : \"icon_16.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"16x16\"\n    },\n    {\n      \"filename\" : \"icon_32.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"16x16\"\n    },\n    {\n      \"filename\" : \"icon_32.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"filename\" : \"icon_64.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"filename\" : \"icon_128.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"icon_256.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"icon_256.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"icon_512.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"icon_512.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"512x512\"\n    },\n    {\n      \"filename\" : \"icon_1024.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"512x512\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "approf/Assets.xcassets/Gopple.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Gopple.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "approf/Assets.xcassets/jobs.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"jobs.jpeg\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "approf/Component/Buttons.swift",
    "content": "import Pow\nimport SwiftUI\n\nstruct CopyButton: View {\n  let textGenerator: () -> String\n  @State var clicked = false\n\n  init(textGenerator: @escaping () -> String) {\n    self.textGenerator = textGenerator\n  }\n\n  var body: some View {\n    Button(action: {\n      let pasteboard = NSPasteboard.general\n      pasteboard.clearContents()\n      pasteboard.setString(textGenerator(), forType: .string)\n      withAnimation {\n        clicked = true\n      }\n      DispatchQueue.main.asyncAfter(deadline: .now() + 2) {\n        withAnimation {\n          clicked = false\n        }\n      }\n    }) {\n      Image(systemName: icon)\n        .opacity(clicked ? 0 : 1)\n        .overlay {\n          if clicked {\n            Image(systemName: \"checkmark.circle\")\n              .foregroundStyle(.green)\n              .transition(\n                .movingParts.pop(.green)\n              )\n          }\n        }\n    }\n    .buttonStyle(PlainButtonStyle())\n  }\n\n  var icon: String {\n    if #available(macOS 15.0, *) {\n      \"document.on.clipboard\"\n    } else {\n      \"doc.on.clipboard\"\n    }\n  }\n}\n\nstruct LightsOnButton: View {\n  @Binding var lightsOn: Bool\n  @State var clickedDate: Date?\n\n  var body: some View {\n    Button(action: {\n      let now = Date()\n      if let lastClicked = clickedDate, now.timeIntervalSince(lastClicked) < 1.5 {\n        // to avoid wkwebview glitch, do nothing if the button was clicked in the past 1.5 second\n        return\n      }\n      withAnimation {\n        lightsOn.toggle()\n      }\n      clickedDate = now\n    }) {\n      LightbulbSlash(lightsOn: $lightsOn)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/Component/CountDown.swift",
    "content": "import Combine\nimport SwiftUI\n\nclass CountDown: ObservableObject {\n  @Published var remainingSeconds: Int\n  private var timer: AnyCancellable?\n\n  init(_ seconds: Int) {\n    self.remainingSeconds = seconds\n  }\n\n  func start() {\n    \n    timer = Timer.publish(every: 1.0, on: .main, in: .common)\n      .autoconnect()\n      .sink { [weak self] _ in\n        self?.tick() // Separate the tick logic into a function\n      }\n  }\n\n  private func tick() {\n    remainingSeconds -= 1\n    if remainingSeconds <= 0 {\n      destroy()\n    }\n  }\n\n  func destroy() {\n    timer?.cancel()\n    timer = nil\n  }\n\n  deinit {\n    destroy() // Ensure the timer is stopped when the object is deallocated\n  }\n}\n"
  },
  {
    "path": "approf/Component/FloatTopTrailing.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct NotificationView: View {\n  @Bindable var store: StoreOf<NotificationFeature>\n\n  var body: some View {\n    ZStack {\n      RoundedRectangle(cornerRadius: 10)\n        .fill(.background)\n\n      HStack(spacing: 7) {\n        Circle()\n          .foregroundStyle(.orange)\n          .frame(width: 10, height: 10)\n\n        VStack(alignment: .leading, spacing: 2) {\n          Text(store.text)\n            .fontWeight(.bold)\n          HStack {\n            Text(\"\\(Date().formatted(date: .omitted, time: .shortened))\")\n              .foregroundStyle(.secondary)\n              .padding(.trailing, 8)\n            Spacer()\n            if let seconds = store.seconds {\n              Text(\"Disappears in \\(seconds) seconds\")\n                .foregroundStyle(.secondary)\n                .font(.footnote)\n            }\n          }\n        }\n      }\n      .padding(8)\n    }\n    .fixedSize()\n    .onAppear {\n      store.send(.onAppear)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/Component/Symbols.swift",
    "content": "import SwiftUI\n\nstruct HeartSlash: View {\n  @State var slashed = false\n\n  var body: some View {\n    Image(systemName: slashed ? \"heart.slash.fill\" : \"heart.fill\")\n      .symbolRenderingMode(.multicolor)\n      .contentTransition(.symbolEffect(.replace))\n      .onAppear(delay: .seconds(0.25)) {\n        withAnimation {\n          slashed.toggle()\n        }\n      }\n      .onDisappear {\n        withAnimation {\n          slashed.toggle()\n        }\n      }\n  }\n}\n\nstruct LightbulbSlash: View {\n  @Binding var lightsOn: Bool\n\n  var body: some View {\n    Image(systemName: lightsOn ? \"lightbulb\" : \"lightbulb.slash\")\n      .contentTransition(.symbolEffect(.replace))\n  }\n}\n"
  },
  {
    "path": "approf/Component/Texts.swift",
    "content": "import SwiftUI\n\nstruct ScrollableTextBox<Content>: View where Content: View {\n  var heightLimit: CGFloat? = nil\n  @ViewBuilder\n  var content: () -> Content\n  @State var contentHeight: CGFloat = 10\n\n  var body: some View {\n    Group {\n      if let limit = heightLimit {\n        ScrollView {\n          HStack {\n            VStack(alignment: .leading) {\n              content()\n            }\n            Spacer()\n          }\n          .textSelection(.enabled)\n          .onGeometryChange(for: CGFloat.self) { proxy in proxy.size.height } action: { contentHeight = $0 }\n        }\n        .frame(height: min(contentHeight, limit))\n      } else {\n        ScrollView {\n          HStack {\n            VStack(alignment: .leading) {\n              content()\n            }\n            Spacer()\n          }\n          .textSelection(.enabled)\n        }\n      }\n    }\n    .padding(8)\n    .background(\n      RoundedRectangle(cornerRadius: 10)\n        .fill(.bar)\n        .strokeBorder(.secondary.opacity(0.5), lineWidth: 0.5)\n    )\n  }\n}\n"
  },
  {
    "path": "approf/Component/effcts/GradientBackgroundAnimation.swift",
    "content": "/*\n Thanks to https://github.com/flawless-code/swiftui-animations/blob/main/SwiftUIAnimations/SwiftUIAnimations/GradientBackgroundAnimation.swift\n  */\nimport SwiftUI\n\nstruct GradientBackgroundAnimation: View {\n  @State private var animateGradient: Bool = false\n  @State private var showName: Bool = false\n  @State private var showFullContent: Bool = false\n\n  private let startColor: Color = .blue\n  private let endColor: Color = .green\n\n  var body: some View {\n    VStack(spacing: 20) {\n      if showFullContent {\n        Image(\"jobs\")\n          .resizable()\n          .scaledToFit()\n          .clipShape(RoundedRectangle(cornerRadius: 15))\n          .containerRelativeFrame(.vertical) { v, _ in v * 0.4 }\n          .padding(.top, 40)\n          .padding(.bottom, 40)\n      } else {\n        Image(systemName: \"swiftdata\")\n          .font(.system(size: 72, weight: .light))\n          .padding(.top, 80)\n          .padding(.bottom, 64)\n      }\n\n      Text(\"Here's to the crazy ones.\")\n        .font(.largeTitle).bold()\n      Text(\"The misfits, the rebels, the troublemakers,\")\n        .font(.title)\n      Text(\"the round pegs in the square holes, the ones who see things differently.\")\n        .font(.title)\n      Text(\"You can quote them, disagree with them, glorify or vilify them. About the only thing you can't do is ignore them. \\nBecause they change things - they push the human race forward. And while some may see them as the crazy ones, we see genius. \\nBecause the people who are crazy enough to think they can change the world, are the ones who do.\")\n        .scaleEffect(showFullContent ? 1 : 0)\n        .opacity(showFullContent ? 1 : 0)\n      Spacer()\n      Text(\"Steven Paul Jobs (February 24, 1955 – October 5, 2011)\")\n        .fontWeight(.thin)\n        .padding(6)\n        .opacity(showName ? 1 : 0)\n    }\n    .frame(maxWidth: .infinity)\n    .foregroundColor(.black)\n    .padding(.horizontal)\n    .multilineTextAlignment(.center)\n    .background {\n      LinearGradient(colors: [startColor, endColor], startPoint: .topLeading, endPoint: .bottomTrailing)\n        .edgesIgnoringSafeArea(.all)\n        .hueRotation(.degrees(animateGradient ? 45 : 0))\n        .onAppear {\n          withAnimation(.easeInOut(duration: 3).repeatForever(autoreverses: true)) {\n            animateGradient.toggle()\n          }\n        }\n//          .reverseMask {\n//            RoundedRectangle(cornerRadius: 10)\n//              .padding(6)\n//          }\n    }\n    .delayedHover(5) { h in\n      withAnimation {\n        showName = h\n      }\n    }\n    .delayedHover(10) { h in\n      withAnimation(.easeInOut(duration: 1)) {\n        showFullContent = h\n      }\n    }\n    .ignoresSafeArea()\n    .toolbar(.hidden, for: .windowToolbar)\n  }\n}\n\nstruct GradientBackgroundAnimation_Previews: PreviewProvider {\n  static var previews: some View {\n    GradientBackgroundAnimation()\n      .ignoresSafeArea()\n  }\n}\n"
  },
  {
    "path": "approf/Component/effcts/LightsOff.metal",
    "content": "#include <metal_stdlib>\n#include <SwiftUI/SwiftUI.h>\nusing namespace metal;\n\n[[stitchable]] half4 lightsOff(float2 pos, half4 color){\n   return 1 - color;\n}\n"
  },
  {
    "path": "approf/Component/effcts/Ripple.metal",
    "content": "/*\nSee the LICENSE.txt file for this sample’s licensing information.\n\nAbstract:\nA shader that applies a ripple effect to a view when using it as a SwiftUI layer\n effect.\n*/\n\n#include <metal_stdlib>\n#include <SwiftUI/SwiftUI.h>\nusing namespace metal;\n\n[[ stitchable ]]\nhalf4 Ripple(\n    float2 position,\n    SwiftUI::Layer layer,\n    float2 origin,\n    float time,\n    float amplitude,\n    float frequency,\n    float decay,\n    float speed\n) {\n    // The distance of the current pixel position from `origin`.\n    float distance = length(position - origin);\n    // The amount of time it takes for the ripple to arrive at the current pixel position.\n    float delay = distance / speed;\n\n    // Adjust for delay, clamp to 0.\n    time -= delay;\n    time = max(0.0, time);\n\n    // The ripple is a sine wave that Metal scales by an exponential decay\n    // function.\n    float rippleAmount = amplitude * sin(frequency * time) * exp(-decay * time);\n\n    // A vector of length `amplitude` that points away from position.\n    float2 n = normalize(position - origin);\n\n    // Scale `n` by the ripple amount at the current pixel position and add it\n    // to the current pixel position.\n    //\n    // This new position moves toward or away from `origin` based on the\n    // sign and magnitude of `rippleAmount`.\n    float2 newPosition = position + rippleAmount * n;\n\n    // Sample the layer at the new position.\n    half4 color = layer.sample(newPosition);\n\n    // Lighten or darken the color based on the ripple amount and its alpha\n    // component.\n    color.rgb += 0.3 * (rippleAmount / amplitude) * color.a;\n\n    return color;\n}\n"
  },
  {
    "path": "approf/Component/effcts/Ripple.swift",
    "content": "/*\n Copyright © 2024 Apple Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\nimport SwiftUI\n\n@available(macOS 15.0, *)\n#Preview(\"Ripple\") {\n  RPView()\n}\n\n@available(macOS 15.0, *)\nstruct RPView: View {\n  @State var counter: Int = 0\n  @State var origin: CGPoint = .zero\n\n  var body: some View {\n    VStack {\n      Spacer()\n\n      Image(\"About\")\n        .resizable()\n        .aspectRatio(contentMode: .fit)\n        .clipShape(RoundedRectangle(cornerRadius: 24))\n        .modifier(RippleEffect(at: origin, trigger: counter))\n\n      Spacer()\n    }\n    .padding()\n  }\n}\n\nstruct PushEffect<T: Equatable>: ViewModifier {\n  var trigger: T\n\n  func body(content: Content) -> some View {\n    content.keyframeAnimator(\n      initialValue: 1.0,\n      trigger: trigger\n    ) { view, value in\n      view.visualEffect { view, _ in\n        view.scaleEffect(value)\n      }\n    } keyframes: { _ in\n      SpringKeyframe(0.95, duration: 0.2, spring: .snappy)\n      SpringKeyframe(1.0, duration: 0.2, spring: .bouncy)\n    }\n  }\n}\n\n/// A modifer that performs a ripple effect to its content whenever its\n/// trigger value changes.\nstruct RippleEffect<T: Equatable>: ViewModifier {\n  var origin: CGPoint\n\n  var trigger: T\n\n  init(at origin: CGPoint, trigger: T) {\n    self.origin = origin\n    self.trigger = trigger\n  }\n\n  func body(content: Content) -> some View {\n    let origin = origin\n    let duration = duration\n\n    content.keyframeAnimator(\n      initialValue: 0,\n      trigger: trigger\n    ) { view, elapsedTime in\n      view.modifier(RippleModifier(\n        origin: origin,\n        elapsedTime: elapsedTime,\n        duration: duration\n      ))\n    } keyframes: { _ in\n      MoveKeyframe(0)\n      LinearKeyframe(duration, duration: duration)\n    }\n  }\n\n  var duration: TimeInterval { 3 }\n}\n\n/// A modifier that applies a ripple effect to its content.\nstruct RippleModifier: ViewModifier {\n  var origin: CGPoint\n\n  var elapsedTime: TimeInterval\n\n  var duration: TimeInterval\n\n  var amplitude: Double = 12\n  var frequency: Double = 15\n  var decay: Double = 8\n  var speed: Double = 1200\n\n  func body(content: Content) -> some View {\n    let shader = ShaderLibrary.Ripple(\n      .float2(origin),\n      .float(elapsedTime),\n\n      // Parameters\n      .float(amplitude),\n      .float(frequency),\n      .float(decay),\n      .float(speed)\n    )\n\n    let maxSampleOffset = maxSampleOffset\n    let elapsedTime = elapsedTime\n    let duration = duration\n\n    content.visualEffect { view, _ in\n      view.layerEffect(\n        shader,\n        maxSampleOffset: maxSampleOffset,\n        isEnabled: elapsedTime > 0 && elapsedTime < duration\n      )\n    }\n  }\n\n  var maxSampleOffset: CGSize {\n    CGSize(width: amplitude, height: amplitude)\n  }\n}\n"
  },
  {
    "path": "approf/ContentView.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct ContentView: View {\n  @Bindable var store: StoreOf<AppFeature>\n  @State var uiState = UIState.shared\n\n  var body: some View {\n    NavigaionView(store: store)\n      .onHover { uiState.mouseInsideWindow = $0 }\n      .overlay {\n        DropAndImportView(store: store.scope(state: \\.drop, action: \\.drop))\n      }\n  }\n}\n"
  },
  {
    "path": "approf/Exts.swift",
    "content": "import Foundation\nimport Logging\nimport Network\n\nextension String: @retroactive Error {}\n\nfunc findRandomAvailablePort() throws -> UInt16 {\n  let parameters = NWParameters.tcp\n  parameters.requiredLocalEndpoint = NWEndpoint.hostPort(host: .ipv4(.loopback), port: .any)\n\n  let listener = try NWListener(using: parameters)\n\n  guard let port = listener.port else {\n    throw thr(\"port is nil\")\n  }\n\n  listener.cancel()\n\n  return port.rawValue\n}\n\nfunc createTemporaryDirectory() -> URL? {\n  let tempDirectoryURL = FileManager.default.temporaryDirectory\n  let temporaryDirectoryName = UUID().uuidString\n  let temporaryDirectoryURL = tempDirectoryURL.appendingPathComponent(temporaryDirectoryName, isDirectory: true)\n\n  do {\n    try FileManager.default.createDirectory(at: temporaryDirectoryURL, withIntermediateDirectories: true, attributes: nil)\n    return temporaryDirectoryURL\n  } catch {\n    print(\"Error creating temporary directory: \\(error)\")\n    return nil\n  }\n}\n\nfunc detectHttpOk(httpUrl: URL, followIndirect: Bool = false, interval: Duration = .seconds(0.1), bodyShouldContain: String? = nil) async throws(Error) {\n  var tried = 0\n  while true {\n    if tried > 0 {\n      log.debug(\"detectHttpOk will continue, tried:\\(tried)\")\n      try await Task.sleep(for: interval)\n    }\n\n    tried += 1\n\n    var d: Data?\n    var r: URLResponse?\n    do {\n      (d, r) = try await URLSession.shared.data(for: URLRequest(url: httpUrl))\n    } catch {\n      log.debug(\"detecting http liveness: failed, Unexpected response body: \\(error))\")\n      continue\n    }\n\n    let data = d!\n    let response = r!\n\n    if let httpResponse = response as? HTTPURLResponse {\n      if (200 ... 299).contains(httpResponse.statusCode) {\n        if let text = bodyShouldContain {\n          let dataString = String(data: data, encoding: .utf8)\n          if dataString?.contains(text) ?? false {\n            log.debug(\"detecting http liveness: success)\")\n            return\n          } else {\n            log.debug(\"detecting http liveness: failed, Unexpected response body: \\(String(describing: dataString))\")\n          }\n        } else {\n          log.debug(\"detecting http liveness: success)\")\n          return\n        }\n      } else {\n        log.debug(\"detecting http liveness: failed, Request failed with status code: \\(httpResponse.statusCode)\")\n      }\n    }\n    try await Task.sleep(for: interval)\n  }\n}\n\nfunc detectPipeContains(_ pipe: Pipe, _ shouldStartWith: String) async throws(Error) {\n  let handle = pipe.fileHandleForReading\n\n  var read = \"\"\n\n  while let data = try handle.readToEnd(),\n        let output = String(data: data, encoding: .utf8)\n  {\n    read.append(output)\n\n    if read.count >= shouldStartWith.count {\n      if read.starts(with: shouldStartWith) {\n        log.debug(\"detecting pipe: success)\")\n        return\n      } else {\n        throw thr(\"Unexpected output: \\(read)\")\n      }\n    } else {\n      if shouldStartWith.starts(with: read) {\n        // continue to read\n        continue\n      } else {\n        throw thr(\"Unexpected output: \\(read)\")\n      }\n    }\n  }\n  throw thr(\"Unexpected output: \\(read)\")\n}\n\nextension Logger {\n  func infoString(_ s: String) {\n    self.info(\"\\(s)\")\n  }\n\n  func thr(_ s: String) throws {\n    self.error(\"\\(s)\")\n    throw s\n  }\n\n  func thr<T>(_ e: T) -> T where T: Error {\n    self.error(\"== Throwing \\(e.self) ==\")\n    return e\n  }\n}\n\nfunc thr<T>(_ e: T) -> T where T: Error {\n  log.error(\"== Throwing \\(e.self) ==\")\n  return e\n}\n\nfunc readFirstLine(from fileURL: URL) -> String? {\n  do {\n    let content = try String(contentsOf: fileURL, encoding: .utf8)\n    let lines = content.components(separatedBy: .newlines)\n    return lines.first\n  } catch {\n    print(\"Error reading file: \\(error.localizedDescription)\")\n    return nil\n  }\n}\n\nfunc getAppVersion() -> String {\n  if let version = Bundle.main.infoDictionary?[\"CFBundleShortVersionString\"] as? String,\n     let build = Bundle.main.infoDictionary?[\"CFBundleVersion\"] as? String\n  {\n    return \"\\(version) (\\(build))\"\n  }\n  return \"\"\n}\n\nextension String {\n  // \"🇩🇪€4€9\".extract(\"[0-9]\") ==> [\"4\", \"9\"]\n  func extract(regex: String) -> [String] {\n    do {\n      let regex = try NSRegularExpression(pattern: regex)\n      let results = regex.matches(in: self,\n                                  range: NSRange(self.startIndex..., in: self))\n      return results.map {\n        String(self[Range($0.range, in: self)!])\n      }\n    } catch {\n      log.error(\"invalid regex: \\(error.localizedDescription)\")\n      return []\n    }\n  }\n\n  func extractPort() -> UInt16? {\n    let pattern = \"Serving web UI on http://localhost:(\\\\d+)\"\n    let regex = try! NSRegularExpression(pattern: pattern, options: [])\n\n    if let match = regex.firstMatch(in: self, options: [], range: NSRange(location: 0, length: self.utf16.count)) {\n      if let range = Range(match.range(at: 1), in: self) {\n        let port = UInt16(self[range])\n        return port\n      }\n    }\n    return nil\n  }\n}\n\n// How to force SwiftUI Text to ‘break by character\n// https://medium.com/@Jager-yoo/watchos-how-to-force-swiftui-text-to-break-by-character-cd22526568b8\nextension String {\n  /// Forces the string to apply the break by character mode.\n  ///\n  /// Text(\"This is a long text.\".forceCharWrapping)\n  var forceCharWrapping: Self {\n    self.map { String($0) }.joined(separator: \"\\u{200B}\")\n  }\n}\n\nextension String {\n  var asUrl: URL? {\n    URL(string: self)\n  }\n}\n\nextension UInt64 {\n  /// Returns a human-readable file size string (e.g., \"18B\", \"20KB\", \"20MB\").\n  func humanReadableFileSize() -> String {\n    let size = Double(self)\n    if size < 1024 {\n      return \"\\(self)B\"\n    }\n    let units = [\"KB\", \"MB\", \"GB\", \"TB\", \"PB\"]\n    var unitIndex = 0\n    var adjustedSize = size / 1024.0\n    while adjustedSize >= 1024 && unitIndex < units.count - 1 {\n      adjustedSize /= 1024\n      unitIndex += 1\n    }\n    return String(format: \"%.1f%@\", adjustedSize, units[unitIndex])\n  }\n}\n\nfunc getFileSize(atPath path: String) -> UInt64? {\n  do {\n    let attributes = try FileManager.default.attributesOfItem(atPath: path)\n    if let fileSize = attributes[FileAttributeKey.size] as? UInt64 {\n      return fileSize\n    }\n  } catch {\n    print(\"Error: \\(error)\")\n  }\n  return nil\n}\n\nfunc getFileSize(atURL url: URL) -> UInt64? {\n  return getFileSize(atPath: url.path)\n}\n\nextension String {\n  var fileSize: UInt64? {\n    getFileSize(atPath: self)\n  }\n}\n\nextension URL {\n  func replaceHomeWithTilde() -> String {\n    let homeDirectory = FileManager.default.homeDirectoryForCurrentUser\n\n    if self.path.hasPrefix(homeDirectory.path) {\n      let relativePath = self.path(percentEncoded: false).replacingOccurrences(of: homeDirectory.path, with: \"~\")\n      return relativePath\n    } else {\n      return self.path(percentEncoded: false)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/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>CFBundleDocumentTypes</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>CFBundleTypeName</key>\n\t\t\t<string>public data</string>\n\t\t\t<key>CFBundleTypeRole</key>\n\t\t\t<string>Editor</string>\n\t\t\t<key>LSHandlerRank</key>\n\t\t\t<string>Default</string>\n\t\t\t<key>LSItemContentTypes</key>\n\t\t\t<array>\n\t\t\t\t<string>public.data</string>\n\t\t\t</array>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>CFBundleTypeName</key>\n\t\t\t<string>gz</string>\n\t\t\t<key>CFBundleTypeRole</key>\n\t\t\t<string>Editor</string>\n\t\t\t<key>LSHandlerRank</key>\n\t\t\t<string>Default</string>\n\t\t\t<key>LSItemContentTypes</key>\n\t\t\t<array>\n\t\t\t\t<string>org.gnu.gnu-zip-archive</string>\n\t\t\t</array>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>CFBundleTypeName</key>\n\t\t\t<string>pb</string>\n\t\t\t<key>CFBundleTypeRole</key>\n\t\t\t<string>Editor</string>\n\t\t\t<key>LSHandlerRank</key>\n\t\t\t<string>Default</string>\n\t\t\t<key>LSItemContentTypes</key>\n\t\t\t<array>\n\t\t\t\t<string>the.future.app.pprof.pprof.filetype.pb</string>\n\t\t\t</array>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>CFBundleTypeName</key>\n\t\t\t<string>prof</string>\n\t\t\t<key>CFBundleTypeRole</key>\n\t\t\t<string>Editor</string>\n\t\t\t<key>LSHandlerRank</key>\n\t\t\t<string>Default</string>\n\t\t\t<key>LSItemContentTypes</key>\n\t\t\t<array>\n\t\t\t\t<string>the.future.app.pprof.pprof.filetype.prof</string>\n\t\t\t</array>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>CFBundleTypeName</key>\n\t\t\t<string>proff</string>\n\t\t\t<key>CFBundleTypeRole</key>\n\t\t\t<string>Editor</string>\n\t\t\t<key>LSHandlerRank</key>\n\t\t\t<string>Default</string>\n\t\t\t<key>LSItemContentTypes</key>\n\t\t\t<array>\n\t\t\t\t<string>the.future.app.pprof.pprof.filetype.proff</string>\n\t\t\t</array>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>CFBundleTypeName</key>\n\t\t\t<string>pprof</string>\n\t\t\t<key>CFBundleTypeRole</key>\n\t\t\t<string>Editor</string>\n\t\t\t<key>LSHandlerRank</key>\n\t\t\t<string>Default</string>\n\t\t\t<key>LSItemContentTypes</key>\n\t\t\t<array>\n\t\t\t\t<string>the.future.app.pprof.pprof.filetype.pprof</string>\n\t\t\t</array>\n\t\t</dict>\n\t</array>\n\t<key>INAlternativeAppNames</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>INAlternativeAppName</key>\n\t\t\t<string>go</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>INAlternativeAppName</key>\n\t\t\t<string>pprof</string>\n\t\t</dict>\n\t</array>\n\t<key>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSAllowsArbitraryLoads</key>\n\t\t<true/>\n\t</dict>\n\t<key>UTExportedTypeDeclarations</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>UTTypeConformsTo</key>\n\t\t\t<array>\n\t\t\t\t<string>public.data</string>\n\t\t\t</array>\n\t\t\t<key>UTTypeDescription</key>\n\t\t\t<string>google pprof file format - pb</string>\n\t\t\t<key>UTTypeIcons</key>\n\t\t\t<dict>\n\t\t\t\t<key>UTTypeIconBadgeName</key>\n\t\t\t\t<string>DocIcon</string>\n\t\t\t\t<key>UTTypeIconText</key>\n\t\t\t\t<string>pprof</string>\n\t\t\t</dict>\n\t\t\t<key>UTTypeIdentifier</key>\n\t\t\t<string>the.future.app.pprof.pprof.filetype.pb</string>\n\t\t\t<key>UTTypeTagSpecification</key>\n\t\t\t<dict>\n\t\t\t\t<key>public.filename-extension</key>\n\t\t\t\t<array>\n\t\t\t\t\t<string>pb</string>\n\t\t\t\t</array>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>UTTypeConformsTo</key>\n\t\t\t<array>\n\t\t\t\t<string>public.data</string>\n\t\t\t</array>\n\t\t\t<key>UTTypeDescription</key>\n\t\t\t<string>google pprof file format - prof</string>\n\t\t\t<key>UTTypeIcons</key>\n\t\t\t<dict>\n\t\t\t\t<key>UTTypeIconBadgeName</key>\n\t\t\t\t<string>DocIcon</string>\n\t\t\t\t<key>UTTypeIconText</key>\n\t\t\t\t<string>pprof</string>\n\t\t\t</dict>\n\t\t\t<key>UTTypeIdentifier</key>\n\t\t\t<string>the.future.app.pprof.pprof.filetype.prof</string>\n\t\t\t<key>UTTypeTagSpecification</key>\n\t\t\t<dict>\n\t\t\t\t<key>public.filename-extension</key>\n\t\t\t\t<array>\n\t\t\t\t\t<string>prof</string>\n\t\t\t\t</array>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>UTTypeConformsTo</key>\n\t\t\t<array>\n\t\t\t\t<string>public.data</string>\n\t\t\t</array>\n\t\t\t<key>UTTypeDescription</key>\n\t\t\t<string>google pprof file format - proff</string>\n\t\t\t<key>UTTypeIcons</key>\n\t\t\t<dict>\n\t\t\t\t<key>UTTypeIconBadgeName</key>\n\t\t\t\t<string>DocIcon</string>\n\t\t\t\t<key>UTTypeIconText</key>\n\t\t\t\t<string>pprof</string>\n\t\t\t</dict>\n\t\t\t<key>UTTypeIdentifier</key>\n\t\t\t<string>the.future.app.pprof.pprof.filetype.proff</string>\n\t\t\t<key>UTTypeTagSpecification</key>\n\t\t\t<dict>\n\t\t\t\t<key>public.filename-extension</key>\n\t\t\t\t<array>\n\t\t\t\t\t<string>proff</string>\n\t\t\t\t</array>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>UTTypeConformsTo</key>\n\t\t\t<array>\n\t\t\t\t<string>public.data</string>\n\t\t\t</array>\n\t\t\t<key>UTTypeDescription</key>\n\t\t\t<string>google pprof file format - pprof</string>\n\t\t\t<key>UTTypeIcons</key>\n\t\t\t<dict>\n\t\t\t\t<key>UTTypeIconBadgeName</key>\n\t\t\t\t<string>DocIcon</string>\n\t\t\t\t<key>UTTypeIconText</key>\n\t\t\t\t<string>pprof</string>\n\t\t\t</dict>\n\t\t\t<key>UTTypeIdentifier</key>\n\t\t\t<string>the.future.app.pprof.pprof.filetype.pprof</string>\n\t\t\t<key>UTTypeTagSpecification</key>\n\t\t\t<dict>\n\t\t\t\t<key>public.filename-extension</key>\n\t\t\t\t<array>\n\t\t\t\t\t<string>pprof</string>\n\t\t\t\t</array>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "approf/Preview/PerviewData.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\nextension UnderTheHood {\n  static var mock = Store(initialState:\n    UnderTheHood.State(basic:\n      Shared(PProfBasic(\n        uuid: UUID(),\n        urls: [\n          URL(fileURLWithPath: \"/Library/Application\\\\ Support/Apple/ParentasdlControls/ALRHelperJobs/pprof.etcd.alloc_objects.alloc_space.inuse_objects.inuse_space.002.pb.gz\"),\n          URL(fileURLWithPath: \"/Library/Application\\\\ Support/Apple/ParesdfntalControls/ALRHelperJobs/pprof.etcd.alloc_objects.alloc_space.inuse_objects.inuse_space.002.pb.gz\"),\n          URL(fileURLWithPath: \"/Library/Application\\\\ Support/Apple/ParentalControls/ALRHelperJobs/pprof.etcd.alloc_objects.alloc_space.inuse_object3s.inuse_space.002.pb.gz\"),\n          URL(fileURLWithPath: \"/Library/Application\\\\ Support/Apple/ParentalControls/ALRHelperJobs/pprof.etcd.alloc_objects.alloc_space.inuse_objects.inuse_space.002.pb.gz\"),\n          URL(fileURLWithPath: \"/Library/Applicdfgation\\\\ Support/Apple/ParentalControls/ALRHelperJobs/pprof.etcd.alloc_objects.alloc_space.inuse_objects.inuse_space.002.pb.gz\"),\n          URL(fileURLWithPath: \"/Library/Applicadfgtion\\\\ Support/Apple/ParentalControls/ALRHelperJobs/pprof.etcd.alloc_objects.alloc_space.inuse_objects.infgfguse_space.002.pb.gz\"),\n          URL(fileURLWithPath: \"/Users/clement/Documents/example.txt\"),\n          URL(fileURLWithPath: \"/Users/username/Documents/example.txt\")\n        ],\n        createdAt: Date(),\n        presentation: .dft))))\n  {\n    UnderTheHood()\n  }\n}\n"
  },
  {
    "path": "approf/Preview Content/Preview Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "approf/Process/Command.swift",
    "content": "import Foundation\n\n// create the process without running it\nfunc createPProfProcess(_ args: [CommandLine.CommandArg]) throws(PProfError) -> ([CommandLine.CommandArg], Process, AsyncStream<String>) {\n  let pprofPath = \"\\(Bundle.main.bundlePath)/Contents/Frameworks/pprof\"\n  let process = Process()\n  process.executableURL = URL(fileURLWithPath: pprofPath)\n  process.arguments = args.asProcessArgs()\n  let finalCommandArgs = [CommandLine.CommandArg.filePath(pprofPath)] + args\n\n  var environment = ProcessInfo.processInfo.environment\n  let additional = AppStorageManager.shared.graphvizBinDir.replacingOccurrences(of: \":\", with: \"\")\n  environment[\"PATH\"] = \"\\(additional):\\(environment[\"PATH\"] ?? \"\")\"\n  log.info(\"PATH:\\(String(describing: environment[\"PATH\"]))\")\n  process.environment = environment\n\n  let pipe = Pipe()\n  process.standardOutput = pipe\n  process.standardError = pipe\n\n  log.debug(\"pipe created. fileDescriptor:  \\(pipe.fileHandleForReading.fileDescriptor)\")\n\n  let terminalStream = AsyncStream<String> { con in\n    let handle = pipe.fileHandleForReading\n\n    handle.readabilityHandler = { fh in\n      if let output = String(data: fh.availableData, encoding: .utf8) {\n        con.yield(output)\n      }\n      // read only once to get the port or an error, preventing next reading operation from blocking loop\n      con.finish()\n      handle.readabilityHandler = nil\n    }\n\n    process.terminationHandler = { _ in\n      con.finish()\n      do {\n        try handle.close()\n      } catch {\n        log.error(\"failed to close pipe: \\(error.localizedDescription)\")\n      }\n    }\n  }\n\n  return (finalCommandArgs, process, terminalStream)\n}\n\nfunc detectHttpOk2(httpUrl: URL, followIndirect: Bool = false, bodyShouldContain: String? = nil) async -> (Bool, HTTPResult) {\n  var d: Data?\n  var r: URLResponse?\n  do {\n    (d, r) = try await URLSession.shared.data(for: URLRequest(url: httpUrl))\n  } catch {\n    log.debug(\"detecting http liveness: failed, Unexpected response body: \\(error))\")\n    return (false, HTTPResult.err(error.localizedDescription))\n  }\n\n  let data = d!\n  let response = r!\n\n  let dataString = String(data: data, encoding: .utf8) ?? \"\"\n  if let httpResponse = response as? HTTPURLResponse {\n    if (200 ... 299).contains(httpResponse.statusCode) {\n      if let text = bodyShouldContain {\n        if dataString.contains(text) {\n          log.debug(\"detecting http liveness: success)\")\n          return (true, HTTPResult.http(code: httpResponse.statusCode, html: dataString))\n        } else {\n          let trunc = dataString.prefix(100)\n          log.debug(\"detecting http liveness: failed, Unexpected response body: \\(trunc)\")\n          return (false, HTTPResult.http(code: httpResponse.statusCode, html: dataString))\n        }\n      } else {\n        log.debug(\"detecting http liveness: success)\")\n        return (true, HTTPResult.http(code: httpResponse.statusCode, html: dataString))\n      }\n    } else {\n      log.debug(\"detecting http liveness: failed, Request failed with status code: \\(httpResponse.statusCode)\")\n      return (false, HTTPResult.http(code: httpResponse.statusCode, html: dataString))\n    }\n  }\n  return (false, HTTPResult.err(\"response is not of type HTTPURLResponse, data: \\(dataString)\"))\n}\n"
  },
  {
    "path": "approf/Process/CommandGenerate.swift",
    "content": "import Foundation\n\nextension CommandLine {\n  enum CommandArg: Equatable {\n    case string(String), url(URL), filePath(String), newLine\n  }\n\n  static func commandPreview(_ presentation: PProfPresentation, _ filePaths: [String]) -> [CommandArg] {\n    var args = commandArgs(presentation, filePaths)\n    args.insert(.string(\"go tool pprof\"), at: 0)\n    return args\n  }\n\n  static func commandPreview(_ presentation: PProfPresentation, _ urls: [URL]) -> [CommandArg] {\n    let filePahts = urls.map { $0.path(percentEncoded: false) }\n    var args = commandArgs(presentation, filePahts)\n    args.insert(.string(\"go tool pprof\"), at: 0)\n    return args\n  }\n\n  static func commandArgs(_ presentation: PProfPresentation, _ urls: [URL]) -> [CommandArg] {\n    let filePahts = urls.map { $0.path(percentEncoded: false) }\n    return commandArgs(presentation, filePahts)\n  }\n\n  static func commandArgs(_ presentation: PProfPresentation, _ filePaths: [String]) -> [CommandArg] {\n    var preview: [CommandArg] = []\n    preview.append(.string(\"-http=:\"))\n    preview.append(.string(\"-no_browser\"))\n    switch presentation {\n    case .dft:\n      preview.append(.filePath(filePaths.first ?? \"\"))\n    case .acc:\n      preview.append(.newLine)\n      for fp in filePaths {\n        preview.append(.filePath(fp))\n        preview.append(.newLine)\n      }\n      if case .newLine = preview.last {\n        preview.removeLast()\n      }\n    case .diff:\n      preview.append(.string(\"-diff_base\"))\n      preview.append(.newLine)\n      for fp in filePaths {\n        preview.append(.filePath(fp))\n        preview.append(.newLine)\n      }\n      if case .newLine = preview.last {\n        preview.removeLast()\n      }\n    }\n    return preview\n  }\n}\n\nextension [CommandLine.CommandArg] {\n  func asProcessArgs() -> [String] {\n    var args: [String] = []\n    for arg in self {\n      switch arg {\n      case let .string(a), let .filePath(a):\n        args.append(a)\n      case let .url(a):\n        args.append(a.path(percentEncoded: false))\n      case .newLine:\n        continue\n      }\n    }\n    return args\n  }\n\n  func asCopiable() -> String {\n    return self.map { arg in\n      switch arg {\n      case let .string(a):\n        a.trimmingCharacters(in: .whitespacesAndNewlines)\n      case let .url(a):\n        a.path(percentEncoded: false).replacingOccurrences(of: \" \", with: \"\\\\ \")\n      case let .filePath(a):\n        a.trimmingCharacters(in: .whitespacesAndNewlines).replacingOccurrences(of: \" \", with: \"\\\\ \")\n      case .newLine:\n        \"\\\\\\n\"\n      }\n    }.joined(separator: \" \")\n  }\n\n  func asPrintable() -> String {\n    return self.map { arg in\n      switch arg {\n      case let .string(a):\n        a.trimmingCharacters(in: .whitespacesAndNewlines)\n      case let .url(a):\n        a.path(percentEncoded: false)\n      case let .filePath(a):\n        a.trimmingCharacters(in: .whitespacesAndNewlines)\n      case .newLine:\n        \"\\\\\\n\"\n      }\n    }.joined(separator: \" \").forceCharWrapping\n  }\n}\n"
  },
  {
    "path": "approf/Process/README.md",
    "content": "* pprof: /opt/homebrew/Cellar/go/1.22.4/libexec/pkg/tool/darwin_arm64/pprof\n"
  },
  {
    "path": "approf/Process/Whatever.swift",
    "content": "import Foundation\n\nfunc dotExist(_ dirPath: String) -> (String, Bool) {\n  let dotFilePath = URL(fileURLWithPath: dirPath).appending(component: \"dot\").path(percentEncoded: false)\n  return (dotFilePath, FileManager.default.fileExists(atPath: dotFilePath))\n}\n"
  },
  {
    "path": "approf/State/AppStorage.swift",
    "content": "import SwiftUI\n\nclass AppStorageManager: ObservableObject {\n  static var shared = AppStorageManager()\n  // Appearance\n  @AppStorage(\"colorScheme\") var colorScheme = AppColorScheme.dark\n  @AppStorage(\"lightsOn\") var lightsOn = true\n  @AppStorage(\"materialType\") var materialType = MaterialType.ultraThin\n\n  // Function\n  @AppStorage(\"graphvizBinDir\") var graphvizBinDir = \"/opt/homebrew/bin\"\n\n  @AppStorage(\"selectedSettingsTab\")\n  var selectedSettingsTab = SettingsTab.appearance\n}\n\nenum AppColorScheme: String, CaseIterable, Codable {\n  case automatic = \"Automatic\"\n  case light = \"Light\"\n  case dark = \"Dark\"\n}\n\nextension AppStorageManager {\n  var computedColorScheme: ColorScheme? {\n    switch colorScheme {\n    case .light:\n      return ColorScheme.light\n    case .dark:\n      return ColorScheme.dark\n    case .automatic:\n      return nil\n    }\n  }\n}\n\nenum MaterialType: String, CaseIterable, Codable {\n  case ultraThin = \"UltraThin\", thin = \"Thin\", regular = \"Regular\", thick = \"Thick\", ultraThick = \"UltraThick\", bar = \"Bar\"\n\n  var actualMaterial: Material {\n    switch self {\n    case .regular:\n      return Material.regular\n    case .thick:\n      return Material.thick\n    case .thin:\n      return Material.thin\n    case .ultraThin:\n      return Material.ultraThin\n    case .ultraThick:\n      return Material.ultraThick\n    case .bar:\n      return Material.bar\n    }\n  }\n}\n"
  },
  {
    "path": "approf/State/State.swift",
    "content": "import Foundation\n\n@Observable\nclass UIState {\n  static var shared = UIState()\n  private init() {}\n\n  var mouseInsideWindow = true\n}\n"
  },
  {
    "path": "approf/State/WKState.swift",
    "content": "import Foundation\n\n@Observable\nclass WKState {\n  var url: URL?\n  var loading = false\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Color+Luminance.swift",
    "content": "import SwiftUI\n\nextension Color {\n    func luminance() -> Double {\n        // Convert SwiftUI Color to CGColor\n        guard let cgColor = self.cgColor else {\n            return 0.0 // Default luminance if conversion fails\n        }\n\n        // Extract RGB values\n        let components = cgColor.components\n        let red = components?[0] ?? 0.0\n        let green = components?[1] ?? 0.0\n        let blue = components?[2] ?? 0.0\n        \n        // Compute luminance.\n        return 0.2126 * Double(red) + 0.7152 * Double(green) + 0.0722 * Double(blue)\n    }\n    \n    func isLight() -> Bool {\n        return luminance() > 0.5\n    }\n    \n    func adaptedTextColor() -> Color {\n        return isLight() ? Color.black : Color.white\n    }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Color.swift",
    "content": "import SwiftUI\n\nstruct AdaptiveForegroundColorModifier: ViewModifier {\n    var lightModeColor: Color\n    var darkModeColor: Color\n    \n    @Environment(\\.colorScheme) private var colorScheme\n    \n    func body(content: Content) -> some View {\n        content.foregroundStyle(resolvedColor)\n    }\n    \n    private var resolvedColor: Color {\n        switch colorScheme {\n        case .light:\n            return lightModeColor\n        case .dark:\n            return darkModeColor\n        @unknown default:\n            return lightModeColor\n        }\n    }\n}\n\nextension View {\n//    func foregroundColor(\n//        light lightModeColor: Color,\n//        dark darkModeColor: Color\n//    ) -> some View {\n//        modifier(AdaptiveForegroundColorModifier(\n//            lightModeColor: lightModeColor,\n//            darkModeColor: darkModeColor\n//        ))\n//    }\n}\n\n\nstruct AdaptiveBackgroundColorModifier: ViewModifier {\n    var lightModeColor: Color\n    var darkModeColor: Color\n    \n    @Environment(\\.colorScheme) private var colorScheme\n    \n    func body(content: Content) -> some View {\n      content.backgroundStyle(resolvedColor)\n    }\n    \n    private var resolvedColor: Color {\n        switch colorScheme {\n        case .light:\n            return lightModeColor\n        case .dark:\n            return darkModeColor\n        @unknown default:\n            return lightModeColor\n        }\n    }\n}\n\nextension View {\n    func backgroundColor(\n        light lightModeColor: Color,\n        dark darkModeColor: Color\n    ) -> some View {\n        modifier(AdaptiveBackgroundColorModifier(\n            lightModeColor: lightModeColor,\n            darkModeColor: darkModeColor\n        ))\n    }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Date.swift",
    "content": "// Created for approf in 2024\n\nimport Foundation\n\nextension Date {\n  func isToday() -> Bool {\n    return Calendar.current.isDateInToday(self)\n  }\n\n  func isYesterday() -> Bool {\n    return Calendar.current.isDateInYesterday(self)\n  }\n\n  func humanReadable(_ includeTime: Bool = true) -> String {\n    var text = \"\"\n    if isToday() {\n      text = \"Today\"\n    } else if isYesterday() {\n      text = \"Yesterday\"\n    } else {\n      text = formatted(date: .abbreviated, time: .omitted)\n    }\n\n    if includeTime {\n      return text + \" \" + formatted(date: .omitted, time: .shortened)\n    }\n    return text\n  }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Delay.swift",
    "content": "import SwiftUI\n\npublic extension View {\n  func onAppear(delay: Duration, action: @escaping () -> Void) -> some View {\n    task {\n      do {\n        try await Task.sleep(for: delay)\n      } catch { // Task canceled\n        return\n      }\n\n      await MainActor.run {\n        action()\n      }\n    }\n  }\n\n  func task(delay: Duration, action: @escaping () -> Void) -> some View {\n    task {\n      do {\n        try await Task.sleep(for: delay)\n      } catch { // Task canceled\n        return\n      }\n\n      await MainActor.run {\n        action()\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/File.swift",
    "content": "import SwiftUI\nimport UniformTypeIdentifiers\n\nfunc selectFolder(_ filePath: String?) -> String? {\n  let panel = NSOpenPanel()\n  if let filePath = filePath {\n    panel.directoryURL = URL(filePath: filePath)\n  }\n  panel.allowedContentTypes = [.folder]\n\n  panel.canChooseFiles = false\n  panel.canChooseDirectories = true\n  panel.allowsMultipleSelection = false\n\n  if panel.runModal() == .OK {\n    return panel.url?.path\n  }\n  return nil\n}\n\nfunc selectMultiFiles(_ filePath: String? = nil, utTypes: [UTType]? = nil) -> [URL] {\n  let panel = NSOpenPanel()\n  if let filePath = filePath {\n    panel.directoryURL = URL(filePath: filePath)\n  }\n  if let utTypes = utTypes {\n    panel.allowedContentTypes = utTypes\n  }\n\n  panel.canChooseFiles = true\n  panel.allowsMultipleSelection = true\n  panel.canChooseDirectories = false\n\n  if panel.runModal() == .OK {\n    return panel.urls\n  }\n  return []\n}\n\nextension URL {\n  // doesn't encode; remove last '/'\n  var nicePath: String {\n    let path = self.path(percentEncoded: false)\n    if path.hasSuffix(\"/\") {\n      return String(path.dropLast())\n    } else {\n      return path\n    }\n  }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Hover.swift",
    "content": "import Combine\nimport Foundation\nimport SwiftUI\n\nstruct DelayedHoverModifier: ViewModifier {\n  let delay: Double\n  @State private var hovering = false\n  @State private var timerSubscription: AnyCancellable?\n\n  let onHoverAction: (Bool) -> Void\n\n  func body(content: Content) -> some View {\n    content\n      .onHover { isHovering in\n        if isHovering {\n          startTimer()\n        } else {\n          stopTimer()\n          onHoverAction(false)\n        }\n      }\n  }\n\n  private func startTimer() {\n    timerSubscription = Timer.publish(every: delay, on: .main, in: .common).autoconnect().sink { _ in\n      hovering = true\n      onHoverAction(true)\n      stopTimer()\n    }\n  }\n\n  private func stopTimer() {\n    timerSubscription?.cancel()\n    timerSubscription = nil\n  }\n}\n\nextension View {\n  func delayedHover(_ delay: Double = 1, perform action: @escaping (Bool) -> Void) -> some View {\n    modifier(DelayedHoverModifier(delay: delay, onHoverAction: action))\n  }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Image.swift",
    "content": "import SwiftUI\nimport AppKit\n\nstruct RotatingSF: View {\n  let systemName: String\n  let speed: Double\n  @State var degreesRotating = 0.0\n\n  init(_ systemName: String, _ speed: Double = 4.0) {\n    self.systemName = systemName\n    self.speed = speed\n  }\n  \n  var body: some View {\n    Image(systemName: systemName)\n      .rotationEffect(.degrees(degreesRotating))\n      .onAppear {\n        degreesRotating = 0.0\n        Task { @MainActor in\n          withAnimation(.linear(duration: speed).speed(speed).repeatForever(autoreverses: false)) {\n            degreesRotating = 360.0\n          }\n        }\n      }\n  }\n}\n\n\nextension NSImage {\n    \n    /**\n     Resizes the image to the given size.\n     */\n    func resize(withSize targetSize: NSSize) -> NSImage {\n        let newImage = NSImage(size: targetSize)\n        newImage.lockFocus()\n        draw(in: CGRect(origin: .zero, size: targetSize), from: CGRect(origin: .zero, size: size), operation: .sourceOver, fraction: 1.0)\n        newImage.unlockFocus()\n        return newImage\n    }\n    \n    /**\n     Resizes the image to the given size maintaining its original aspect ratio.\n     */\n    func resizeMaintainingAspectRatio(withSize targetSize: NSSize) -> NSImage {\n        let newSize: NSSize\n        let widthRatio = targetSize.width / size.width\n        let heightRatio = targetSize.height / size.height\n        if(widthRatio > heightRatio) {\n            newSize = NSSize(width: floor(size.width * widthRatio), height: floor(size.height * widthRatio))\n        } else {\n            newSize = NSSize(width: floor(size.width * heightRatio), height: floor(size.height * heightRatio))\n        }\n        return resize(withSize: newSize)\n    }\n\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Other.swift",
    "content": "import SwiftUI\n\nextension View {\n  @ViewBuilder func onWidthChange(_ action: @escaping (CGFloat) -> Void) -> some View {\n    self\n      .background(\n        GeometryReader { reader in\n          Color.clear\n            .onChange(of: reader.frame(in: .global).width) { _, newValue in\n              action(newValue)\n            }\n        }\n      )\n  }\n}\n\nextension View {\n  static func printChagesWhenDebug() {\n    #if DEBUG\n    _printChanges()\n    #endif\n  }\n}\n\nextension View {\n  @ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {\n    if condition {\n      transform(self)\n    } else {\n      self\n    }\n  }\n}\n\nextension View {\n  @ViewBuilder func apply<Content: View>(transform: (Self) -> Content) -> some View {\n    transform(self)\n  }\n}\n\nfunc showInFinder(_ path: String) {\n  let url = URL(fileURLWithPath: path)\n  if url.isFileURL {\n    NSWorkspace.shared.activateFileViewerSelecting([url])\n  }\n}\n\nfunc showInFinder(_ url: URL) {\n  if url.isFileURL {\n    NSWorkspace.shared.activateFileViewerSelecting([url])\n  }\n}\n\n\npublic extension View {\n    @inlinable\n    func reverseMask<Mask: View>(\n        alignment: Alignment = .center,\n        @ViewBuilder _ mask: () -> Mask\n    ) -> some View {\n        self.mask {\n            Rectangle()\n                .overlay(alignment: alignment) {\n                    mask()\n                        .blendMode(.destinationOut)\n                }\n        }\n    }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Shortcuts.swift",
    "content": "import SwiftUI\n\nextension View {\n  /// Add a shortcut to an hidden button\n  func sc(_ key: KeyEquivalent, modifiers: EventModifiers = .command, action: @escaping () -> Void) -> some View {\n    overlay {\n      Button(\"\") {\n        action()\n      }\n      .buttonStyle(.plain)\n      .allowsHitTesting(false)\n      .hidden()\n      .keyboardShortcut(key, modifiers: modifiers)\n    }\n  }\n\n  /// Sometimes, the hidden view doesn’t get created. Use an ID to fix this.\n  func addHiddenView<ID>(_ id: ID, @ViewBuilder content: () -> some View) -> some View where ID: Hashable {\n    self.background { content().frame(width: 1, height: 1).opacity(0).allowsTightening(false).id(id) }\n  }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Toolbar.swift",
    "content": "import SwiftUI\n\nstruct SidebarButton: View {\n  var body: some View {\n    Button(action: toggleSidebar, label: {\n      Image(systemName: \"sidebar.leading\")\n    })\n  }\n\n  private func toggleSidebar() {\n    NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)\n  }\n}\n"
  },
  {
    "path": "approf/SwiftUI AppKit/Tooltip.swift",
    "content": "import Combine\nimport SwiftUI\n\nstruct TooltipModifier<TooltipContent: View>: ViewModifier {\n  let delay: Double\n  let arrowEdge: Edge\n  @ViewBuilder let tooltipContent: () -> TooltipContent\n\n  @State private var hovering = false\n  @State private var timerSubscription: AnyCancellable?\n  @State private var isPresented = false\n\n  func body(content: Content) -> some View {\n    content\n      .onHover { isHovering in\n        if isHovering {\n          startTimer()\n        } else {\n          stopTimer()\n          isPresented = false\n        }\n      }\n      .popover(isPresented: $isPresented, arrowEdge: arrowEdge) {\n        tooltipContent()\n      }\n  }\n\n  private func startTimer() {\n    timerSubscription = Timer.publish(every: delay, on: .main, in: .common).autoconnect().sink { _ in\n      isPresented = true\n      stopTimer()\n    }\n  }\n\n  private func stopTimer() {\n    timerSubscription?.cancel()\n    timerSubscription = nil\n  }\n}\n\nextension View {\n  func tooltip<T: View>(delay: Double = 1, arrowEdge: Edge = .top, @ViewBuilder content: @escaping () -> T) -> some View {\n    modifier(TooltipModifier(delay: delay, arrowEdge: arrowEdge, tooltipContent: content))\n  }\n}\n"
  },
  {
    "path": "approf/Types/Others.swift",
    "content": "import UniformTypeIdentifiers\n\nlet allowedImportFileTypes = [\n  UTType.data\n]\n\nenum PProfError: Error {\n  case ordinay(String)\n}\n\nstruct TerminalRecord: Equatable {\n  let date: Date\n  let std: Std\n  let text: String\n\n  enum Std {\n    case out, err\n  }\n}\n\nstruct TrakcingProcess: Identifiable, Equatable {\n  var process: Process\n  var id: Int32 {\n    process.processIdentifier\n  }\n}\n"
  },
  {
    "path": "approf/Types/PProfBasic.swift",
    "content": "import Foundation\n\nstruct PProfBasic: Equatable, Identifiable, Codable {\n  var id: UUID\n  var name: String\n  var filePaths: [String]\n  var createdAt: Date\n  var presentation: PProfPresentation\n  var httpDetectLog: [HTTPResult]\n  var terminalOutput: [TerminalRecord]\n  var finalCommandArgs: [CommandLine.CommandArg]\n\n  init(uuid: UUID, filePaths: [String], createdAt: Date, presentation: PProfPresentation = .dft, httpDetectLog: [HTTPResult] = [], terminalOutput: [TerminalRecord] = [], finalCommandArgs: [CommandLine.CommandArg] = []) {\n    self.id = uuid\n    self.name = \"\"\n    self.filePaths = filePaths\n    self.createdAt = createdAt\n    self.presentation = presentation\n    self.httpDetectLog = httpDetectLog\n    self.terminalOutput = terminalOutput\n    self.finalCommandArgs = finalCommandArgs\n  }\n\n  init(uuid: UUID, urls: [URL], createdAt: Date, presentation: PProfPresentation = .dft) {\n    let filePaths = urls.map { $0.path(percentEncoded: false) }\n    self.init(uuid: uuid, filePaths: filePaths, createdAt: createdAt, presentation: presentation)\n  }\n\n  // Custom encoding\n  func encode(to encoder: Encoder) throws {\n    var container = encoder.container(keyedBy: CodingKeys.self)\n    try container.encode(self.id, forKey: .id)\n    try container.encode(self.name, forKey: .name)\n    try container.encode(self.name, forKey: .name)\n    try container.encode(self.filePaths, forKey: .filePaths)\n    try container.encode(self.createdAt, forKey: .createdAt)\n    try container.encode(self.presentation, forKey: .presentation)\n  }\n\n  // Custom decoding\n  init(from decoder: Decoder) throws {\n    let container = try decoder.container(keyedBy: CodingKeys.self)\n    self.id = try container.decode(UUID.self, forKey: .id)\n    self.name = try container.decodeIfPresent(String.self, forKey: .name) ?? \"\"\n    self.filePaths = try container.decode([String].self, forKey: .filePaths)\n    self.createdAt = try container.decode(Date.self, forKey: .createdAt)\n    self.presentation = try container.decode(PProfPresentation.self, forKey: .presentation)\n    self.httpDetectLog = []\n    self.terminalOutput = []\n    self.finalCommandArgs = []\n  }\n\n  // Define coding keys\n  enum CodingKeys: String, CodingKey {\n    case id\n    case name\n    case filePaths\n    case createdAt\n    case presentation\n  }\n}\n\nextension PProfBasic {\n  static let mock = PProfBasic(\n    uuid: UUID(),\n    filePaths: [\"/Users/mark/projects/mark/pprof\"],\n    createdAt: Date(),\n    httpDetectLog: [\n      HTTPResult.http(code: 200, html: \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF - 8\\\"?>\"),\n      HTTPResult.http(code: 403, html: \"<!DOCTYPE plist PUBLIC \\\"-//Apple//DTD PLIST 1.0//EN\\\" \\\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\\">\"),\n    ],\n    terminalOutput: [\n      .init(date: Date.now, std: .err, text: \"remote: Enumerating objects: 216520, done.\"),\n      .init(date: Date.now, std: .out, text: \"Resolving deltas: 100% (195133/195133), done..\"),\n    ],\n    finalCommandArgs: [.string(\"pprof\"), .string(\"-http=:\"), .filePath(\"/Users/mark/projects/mark/pprof\")]\n  )\n}\n\nextension PProfBasic {\n  var computedName: String {\n    if !self.name.isEmpty {\n      return self.name\n    }\n\n    guard let firstFile = self.filePaths.first else {\n      return \"No file\"\n    }\n\n    guard let firstFileName = firstFile.asUrl?.lastPathComponent else {\n      return \"No file\"\n    }\n    return firstFileName\n  }\n\n  func equalsSnapshot(_ snapshot: Self) -> Bool {\n    snapshot.filePaths == self.filePaths && snapshot.presentation == self.presentation\n  }\n}\n\nextension PProfBasic {\n  func commandArgs() -> [CommandLine.CommandArg] {\n    CommandLine.commandArgs(self.presentation, self.filePaths)\n  }\n\n  func commandPreview() -> [CommandLine.CommandArg] {\n    CommandLine.commandPreview(self.presentation, self.filePaths)\n  }\n}\n"
  },
  {
    "path": "approf/Types/PProfPresentation.swift",
    "content": "enum PProfPresentation: String, Codable, CaseIterable {\n  case dft = \"Isolated\", acc = \"Accumulate\", diff = \"Diff\"\n\n  var explanation: String {\n    switch self {\n    case .dft:\n      \"Run `go tool pprof` on each file separately\"\n    case .acc:\n      \"Run `go tool pprof` on all files at once\"\n    case .diff:\n      \"Run `go tool pprof` on all files at once, comparing them to the base\"\n    }\n  }\n\n  var next: PProfPresentation {\n    var nextIndex = Self.allCases.firstIndex(of: self)! + 1\n    if nextIndex == Self.allCases.count {\n      nextIndex = 0\n    }\n    return Self(rawValue: Self.allCases[nextIndex].rawValue)!\n  }\n\n  var prev: PProfPresentation {\n    var nextIndex = Self.allCases.firstIndex(of: self)! - 1\n    if nextIndex < 0 {\n      nextIndex = Self.allCases.count - 1\n    }\n    return Self(rawValue: Self.allCases[nextIndex].rawValue)!\n  }\n}\n"
  },
  {
    "path": "approf/View/AboutView.swift",
    "content": "import SwiftUI\n\nstruct AboutView: View {\n  var body: some View {\n    HStack(spacing: 50) {\n      Image(\"About\")\n        .resizable()\n        .scaledToFit()\n      VStack(alignment: .leading) {\n        VStack(alignment: .leading){\n          Text(\"approf\")\n            .font(.system(size: 40))\n            .fontWeight(.semibold)\n          Spacer().frame(height: 5)\n          Text(\"Version \\(getAppVersion())\")\n            .font(.headline)\n            .fontWeight(.regular)\n        }\n        .offset(y: -15)\n\n        Spacer()\n        Text(\"Copyright © 2024 https://github.com/moderato-app/approf\")\n          .font(.footnote)\n      }\n      .padding(.bottom, 5)\n    }\n    .frame(height: 100)\n    .padding(40)\n  }\n}\n\n#Preview {\n  AboutView()\n}\n"
  },
  {
    "path": "approf/View/AppFeature.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\n@Reducer\nstruct AppFeature {\n  @ObservableState\n  struct State: Equatable {\n    var synced = false // whether pprofs is synced with basics\n    @Shared(.approf) var basics: IdentifiedArrayOf<PProfBasic> = .init(uniqueElements: [])\n    var pprofs: IdentifiedArrayOf<DetailFeature.State> = .init()\n    var pprofsSelectedId: UUID?\n\n    var drop: DropAndImportFeature.State = .init()\n  }\n\n  enum Action {\n    case onAppear\n    case onPprofsSelectedIdChanged(UUID?)\n    case onAppTermination\n    case deleteButtonTapped(UUID)\n    case onDeleteCommand\n    case onCloseTabCommand\n    case onMove(from: IndexSet, to: Int)\n    case onMoveUpCommand\n    case onMoveDownCommand\n\n    case deleteNow(UUID)\n    case pprofs(IdentifiedActionOf<DetailFeature>)\n\n    case drop(DropAndImportFeature.Action)\n  }\n\n  @Dependency(\\.uuid) var uuid\n  @Dependency(\\.continuousClock) var clock\n\n  var body: some ReducerOf<Self> {\n    Scope(state: \\.drop, action: \\.drop) {\n      DropAndImportFeature()\n    }\n\n    Reduce { state, action in\n      switch action {\n      case .onAppear:\n        self.sync(&state)\n        return .none\n      case let .onPprofsSelectedIdChanged(uuidOpt):\n        state.pprofsSelectedId = uuidOpt\n        return .none\n      case let .deleteButtonTapped(id):\n        if let pprof = state.pprofs.first(where: { $0.id == id }) {\n          state.basics.removeAll(where: { $0.id == pprof.basic.id })\n          switch pprof.period {\n          case let .launching(la):\n            if let process = la.process {\n              if process.isRunning {\n                process.terminate()\n              }\n            }\n          case let .success(su):\n            if su.process.isRunning {\n              su.process.terminate()\n            }\n          default:\n            let _ = 1\n          }\n          return .run { send in\n            await send(.pprofs(.element(id: pprof.id, action: .period(.launching(.stop)))))\n            await send(.pprofs(.element(id: pprof.id, action: .period(.success(.stop)))))\n            await send(.deleteNow(id))\n          }\n        }\n        log.warning(\"onDeleteTapped: pprof does not exist, id: \\(id)\")\n        return .none\n      case .onDeleteCommand:\n        if let id = state.pprofsSelectedId {\n          return .send(.deleteButtonTapped(id))\n        }\n        return .none\n      case let .deleteNow(id):\n        delete(&state, id)\n        return .none\n      case .onAppTermination:\n        terminateAllProcesses(state: &state)\n        return .none\n      case .onCloseTabCommand:\n        state.pprofsSelectedId = nil\n        return .none\n      case let .onMove(from, to):\n        move(&state, from, to)\n        return .none\n      case .onMoveUpCommand:\n        if let pprofsSelectedId = state.pprofsSelectedId {\n          moveUp(&state, pprofsSelectedId)\n        }\n        return .none\n      case .onMoveDownCommand:\n        if let pprofsSelectedId = state.pprofsSelectedId {\n          moveDown(&state, pprofsSelectedId)\n        }\n        return .none\n      case let .pprofs(.element(id: id, action: .delegate(.onPprofsSelectedIdChanged))):\n        state.pprofsSelectedId = id\n        return .none\n      case .pprofs:\n        return .none\n      case let .drop(.delegate(.addNewBasic(basic))):\n        self.addNewBasics(&state, [basic])\n        return .run { send in\n          try await clock.sleep(for: .seconds(0.2))\n          await send(.onPprofsSelectedIdChanged(basic.id))\n        }\n      case let .drop(.delegate(.addNewBasics(basics))):\n        self.addNewBasics(&state, basics)\n        if let first = basics.first {\n          return .run { send in\n            try await clock.sleep(for: .seconds(0.2))\n            await send(.onPprofsSelectedIdChanged(first.id))\n          }\n        }\n        return .none\n      case let .drop(.delegate(.selectPProf(uuid))):\n        if state.pprofs.contains(where: { $0.id == uuid }) {\n          state.pprofsSelectedId = uuid\n        }\n        return .none\n      case .drop:\n        return .none\n      }\n    }\n    .forEach(\\.pprofs, action: \\.pprofs) {\n      DetailFeature()\n    }\n  }\n\n  func addNewBasics(_ state: inout Self.State, _ basics: [PProfBasic]) {\n    state.basics.insert(contentsOf: basics, at: 0)\n    state.synced = false\n    sync(&state)\n  }\n\n  func sync(_ state: inout Self.State) {\n    if !state.synced {\n      var result: IdentifiedArrayOf<DetailFeature.State> = .init()\n      for basic in state.$basics.elements {\n        if let pprof = state.pprofs.first(where: { $0.id == basic.id }) {\n          result.append(pprof)\n        } else {\n          let pprof = DetailFeature.State(basic: basic, period: .idle(.init()))\n          result.append(pprof)\n        }\n      }\n      state.pprofs = result\n      state.synced = true\n    }\n  }\n\n  func terminateAllProcesses(state: inout Self.State) {\n    for pprof in state.pprofs {\n      if case let .launching(l) = pprof.period, let process = l.process, process.isRunning {\n        let pid = process.processIdentifier\n        log.info(\"terminating process [pid=\\(pid)]\")\n        process.terminate()\n      } else if case let .success(s) = pprof.period, s.process.isRunning {\n        let pid = s.process.processIdentifier\n        log.info(\"terminating process [pid=\\(pid)]\")\n        s.process.terminate()\n      }\n    }\n  }\n\n  /// Remove an element and update the selection accordingly\n  private func delete(_ state: inout Self.State, _ id: UUID) {\n    // Remember the selection index before deleting an element\n    var originalIndex: Int?\n    if let selection = state.pprofsSelectedId {\n      originalIndex = state.pprofs.firstIndex { $0.id == selection }\n    }\n\n    state.pprofs.removeAll { $0.id == id }\n\n    if let selection = state.pprofsSelectedId {\n      // If the selected element is deleted\n      if !state.pprofs.contains(where: { $0.id == selection }), let originalIndex = originalIndex {\n        if originalIndex < state.pprofs.count {\n          // If there were elements after it, select the next one\n          state.pprofsSelectedId = state.pprofs[originalIndex].id\n        } else {\n          // Otherwise(selection was the last element), select the last element in the list\n          state.pprofsSelectedId = state.pprofs.last?.id\n        }\n      }\n    }\n  }\n\n  private func move(_ state: inout Self.State, _ source: IndexSet, _ destination: Int) {\n    state.pprofs.move(fromOffsets: source, toOffset: destination)\n  }\n\n  private func moveUp(_ state: inout Self.State, _ pprofsSelectedId: UUID) {\n    guard let index = state.pprofs.firstIndex(where: { $0.id == pprofsSelectedId }) else {\n      return\n    }\n    if index - 1 >= 0 {\n      state.pprofs.move(fromOffsets: IndexSet([index]), toOffset: index - 1)\n    }\n  }\n\n  private func moveDown(_ state: inout Self.State, _ pprofsSelectedId: UUID) {\n    guard let index = state.pprofs.firstIndex(where: { $0.id == pprofsSelectedId }) else {\n      return\n    }\n    if index + 2 <= state.pprofs.count {\n      state.pprofs.move(fromOffsets: IndexSet([index]), toOffset: index + 2)\n    }\n  }\n}\n\nextension PersistenceReaderKey\n  where Self == PersistenceKeyDefault<FileStorageKey<IdentifiedArrayOf<PProfBasic>>>\n{\n  static var approf: Self {\n    PersistenceKeyDefault(\n      .fileStorage(.homeDirectory.appending(component: \".approf.json\")),\n      []\n    )\n  }\n}\n"
  },
  {
    "path": "approf/View/DetailFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\nimport WebKit\n\n@Reducer\nstruct DetailFeature {\n  @ObservableState\n  struct State: Equatable, Identifiable {\n    var id: UUID\n    @Shared var basic: PProfBasic\n    var period: PProfPeriod.State\n    var subViewType: DetailSubViewType\n    var uth: UnderTheHood.State\n\n    var showGoToWEB = false\n\n    init(basic: Shared<PProfBasic>, period: PProfPeriod.State) {\n      self.id = basic.id\n      _basic = basic\n      self.period = period\n      self.subViewType = .underTheHood\n      self.uth = UnderTheHood.State(basic: basic)\n    }\n  }\n\n  enum Action {\n    case period(PProfPeriod.Action)\n    case uth(UnderTheHood.Action)\n    case onAppear\n    case onSwitchViewChanged(DetailSubViewType)\n    case onStartButtonTapped\n\n    case launchButtonTapped\n    case relaunchButtonTapped\n    case stopButtonTapped\n    case goToWEBButtonTapped\n\n    case onLaunch\n\n    case delegate(Delegate)\n\n    @CasePathable\n    enum Delegate: Equatable {\n      case onPprofsSelectedIdChanged\n    }\n  }\n\n  @Dependency(\\.continuousClock) var clock\n\n  var body: some ReducerOf<Self> {\n    Scope(state: \\.uth, action: \\.uth) {\n      UnderTheHood()\n    }\n\n    Reduce { state, action in\n      switch action {\n      case .delegate, .onAppear:\n        return .none\n      case .onStartButtonTapped:\n        switch state.period {\n        case .idle, .terminated:\n          state.period = .launching(LaunchingFeature.State(basic: state.$basic, goToWebOnSuccess: true))\n          return .merge(\n            .send(.period(.launching(.start))),\n            .send(.delegate(.onPprofsSelectedIdChanged))\n          )\n        default:\n          return .none\n        }\n      case let .onSwitchViewChanged(t):\n        state.subViewType = t\n        state.showGoToWEB = false\n        return .none\n      case .onLaunch,\n           .launchButtonTapped,\n           .period(.failure(.delegate(.launchButtonTapped))),\n           .period(.idle(.delegate(.launchButtonTapped))),\n           .period(.terminated(.delegate(.launchButtonTapped))):\n        self.cleanUp(state: &state)\n        state.period = .launching(LaunchingFeature.State(basic: state.$basic))\n        return .send(.period(.launching(.start)))\n      case .relaunchButtonTapped:\n        return .merge(\n          .send(.period(.launching(.stop))),\n          .send(.onLaunch)\n        )\n      case let .period(.launching(.delegate(.onSuccess(process, portReady, goToWEB)))):\n        let conf = WKWebViewConfiguration()\n        conf.defaultWebpagePreferences.allowsContentJavaScript = true\n        conf.allowsAirPlayForMediaPlayback = false\n        conf.preferences.setValue(true, forKey: \"developerExtrasEnabled\")\n\n        let wk = WKWebView(frame: .zero, configuration: conf)\n        wk.layer?.borderWidth = 0\n        state.period = .success(.init(basic: state.$basic, process: process, port: portReady, wk: wk))\n        if goToWEB {\n          state.subViewType = .graphic\n        } else {\n          state.showGoToWEB = true\n        }\n        return .merge(\n          .run { _ in\n            await wk.load(URLRequest(url: URL(string: \"http://localhost:\\(portReady)\")!))\n          },\n          .run { send in\n            try await self.clock.sleep(for: .seconds(0.3))\n            await send(.period(.success(.onFullyLoaded)), animation: .default)\n          }\n        )\n      case let .period(.launching(.delegate(.onFailed(cause)))):\n        state.period = .failure(.init(basic: state.$basic, cause: cause))\n        return .none\n      case .stopButtonTapped:\n        return .merge(\n          .send(.period(.launching(.stop))),\n          .send(.period(.success(.stop)))\n        )\n      case .goToWEBButtonTapped:\n        state.subViewType = .graphic\n        state.showGoToWEB = false\n        return .none\n      case .period(.launching(.delegate(.onTermimated))),\n           .period(.success(.delegate(.onTermimated))):\n        state.period = .terminated(.init())\n        return .none\n      case .period:\n        return .none\n      case .uth:\n        return .none\n      }\n    }\n    .ifLet(\\.period.idle, action: \\.period.idle) {\n      IdleFeature()\n    }\n    .ifLet(\\.period.terminated, action: \\.period.terminated) {\n      IdleFeature()\n    }\n    .ifLet(\\.period.launching, action: \\.period.launching) {\n      LaunchingFeature()\n    }\n    .ifLet(\\.period.success, action: \\.period.success) {\n      SuccessFeature()\n    }\n    .ifLet(\\.period.failure, action: \\.period.failure) {\n      FailureFeature()\n    }\n  }\n\n  func cleanUp(state: inout Self.State) {\n    state.subViewType = .underTheHood\n    state.basic.terminalOutput = []\n    state.basic.httpDetectLog = []\n    state.basic.finalCommandArgs = []\n  }\n}\n\nextension DetailFeature {\n  @Reducer(state: .equatable)\n  enum PProfPeriod {\n    case idle(IdleFeature)\n    case terminated(IdleFeature)\n    case launching(LaunchingFeature)\n    case failure(FailureFeature)\n    case success(SuccessFeature)\n\n    func isRunning() -> Bool {\n      if case .launching = self {\n        return true\n      } else {\n        return false\n      }\n    }\n  }\n}\n\nextension DetailFeature.State {\n  var isRunning: Bool {\n    if case .success = self.period {\n      return true\n    } else {\n      return false\n    }\n  }\n}\n\nenum DetailSubViewType: String, Codable, CaseIterable {\n  case underTheHood = \"Terminal\", graphic = \"WEB\"\n\n  func switchView() -> Self {\n    switch self {\n    case .underTheHood:\n      .graphic\n    case .graphic:\n      .underTheHood\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/DetailView.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct DetailView: View {\n  @Bindable var store: StoreOf<DetailFeature>\n\n  var body: some View {\n    VStack {\n      if store.subViewType == .graphic, let s = store.scope(state: \\.period.success, action: \\.period.success) {\n        SuccessView(store: s)\n      } else {\n        UnderTheHoodView(store: store.scope(state: \\.uth, action: \\.uth), detailStore: store)\n      }\n    }\n    .padding(.horizontal, 8)\n    .padding(.bottom, 8)\n    .onAppear {\n      store.send(.onAppear)\n    }\n    .toolbar {\n      if case .success = store.period {\n        ToolbarItem(placement: .navigation) {\n          Picker(\"\", selection: $store.subViewType.sending(\\.onSwitchViewChanged)) {\n            ForEach(DetailSubViewType.allCases, id: \\.self) { c in\n              Text(\"\\(c.rawValue)\")\n            }\n          }\n          .pickerStyle(.segmented)\n          .labelsHidden()\n          .background(RoundedRectangle(cornerRadius: 6).fill(.thinMaterial))\n        }\n      }\n    }\n    .animation(.default, value: store.period)\n    .animation(.easeInOut(duration: 0.1), value: store.subViewType)\n  }\n}\n\nstruct StatusView: View {\n  var body: some View {\n    HStack(spacing: 1) {\n      Image(systemName: \"smallcircle.filled.circle\")\n        .symbolRenderingMode(.palette)\n        .foregroundStyle(.green, .clear)\n        .scaleEffect(2)\n        .symbolEffect(.pulse, options: .speed(0.5))\n      Text(\"Running\")\n        .foregroundStyle(.secondary)\n    }\n    .font(.caption)\n    .padding(.horizontal, 3)\n    .padding(.vertical, 1)\n    .background(.ultraThinMaterial)\n    .clipShape(RoundedRectangle(cornerRadius: 7))\n    .padding(.trailing, 4)\n    .padding(.bottom, 2)\n  }\n}\n"
  },
  {
    "path": "approf/View/DetectingHTTPView.swift",
    "content": "import SwiftUI\nimport ComposableArchitecture\n\nstruct DetectingHTTPView: View {\n  @Bindable var store: StoreOf<DetailFeature>\n\n  var body: some View {\n    switch store.period {\n    case .launching:\n      TringHttpView()\n      HttpResultView(basic: store.basic)\n    case .failure:\n      HttpResultView(basic: store.basic)\n    default:\n      EmptyView()\n    }\n  }\n}\n\nstruct TringHttpView: View {\n  var body: some View {\n    HStack {\n      // bug: .rotate effect is not woking on macos 15 beta 3\n      //          if #available(macOS 15.0, *) {\n      //            Image(systemName: \"circle.hexagonpath.fill\")\n      //              .symbolEffect(.rotate)\n      //          }\n      Spacer().frame(width: 5)\n      ProgressView()\n        .scaleEffect(0.5)\n        .frame(width: 5, height: 5)\n      Text(\"Trying HTTP request\")\n        .font(.caption)\n        .foregroundColor(.secondary)\n    }\n  }\n}\n\nstruct HttpResultView: View {\n  let basic: PProfBasic\n\n  var body: some View {\n    if let last = basic.httpDetectLog.last {\n      HStack(alignment: .firstTextBaseline) {\n        Text(\"HTTP result: \").foregroundStyle(.secondary)\n        switch last {\n        case let .err(str):\n          Image(\"circle.fill\").foregroundStyle(.red)\n          Text(str).lineLimit(5)\n        case let .http(code, html):\n          Text(\"\\(code)\").foregroundStyle(code <= 299 && code >= 200 ? .green : .red)\n          Text(html).lineLimit(5)\n        }\n      }\n      .animation(.linear, value: last)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/DragNDrop/DropAndAppendFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\n@Reducer\nstruct DropAndAppendFeature {\n  @ObservableState\n  struct State: Equatable {\n    @Shared var basic: PProfBasic\n  }\n\n  enum Action {\n    case onDropEnds([URL])\n  }\n\n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case let .onDropEnds(urls):\n        let u = urls.map { $0.path(percentEncoded: false) }\n        state.basic.filePaths.append(contentsOf: u)\n        return .none\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/DragNDrop/DropAndAppendView.swift",
    "content": "import Combine\nimport ComposableArchitecture\nimport SwiftUI\nimport UniformTypeIdentifiers\n\nstruct DropAndAppendView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n\n  @State var dropping = false\n\n  var body: some View {\n    Rectangle()\n      .fill(.clear)\n      .allowsHitTesting(false)\n      .onDrop(of: allowedImportFileTypes, delegate: DropFileDelegate(dropping: $dropping) { urls in\n        store.send(.onAddURLs(urls))\n      })\n  }\n}\n"
  },
  {
    "path": "approf/View/DragNDrop/DropAndImportFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\n@Reducer\nstruct DropAndImportFeature {\n  @Reducer(state: .equatable)\n  enum Destination {\n    case uth(UnderTheHood)\n  }\n\n  @ObservableState\n  struct State: Equatable {\n    @Presents var destination: Destination.State?\n  }\n\n  enum Action {\n    case destination(PresentationAction<Destination.Action>)\n    case onDropEnds([URL])\n\n    case delegate(Delegate)\n\n    @CasePathable\n    enum Delegate {\n      case addNewBasic(PProfBasic)\n      case addNewBasics([PProfBasic])\n      case selectPProf(UUID)\n    }\n  }\n\n  @Dependency(\\.continuousClock) var clock\n  @Dependency(\\.uuid) var uuid\n  @Dependency(\\.date) var date\n\n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case .delegate:\n        return .none\n      case let .onDropEnds(urls):\n        let filePaths = urls.map { $0.path(percentEncoded: false) }\n        if filePaths.isEmpty {\n          return .none\n        } else if filePaths.count == 1 {\n          let basic = PProfBasic(uuid: uuid(), filePaths: filePaths, createdAt: date.now, presentation: .dft)\n          return .send(.delegate(.addNewBasic(basic)))\n        } else if filePaths.count == 2 {\n          state.destination = .uth(UnderTheHood.State(basic: Shared(PProfBasic(uuid: uuid(), filePaths: filePaths, createdAt: date.now, presentation: .diff))))\n          return .none\n        } else {\n          state.destination = .uth(UnderTheHood.State(basic: Shared(PProfBasic(uuid: uuid(), filePaths: filePaths, createdAt: date.now, presentation: .acc))))\n          return .none\n        }\n      case .destination(.presented(.uth(.delegate(.onConfirmImportButtonTapped)))):\n        guard case let .uth(uthFeature) = state.destination else {\n          return .none\n        }\n        state.destination = nil\n        // When DropView disappears, the animation for the profs list doesn't work.\n        // To fix this, update the profs list after DropView has fully disappeared.\n        if case .dft = uthFeature.basic.presentation {\n          let basics = uthFeature.basic.filePaths.reversed().map {\n            PProfBasic(uuid: uuid(), filePaths: [$0], createdAt: date.now, presentation: .dft)\n          }\n          return .run { send in\n            try await clock.sleep(for: .seconds(0.25))\n            await send(.delegate(.addNewBasics(basics)))\n          }\n        } else {\n          let basic = PProfBasic(uuid: uuid(), filePaths: uthFeature.basic.filePaths, createdAt: date.now, presentation: uthFeature.basic.presentation)\n          return .run { send in\n            try await clock.sleep(for: .seconds(0.25))\n            await send(.delegate(.addNewBasic(basic)))\n          }\n        }\n      case .destination:\n        return .none\n      }\n    }\n    .ifLet(\\.$destination, action: \\.destination)\n  }\n}\n"
  },
  {
    "path": "approf/View/DragNDrop/DropAndImportView.swift",
    "content": "import Combine\nimport ComposableArchitecture\nimport SwiftUI\nimport UniformTypeIdentifiers\n\nstruct DropAndImportView: View {\n  @Bindable var store: StoreOf<DropAndImportFeature>\n\n  @State var viewSize = CGSize(width: 800, height: 600)\n  @State var dropping = false\n  @State var uiState = UIState.shared\n\n  var body: some View {\n    Rectangle()\n      .fill(.clear)\n      .onGeometryChange(for: CGSize.self) { proxy in\n        proxy.size\n      } action: { viewSize = $0 }\n      .allowsHitTesting(false)\n      .overlay {\n        if dropping && store.destination == nil {\n          GradientBackgroundAnimation()\n        }\n      }\n      .animation(.default, value: dropping)\n      .onDrop(of: allowedImportFileTypes, delegate: DropFileDelegate(dropping: $dropping) { urls in\n        if store.destination == nil{\n          store.send(.onDropEnds(urls))\n        }\n      })\n      .sheet(\n        item: $store.scope(state: \\.destination?.uth, action: \\.destination.uth)\n      ) { importingStore in\n        ImportView(store: importingStore)\n          .padding(20)\n          .frame(width: viewSize.width * 0.7, height: viewSize.height * 0.8)\n          .presentationCornerRadius(20)\n          .presentationBackgroundInteraction(.disabled)\n      }\n  }\n}\n\nclass DropFileDelegate: DropDelegate {\n  @Binding var dropping: Bool\n  let onDropEnds: ([URL]) -> Void\n  let excludeArea: CGRect?\n\n  private var cancellables = Set<AnyCancellable>()\n\n  init(dropping: Binding<Bool>, excludeArea: CGRect? = nil, onDropEnds: @escaping ([URL]) -> Void) {\n    _dropping = dropping\n    self.excludeArea = excludeArea\n    self.onDropEnds = onDropEnds\n  }\n\n  func validateDrop(info: DropInfo) -> Bool {\n    return true\n  }\n\n  func dropEntered(info: DropInfo) {\n    if let excludeArea = excludeArea, excludeArea.contains(info.location) {\n      dropping = false\n    } else {\n      dropping = true\n    }\n  }\n\n  func dropUpdated(info: DropInfo) -> DropProposal? {\n    dropEntered(info: info)\n    return nil\n  }\n\n  func dropExited(info: DropInfo) {\n    dropping = false\n  }\n\n  func performDrop(info: DropInfo) -> Bool {\n    let providers = info.itemProviders(for: allowedImportFileTypes)\n    let futureArray = providers.compactMap { provider in\n      allowedImportFileTypes.compactMap { ptype in\n        if provider.hasItemConformingToTypeIdentifier(ptype.identifier) {\n          return Future<URL?, Never> { promise in\n            _ = provider.loadFileRepresentation(for: ptype, openInPlace: true) { url, _, error in\n              if let error = error {\n                print(\"Error loading file representation: \\(error)\")\n                promise(.success(nil))\n                return\n              }\n              promise(.success(url))\n            }\n          }\n        }\n        return nil\n      }\n    }.flatMap { $0 }\n\n    if futureArray.isEmpty {\n      return true\n    }\n\n    Publishers.MergeMany(futureArray)\n      .collect()\n      .receive(on: DispatchQueue.main)\n      .sink { result in\n        let urls = result.compactMap { $0 } as [URL]\n        log.info(\"imported \\(urls.count) files\")\n        Task { @MainActor in\n          self.onDropEnds(urls)\n        }\n      }\n      .store(in: &cancellables)\n    return true\n  }\n}\n"
  },
  {
    "path": "approf/View/DragNDrop/ImportView.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct ImportView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n\n  var body: some View {\n    VStack(spacing: 20) {\n      FileListView(store: store, importing: true)\n      Spacer()\n      CommandPreviewView(store: store, importing: true)\n    }\n    .background {\n      ShortcutsView(store: store)\n    }\n    .toolbar {\n      toolbar()\n    }\n  }\n\n  @ToolbarContentBuilder\n  private func toolbar() -> some ToolbarContent {\n    ToolbarItem(placement: .destructiveAction) {\n      Button(\"Cancel(ESC)\", role: .cancel) {\n        store.send(.onCancelImportButtonTapped)\n      }\n    }\n    ToolbarItem(placement: .confirmationAction) {\n      Button(\"Done⏎\") {\n        store.send(.delegate(.onConfirmImportButtonTapped))\n      }\n      .keyboardShortcut(.return, modifiers: [])\n    }\n  }\n}\n\nstruct ImportViewV2App: App {\n  var body: some Scene {\n    WindowGroup {\n      ImportView(store: UnderTheHood.mock)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/FailureFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\nextension FailureFeature {\n  enum Cause: Equatable {\n    case file(String)\n    case process(String)\n    case httpDetect(String)\n    case pipeDetect(String)\n  }\n}\n\n@Reducer\nstruct FailureFeature {\n  @ObservableState\n  struct State: Equatable {\n    @Shared var basic: PProfBasic\n    let cause: Cause\n  }\n\n  enum Action {\n    case launchButtonTapped\n    case delegate(Delegate)\n\n    @CasePathable\n    enum Delegate {\n      case launchButtonTapped\n    }\n  }\n\n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case .delegate:\n        .none\n      case .launchButtonTapped:\n        .send(.delegate(.launchButtonTapped))\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/IdleFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\n@Reducer\nstruct IdleFeature {\n  @ObservableState\n  struct State: Equatable {}\n\n  enum Action {\n    case delegate(Delegate)\n\n    @CasePathable\n    enum Delegate: Equatable {\n      case launchButtonTapped\n    }\n  }\n\n  var body: some ReducerOf<Self> {\n    Reduce { _, action in\n      switch action {\n      case .delegate:\n        .none\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/LaunchingFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\n@Reducer\nstruct LaunchingFeature {\n  @ObservableState\n  struct State: Equatable {\n    @Shared var basic: PProfBasic\n    var process: Process?\n    var readingTerminal = false\n    var portReady: UInt16?\n    var detectingHttp = false\n    var httpReady = false\n    \n    var goToWebOnSuccess = false\n  }\n  \n  enum Action {\n    case start\n    case stop\n    case launchingTimeout(Int)\n    case readTerminal(AsyncStream<String>)\n    case portReady(UInt16)\n    case tryHttp(UInt16)\n    case httpReady\n    case fail(FailureFeature.Cause)\n    case terminalUpdated(String)\n    case httpUpdated(HTTPResult)\n    case delegate(Delegate)\n    \n    @CasePathable\n    enum Delegate: Equatable {\n      case onSuccess(Process, UInt16, Bool) // goToWEB: Bool\n      case onFailed(FailureFeature.Cause)\n      case onTermimated\n    }\n  }\n  \n  enum CancelID { case terminalReader, httpDetector }\n  @Dependency(\\.continuousClock) var clock\n  @Dependency(\\.date) var date\n  \n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case .delegate:\n        return .none\n      case .start:\n        if let p = state.process {\n          log.error(\"process already exeists\")\n          return .send(.fail(.process(\"process already exeists. process.processIdentifier: \\(p.processIdentifier)\")))\n        }\n        \n        state.basic.terminalOutput = []\n        state.basic.httpDetectLog = []\n              \n        var processOptional: Process?\n        var streamOptional: AsyncStream<String>?\n        do {\n          let args = state.basic.commandArgs()\n          let (commandArgs, process, terminalStream) = try createPProfProcess(args)\n          state.process = process\n          state.basic.finalCommandArgs = commandArgs\n          processOptional = process\n          streamOptional = terminalStream\n        } catch {\n          return .send(.fail(.process(error.localizedDescription)))\n        }\n        \n        let process = processOptional!\n        let stream = streamOptional!\n        \n        return .run { send in\n          do {\n            try process.run()\n            log.info(\"process.isRunning: \\(process.isRunning), process.processIdentifier.: \\(process.processIdentifier)\")\n            if !process.isRunning {\n              log.error(\"process.terminationStatus: \\(process.terminationStatus), process.terminationReason: \\(process.terminationReason)\")\n            }\n          } catch {\n            return await send(.fail(.process(error.localizedDescription)))\n          }\n          await send(.readTerminal(stream))\n          await send(.launchingTimeout(5))\n        }\n      case .stop:\n        if let process = state.process {\n          if process.isRunning {\n            process.terminate()\n          }\n          state.process = nil\n        }\n        return .send(.delegate(.onTermimated))\n      case let .readTerminal(stream):\n        state.readingTerminal.toggle()\n        if state.readingTerminal {\n          return .run { send in\n            for try await data in stream {\n              log.debug(\"read from stream: \\(data)\")\n              await send(.terminalUpdated(data))\n            }\n            log.debug(\"finished reading from stream\")\n          }\n          .cancellable(id: CancelID.terminalReader)\n        } else {\n          return .cancel(id: CancelID.terminalReader)\n        }\n      case let .portReady(port):\n        state.portReady = port\n        return .send(.tryHttp(port))\n      case let .tryHttp(port):\n        state.detectingHttp.toggle()\n        if state.detectingHttp {\n          let httpAddr = \"http://localhost:\\(port)\"\n          guard let httpUrl = URL(string: httpAddr) else {\n            let e = \"can't make a URL from \\(httpAddr)\"\n            log.error(\"\\(e)\")\n            return .none\n          }\n          \n          return .run { send in\n            \n            let (ok, httpResult) = await detectHttpOk2(httpUrl: httpUrl, bodyShouldContain: \"<h1><a href=\\\"./\\\">pprof</a></h1>\")\n            if ok {\n              return await send(.httpReady)\n            } else {\n              await send(.httpUpdated(httpResult))\n            }\n            \n            for await _ in self.clock.timer(interval: .seconds(1)) {\n              let (ok, httpResult) = await detectHttpOk2(httpUrl: httpUrl, bodyShouldContain: \"<h1><a href=\\\"./\\\">pprof</a></h1>\")\n              if ok {\n                return await send(.httpReady)\n              } else {\n                await send(.httpUpdated(httpResult))\n              }\n            }\n          }\n          .cancellable(id: CancelID.httpDetector)\n        } else {\n          return .cancel(id: CancelID.httpDetector)\n        }\n      case let .terminalUpdated(text):\n        state.basic.terminalOutput.append(.init(date: date.now, std: .out, text: text))\n        if let port = state.basic.terminalOutput.map({ $0.text }).joined().extractPort() {\n          state.portReady = port\n          return .send(.portReady(port))\n        }\n        return .none\n      case let .httpUpdated(HTTPResult):\n        state.basic.httpDetectLog.append(HTTPResult)\n        return .none\n      case .httpReady:\n        if let process = state.process, let port = state.portReady {\n          return .send(.delegate(.onSuccess(process, port, state.goToWebOnSuccess)))\n        } else {\n          return .send(.fail(.process(\"failed: let process = state.process, let port = state.portReady\")))\n        }\n      case let .launchingTimeout(timeout):\n        if timeout > 0 {\n          return .run { send in\n            try await self.clock.sleep(for: .seconds(timeout))\n            await send(.launchingTimeout(0))\n          }\n        }\n        \n        if state.portReady == nil || !state.httpReady || state.process?.isRunning ?? false {\n          return .send(.fail(.process(\"launch timeout\")))\n        }\n        return .none\n      case let .fail(cause):\n        state.process?.terminate()\n        return .send(.delegate(.onFailed(cause)))\n      }\n    }\n  }\n}\n\nextension LaunchingFeature.State {}\n\nenum HTTPResult: Equatable {\n  case http(code: Int, html: String), err(String)\n}\n"
  },
  {
    "path": "approf/View/NavigaionView.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct NavigaionView: View {\n  @Bindable var store: StoreOf<AppFeature>\n\n  var body: some View {\n    NavigationSplitView {\n      list().navigationSplitViewColumnWidth(min: 200, ideal: 300)\n    } detail: {\n      detail()\n    }\n    .navigationTitle(\"\")\n    .onAppear {\n      store.send(.onAppear)\n    }\n  }\n\n  @ViewBuilder\n  private func list() -> some View {\n    ScrollViewReader { proxy in\n      List(selection: $store.pprofsSelectedId.sending(\\.onPprofsSelectedIdChanged).animation()) {\n        ForEach(store.scope(state: \\.pprofs, action: \\.pprofs), id: \\.basic.id) { pprofStore in\n          PProfRowView(store: pprofStore)\n            .addHiddenView(pprofStore.id) {\n              if store.pprofsSelectedId == pprofStore.id {\n                rowContextMenu(pprofUUID: pprofStore.id)\n              }\n            }\n            .contextMenu { rowContextMenu(pprofUUID: pprofStore.id) }\n            .listRowSeparator(.visible)\n            .listRowSeparatorTint(.secondary.opacity(0.5))\n            .id(pprofStore.id)\n        }\n        .onMove { from, to in\n          store.send(.onMove(from: from, to: to), animation: .default)\n        }\n      }\n      .onChange(of: store.pprofs.count) { old, neu in\n        // scroll to top of the list when new elements are added\n        if neu > old, let first = store.pprofs.first {\n          withAnimation {\n            proxy.scrollTo(first.id, anchor: .top)\n          }\n        }\n      }\n    }\n  }\n\n  @ViewBuilder\n  private func detail() -> some View {\n    if let selectedId = store.pprofsSelectedId, let st = store.scope(state: \\.pprofs[id: selectedId], action: \\.pprofs[id: selectedId]) {\n      DetailView(store: st).id(st.id)\n        .sc(\"w\", modifiers: [.command]) {\n          store.send(.onCloseTabCommand)\n        }\n    } else {\n      WelcomeView()\n    }\n  }\n\n  @ViewBuilder\n  private func rowContextMenu(pprofUUID: UUID) -> some View {\n    Button(action: {\n      store.send(.onMoveUpCommand, animation: .default)\n    }) {\n      Text(\"Move Up\")\n    }\n    .keyboardShortcut(.upArrow, modifiers: [.option, .command])\n    Button(action: {\n      store.send(.onMoveDownCommand, animation: .default)\n    }) {\n      Text(\"Move Down\")\n    }\n    .keyboardShortcut(.downArrow, modifiers: [.option, .command])\n    Button(action: {\n      store.send(.deleteButtonTapped(pprofUUID))\n    }) {\n      Text(\"Delete\").foregroundStyle(.red)\n    }\n    .keyboardShortcut(.delete, modifiers: [.shift, .command])\n  }\n}\n"
  },
  {
    "path": "approf/View/PProfRowView.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct PProfRowView: View {\n  @Bindable var store: StoreOf<DetailFeature>\n\n  @State var hoveringOnButton = false\n  @State var hoveringOnRow = false\n\n  var body: some View {\n    VStack(alignment: .leading, spacing: 4) {\n      name()\n      HStack(alignment: .firstTextBaseline) {\n        meta()\n        Spacer()\n        Text(store.basic.createdAt.humanReadable()).help(\"This record is created at \\(store.basic.createdAt).\")\n        buttons()\n      }\n      .font(.callout)\n      .foregroundStyle(.secondary)\n      .animation(.default, value: store.isRunning)\n    }\n    .onHover { h in\n      withAnimation {\n        hoveringOnRow = h\n      }\n    }\n    .contentShape(RoundedRectangle(cornerRadius: 8))\n  }\n\n  @ViewBuilder\n  func buttons() -> some View {\n    ZStack {\n      if store.isRunning {\n        if hoveringOnButton {\n          stopButton()\n        } else {\n          runningButton()\n        }\n      } else if showStartButton {\n        startButton()\n      }\n    }\n    .onHover { h in\n      withAnimation {\n        hoveringOnButton = h\n      }\n    }\n  }\n\n  var showStartButton: Bool {\n    switch store.period {\n    case .idle, .terminated, .failure:\n      return hoveringOnRow\n    default:\n      return false\n    }\n  }\n\n  @ViewBuilder\n  func startButton() -> some View {\n    Button(action: { store.send(.onStartButtonTapped) }) {\n      Image(systemName: \"restart.circle\")\n        .foregroundStyle(.foreground)\n    }\n    .buttonStyle(.plain)\n    .transition(.movingParts.iris(blurRadius: 50))\n    .help(\"Start pprof process and show the WEB page.\")\n  }\n\n  @ViewBuilder\n  func runningButton() -> some View {\n    Image(systemName: \"circle.fill\")\n      .foregroundStyle(.green)\n      .scaleEffect(0.4)\n      .transition(.movingParts.iris(blurRadius: 50))\n      .help(\"pprof process is running\")\n  }\n\n  @ViewBuilder\n  func stopButton() -> some View {\n    Image(systemName: \"square.fill\")\n      .foregroundStyle(.red.gradient)\n      .scaleEffect(1.3)\n      .transition(.movingParts.iris(blurRadius: 50))\n      .onTapGesture {\n        store.send(.period(.success(.stop)))\n      }\n      .help(\"Terminate pprof process\")\n  }\n\n  @ViewBuilder\n  func name() -> some View {\n    Text(store.basic.computedName.forceCharWrapping)\n      .font(.title3)\n      .fontWeight(.semibold)\n      .lineLimit(2)\n  }\n\n  @ViewBuilder\n  func meta() -> some View {\n    let count = store.basic.filePaths.count\n    if count > 1 {\n      HStack(alignment: .firstTextBaseline, spacing: 0) {\n        Image(systemName: \"document\")\n        Text(\"×\\(count)\")\n      }\n      .help(\"This record contains \\(count) files.\")\n    }\n\n    if store.basic.presentation != .dft {\n      Text(\"\\(store.basic.presentation)\").help(store.basic.presentation.explanation)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/Setting/DefaultGzAppView.swift",
    "content": "// Created for approf in 2024\n\nimport AppKit\nimport SwiftUI\nimport UniformTypeIdentifiers\n\nstruct DefaultGzAppView: View {\n  @State private var defaultApp: GzApp = .dummy\n  @State var apps: [GzApp] = []\n\n  var body: some View {\n    GridRow {\n      Text(\"Open `.pb.gz` with\").gridColumnAlignment(.trailing)\n      // Neither image.frame() nor VStack{Text() Text()} works in Picker\n      Picker(\"\", selection: $defaultApp) {\n        ForEach(apps, id: \\.self) { app in\n          HStack(alignment: .center) {\n            Image(nsImage: app.icon.resize(withSize: .init(width: 18, height: 18)))\n            if app.hasDupName {\n              Text(app.name) + Text(\"\\n\") +\n                Text(app.url.nicePath).foregroundStyle(.secondary).font(.footnote)\n            } else {\n              Text(app.name)\n            }\n          }\n        }\n      }\n      .pickerStyle(.automatic)\n      .labelsHidden()\n    }\n    .onAppear {\n      guard let url = Bundle.main.url(forResource: \"test-default-app.pb\", withExtension: \"gz\") else {\n        log.error(\"test-default-app.pb.gz not found\")\n        return\n      }\n      self.loadApps(for: url)\n      self.loadDefaultApp(for: url)\n    }\n    .onChange(of: defaultApp) { old, neu in\n      if old != .dummy && neu != .dummy {\n        log.info(\"setting \\(neu.url) as default app for .gz\")\n        NSWorkspace.shared.setDefaultApplication(at: neu.url, toOpen: UTType.gzip) { err in\n          if let err = err {\n            log.error(\"NSWorkspace.shared.setDefaultApplication error: \\(err)\")\n          }\n        }\n      }\n    }\n  }\n\n  func loadApps(for url: URL) {\n    let appURLs = NSWorkspace.shared.urlsForApplications(toOpen: url)\n    var loadedApps: [GzApp] = []\n    var names: [String] = []\n\n    for appURL in appURLs {\n      let appName = appURL.lastPathComponent\n      let icon = NSWorkspace.shared.icon(forFile: appURL.path)\n      loadedApps.append(GzApp(name: appName, url: appURL, icon: icon, hasDupName: false))\n      names.append(appName)\n    }\n\n    if names.count == Set(names).count {\n      apps = loadedApps\n    } else {\n      // some apps hav the same name\n      var newApps: [GzApp] = []\n      for app in loadedApps {\n        let hasDupName = names.count(where: { $0 == app.name }) > 1\n        newApps.append(.init(name: app.name, url: app.url, icon: app.icon, hasDupName: hasDupName))\n      }\n      apps = newApps\n    }\n  }\n\n  func loadDefaultApp(for url: URL) {\n    let url = NSWorkspace.shared.urlForApplication(toOpen: url)\n    if let url = url {\n      let appName = url.lastPathComponent\n      let icon = NSWorkspace.shared.icon(forFile: url.path)\n      defaultApp = GzApp(name: appName, url: url, icon: icon, hasDupName: false)\n    }\n  }\n\n  struct GzApp: Identifiable, Hashable {\n    var id: String {\n      url.absoluteString\n    }\n\n    let name: String\n    let url: URL\n    let icon: NSImage\n    let hasDupName: Bool\n\n    func hash(into hasher: inout Hasher) {\n      hasher.combine(url)\n    }\n\n    static func == (lhs: GzApp, rhs: GzApp) -> Bool {\n      return lhs.url == rhs.url\n    }\n\n    static var dummy = GzApp(name: \"\", url: URL(fileURLWithPath: \"\"), icon: .init(), hasDupName: false)\n  }\n}\n"
  },
  {
    "path": "approf/View/Setting/GraphvizGuideView.swift",
    "content": "// Created for approf in 2024\n\nimport SwiftUI\n\nstruct GraphvizGuideView: View {\n  @ObservedObject var asm = AppStorageManager.shared\n  @State var dotFileExists: (dotPath: String, exist: Bool)? = nil\n  @FocusState private var isTextFieldFocused: Bool\n\n  var showTitle = true\n  var callback: ((Bool) -> Void)? = nil\n\n  var body: some View {\n    Group {\n      GridRow {\n        Text(showTitle ? \"Graphviz folder\" : \"\").gridColumnAlignment(.trailing)\n        TextField(\"\", text: $asm.graphvizBinDir)\n          .fontDesign(.monospaced)\n          .frame(width: 250)\n          .focused($isTextFieldFocused)\n        Button(\"Open\") {\n          if let dir = selectFolder(asm.graphvizBinDir) {\n            asm.graphvizBinDir = dir\n          }\n        }\n      }\n      GridRow {\n        Text(\"\").gridColumnAlignment(.trailing)\n        HStack(spacing: 2) {\n          if let (path, exist) = dotFileExists {\n            Spacer().frame(width: 2)\n            Text(path)\n              .fontDesign(.monospaced)\n            if exist {\n              Text(\"exists\")\n                .foregroundStyle(.secondary)\n              Image(systemName: \"checkmark.circle.fill\")\n                .foregroundStyle(.green)\n            } else {\n              Text(\"doesn't exist\")\n              Image(systemName: \"xmark.circle.fill\")\n                .foregroundStyle(.red)\n            }\n          }\n        }\n        .font(.footnote)\n        .foregroundStyle(.secondary)\n        .gridCellColumns(2)\n      }\n    }\n    .onAppear {\n      if !asm.graphvizBinDir.isEmpty {\n        dotFileExists = dotExist(asm.graphvizBinDir)\n        callback?(dotFileExists?.exist ?? false)\n      }\n    }\n    .onAppear(delay: .seconds(0.01)) {\n      // prevent auto focus\n      isTextFieldFocused = false\n    }\n    .onChange(of: asm.graphvizBinDir) { _, b in\n      if !asm.graphvizBinDir.isEmpty {\n        dotFileExists = dotExist(b)\n        callback?(dotFileExists?.exist ?? false)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/Setting/SettingView.swift",
    "content": "import SwiftUI\nimport UniformTypeIdentifiers\n\nstruct SettingsView: View {\n  @StateObject var asm = AppStorageManager.shared\n  @Environment(\\.dismiss) var dismiss\n  @State var dotFileExists: (dotPath: String, exist: Bool)? = nil\n\n  var body: some View {\n    Group {\n      if #available(macOS 15.0, *) {\n        TabView(selection: $asm.selectedSettingsTab) {\n          Tab(\"General\", systemImage: \"medal.star.fill\", value: .general) {\n            general()\n          }\n          Tab(\"Appearance\", systemImage: \"paintpalette\", value: .appearance) {\n            appearance()\n          }\n        }\n      } else {\n        TabView(selection: $asm.selectedSettingsTab) {\n          general()\n            .tag(SettingsTab.general)\n            .tabItem {\n              Image(systemName: \"medal.star.fill\").symbolRenderingMode(.multicolor)\n              Text(\"General\")\n            }\n          appearance()\n            .tag(SettingsTab.appearance)\n            .tabItem {\n              Image(systemName: \"paintpalette\")\n              Text(\"Appearance\")\n            }\n        }\n      }\n    }\n    .padding(20)\n    .frame(width: 600, height: 400)\n    .sc(\",\", modifiers: [.command]) {\n      dismiss()\n    }\n  }\n  \n  @ViewBuilder\n  func general() -> some View {\n    VStack {\n      Grid(alignment: .leadingFirstTextBaseline) {\n        GraphvizGuideView()\n        DefaultGzAppView()\n      }\n    }\n  }\n\n  @ViewBuilder\n  func appearance() -> some View {\n    Grid(alignment: .leadingFirstTextBaseline) {\n      GridRow {\n        Label(\"Color Scheme\", systemImage: \"paintpalette\")\n          .symbolRenderingMode(.multicolor)\n          .modifier(RippleEffect(at: .zero, trigger: asm.colorScheme))\n          .gridColumnAlignment(.trailing)\n        Picker(\"\", selection: $asm.colorScheme) {\n          ForEach(AppColorScheme.allCases, id: \\.self) { c in\n            Text(\"\\(c.rawValue)\")\n          }\n        }\n        .pickerStyle(.segmented)\n        .labelsHidden()\n        .containerRelativeFrame(.horizontal) { x, _ in\n          x / 2\n        }\n      }\n      if #available(macOS 15.0, *) {\n        // .containerBackground(asm.materialType.actualMaterial, for: .window) is not available on 14\n        GridRow {\n          Label(\"Background\", systemImage: \"rectangle\")\n            .modifier(RippleEffect(at: .zero, trigger: asm.materialType))\n            .gridColumnAlignment(.trailing)\n          Picker(\"\", selection: $asm.materialType) {\n            ForEach(MaterialType.allCases, id: \\.self) { c in\n              Text(\"\\(c.rawValue)\")\n            }\n          }\n          .pickerStyle(.automatic)\n          .labelsHidden()\n          .containerRelativeFrame(.horizontal) { x, _ in\n            x / 4\n          }\n        }\n      }\n    }\n  }\n}\n\n\n\nenum SettingsTab: Int {\n  case general\n  case appearance\n  case shortcuts\n}\n\n#Preview {\n  SettingsView()\n}\n"
  },
  {
    "path": "approf/View/ShortcutView.swift",
    "content": "import KeyboardShortcuts\nimport SwiftUI\n\nextension KeyboardShortcuts.Name {\n  static let sidebar = Self(\"Show/Hide Sidebar\", default: .init(.l, modifiers: [.command, .shift]))\n  static let refresh = Self(\"Refresh the Page\", default: .init(.r, modifiers: [.command]))\n  static let openAFile = Self(\"Open a File\", default: .init(.t, modifiers: [.command]))\n  static let closeTab = Self(\"Close Tab\", default: .init(.w, modifiers: [.command]))\n  static let stop = Self(\"Stop\", default: .init(.c, modifiers: [.control]))\n}\n\nstruct ShortcutView: View {\n  var body: some View {\n    Form {\n      KeyboardShortcuts.Recorder(\"Show/Hide Sidebar\", name: .sidebar)\n      KeyboardShortcuts.Recorder(\"Refresh the Page\", name: .refresh)\n      KeyboardShortcuts.Recorder(\"Open a File\", name: .openAFile)\n      KeyboardShortcuts.Recorder(\"Close Tab\", name: .closeTab)\n      KeyboardShortcuts.Recorder(\"Stop\", name: .stop)\n    }\n  }\n}\n\n#Preview {\n  ShortcutView()\n}\n"
  },
  {
    "path": "approf/View/SuccessFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\nimport WebKit\n\n@Reducer\nstruct SuccessFeature {\n  @ObservableState\n  struct State: Equatable {\n    @Shared var basic: PProfBasic\n    let process: Process\n    let port: UInt16\n    let wk: WKWebView\n    var fullyLoaded = false\n\n    // this is a copy of basic, and is used detect if changes have been made before process is terminated\n    let snapshot: PProfBasic\n\n    init(basic: Shared<PProfBasic>, process: Process, port: UInt16, wk: WKWebView) {\n      _basic = basic\n      self.process = process\n      self.port = port\n      self.wk = wk\n      self.snapshot = basic.wrappedValue\n    }\n  }\n\n  enum Action {\n    case stop\n    case onFullyLoaded\n    case onRefreshButtonTapped\n    case onHomeButtonTapped\n\n    case delegate(Delegate)\n\n    @CasePathable\n    enum Delegate: Equatable {\n      case onTermimated\n    }\n  }\n\n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case .delegate:\n        return .none\n      case .onFullyLoaded:\n        state.fullyLoaded = true\n        return .none\n      case .onHomeButtonTapped:\n        state.wk.load(URLRequest(url: URL(string: \"http://localhost:\\(state.port)\")!))\n        return .none\n      case .onRefreshButtonTapped:\n        state.wk.reload()\n        return .none\n      case .stop:\n        if state.process.isRunning {\n          state.process.terminate()\n        }\n        return .send(.delegate(.onTermimated))\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/SuccessView.swift",
    "content": "import ComposableArchitecture\nimport KeyboardShortcuts\nimport SwiftUI\n\nstruct SuccessView: View {\n  @Bindable var store: StoreOf<SuccessFeature>\n  @State var invert = false\n  @ObservedObject var asm = AppStorageManager.shared\n  @Environment(\\.openURL) var openURL\n  @State var addrBarWidth: CGFloat = 300\n  @State var wkState = WKState()\n\n  var body: some View {\n    VStack {\n      WkWrapper(wk: store.wk, wkState: wkState)\n        .if(!asm.lightsOn) {\n          $0.colorInvert()\n        }\n    }\n    // Before 'wk' is fully loaded, it shows a background color. colorInvert turns this background color into a blinding foreground color.\n    // Adding a short delay to prevent a color flash. This only occurs the first time 'wk' displays.\n    .opacity(store.fullyLoaded ? 1 : 0)\n    .toolbar {\n      ToolbarItem(placement: .status) {\n        LightsOnButton(lightsOn: $asm.lightsOn)\n          .help(\"Toggle Lights\\nJust a simple color inversion in the app window, no CSS involved.\")\n          .opacity(store.fullyLoaded ? 1 : 0)\n      }\n\n      ToolbarItem(placement: .status) {\n        Button(action: { store.send(.onHomeButtonTapped) }) {\n          Image(systemName: \"house\")\n        }\n        .buttonStyle(.borderless)\n        .help(\"Home\")\n        .opacity(store.fullyLoaded ? 1 : 0)\n      }\n\n      ToolbarItem(placement: .status) {\n        statusBar()\n          .frame(width: addrBarWidth)\n          .opacity(store.fullyLoaded ? 1 : 0)\n      }\n\n      ToolbarItem(placement: .automatic) {\n        Button(action: { store.send(.stop) }) {\n          Image(systemName: \"square\")\n        }\n        .padding(.horizontal, 10)\n        .padding(.vertical, 4)\n        .help(\"Terminate pprof process\")\n        .opacity(store.fullyLoaded ? 1 : 0)\n      }\n    }\n    .onGeometryChange(for: CGFloat.self) { proxy in\n      proxy.size.width / 2\n    } action: {\n      self.addrBarWidth = $0\n    }\n  }\n\n  @State var wkRefreshCount = 0\n  @ViewBuilder\n  func statusBar() -> some View {\n    HStack(alignment: .firstTextBaseline) {\n      Button(action: {\n        if let url = wkState.url {\n          openURL(url)\n        }\n      }) {\n        Image(systemName: \"safari\")\n      }\n      .buttonStyle(.borderless)\n      .help(\"Open in Browser\")\n\n      Spacer()\n\n      if let url = wkState.url {\n        Text(url.absoluteString)\n          .lineLimit(1)\n          .foregroundStyle(.foreground.opacity(0.8))\n          .modifier(RippleEffect(at: .zero, trigger: wkRefreshCount))\n        ProgressView()\n          .scaleEffect(0.4)\n          .frame(width: 5, height: 5)\n          .opacity(wkState.loading ? 1 : 0)\n      }\n\n      Spacer()\n\n      Button(action: {\n        wkRefreshCount += 1\n        store.send(.onRefreshButtonTapped)\n      }) {\n        Image(systemName: \"arrow.clockwise\")\n      }\n      .buttonStyle(.borderless)\n      .keyboardShortcut(\"r\", modifiers: [.command])\n      .help(\"Refresh\")\n    }\n    .padding(.horizontal, 6)\n    .padding(.vertical, 4)\n    .background(\n      RoundedRectangle(cornerRadius: 10)\n        .strokeBorder(.secondary.opacity(0.5), lineWidth: 0.5)\n    )\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/ActionButtonView.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport SwiftUI\n\nstruct ActionButtonView: View {\n  @Bindable var store: StoreOf<DetailFeature>\n\n  var body: some View {\n    HStack {\n      VStack(alignment: .leading) {\n        HStack {\n          UTHStatusView(store: store)\n          actionButton()\n        }\n        DetectingHTTPView(store: store)\n      }\n      Spacer()\n    }\n  }\n\n  @ViewBuilder\n  private func actionButton() -> some View {\n    switch store.period {\n    case .idle, .terminated:\n      Button(\"Launch\") {\n        store.send(.launchButtonTapped)\n      }\n      .buttonStyle(BorderedProminentButtonStyle())\n    case .failure:\n      Button(\"Relaunch\") {\n        store.send(.launchButtonTapped)\n      }\n      .buttonStyle(BorderedProminentButtonStyle())\n    case let .success(su):\n      HStack(alignment: .firstTextBaseline) {\n        Button(\"Stop\") {\n          store.send(.stopButtonTapped)\n        }\n        if !store.basic.equalsSnapshot(su.snapshot) {\n          HStack(alignment: .firstTextBaseline, spacing: 0) {\n            Text(\"Changes detected, \").foregroundStyle(.secondary)\n            Button(\"reluanch\") {\n              store.send(.relaunchButtonTapped)\n            }\n            .buttonStyle(.plain)\n            .foregroundStyle(.tint)\n            Text(\"?\").foregroundStyle(.secondary)\n          }\n        } else if store.showGoToWEB {\n          HStack(alignment: .firstTextBaseline, spacing: 0) {\n            Text(\"Go to \").foregroundStyle(.secondary)\n            Button(\"WEB\") {\n              store.send(.goToWEBButtonTapped)\n            }\n            .buttonStyle(.plain)\n            .foregroundStyle(.tint)\n            Text(\"?\").foregroundStyle(.secondary)\n          }\n        }\n      }\n    case .launching:\n      Button(\"Cancel\") {\n        store.send(.stopButtonTapped)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/CommandPreviewView.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport SwiftUI\n\nstruct CommandPreviewView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n  var importing: Bool = false\n\n  var body: some View {\n    VStack(alignment: .leading) {\n      HStack(alignment: .bottom, spacing: 4) {\n        Image(systemName: \"command\")\n        Text(\"Command Preview\")\n          .foregroundStyle(.secondary)\n        CopyButton {\n          copiable\n        }\n        Spacer()\n\n        if store.basic.filePaths.count > 1 {\n          Picker(\"\", selection: $store.basic.presentation.sending(\\.onPresentationChanged)) {\n            ForEach(PProfPresentation.allCases, id: \\.self) { c in\n              Text(\"\\(c.rawValue)\")\n                .help(c.explanation)\n            }\n          }\n          .pickerStyle(.segmented)\n          .labelsHidden()\n          .frame(width: 200)\n        }\n      }\n      ScrollableTextBox(heightLimit: 100) {\n        if importing && store.basic.presentation == .dft {\n          ForEach(store.basic.filePaths, id: \\.self) { fp in\n            Text(CommandLine.commandPreview(.dft, [fp]).asPrintable())\n          }\n        } else {\n          ForEach(printable, id: \\.self) { line in\n            Text(line)\n          }\n        }\n      }\n    }\n  }\n\n  var copiable: String {\n    if importing && store.basic.presentation == .dft {\n      store.basic.filePaths.map { CommandLine.commandPreview(.dft, [$0]).asCopiable() }\n        .joined(separator: \"\\n\")\n    } else {\n      store.basic.commandPreview().asCopiable()\n    }\n  }\n\n  var printable: [String] {\n    if importing && store.basic.presentation == .dft {\n      store.basic.filePaths.map { CommandLine.commandPreview(.dft, [$0]).asPrintable() }\n    } else {\n      store.basic.commandPreview().asPrintable().components(separatedBy: \"\\n\")\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/FileListView.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport Foundation\nimport SwiftUI\n\nstruct FileListView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n  var importing: Bool = false\n  @State var uiState = UIState.shared\n\n  var body: some View {\n    VStack(alignment: .leading) {\n      HStack(alignment: .firstTextBaseline, spacing: 4) {\n        Image(systemName: \"folder\")\n        Text(\"Files\")\n          .foregroundStyle(.secondary)\n      }\n      VStack(spacing: 0) {\n        List(selection: $store.selection.sending(\\.onSelectionChanged)) {\n          ForEach(store.basic.filePaths, id: \\.self) { filePath in\n            FileRowView(\n              filePath: filePath,\n              ignored: !importing && (store.basic.presentation == .dft && filePath != store.basic.filePaths.first),\n              isBase: store.basic.presentation == .diff && filePath == store.basic.filePaths.first\n            )\n            .addHiddenView(filePath) {\n              if store.selection == filePath {\n                rowContextMenu(filePath: filePath, deleteDisabled: store.basic.filePaths.count == 1)\n              }\n            }\n            .contextMenu {\n              rowContextMenu(filePath: filePath, deleteDisabled: store.basic.filePaths.count == 1)\n            }\n          }\n          .onMove { from, to in\n            store.send(.onMove(from: from, to: to), animation: .default)\n          }\n        }\n        .scrollContentBackground(.hidden)\n\n        Divider()\n\n        HStack(alignment: .center, spacing: 2) {\n          Button(action: {\n            let urls = selectMultiFiles(utTypes: allowedImportFileTypes)\n            if !urls.isEmpty {\n              let filePaths = urls.map { $0.path(percentEncoded: false) }\n              store.send(.onSelectFilesEnd(filePaths))\n            }\n          }) {\n            Image(systemName: \"rectangle.fill\")\n              .opacity(0.001)\n              .overlay {\n                Image(systemName: \"plus\")\n              }\n          }\n          .buttonStyle(.plain)\n          .contentShape(Rectangle())\n\n          Divider().frame(height: 14)\n          Button(action: { store.send(.onDeleteSelectedCommand) }) {\n            Image(systemName: \"rectangle.fill\")\n              .opacity(0.001)\n              .overlay {\n                Image(systemName: \"minus\")\n              }\n          }\n          .buttonStyle(.plain)\n          .contentShape(Rectangle())\n          Spacer()\n        }\n        .padding(.leading, 8)\n        .padding(.vertical, 3)\n      }\n      .background(\n        RoundedRectangle(cornerRadius: 10)\n          .fill(.bar)\n          .strokeBorder(.secondary.opacity(0.5), lineWidth: 0.5)\n      )\n    }\n    .overlay{\n      DropAndAppendView(store: store)\n    }\n  }\n\n  @ViewBuilder\n  private func rowContextMenu(filePath: String, deleteDisabled: Bool) -> some View {\n    Button(\"Show in Finder\") {\n      showInFinder(filePath)\n    }\n    .keyboardShortcut(\"j\", modifiers: [.command, .shift])\n\n    Button(action: {\n      store.send(.onMoveUpCommand, animation: .default)\n    }) {\n      Text(\"Move Up\")\n    }\n    .keyboardShortcut(.upArrow, modifiers: [.command])\n\n    Button(action: {\n      store.send(.onMoveDownCommand, animation: .default)\n    }) {\n      Text(\"Move Down\")\n    }\n    .keyboardShortcut(.downArrow, modifiers: [.command])\n\n    Button(action: {\n      store.send(.onDeleteMenuTapped(filePath), animation: .default)\n    }) {\n      Text(\"Delete\").foregroundStyle(.red)\n    }\n    .keyboardShortcut(.delete, modifiers: [.command])\n    .disabled(deleteDisabled)\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/FileRowView.swift",
    "content": "import SwiftUI\n\nstruct FileRowView: View {\n  @State var failedToReadFileReason: String?\n  @State var fileAttrs: FileAttrs?\n  @State var hoveringOnLM = false\n  \n  let filePath: String\n  let ignored: Bool\n  let isBase: Bool\n  \n  var body: some View {\n    VStack(alignment: .leading, spacing: 2) {\n      Text(filePath.forceCharWrapping)\n        .multilineTextAlignment(.leading)\n      HStack(alignment: .firstTextBaseline) {\n        Button(action: {\n          showInFinder(filePath)\n        }) {\n          Image(systemName: \"arrowshape.right.circle.fill\")\n        }\n        .buttonStyle(PlainButtonStyle())\n        .help(\"Show in Finder\")\n        \n        if let fileSize = fileAttrs?.fileSize {\n          Text(fileSize.humanReadableFileSize())\n            .foregroundStyle(.secondary)\n        } else {\n          // reserve vertical space before filesize shows up fix unsatalbe row height\n          Text(\"f\").opacity(0)\n        }\n\n        if let reason = failedToReadFileReason {\n          Text(\"error\")\n            .foregroundStyle(.white)\n            .padding(.horizontal, 6)\n            .background(Rectangle().fill(.red))\n            .clipShape(RoundedRectangle(cornerRadius: 8))\n            .tooltip(delay: 0.3) {\n              Text(reason)\n                .padding(.horizontal, 10)\n                .padding(.vertical, 4)\n            }\n        }\n        \n        Spacer()\n        if isBase {\n          Text(\"base\")\n            .foregroundStyle(.background)\n            .padding(.horizontal, 6)\n            .background(Rectangle().fill(.teal))\n            .clipShape(RoundedRectangle(cornerRadius: 8))\n        } else if ignored {\n          Text(\"ignored\")\n            .foregroundStyle(.background)\n            .padding(.horizontal, 6)\n            .background(Rectangle().fill(.orange))\n            .clipShape(RoundedRectangle(cornerRadius: 8))\n        }\n        if let lastModified = fileAttrs?.lastModified {\n          HStack(alignment: .firstTextBaseline, spacing: 2) {\n            if hoveringOnLM {\n              Text(\"Last Modified: \")\n            }\n            Text(lastModified.humanReadable())\n          }\n          .foregroundStyle(.secondary)\n          .onHover { h in\n            withAnimation {\n              hoveringOnLM = h\n            }\n          }\n        } else {\n          Text(\"f\").opacity(0)\n        }\n      }\n      .font(.footnote)\n    }\n    .task(priority: .background){\n        readFile()\n    }\n  }\n  \n  func readFile() {\n    if fileAttrs != nil || failedToReadFileReason != nil {\n      return\n    }\n    do {\n      let attrs = try FileManager.default.attributesOfItem(atPath: filePath)\n      if let fileSize = attrs[.size] as? UInt64, let date = attrs[.modificationDate] as? Date {\n        Task { @MainActor in\n          withAnimation {\n            fileAttrs = .init(fileSize: fileSize, lastModified: date)\n          }\n        }\n      }\n    } catch {\n      Task { @MainActor in\n        withAnimation {\n          failedToReadFileReason = error.localizedDescription\n        }\n      }\n    }\n  }\n  \n  struct FileAttrs {\n    let fileSize: UInt64\n    let lastModified: Date\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/ImportView.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct ImportView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n\n  var body: some View {\n    VStack(spacing: 20) {\n      FileListView(store: store)\n      CommandPreviewView(store: store)\n      Spacer()\n    }\n    .background {\n      ShortcutsView(store: store)\n    }\n    .toolbar {\n      toolbar()\n    }\n    .onDisappear {\n      store.send(.delegate(.onImportViewAutoDismissed))\n    }\n  }\n  \n  @ToolbarContentBuilder\n  private func toolbar() -> some ToolbarContent {\n    ToolbarItem(placement: .destructiveAction) {\n      Button(\"Cancel(ESC)\", role: .cancel) {\n        store.send(.delegate(.onCancelImportButtonTapped))\n      }\n    }\n    ToolbarItem(placement: .confirmationAction) {\n      Button(\"Done⏎\") {\n        store.send(.delegate(.onConfirmImportButtonTapped))\n      }\n      .keyboardShortcut(.return, modifiers: [])\n    }\n  }\n}\n\nstruct ImportViewV2App: App {\n  var body: some Scene {\n    WindowGroup {\n      ImportViewV2(store: UnderTheHood.mock)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/NameFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\n@Reducer\nstruct NameFeature {\n\n  @ObservableState\n  struct State: Equatable {\n    @Shared var basic: PProfBasic\n    var editMode: Bool = false\n  }\n\n  enum Action {\n    case onNameChanged(String)\n  }\n\n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case let .onNameChanged(name):\n        state.basic.name = name\n        return .none\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/NameView.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport SwiftUI\n\nstruct NameView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n  var importing: Bool = false\n\n  var body: some View {\n    HStack(alignment: .firstTextBaseline, spacing: 4) {\n      Text(\"Name\")\n        .foregroundStyle(.secondary)\n      TextField(store.basic.computedName, text: $store.basic.name.sending(\\.onNameChanged))\n        .textFieldStyle(.plain)\n        .background(.clear)\n        .padding(.leading, 8)\n        .padding(.vertical, 3)\n        .background(\n          RoundedRectangle(cornerRadius: 6)\n            .fill(.bar)\n            .strokeBorder(.secondary.opacity(0.5), lineWidth: 0.5)\n        )\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/NotificationFeature.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\n@Reducer\nstruct NotificationFeature {\n  @ObservableState\n  struct State: Equatable {\n    var text: String\n    var seconds: UInt?\n  }\n\n  enum Action {\n    case onAppear\n    case countDown\n  }\n\n  enum CancelID { case timer }\n  @Dependency(\\.continuousClock) var clock\n  @Dependency(\\.dismiss) var dismiss\n\n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case .onAppear:\n        if let s = state.seconds {\n          if s == 0 {\n            fatalError(\"don't do this\")\n          }\n          return .run { send in\n            for await _ in self.clock.timer(interval: .seconds(1)) {\n              await send(.countDown)\n            }\n          }.cancellable(id: CancelID.timer)\n        } else {\n          return .none\n        }\n      case .countDown:\n        state.seconds? -= 1\n        if state.seconds == 0 {\n          return .merge(\n            .cancel(id: CancelID.timer),\n            .run { _ in await dismiss() }\n          )\n        }\n        return .none\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/ShortcutsView.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport SwiftUI\n\nstruct ShortcutsView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n\n  var body: some View {\n    Rectangle()\n      .fill(.clear)\n      .frame(width: 1, height: 1)\n      .allowsHitTesting(false)\n      .sc(.rightArrow, modifiers: []) {\n        store.send(.onNextPresentationCommand, animation: .default)\n      }\n      .sc(.tab, modifiers: []) {\n        store.send(.onNextPresentationCommand, animation: .default)\n      }\n      .sc(.leftArrow, modifiers: []) {\n        store.send(.onPrevPresentationCommand, animation: .default)\n      }\n      .sc(.tab, modifiers: [.control]) {\n        store.send(.onPrevPresentationCommand, animation: .default)\n      }\n      .sc(.tab, modifiers: [.shift]) {\n        store.send(.onPrevPresentationCommand, animation: .default)\n      }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/StatusView.swift",
    "content": "import SwiftUI\nimport ComposableArchitecture\n\nstruct UTHStatusView: View {\n  @Bindable var store: StoreOf<DetailFeature>\n\n  var body: some View {\n    HStack(alignment: .firstTextBaseline) {\n      switch store.period {\n      case .idle:\n        EmptyView()\n      case .terminated:\n        Image(systemName: \"moon.zzz\")\n        Text(\"Terminated\")\n      case .launching:\n        RotatingSF(\"arrow.clockwise\")\n          .foregroundStyle(.orange)\n        Text(\"Launching\")\n          .foregroundStyle(.orange)\n        EmptyView()\n      case .failure:\n        HeartSlash()\n        Text(\"Failed\")\n          .foregroundStyle(.red)\n      case .success:\n        Image(systemName: \"smallcircle.filled.circle\")\n          .foregroundStyle(.green)\n          .symbolEffect(.pulse.wholeSymbol, options: .speed(0.5))\n        Text(\"Running\")\n          .foregroundStyle(.green)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/TerminalView.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport SwiftUI\n\nstruct TerminalView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n\n  var body: some View {\n    VStack(alignment: .leading) {\n      HStack {\n        Image(systemName: \"apple.terminal\")\n        //          .foregroundColor(.blue)\n        Text(\"Terminal\").foregroundStyle(.secondary)\n      }\n      if #available(macOS 15.0, *) {\n        ScrollableTextBox(heightLimit: 100) {\n          Text(store.basic.finalCommandArgs.asCopiable())\n          Text(\" \")\n          Text(store.basic.terminalOutput.map { $0.text }.joined())\n        }\n        .defaultScrollAnchor(.bottom)\n      } else {\n        ScrollableTextBox(heightLimit: 100) {\n          Text(store.basic.finalCommandArgs.asCopiable())\n          Text(\" \")\n          Text(store.basic.terminalOutput.map { $0.text }.joined())\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/UTH.swift",
    "content": "import ComposableArchitecture\nimport Foundation\n\n@Reducer\nstruct UnderTheHood {\n  @Reducer(state: .equatable)\n  enum Destination {\n    case notification(NotificationFeature)\n  }\n\n  @ObservableState\n  struct State: Equatable {\n    @Shared var basic: PProfBasic\n    var selection: String?\n    @Presents var destination: Destination.State?\n  }\n\n  enum Action {\n    case destination(PresentationAction<Destination.Action>)\n    case onSelectionChanged(String?)\n    case onNameChanged(String)\n    case onPresentationChanged(PProfPresentation)\n    case onSelectFilesEnd([String])\n    case onAddURLs([URL])\n\n    case onMove(from: IndexSet, to: Int)\n    case onDeleteSelectedCommand\n    case onDeleteMenuTapped(String)\n    case onMoveUpCommand\n    case onMoveDownCommand\n    case onNextPresentationCommand\n    case onPrevPresentationCommand\n    case newNotification(String)\n    case newCountDownNotification(String, UInt)\n\n    case onCancelImportButtonTapped\n\n    case delegate(Delegate)\n\n    @CasePathable\n    enum Delegate {\n      // MARK: for import view\n      case onConfirmImportButtonTapped\n    }\n  }\n\n  @Dependency(\\.dismiss) var dismiss\n\n  var body: some ReducerOf<Self> {\n    Reduce { state, action in\n      switch action {\n      case .delegate, .destination:\n        return .none\n      case let .onPresentationChanged(p):\n        changePresentation(&state, p)\n        return .none\n      case let .onSelectionChanged(filePath):\n        state.selection = filePath\n        return .none\n      case let .onNameChanged(name):\n        state.basic.name = name\n        return .none\n      case let .onSelectFilesEnd(filePaths):\n        addFiles(&state, filePaths: filePaths)\n        return .none\n      case let .onAddURLs(urls):\n        let u = urls.map { $0.path(percentEncoded: false) }\n        addFiles(&state, filePaths: u)\n        return .none\n      case let .onMove(from, to):\n        move(&state, from, to)\n        return .none\n      case .onDeleteSelectedCommand:\n        if let selection = state.selection {\n          delete(&state, selection)\n        }\n        return .none\n      case let .onDeleteMenuTapped(filePath):\n        delete(&state, filePath)\n        return .none\n      case .onMoveUpCommand:\n        if let selection = state.selection {\n          moveUp(&state, selection)\n        }\n        return .none\n      case .onMoveDownCommand:\n        if let selection = state.selection {\n          moveDown(&state, selection)\n        }\n        return .none\n      case .onNextPresentationCommand:\n        changePresentation(&state, state.basic.presentation.next)\n        return .none\n      case .onPrevPresentationCommand:\n        state.basic.presentation = state.basic.presentation.prev\n        return .none\n      case let .newNotification(text):\n        state.destination = .notification(.init(text: text))\n        return .none\n      case let .newCountDownNotification(text, seconds):\n        state.destination = .notification(.init(text: text, seconds: seconds))\n        return .none\n      case .onCancelImportButtonTapped:\n        return .run { _ in await dismiss() }\n      }\n    }\n    .ifLet(\\.$destination, action: \\.destination)\n  }\n\n  private func changePresentation(_ state: inout Self.State, _ presentation: PProfPresentation) {\n    if state.basic.filePaths.count <= 1 {\n      state.basic.presentation = .dft\n    } else {\n      state.basic.presentation = presentation\n    }\n  }\n\n  private func move(_ state: inout Self.State, _ source: IndexSet, _ destination: Int) {\n    state.basic.filePaths.move(fromOffsets: source, toOffset: destination)\n  }\n\n  private func addFiles(_ state: inout Self.State, filePaths: [String]) {\n    var dup = 0\n    for fp in filePaths {\n      if state.basic.filePaths.contains(fp) {\n        dup += 1\n      } else {\n        state.basic.filePaths.append(fp)\n      }\n    }\n\n    if dup > 0 {\n      return state.destination = .notification(.init(text: \"\\(dup) duplicate files ignored\", seconds: 5))\n    }\n  }\n\n  /// Remove an element and update the selection accordingly\n  private func delete(_ state: inout Self.State, _ filePath: String) {\n    // Remember the selection index before deleting an element\n    var originalIndex: Int?\n    if let selection = state.selection {\n      originalIndex = state.basic.filePaths.firstIndex(of: selection)\n    }\n\n    if state.basic.filePaths.count > 1 {\n      state.basic.filePaths.removeAll { $0 == filePath }\n      if state.basic.filePaths.count == 1 {\n        state.basic.presentation = .dft\n      }\n    }\n\n    if let selection = state.selection {\n      // If the selected element is deleted\n      if !state.basic.filePaths.contains(where: { $0 == selection }), let originalIndex = originalIndex {\n        if originalIndex < state.basic.filePaths.count {\n          // If there were elements after it, select the next one\n          state.selection = state.basic.filePaths[originalIndex]\n        } else {\n          // Otherwise(selection was the last element), select the last element in the list\n          state.selection = state.basic.filePaths.last\n        }\n      }\n    }\n  }\n\n  private func moveUp(_ state: inout Self.State, _ filePath: String) {\n    guard let index = state.basic.filePaths.firstIndex(where: { $0 == filePath }) else {\n      return\n    }\n    if index - 1 >= 0 {\n      state.basic.filePaths.move(fromOffsets: IndexSet([index]), toOffset: index - 1)\n    }\n  }\n\n  private func moveDown(_ state: inout Self.State, _ filePath: String) {\n    guard let index = state.basic.filePaths.firstIndex(where: { $0 == filePath }) else {\n      return\n    }\n    if index + 2 <= state.basic.filePaths.count {\n      state.basic.filePaths.move(fromOffsets: IndexSet([index]), toOffset: index + 2)\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/UnderTheHood/UnderTheHoodView.swift",
    "content": "import ComposableArchitecture\nimport PopupView\nimport SwiftUI\n\nstruct UnderTheHoodView: View {\n  @Bindable var store: StoreOf<UnderTheHood>\n  @Bindable var detailStore: StoreOf<DetailFeature>\n\n  var body: some View {\n    VStack(spacing: 20) {\n      NameView(store: store)\n      FileListView(store: store, importing: false)\n      CommandPreviewView(store: store, importing: false)\n      Spacer().frame(height: 10)\n      TerminalView(store: store)\n      ActionButtonView(store: detailStore)\n      Spacer()\n    }\n    .background {\n      ShortcutsView(store: store)\n    }\n    .popup(item: $store.scope(state: \\.destination?.notification, action: \\.destination.notification), itemView: { notiStore in\n      NotificationView(store: notiStore)\n    }) {\n      $0.type(.floater())\n        .position(.bottomTrailing)\n        .animation(.spring())\n    }\n  }\n}\n"
  },
  {
    "path": "approf/View/WebIndicatorView.swift",
    "content": "import ComposableArchitecture\nimport SwiftUI\n\nstruct WebIndicatorView: View {\n  let url: URL\n  var wkRefreshCount: Int\n  @State var infoPopOver = false\n\n  var body: some View {\n    HStack(spacing: 4) {\n      Text(url.lastPathComponent)\n      HStack {\n        Button(action: { infoPopOver.toggle() }) {\n          Image(systemName: \"info.circle\")\n        }\n        .buttonStyle(PlainButtonStyle())\n        .popover(isPresented: $infoPopOver) {\n          HStack(spacing: 4) {\n            let abs = url.path(percentEncoded: false)\n            Text(abs)\n              .padding(.horizontal, 10)\n              .padding(.vertical, 4)\n            CopyButton{\n              abs\n            }\n          }\n          .padding(.horizontal, 10)\n          .padding(.vertical, 4)\n        }\n      }\n    }\n    .modifier(RippleEffect(at: .zero, trigger: wkRefreshCount))\n  }\n}\n"
  },
  {
    "path": "approf/View/WelcomeView.swift",
    "content": "import SwiftUI\n\nstruct WelcomeView: View {\n  @ObservedObject private var asm = AppStorageManager.shared\n  @State private var showGraphvizGuide = false\n  @State private var titleHeight: CGFloat = 30\n\n  var body: some View {\n    Group {\n      if showGraphvizGuide {\n        VStack {\n          Spacer()\n          HStack(alignment: .firstTextBaseline) {\n            Image(\"Gopple\").resizable().scaledToFit().frame(height: titleHeight * 2)\n            Text(\", have you got Graphviz installed?\").font(.largeTitle)\n              .onGeometryChange(for: CGFloat.self) { proxy in proxy.size.height } action: { titleHeight = $0 }\n          }\n          Spacer().frame(height: 20)\n          Text(\"Let’s locate the bin folder of Graphviz; it should have the `dot` executable.\")\n            .font(.title2)\n            .fontWeight(.thin)\n            .foregroundStyle(.secondary)\n          Spacer()\n          Grid(alignment: .leadingFirstTextBaseline) {\n            GraphvizGuideView(showTitle: false) { exist in\n              if exist {\n                Task.detached {\n                  try await Task.sleep(for: .seconds(1.5))\n                  Task { @MainActor in\n                    withAnimation(.easeInOut(duration: 1.5)) {\n                      showGraphvizGuide = false\n                    }\n                  }\n                }\n              } else {\n                showGraphvizGuide = true\n              }\n            }\n          }\n          Spacer()\n          Spacer()\n          HStack(alignment: .firstTextBaseline) {\n            Text(\"brew install graphviz\")\n              .fontDesign(.monospaced)\n              .textSelection(.enabled)\n            CopyButton {\n              \"brew install graphviz\"\n            }\n          }\n          .padding(30)\n        }\n      } else {\n        OpenFileHint()\n      }\n    }\n    .onAppear {\n      showGraphvizGuide = !dotExist(asm.graphvizBinDir).1\n    }\n  }\n}\n\nstruct OpenFileHint: View {\n  var body: some View {\n    VStack(alignment: .leading) {\n      Label(title: { Text(\"Open a file from Finder\") }) {\n        Image(systemName: \"cursorarrow.click.2\")\n          .foregroundStyle(.blue)\n      }\n      Label(title: { Text(\"or\") }) {\n        Image(systemName: \"cursorarrow.click.2\")\n          .foregroundStyle(.clear)\n      }\n      Label(title: { Text(\"drag 'n' drop\") }) {\n        Image(systemName: \"hand.pinch.fill\")\n          .foregroundStyle(.blue)\n      }\n    }\n    .font(.largeTitle)\n  }\n}\n\n#Preview {\n  WelcomeView()\n}\n"
  },
  {
    "path": "approf/View/WkWrapper.swift",
    "content": "import AppKit\nimport SwiftUI\nimport WebKit\n\nstruct WkWrapper: NSViewRepresentable {\n  let wk: WKWebView\n  @Bindable var wkState: WKState\n\n  public func makeNSView(context: Context) -> WKWebView {\n    wk.wantsLayer = true\n    wk.navigationDelegate = context.coordinator\n    wkState.url = wk.url\n    return wk\n  }\n\n  func updateNSView(_ wk: WKWebView, context: Context) {\n    wkState.url = wk.url\n  }\n\n  class Coordinator: NSObject, WKNavigationDelegate {\n    var parent: WkWrapper\n\n    init(_ parent: WkWrapper) {\n      self.parent = parent\n    }\n\n    func webView(_ wk: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {\n      parent.wkState.loading = true\n    }\n\n    func webView(_ wk: WKWebView, didFinish navigation: WKNavigation!) {\n      parent.wkState.loading = false\n      parent.wkState.url = wk.url\n//      parent.wkState.updateStacks(with: webView)\n    }\n\n    func webView(_ wk: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {\n      parent.wkState.loading = false\n//      parent.wkState.updateStacks(with: webView)\n    }\n  }\n\n  func makeCoordinator() -> Coordinator {\n    Coordinator(self)\n  }\n}\n"
  },
  {
    "path": "approf/WindowController.swift",
    "content": "import SwiftUI\n\nclass CustomWindowController: NSWindowController {\n  override func windowDidLoad() {\n    super.windowDidLoad()\n    window?.tabbingMode = .disallowed // Disable multi-tab. Not working actually.\n  }\n}\n"
  },
  {
    "path": "approf/pprof.entitlements",
    "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</plist>\n"
  },
  {
    "path": "approf.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 70;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tEB0A27312C413CE400AD34ED /* NavigaionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A27302C413CE400AD34ED /* NavigaionView.swift */; };\n\t\tEB1003E72C4A7EFC009E61F2 /* PopupView in Frameworks */ = {isa = PBXBuildFile; productRef = EB1003E62C4A7EFC009E61F2 /* PopupView */; };\n\t\tEB1003E92C4A81D4009E61F2 /* FloatTopTrailing.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1003E82C4A81D4009E61F2 /* FloatTopTrailing.swift */; };\n\t\tEB1003EB2C4A8BC0009E61F2 /* CountDown.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1003EA2C4A8BC0009E61F2 /* CountDown.swift */; };\n\t\tEB1003ED2C4A9860009E61F2 /* NotificationFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1003EC2C4A9860009E61F2 /* NotificationFeature.swift */; };\n\t\tEB11A5162C4515C500E696DF /* WKState.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB11A5152C4515C500E696DF /* WKState.swift */; };\n\t\tEB170FF32C40697100945866 /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB170FF22C40697100945866 /* Buttons.swift */; };\n\t\tEB17F1F62C48169A00ED297A /* FileRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB17F1F52C48169A00ED297A /* FileRowView.swift */; };\n\t\tEB1F1FBD2C4589A400FD585E /* pprof in pprrof executable */ = {isa = PBXBuildFile; fileRef = EB72830A2C44523F00B29D14 /* pprof */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };\n\t\tEB1F1FC12C45AEB700FD585E /* Shortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1F1FC02C45AEB700FD585E /* Shortcuts.swift */; };\n\t\tEB1F1FC32C45B2B300FD585E /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1F1FC22C45B2B300FD585E /* Color.swift */; };\n\t\tEB1F1FC52C45B38D00FD585E /* Color+Luminance.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1F1FC42C45B38D00FD585E /* Color+Luminance.swift */; };\n\t\tEB2619752C60AD0A007D4932 /* test-default-app.pb.gz in Resources */ = {isa = PBXBuildFile; fileRef = EB2619742C60AD0A007D4932 /* test-default-app.pb.gz */; };\n\t\tEB2A0B4A2C4663CB0085609E /* CommandGenerate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB2A0B492C4663CB0085609E /* CommandGenerate.swift */; };\n\t\tEB5026812C3D139F007C6282 /* Other.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB5026802C3D139F007C6282 /* Other.swift */; };\n\t\tEB59362F2C4053D200088AB9 /* Others.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB59362E2C4053D200088AB9 /* Others.swift */; };\n\t\tEB62B5812C5FE9FD00188A9D /* ImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62B5802C5FE9FD00188A9D /* ImportView.swift */; };\n\t\tEB62B5852C5FEB0700188A9D /* FileListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62B5842C5FEB0700188A9D /* FileListView.swift */; };\n\t\tEB62B5872C5FEB9200188A9D /* CommandPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62B5862C5FEB9200188A9D /* CommandPreviewView.swift */; };\n\t\tEB62B5892C5FEBC900188A9D /* TerminalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62B5882C5FEBC900188A9D /* TerminalView.swift */; };\n\t\tEB62B58B2C5FEC1B00188A9D /* ActionButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62B58A2C5FEC1B00188A9D /* ActionButtonView.swift */; };\n\t\tEB62B58F2C5FED3800188A9D /* ShortcutsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62B58E2C5FED3800188A9D /* ShortcutsView.swift */; };\n\t\tEB62B5922C5FEEE800188A9D /* PerviewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62B5902C5FEEE800188A9D /* PerviewData.swift */; };\n\t\tEB6530F52C41C09800A66B7C /* DropAndImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB6530F42C41C09800A66B7C /* DropAndImportView.swift */; };\n\t\tEB6530FB2C41CF8D00A66B7C /* WebIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB6530FA2C41CF8D00A66B7C /* WebIndicatorView.swift */; };\n\t\tEB659BC52C3EE91400F3F84E /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB659BC42C3EE91400F3F84E /* Command.swift */; };\n\t\tEB7ADFC62C439CE500130909 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7ADFC52C439CE500130909 /* WindowController.swift */; };\n\t\tEB8190CA2C4571F8007EDE72 /* GradientBackgroundAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB8190C92C4571F8007EDE72 /* GradientBackgroundAnimation.swift */; };\n\t\tEB85AB822C3DBA0A0080200A /* DetailFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB812C3DBA0A0080200A /* DetailFeature.swift */; };\n\t\tEB85AB852C3DCC2B0080200A /* LaunchingFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB842C3DCC2B0080200A /* LaunchingFeature.swift */; };\n\t\tEB85AB872C3DCC300080200A /* SuccessFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB862C3DCC300080200A /* SuccessFeature.swift */; };\n\t\tEB85AB892C3DCC670080200A /* FailureFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB882C3DCC670080200A /* FailureFeature.swift */; };\n\t\tEB85AB8D2C3E4D8C0080200A /* DetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB8C2C3E4D8C0080200A /* DetailView.swift */; };\n\t\tEB85AB8F2C3E54CF0080200A /* WkWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB8E2C3E54CF0080200A /* WkWrapper.swift */; };\n\t\tEB85AB972C3E94DC0080200A /* IdleFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB962C3E94DC0080200A /* IdleFeature.swift */; };\n\t\tEB85AB992C3EAA410080200A /* SuccessView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB85AB982C3EAA410080200A /* SuccessView.swift */; };\n\t\tEB8624A72C47A03B0010E153 /* Texts.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB8624A62C47A03B0010E153 /* Texts.swift */; };\n\t\tEB8624A92C47B19D0010E153 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB8624A82C47B19D0010E153 /* File.swift */; };\n\t\tEB8BADE32C6E8FA60036B81E /* TestAppDropFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB8BADE22C6E8FA60036B81E /* TestAppDropFiles.swift */; };\n\t\tEB9355652C47E9D10055C90D /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9355642C47E9D10055C90D /* StatusView.swift */; };\n\t\tEB9355672C47F4E50055C90D /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9355662C47F4E50055C90D /* Image.swift */; };\n\t\tEB94442A2C42F6E50050F0D1 /* State.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9444192C42F6E50050F0D1 /* State.swift */; };\n\t\tEB94442C2C42F6E50050F0D1 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB94441B2C42F6E50050F0D1 /* AboutView.swift */; };\n\t\tEB94442E2C42F6E50050F0D1 /* AppDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9444222C42F6E50050F0D1 /* AppDataSource.swift */; };\n\t\tEB94442F2C42F6E50050F0D1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9444252C42F6E50050F0D1 /* ContentView.swift */; };\n\t\tEB9444302C42F6E50050F0D1 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9444212C42F6E50050F0D1 /* App.swift */; };\n\t\tEB9444312C42F6E50050F0D1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9444232C42F6E50050F0D1 /* AppDelegate.swift */; };\n\t\tEB9444332C42F6E50050F0D1 /* AppStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9444182C42F6E50050F0D1 /* AppStorage.swift */; };\n\t\tEB9444352C42F6E50050F0D1 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB94441F2C42F6E50050F0D1 /* WelcomeView.swift */; };\n\t\tEB9444362C42F6E50050F0D1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EB9444242C42F6E50050F0D1 /* Assets.xcassets */; };\n\t\tEB9444372C42F6E50050F0D1 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EB9444162C42F6E50050F0D1 /* Preview Assets.xcassets */; };\n\t\tEB94443F2C42F70E0050F0D1 /* pprofUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB94443D2C42F70E0050F0D1 /* pprofUITestsLaunchTests.swift */; };\n\t\tEB9444402C42F70E0050F0D1 /* pprofUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB94443C2C42F70E0050F0D1 /* pprofUITests.swift */; };\n\t\tEB96D98D2C470E9C00FA6E52 /* UTH.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB96D98B2C470E9C00FA6E52 /* UTH.swift */; };\n\t\tEB96D98E2C470E9C00FA6E52 /* UnderTheHoodView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB96D98C2C470E9C00FA6E52 /* UnderTheHoodView.swift */; };\n\t\tEBAA59FE2C485162006CF326 /* Whatever.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBAA59FD2C485162006CF326 /* Whatever.swift */; };\n\t\tEBB1899D2C430AD00037A8F4 /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = EBB1899C2C430AD00037A8F4 /* ComposableArchitecture */; };\n\t\tEBB37A982C40EFCB00D04474 /* DetectingHTTPView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB37A972C40EFCB00D04474 /* DetectingHTTPView.swift */; };\n\t\tEBB37A9A2C40F7F700D04474 /* Symbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB37A992C40F7F700D04474 /* Symbols.swift */; };\n\t\tEBB794862C410F0900D5AE1C /* AppFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB794852C410F0900D5AE1C /* AppFeature.swift */; };\n\t\tEBB794882C41146000D5AE1C /* PProfRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB794872C41146000D5AE1C /* PProfRowView.swift */; };\n\t\tEBBB83212C60BD2A002F2892 /* DefaultGzAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBB83202C60BD2A002F2892 /* DefaultGzAppView.swift */; };\n\t\tEBBB83232C60DB79002F2892 /* GraphvizGuideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBB83222C60DB79002F2892 /* GraphvizGuideView.swift */; };\n\t\tEBBB83272C60E4D6002F2892 /* NameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBB83262C60E4D6002F2892 /* NameView.swift */; };\n\t\tEBBB83292C60E673002F2892 /* NameFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBB83282C60E673002F2892 /* NameFeature.swift */; };\n\t\tEBBB832B2C60EC3A002F2892 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBB832A2C60EC3A002F2892 /* Date.swift */; };\n\t\tEBBC581A2C668A0F00A72918 /* TestDropFilesLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBC58192C668A0F00A72918 /* TestDropFilesLegacy.swift */; };\n\t\tEBBC581B2C668A0F00A72918 /* Dummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBC58172C668A0F00A72918 /* Dummy.swift */; };\n\t\tEBBC581C2C668A0F00A72918 /* b.pb in Resources */ = {isa = PBXBuildFile; fileRef = EBBC58162C668A0F00A72918 /* b.pb */; };\n\t\tEBBC581D2C668A0F00A72918 /* a.pb.gz in Resources */ = {isa = PBXBuildFile; fileRef = EBBC58152C668A0F00A72918 /* a.pb.gz */; };\n\t\tEBBC581F2C669A8100A72918 /* TestDropFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBC581E2C669A8100A72918 /* TestDropFiles.swift */; };\n\t\tEBC7C85E2C9DD31B00B330D3 /* DropAndAppendFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC7C85D2C9DD31B00B330D3 /* DropAndAppendFeature.swift */; };\n\t\tEBC7C8602C9DD32D00B330D3 /* DropAndAppendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC7C85F2C9DD32D00B330D3 /* DropAndAppendView.swift */; };\n\t\tEBD20FBD2C42D06300EE88D7 /* LightsOff.metal in Sources */ = {isa = PBXBuildFile; fileRef = EBD20FBC2C42D06300EE88D7 /* LightsOff.metal */; };\n\t\tEBD292B42C430F8000FFB285 /* ShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBD292B32C430F8000FFB285 /* ShortcutView.swift */; };\n\t\tEBD292BA2C430F9700FFB285 /* KeyboardShortcuts in Frameworks */ = {isa = PBXBuildFile; productRef = EBD292B92C430F9700FFB285 /* KeyboardShortcuts */; };\n\t\tEBD292BC2C43116400FFB285 /* SettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBD292BB2C43116400FFB285 /* SettingView.swift */; };\n\t\tEBD292BF2C43168100FFB285 /* Pow in Frameworks */ = {isa = PBXBuildFile; productRef = EBD292BE2C43168100FFB285 /* Pow */; };\n\t\tEBD293D32C43945000FFB285 /* AppShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBD293D22C43945000FFB285 /* AppShortcuts.swift */; };\n\t\tEBDCE9162C46D71E00B7DE83 /* PProfBasic.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBDCE9152C46D71E00B7DE83 /* PProfBasic.swift */; };\n\t\tEBDCE9182C46D78000B7DE83 /* PProfPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBDCE9172C46D78000B7DE83 /* PProfPresentation.swift */; };\n\t\tEBE8334C2C3C8AD400FD8A73 /* Hover.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE8334B2C3C8AD400FD8A73 /* Hover.swift */; };\n\t\tEBE8334F2C3C8BBD00FD8A73 /* Tooltip.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE8334E2C3C8BBD00FD8A73 /* Tooltip.swift */; };\n\t\tEBE833532C3C8D9500FD8A73 /* Ripple.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE833522C3C8D9500FD8A73 /* Ripple.swift */; };\n\t\tEBE833542C3C8D9500FD8A73 /* Ripple.metal in Sources */ = {isa = PBXBuildFile; fileRef = EBE833512C3C8D9500FD8A73 /* Ripple.metal */; };\n\t\tEBEAAACA2C467DD60026C328 /* DropAndImportFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBEAAAC92C467DD60026C328 /* DropAndImportFeature.swift */; };\n\t\tEBEC3ABB2C3D0F3C0016F878 /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBEC3ABA2C3D0F3C0016F878 /* Toolbar.swift */; };\n\t\tEBEF3C002C3BBECB0003477D /* Exts.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBEF3BF72C3BBECB0003477D /* Exts.swift */; };\n\t\tEBEF3C0B2C3BBF2A0003477D /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = EBEF3C0A2C3BBF2A0003477D /* Logging */; };\n\t\tEBFC00EF2C3D0AFE004A1B93 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBFC00EE2C3D0AFE004A1B93 /* Delay.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tEBEF3A302C3B255B0003477D /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = EBEF3A162C3B255A0003477D /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = EBEF3A1D2C3B255A0003477D;\n\t\t\tremoteInfo = pprof;\n\t\t};\n\t\tEBEF3A3A2C3B255B0003477D /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = EBEF3A162C3B255A0003477D /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = EBEF3A1D2C3B255A0003477D;\n\t\t\tremoteInfo = pprof;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\tEB7282EA2C4443AE00B29D14 /* pprrof executable */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t\tEB1F1FBD2C4589A400FD585E /* pprof in pprrof executable */,\n\t\t\t);\n\t\t\tname = \"pprrof executable\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\tEB0A27302C413CE400AD34ED /* NavigaionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigaionView.swift; sourceTree = \"<group>\"; };\n\t\tEB1003E82C4A81D4009E61F2 /* FloatTopTrailing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatTopTrailing.swift; sourceTree = \"<group>\"; };\n\t\tEB1003EA2C4A8BC0009E61F2 /* CountDown.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDown.swift; sourceTree = \"<group>\"; };\n\t\tEB1003EC2C4A9860009E61F2 /* NotificationFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFeature.swift; sourceTree = \"<group>\"; };\n\t\tEB11A5152C4515C500E696DF /* WKState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKState.swift; sourceTree = \"<group>\"; };\n\t\tEB170FF22C40697100945866 /* Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = \"<group>\"; };\n\t\tEB17F1F52C48169A00ED297A /* FileRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRowView.swift; sourceTree = \"<group>\"; };\n\t\tEB1F1FC02C45AEB700FD585E /* Shortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shortcuts.swift; sourceTree = \"<group>\"; };\n\t\tEB1F1FC22C45B2B300FD585E /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = \"<group>\"; };\n\t\tEB1F1FC42C45B38D00FD585E /* Color+Luminance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Color+Luminance.swift\"; sourceTree = \"<group>\"; };\n\t\tEB2619742C60AD0A007D4932 /* test-default-app.pb.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = \"test-default-app.pb.gz\"; sourceTree = \"<group>\"; };\n\t\tEB2A0B492C4663CB0085609E /* CommandGenerate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandGenerate.swift; sourceTree = \"<group>\"; };\n\t\tEB5026802C3D139F007C6282 /* Other.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Other.swift; sourceTree = \"<group>\"; };\n\t\tEB59362E2C4053D200088AB9 /* Others.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Others.swift; sourceTree = \"<group>\"; };\n\t\tEB62B5802C5FE9FD00188A9D /* ImportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportView.swift; sourceTree = \"<group>\"; };\n\t\tEB62B5842C5FEB0700188A9D /* FileListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileListView.swift; sourceTree = \"<group>\"; };\n\t\tEB62B5862C5FEB9200188A9D /* CommandPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandPreviewView.swift; sourceTree = \"<group>\"; };\n\t\tEB62B5882C5FEBC900188A9D /* TerminalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalView.swift; sourceTree = \"<group>\"; };\n\t\tEB62B58A2C5FEC1B00188A9D /* ActionButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionButtonView.swift; sourceTree = \"<group>\"; };\n\t\tEB62B58E2C5FED3800188A9D /* ShortcutsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsView.swift; sourceTree = \"<group>\"; };\n\t\tEB62B5902C5FEEE800188A9D /* PerviewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerviewData.swift; sourceTree = \"<group>\"; };\n\t\tEB6530F42C41C09800A66B7C /* DropAndImportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropAndImportView.swift; sourceTree = \"<group>\"; };\n\t\tEB6530FA2C41CF8D00A66B7C /* WebIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebIndicatorView.swift; sourceTree = \"<group>\"; };\n\t\tEB659BC42C3EE91400F3F84E /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = \"<group>\"; };\n\t\tEB6E4C072C45424B005C1225 /* ci_post_clone.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_post_clone.sh; sourceTree = \"<group>\"; };\n\t\tEB6E4C092C4542AF005C1225 /* macros.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = macros.json; sourceTree = \"<group>\"; };\n\t\tEB72830A2C44523F00B29D14 /* pprof */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.executable\"; path = pprof; sourceTree = \"<group>\"; };\n\t\tEB7ADFC52C439CE500130909 /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = \"<group>\"; };\n\t\tEB8190C92C4571F8007EDE72 /* GradientBackgroundAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientBackgroundAnimation.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB812C3DBA0A0080200A /* DetailFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailFeature.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB842C3DCC2B0080200A /* LaunchingFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchingFeature.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB862C3DCC300080200A /* SuccessFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessFeature.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB882C3DCC670080200A /* FailureFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FailureFeature.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB8C2C3E4D8C0080200A /* DetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailView.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB8E2C3E54CF0080200A /* WkWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WkWrapper.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB962C3E94DC0080200A /* IdleFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdleFeature.swift; sourceTree = \"<group>\"; };\n\t\tEB85AB982C3EAA410080200A /* SuccessView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessView.swift; sourceTree = \"<group>\"; };\n\t\tEB8624A62C47A03B0010E153 /* Texts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Texts.swift; sourceTree = \"<group>\"; };\n\t\tEB8624A82C47B19D0010E153 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = \"<group>\"; };\n\t\tEB8BADE22C6E8FA60036B81E /* TestAppDropFiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestAppDropFiles.swift; sourceTree = \"<group>\"; };\n\t\tEB9355642C47E9D10055C90D /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = \"<group>\"; };\n\t\tEB9355662C47F4E50055C90D /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = \"<group>\"; };\n\t\tEB9444162C42F6E50050F0D1 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = \"Preview Assets.xcassets\"; sourceTree = \"<group>\"; };\n\t\tEB9444182C42F6E50050F0D1 /* AppStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorage.swift; sourceTree = \"<group>\"; };\n\t\tEB9444192C42F6E50050F0D1 /* State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = State.swift; sourceTree = \"<group>\"; };\n\t\tEB94441B2C42F6E50050F0D1 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = \"<group>\"; };\n\t\tEB94441F2C42F6E50050F0D1 /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = \"<group>\"; };\n\t\tEB9444212C42F6E50050F0D1 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = \"<group>\"; };\n\t\tEB9444222C42F6E50050F0D1 /* AppDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDataSource.swift; sourceTree = \"<group>\"; };\n\t\tEB9444232C42F6E50050F0D1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\tEB9444242C42F6E50050F0D1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tEB9444252C42F6E50050F0D1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = \"<group>\"; };\n\t\tEB9444272C42F6E50050F0D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tEB9444282C42F6E50050F0D1 /* pprof.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = pprof.entitlements; sourceTree = \"<group>\"; };\n\t\tEB94443C2C42F70E0050F0D1 /* pprofUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = pprofUITests.swift; sourceTree = \"<group>\"; };\n\t\tEB94443D2C42F70E0050F0D1 /* pprofUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = pprofUITestsLaunchTests.swift; sourceTree = \"<group>\"; };\n\t\tEB96D98B2C470E9C00FA6E52 /* UTH.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTH.swift; sourceTree = \"<group>\"; };\n\t\tEB96D98C2C470E9C00FA6E52 /* UnderTheHoodView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderTheHoodView.swift; sourceTree = \"<group>\"; };\n\t\tEBAA59FD2C485162006CF326 /* Whatever.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Whatever.swift; sourceTree = \"<group>\"; };\n\t\tEBB37A972C40EFCB00D04474 /* DetectingHTTPView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectingHTTPView.swift; sourceTree = \"<group>\"; };\n\t\tEBB37A992C40F7F700D04474 /* Symbols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Symbols.swift; sourceTree = \"<group>\"; };\n\t\tEBB794852C410F0900D5AE1C /* AppFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppFeature.swift; sourceTree = \"<group>\"; };\n\t\tEBB794872C41146000D5AE1C /* PProfRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PProfRowView.swift; sourceTree = \"<group>\"; };\n\t\tEBBB83202C60BD2A002F2892 /* DefaultGzAppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultGzAppView.swift; sourceTree = \"<group>\"; };\n\t\tEBBB83222C60DB79002F2892 /* GraphvizGuideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphvizGuideView.swift; sourceTree = \"<group>\"; };\n\t\tEBBB83262C60E4D6002F2892 /* NameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NameView.swift; sourceTree = \"<group>\"; };\n\t\tEBBB83282C60E673002F2892 /* NameFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NameFeature.swift; sourceTree = \"<group>\"; };\n\t\tEBBB832A2C60EC3A002F2892 /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = \"<group>\"; };\n\t\tEBBC58152C668A0F00A72918 /* a.pb.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = a.pb.gz; sourceTree = \"<group>\"; };\n\t\tEBBC58162C668A0F00A72918 /* b.pb */ = {isa = PBXFileReference; lastKnownFileType = file; path = b.pb; sourceTree = \"<group>\"; };\n\t\tEBBC58172C668A0F00A72918 /* Dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dummy.swift; sourceTree = \"<group>\"; };\n\t\tEBBC58192C668A0F00A72918 /* TestDropFilesLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestDropFilesLegacy.swift; sourceTree = \"<group>\"; };\n\t\tEBBC581E2C669A8100A72918 /* TestDropFiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestDropFiles.swift; sourceTree = \"<group>\"; };\n\t\tEBBC58202C669B0500A72918 /* TestPlan.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = TestPlan.xctestplan; path = approfTests/TestPlan.xctestplan; sourceTree = \"<group>\"; };\n\t\tEBC7C85D2C9DD31B00B330D3 /* DropAndAppendFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropAndAppendFeature.swift; sourceTree = \"<group>\"; };\n\t\tEBC7C85F2C9DD32D00B330D3 /* DropAndAppendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropAndAppendView.swift; sourceTree = \"<group>\"; };\n\t\tEBD20FBC2C42D06300EE88D7 /* LightsOff.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = LightsOff.metal; sourceTree = \"<group>\"; };\n\t\tEBD292B32C430F8000FFB285 /* ShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutView.swift; sourceTree = \"<group>\"; };\n\t\tEBD292BB2C43116400FFB285 /* SettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingView.swift; sourceTree = \"<group>\"; };\n\t\tEBD293D22C43945000FFB285 /* AppShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppShortcuts.swift; sourceTree = \"<group>\"; };\n\t\tEBDCE9152C46D71E00B7DE83 /* PProfBasic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PProfBasic.swift; sourceTree = \"<group>\"; };\n\t\tEBDCE9172C46D78000B7DE83 /* PProfPresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PProfPresentation.swift; sourceTree = \"<group>\"; };\n\t\tEBE8334B2C3C8AD400FD8A73 /* Hover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hover.swift; sourceTree = \"<group>\"; };\n\t\tEBE8334E2C3C8BBD00FD8A73 /* Tooltip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tooltip.swift; sourceTree = \"<group>\"; };\n\t\tEBE833512C3C8D9500FD8A73 /* Ripple.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Ripple.metal; sourceTree = \"<group>\"; };\n\t\tEBE833522C3C8D9500FD8A73 /* Ripple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ripple.swift; sourceTree = \"<group>\"; };\n\t\tEBEAAAC92C467DD60026C328 /* DropAndImportFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropAndImportFeature.swift; sourceTree = \"<group>\"; };\n\t\tEBEC3ABA2C3D0F3C0016F878 /* Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toolbar.swift; sourceTree = \"<group>\"; };\n\t\tEBEF3A1E2C3B255A0003477D /* approf.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = approf.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tEBEF3A2F2C3B255B0003477D /* approfTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = approfTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tEBEF3A392C3B255B0003477D /* approfUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = approfUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tEBEF3BF72C3BBECB0003477D /* Exts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exts.swift; sourceTree = \"<group>\"; };\n\t\tEBEF3BFC2C3BBECB0003477D /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = \"<group>\"; };\n\t\tEBFC00EE2C3D0AFE004A1B93 /* Delay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Delay.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFileSystemSynchronizedRootGroup section */\n\t\tEB7D79402C65635200CCD4F3 /* .github */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = .github; sourceTree = \"<group>\"; };\n/* End PBXFileSystemSynchronizedRootGroup section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tEBEF3A1B2C3B255A0003477D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEB1003E72C4A7EFC009E61F2 /* PopupView in Frameworks */,\n\t\t\t\tEBD292BF2C43168100FFB285 /* Pow in Frameworks */,\n\t\t\t\tEBD292BA2C430F9700FFB285 /* KeyboardShortcuts in Frameworks */,\n\t\t\t\tEBB1899D2C430AD00037A8F4 /* ComposableArchitecture in Frameworks */,\n\t\t\t\tEBEF3C0B2C3BBF2A0003477D /* Logging in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEBEF3A2C2C3B255B0003477D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEBEF3A362C3B255B0003477D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tEB13E2C12C499E5E00484479 /* Setting */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBD292BB2C43116400FFB285 /* SettingView.swift */,\n\t\t\t\tEBBB83222C60DB79002F2892 /* GraphvizGuideView.swift */,\n\t\t\t\tEBBB83202C60BD2A002F2892 /* DefaultGzAppView.swift */,\n\t\t\t);\n\t\t\tpath = Setting;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB170FF12C40696600945866 /* Component */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB1003EA2C4A8BC0009E61F2 /* CountDown.swift */,\n\t\t\t\tEB1003E82C4A81D4009E61F2 /* FloatTopTrailing.swift */,\n\t\t\t\tEB8624A62C47A03B0010E153 /* Texts.swift */,\n\t\t\t\tEB170FF22C40697100945866 /* Buttons.swift */,\n\t\t\t\tEBB37A992C40F7F700D04474 /* Symbols.swift */,\n\t\t\t\tEBE833502C3C8D7F00FD8A73 /* effcts */,\n\t\t\t);\n\t\t\tpath = Component;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB2A0B482C4663A10085609E /* App */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBD293D22C43945000FFB285 /* AppShortcuts.swift */,\n\t\t\t\tEB9444222C42F6E50050F0D1 /* AppDataSource.swift */,\n\t\t\t\tEB9444232C42F6E50050F0D1 /* AppDelegate.swift */,\n\t\t\t);\n\t\t\tpath = App;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB62B5912C5FEEE800188A9D /* Preview */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB62B5902C5FEEE800188A9D /* PerviewData.swift */,\n\t\t\t);\n\t\t\tpath = Preview;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB6E4C082C45424B005C1225 /* ci_scripts */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB6E4C072C45424B005C1225 /* ci_post_clone.sh */,\n\t\t\t\tEB6E4C092C4542AF005C1225 /* macros.json */,\n\t\t\t);\n\t\t\tpath = ci_scripts;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB8190EE2C45852F007EDE72 /* DragNDrop */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBEAAAC92C467DD60026C328 /* DropAndImportFeature.swift */,\n\t\t\t\tEB6530F42C41C09800A66B7C /* DropAndImportView.swift */,\n\t\t\t\tEBC7C85D2C9DD31B00B330D3 /* DropAndAppendFeature.swift */,\n\t\t\t\tEBC7C85F2C9DD32D00B330D3 /* DropAndAppendView.swift */,\n\t\t\t\tEB62B5802C5FE9FD00188A9D /* ImportView.swift */,\n\t\t\t);\n\t\t\tpath = DragNDrop;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB9444172C42F6E50050F0D1 /* Preview Content */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB9444162C42F6E50050F0D1 /* Preview Assets.xcassets */,\n\t\t\t);\n\t\t\tpath = \"Preview Content\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB94441A2C42F6E50050F0D1 /* State */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB9444182C42F6E50050F0D1 /* AppStorage.swift */,\n\t\t\t\tEB9444192C42F6E50050F0D1 /* State.swift */,\n\t\t\t\tEB11A5152C4515C500E696DF /* WKState.swift */,\n\t\t\t);\n\t\t\tpath = State;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB9444202C42F6E50050F0D1 /* View */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB13E2C12C499E5E00484479 /* Setting */,\n\t\t\t\tEB8190EE2C45852F007EDE72 /* DragNDrop */,\n\t\t\t\tEBB794852C410F0900D5AE1C /* AppFeature.swift */,\n\t\t\t\tEB0A27302C413CE400AD34ED /* NavigaionView.swift */,\n\t\t\t\tEB85AB812C3DBA0A0080200A /* DetailFeature.swift */,\n\t\t\t\tEB85AB8C2C3E4D8C0080200A /* DetailView.swift */,\n\t\t\t\tEB85AB962C3E94DC0080200A /* IdleFeature.swift */,\n\t\t\t\tEB85AB842C3DCC2B0080200A /* LaunchingFeature.swift */,\n\t\t\t\tEB96D9882C470E5600FA6E52 /* UnderTheHood */,\n\t\t\t\tEBB37A972C40EFCB00D04474 /* DetectingHTTPView.swift */,\n\t\t\t\tEB85AB862C3DCC300080200A /* SuccessFeature.swift */,\n\t\t\t\tEB85AB982C3EAA410080200A /* SuccessView.swift */,\n\t\t\t\tEB6530FA2C41CF8D00A66B7C /* WebIndicatorView.swift */,\n\t\t\t\tEB85AB882C3DCC670080200A /* FailureFeature.swift */,\n\t\t\t\tEB85AB8E2C3E54CF0080200A /* WkWrapper.swift */,\n\t\t\t\tEBB794872C41146000D5AE1C /* PProfRowView.swift */,\n\t\t\t\tEB94441B2C42F6E50050F0D1 /* AboutView.swift */,\n\t\t\t\tEB94441F2C42F6E50050F0D1 /* WelcomeView.swift */,\n\t\t\t\tEBD292B32C430F8000FFB285 /* ShortcutView.swift */,\n\t\t\t);\n\t\t\tpath = View;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB9444292C42F6E50050F0D1 /* approf */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB9444212C42F6E50050F0D1 /* App.swift */,\n\t\t\t\tEB2A0B482C4663A10085609E /* App */,\n\t\t\t\tEB7ADFC52C439CE500130909 /* WindowController.swift */,\n\t\t\t\tEB9444252C42F6E50050F0D1 /* ContentView.swift */,\n\t\t\t\tEBDCE9142C46D70400B7DE83 /* Types */,\n\t\t\t\tEB94441A2C42F6E50050F0D1 /* State */,\n\t\t\t\tEB9444202C42F6E50050F0D1 /* View */,\n\t\t\t\tEBD292B22C430E8B00FFB285 /* Process */,\n\t\t\t\tEB170FF12C40696600945866 /* Component */,\n\t\t\t\tEBE8334D2C3C8AE900FD8A73 /* SwiftUI AppKit */,\n\t\t\t\tEB62B5912C5FEEE800188A9D /* Preview */,\n\t\t\t\tEBEF3BF72C3BBECB0003477D /* Exts.swift */,\n\t\t\t\tEB9444242C42F6E50050F0D1 /* Assets.xcassets */,\n\t\t\t\tEB9444272C42F6E50050F0D1 /* Info.plist */,\n\t\t\t\tEB9444282C42F6E50050F0D1 /* pprof.entitlements */,\n\t\t\t\tEB9444172C42F6E50050F0D1 /* Preview Content */,\n\t\t\t);\n\t\t\tpath = approf;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB94443A2C42F7050050F0D1 /* approfTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBBC58182C668A0F00A72918 /* Files */,\n\t\t\t\tEBBC58192C668A0F00A72918 /* TestDropFilesLegacy.swift */,\n\t\t\t\tEBBC581E2C669A8100A72918 /* TestDropFiles.swift */,\n\t\t\t\tEB8BADE22C6E8FA60036B81E /* TestAppDropFiles.swift */,\n\t\t\t);\n\t\t\tpath = approfTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB94443E2C42F70E0050F0D1 /* approfUITests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB94443C2C42F70E0050F0D1 /* pprofUITests.swift */,\n\t\t\t\tEB94443D2C42F70E0050F0D1 /* pprofUITestsLaunchTests.swift */,\n\t\t\t);\n\t\t\tpath = approfUITests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEB96D9882C470E5600FA6E52 /* UnderTheHood */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB96D98B2C470E9C00FA6E52 /* UTH.swift */,\n\t\t\t\tEB96D98C2C470E9C00FA6E52 /* UnderTheHoodView.swift */,\n\t\t\t\tEB62B58E2C5FED3800188A9D /* ShortcutsView.swift */,\n\t\t\t\tEB62B58A2C5FEC1B00188A9D /* ActionButtonView.swift */,\n\t\t\t\tEB62B5882C5FEBC900188A9D /* TerminalView.swift */,\n\t\t\t\tEB62B5842C5FEB0700188A9D /* FileListView.swift */,\n\t\t\t\tEBBB83262C60E4D6002F2892 /* NameView.swift */,\n\t\t\t\tEBBB83282C60E673002F2892 /* NameFeature.swift */,\n\t\t\t\tEB17F1F52C48169A00ED297A /* FileRowView.swift */,\n\t\t\t\tEB62B5862C5FEB9200188A9D /* CommandPreviewView.swift */,\n\t\t\t\tEB9355642C47E9D10055C90D /* StatusView.swift */,\n\t\t\t\tEB1003EC2C4A9860009E61F2 /* NotificationFeature.swift */,\n\t\t\t);\n\t\t\tpath = UnderTheHood;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBBC58182C668A0F00A72918 /* Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBBC58152C668A0F00A72918 /* a.pb.gz */,\n\t\t\t\tEBBC58162C668A0F00A72918 /* b.pb */,\n\t\t\t\tEBBC58172C668A0F00A72918 /* Dummy.swift */,\n\t\t\t);\n\t\t\tpath = Files;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBD292B22C430E8B00FFB285 /* Process */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB2619742C60AD0A007D4932 /* test-default-app.pb.gz */,\n\t\t\t\tEB2A0B492C4663CB0085609E /* CommandGenerate.swift */,\n\t\t\t\tEB659BC42C3EE91400F3F84E /* Command.swift */,\n\t\t\t\tEBEF3BFC2C3BBECB0003477D /* README.md */,\n\t\t\t\tEB72830A2C44523F00B29D14 /* pprof */,\n\t\t\t\tEBAA59FD2C485162006CF326 /* Whatever.swift */,\n\t\t\t);\n\t\t\tpath = Process;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBDCE9142C46D70400B7DE83 /* Types */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBDCE9152C46D71E00B7DE83 /* PProfBasic.swift */,\n\t\t\t\tEBDCE9172C46D78000B7DE83 /* PProfPresentation.swift */,\n\t\t\t\tEB59362E2C4053D200088AB9 /* Others.swift */,\n\t\t\t);\n\t\t\tpath = Types;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBE8334D2C3C8AE900FD8A73 /* SwiftUI AppKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBE8334B2C3C8AD400FD8A73 /* Hover.swift */,\n\t\t\t\tEBE8334E2C3C8BBD00FD8A73 /* Tooltip.swift */,\n\t\t\t\tEBFC00EE2C3D0AFE004A1B93 /* Delay.swift */,\n\t\t\t\tEBBB832A2C60EC3A002F2892 /* Date.swift */,\n\t\t\t\tEBEC3ABA2C3D0F3C0016F878 /* Toolbar.swift */,\n\t\t\t\tEB5026802C3D139F007C6282 /* Other.swift */,\n\t\t\t\tEB1F1FC02C45AEB700FD585E /* Shortcuts.swift */,\n\t\t\t\tEB1F1FC22C45B2B300FD585E /* Color.swift */,\n\t\t\t\tEB1F1FC42C45B38D00FD585E /* Color+Luminance.swift */,\n\t\t\t\tEB8624A82C47B19D0010E153 /* File.swift */,\n\t\t\t\tEB9355662C47F4E50055C90D /* Image.swift */,\n\t\t\t);\n\t\t\tpath = \"SwiftUI AppKit\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBE833502C3C8D7F00FD8A73 /* effcts */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEB8190C92C4571F8007EDE72 /* GradientBackgroundAnimation.swift */,\n\t\t\t\tEBE833512C3C8D9500FD8A73 /* Ripple.metal */,\n\t\t\t\tEBD20FBC2C42D06300EE88D7 /* LightsOff.metal */,\n\t\t\t\tEBE833522C3C8D9500FD8A73 /* Ripple.swift */,\n\t\t\t);\n\t\t\tpath = effcts;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBEF3A152C3B255A0003477D = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBBC58202C669B0500A72918 /* TestPlan.xctestplan */,\n\t\t\t\tEB7D79402C65635200CCD4F3 /* .github */,\n\t\t\t\tEB9444292C42F6E50050F0D1 /* approf */,\n\t\t\t\tEB94443A2C42F7050050F0D1 /* approfTests */,\n\t\t\t\tEB94443E2C42F70E0050F0D1 /* approfUITests */,\n\t\t\t\tEBEF3A1F2C3B255A0003477D /* Products */,\n\t\t\t\tEBEF3C092C3BBF2A0003477D /* Frameworks */,\n\t\t\t\tEB6E4C082C45424B005C1225 /* ci_scripts */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBEF3A1F2C3B255A0003477D /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEBEF3A1E2C3B255A0003477D /* approf.app */,\n\t\t\t\tEBEF3A2F2C3B255B0003477D /* approfTests.xctest */,\n\t\t\t\tEBEF3A392C3B255B0003477D /* approfUITests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEBEF3C092C3BBF2A0003477D /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tEBEF3A1D2C3B255A0003477D /* approf */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = EBEF3A432C3B255B0003477D /* Build configuration list for PBXNativeTarget \"approf\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tEBEF3A1A2C3B255A0003477D /* Sources */,\n\t\t\t\tEBEF3A1B2C3B255A0003477D /* Frameworks */,\n\t\t\t\tEBEF3A1C2C3B255A0003477D /* Resources */,\n\t\t\t\tEB7282EA2C4443AE00B29D14 /* pprrof executable */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = approf;\n\t\t\tpackageProductDependencies = (\n\t\t\t\tEBEF3C0A2C3BBF2A0003477D /* Logging */,\n\t\t\t\tEBB1899C2C430AD00037A8F4 /* ComposableArchitecture */,\n\t\t\t\tEBD292B92C430F9700FFB285 /* KeyboardShortcuts */,\n\t\t\t\tEBD292BE2C43168100FFB285 /* Pow */,\n\t\t\t\tEB1003E62C4A7EFC009E61F2 /* PopupView */,\n\t\t\t);\n\t\t\tproductName = pprof;\n\t\t\tproductReference = EBEF3A1E2C3B255A0003477D /* approf.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\tEBEF3A2E2C3B255B0003477D /* approfTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = EBEF3A462C3B255B0003477D /* Build configuration list for PBXNativeTarget \"approfTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tEBEF3A2B2C3B255B0003477D /* Sources */,\n\t\t\t\tEBEF3A2C2C3B255B0003477D /* Frameworks */,\n\t\t\t\tEBEF3A2D2C3B255B0003477D /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tEBEF3A312C3B255B0003477D /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = approfTests;\n\t\t\tproductName = pprofTests;\n\t\t\tproductReference = EBEF3A2F2C3B255B0003477D /* approfTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\tEBEF3A382C3B255B0003477D /* approfUITests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = EBEF3A492C3B255B0003477D /* Build configuration list for PBXNativeTarget \"approfUITests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tEBEF3A352C3B255B0003477D /* Sources */,\n\t\t\t\tEBEF3A362C3B255B0003477D /* Frameworks */,\n\t\t\t\tEBEF3A372C3B255B0003477D /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tEBEF3A3B2C3B255B0003477D /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = approfUITests;\n\t\t\tproductName = pprofUITests;\n\t\t\tproductReference = EBEF3A392C3B255B0003477D /* approfUITests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.ui-testing\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tEBEF3A162C3B255A0003477D /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = 1;\n\t\t\t\tLastSwiftUpdateCheck = 1600;\n\t\t\t\tLastUpgradeCheck = 1600;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tEBEF3A1D2C3B255A0003477D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 16.0;\n\t\t\t\t\t};\n\t\t\t\t\tEBEF3A2E2C3B255B0003477D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 16.0;\n\t\t\t\t\t\tTestTargetID = EBEF3A1D2C3B255A0003477D;\n\t\t\t\t\t};\n\t\t\t\t\tEBEF3A382C3B255B0003477D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 16.0;\n\t\t\t\t\t\tTestTargetID = EBEF3A1D2C3B255A0003477D;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = EBEF3A192C3B255A0003477D /* Build configuration list for PBXProject \"approf\" */;\n\t\t\tcompatibilityVersion = \"Xcode 15.0\";\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 = EBEF3A152C3B255A0003477D;\n\t\t\tpackageReferences = (\n\t\t\t\tEBEF3C072C3BBEF80003477D /* XCRemoteSwiftPackageReference \"swift-log\" */,\n\t\t\t\tEB3BC5B92C430A6700C9920F /* XCRemoteSwiftPackageReference \"swift-composable-architecture\" */,\n\t\t\t\tEBD292B12C430D5800FFB285 /* XCRemoteSwiftPackageReference \"KeyboardShortcuts\" */,\n\t\t\t\tEBD292BD2C43151A00FFB285 /* XCRemoteSwiftPackageReference \"Pow\" */,\n\t\t\t\tEB1003E52C4A7EEC009E61F2 /* XCRemoteSwiftPackageReference \"PopupView\" */,\n\t\t\t);\n\t\t\tproductRefGroup = EBEF3A1F2C3B255A0003477D /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tEBEF3A1D2C3B255A0003477D /* approf */,\n\t\t\t\tEBEF3A2E2C3B255B0003477D /* approfTests */,\n\t\t\t\tEBEF3A382C3B255B0003477D /* approfUITests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tEBEF3A1C2C3B255A0003477D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEB9444362C42F6E50050F0D1 /* Assets.xcassets in Resources */,\n\t\t\t\tEB9444372C42F6E50050F0D1 /* Preview Assets.xcassets in Resources */,\n\t\t\t\tEB2619752C60AD0A007D4932 /* test-default-app.pb.gz in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEBEF3A2D2C3B255B0003477D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEBBC581C2C668A0F00A72918 /* b.pb in Resources */,\n\t\t\t\tEBBC581D2C668A0F00A72918 /* a.pb.gz in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEBEF3A372C3B255B0003477D /* 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/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tEBEF3A1A2C3B255A0003477D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEB0A27312C413CE400AD34ED /* NavigaionView.swift in Sources */,\n\t\t\t\tEBD292B42C430F8000FFB285 /* ShortcutView.swift in Sources */,\n\t\t\t\tEBC7C8602C9DD32D00B330D3 /* DropAndAppendView.swift in Sources */,\n\t\t\t\tEB6530FB2C41CF8D00A66B7C /* WebIndicatorView.swift in Sources */,\n\t\t\t\tEBBB832B2C60EC3A002F2892 /* Date.swift in Sources */,\n\t\t\t\tEBEC3ABB2C3D0F3C0016F878 /* Toolbar.swift in Sources */,\n\t\t\t\tEB94442A2C42F6E50050F0D1 /* State.swift in Sources */,\n\t\t\t\tEB2A0B4A2C4663CB0085609E /* CommandGenerate.swift in Sources */,\n\t\t\t\tEBDCE9182C46D78000B7DE83 /* PProfPresentation.swift in Sources */,\n\t\t\t\tEB94442C2C42F6E50050F0D1 /* AboutView.swift in Sources */,\n\t\t\t\tEB11A5162C4515C500E696DF /* WKState.swift in Sources */,\n\t\t\t\tEB62B5872C5FEB9200188A9D /* CommandPreviewView.swift in Sources */,\n\t\t\t\tEB1F1FC12C45AEB700FD585E /* Shortcuts.swift in Sources */,\n\t\t\t\tEB1003EB2C4A8BC0009E61F2 /* CountDown.swift in Sources */,\n\t\t\t\tEB94442E2C42F6E50050F0D1 /* AppDataSource.swift in Sources */,\n\t\t\t\tEB94442F2C42F6E50050F0D1 /* ContentView.swift in Sources */,\n\t\t\t\tEB9355652C47E9D10055C90D /* StatusView.swift in Sources */,\n\t\t\t\tEB9444302C42F6E50050F0D1 /* App.swift in Sources */,\n\t\t\t\tEB9444312C42F6E50050F0D1 /* AppDelegate.swift in Sources */,\n\t\t\t\tEB9444332C42F6E50050F0D1 /* AppStorage.swift in Sources */,\n\t\t\t\tEB9444352C42F6E50050F0D1 /* WelcomeView.swift in Sources */,\n\t\t\t\tEBDCE9162C46D71E00B7DE83 /* PProfBasic.swift in Sources */,\n\t\t\t\tEB170FF32C40697100945866 /* Buttons.swift in Sources */,\n\t\t\t\tEBBB83212C60BD2A002F2892 /* DefaultGzAppView.swift in Sources */,\n\t\t\t\tEB8624A72C47A03B0010E153 /* Texts.swift in Sources */,\n\t\t\t\tEB85AB8D2C3E4D8C0080200A /* DetailView.swift in Sources */,\n\t\t\t\tEB85AB872C3DCC300080200A /* SuccessFeature.swift in Sources */,\n\t\t\t\tEB96D98D2C470E9C00FA6E52 /* UTH.swift in Sources */,\n\t\t\t\tEB1003E92C4A81D4009E61F2 /* FloatTopTrailing.swift in Sources */,\n\t\t\t\tEB9355672C47F4E50055C90D /* Image.swift in Sources */,\n\t\t\t\tEB96D98E2C470E9C00FA6E52 /* UnderTheHoodView.swift in Sources */,\n\t\t\t\tEBB794862C410F0900D5AE1C /* AppFeature.swift in Sources */,\n\t\t\t\tEBE8334F2C3C8BBD00FD8A73 /* Tooltip.swift in Sources */,\n\t\t\t\tEB62B58B2C5FEC1B00188A9D /* ActionButtonView.swift in Sources */,\n\t\t\t\tEB62B5892C5FEBC900188A9D /* TerminalView.swift in Sources */,\n\t\t\t\tEBD20FBD2C42D06300EE88D7 /* LightsOff.metal in Sources */,\n\t\t\t\tEB85AB822C3DBA0A0080200A /* DetailFeature.swift in Sources */,\n\t\t\t\tEBD292BC2C43116400FFB285 /* SettingView.swift in Sources */,\n\t\t\t\tEBAA59FE2C485162006CF326 /* Whatever.swift in Sources */,\n\t\t\t\tEBEF3C002C3BBECB0003477D /* Exts.swift in Sources */,\n\t\t\t\tEBE833532C3C8D9500FD8A73 /* Ripple.swift in Sources */,\n\t\t\t\tEBD293D32C43945000FFB285 /* AppShortcuts.swift in Sources */,\n\t\t\t\tEB62B5852C5FEB0700188A9D /* FileListView.swift in Sources */,\n\t\t\t\tEBEAAACA2C467DD60026C328 /* DropAndImportFeature.swift in Sources */,\n\t\t\t\tEBB37A982C40EFCB00D04474 /* DetectingHTTPView.swift in Sources */,\n\t\t\t\tEB8190CA2C4571F8007EDE72 /* GradientBackgroundAnimation.swift in Sources */,\n\t\t\t\tEB17F1F62C48169A00ED297A /* FileRowView.swift in Sources */,\n\t\t\t\tEBBB83272C60E4D6002F2892 /* NameView.swift in Sources */,\n\t\t\t\tEB62B5922C5FEEE800188A9D /* PerviewData.swift in Sources */,\n\t\t\t\tEB85AB8F2C3E54CF0080200A /* WkWrapper.swift in Sources */,\n\t\t\t\tEBE833542C3C8D9500FD8A73 /* Ripple.metal in Sources */,\n\t\t\t\tEB7ADFC62C439CE500130909 /* WindowController.swift in Sources */,\n\t\t\t\tEBBB83232C60DB79002F2892 /* GraphvizGuideView.swift in Sources */,\n\t\t\t\tEBB37A9A2C40F7F700D04474 /* Symbols.swift in Sources */,\n\t\t\t\tEB59362F2C4053D200088AB9 /* Others.swift in Sources */,\n\t\t\t\tEBE8334C2C3C8AD400FD8A73 /* Hover.swift in Sources */,\n\t\t\t\tEB62B58F2C5FED3800188A9D /* ShortcutsView.swift in Sources */,\n\t\t\t\tEBC7C85E2C9DD31B00B330D3 /* DropAndAppendFeature.swift in Sources */,\n\t\t\t\tEBBB83292C60E673002F2892 /* NameFeature.swift in Sources */,\n\t\t\t\tEBB794882C41146000D5AE1C /* PProfRowView.swift in Sources */,\n\t\t\t\tEB1F1FC32C45B2B300FD585E /* Color.swift in Sources */,\n\t\t\t\tEB62B5812C5FE9FD00188A9D /* ImportView.swift in Sources */,\n\t\t\t\tEB85AB972C3E94DC0080200A /* IdleFeature.swift in Sources */,\n\t\t\t\tEB5026812C3D139F007C6282 /* Other.swift in Sources */,\n\t\t\t\tEB659BC52C3EE91400F3F84E /* Command.swift in Sources */,\n\t\t\t\tEB85AB992C3EAA410080200A /* SuccessView.swift in Sources */,\n\t\t\t\tEB85AB892C3DCC670080200A /* FailureFeature.swift in Sources */,\n\t\t\t\tEB1003ED2C4A9860009E61F2 /* NotificationFeature.swift in Sources */,\n\t\t\t\tEB1F1FC52C45B38D00FD585E /* Color+Luminance.swift in Sources */,\n\t\t\t\tEB6530F52C41C09800A66B7C /* DropAndImportView.swift in Sources */,\n\t\t\t\tEB85AB852C3DCC2B0080200A /* LaunchingFeature.swift in Sources */,\n\t\t\t\tEB8624A92C47B19D0010E153 /* File.swift in Sources */,\n\t\t\t\tEBFC00EF2C3D0AFE004A1B93 /* Delay.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEBEF3A2B2C3B255B0003477D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEBBC581A2C668A0F00A72918 /* TestDropFilesLegacy.swift in Sources */,\n\t\t\t\tEBBC581B2C668A0F00A72918 /* Dummy.swift in Sources */,\n\t\t\t\tEB8BADE32C6E8FA60036B81E /* TestAppDropFiles.swift in Sources */,\n\t\t\t\tEBBC581F2C669A8100A72918 /* TestDropFiles.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEBEF3A352C3B255B0003477D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEB94443F2C42F70E0050F0D1 /* pprofUITestsLaunchTests.swift in Sources */,\n\t\t\t\tEB9444402C42F70E0050F0D1 /* pprofUITests.swift 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\tEBEF3A312C3B255B0003477D /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = EBEF3A1D2C3B255A0003477D /* approf */;\n\t\t\ttargetProxy = EBEF3A302C3B255B0003477D /* PBXContainerItemProxy */;\n\t\t};\n\t\tEBEF3A3B2C3B255B0003477D /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = EBEF3A1D2C3B255A0003477D /* approf */;\n\t\t\ttargetProxy = EBEF3A3A2C3B255B0003477D /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\tEBEF3A412C3B255B0003477D /* 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_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++20\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES;\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_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu17;\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_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\tLOCALIZATION_PREFERS_STRING_CATALOGS = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"DEBUG $(inherited)\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEBEF3A422C3B255B0003477D /* 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_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++20\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES;\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_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu17;\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\tLOCALIZATION_PREFERS_STRING_CATALOGS = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tEBEF3A442C3B255B0003477D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = approf/pprof.entitlements;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=macosx*]\" = \"Apple Development\";\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\tDEVELOPMENT_ASSET_PATHS = \"\\\"approf/Preview Content\\\"\";\n\t\t\t\tDEVELOPMENT_TEAM = 46PN73H4K6;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tENABLE_PREVIEWS = YES;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_FILE = approf/Info.plist;\n\t\t\t\tINFOPLIST_KEY_CFBundleDisplayName = approf;\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.developer-tools\";\n\t\t\t\tINFOPLIST_KEY_NSHumanReadableCopyright = \"\";\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\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/approf/Process\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tMARKETING_VERSION = 14.1.3;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = the.future.app.approf.approf;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEBEF3A452C3B255B0003477D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = approf/pprof.entitlements;\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\tDEVELOPMENT_ASSET_PATHS = \"\\\"approf/Preview Content\\\"\";\n\t\t\t\tDEVELOPMENT_TEAM = 46PN73H4K6;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tENABLE_PREVIEWS = YES;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_FILE = approf/Info.plist;\n\t\t\t\tINFOPLIST_KEY_CFBundleDisplayName = approf;\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.developer-tools\";\n\t\t\t\tINFOPLIST_KEY_NSHumanReadableCopyright = \"\";\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\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/approf/Process\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tMARKETING_VERSION = 14.1.3;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = the.future.app.approf.approf;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tEBEF3A472C3B255B0003477D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 46PN73H4K6;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = the.future.app.pprof.pprofTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = NO;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/approf.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/approf\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEBEF3A482C3B255B0003477D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 46PN73H4K6;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = the.future.app.pprof.pprofTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = NO;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/approf.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/approf\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tEBEF3A4A2C3B255B0003477D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 46PN73H4K6;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = the.future.app.pprof.pprofUITests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = NO;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTEST_TARGET_NAME = pprof;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEBEF3A4B2C3B255B0003477D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 46PN73H4K6;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = the.future.app.pprof.pprofUITests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = NO;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTEST_TARGET_NAME = pprof;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tEBEF3A192C3B255A0003477D /* Build configuration list for PBXProject \"approf\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEBEF3A412C3B255B0003477D /* Debug */,\n\t\t\t\tEBEF3A422C3B255B0003477D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tEBEF3A432C3B255B0003477D /* Build configuration list for PBXNativeTarget \"approf\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEBEF3A442C3B255B0003477D /* Debug */,\n\t\t\t\tEBEF3A452C3B255B0003477D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tEBEF3A462C3B255B0003477D /* Build configuration list for PBXNativeTarget \"approfTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEBEF3A472C3B255B0003477D /* Debug */,\n\t\t\t\tEBEF3A482C3B255B0003477D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tEBEF3A492C3B255B0003477D /* Build configuration list for PBXNativeTarget \"approfUITests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEBEF3A4A2C3B255B0003477D /* Debug */,\n\t\t\t\tEBEF3A4B2C3B255B0003477D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\n/* Begin XCRemoteSwiftPackageReference section */\n\t\tEB1003E52C4A7EEC009E61F2 /* XCRemoteSwiftPackageReference \"PopupView\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/exyte/PopupView.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 3.0.4;\n\t\t\t};\n\t\t};\n\t\tEB3BC5B92C430A6700C9920F /* XCRemoteSwiftPackageReference \"swift-composable-architecture\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/pointfreeco/swift-composable-architecture\";\n\t\t\trequirement = {\n\t\t\t\tkind = exactVersion;\n\t\t\t\tversion = 1.14.0;\n\t\t\t};\n\t\t};\n\t\tEBD292B12C430D5800FFB285 /* XCRemoteSwiftPackageReference \"KeyboardShortcuts\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/sindresorhus/KeyboardShortcuts\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 2.0.1;\n\t\t\t};\n\t\t};\n\t\tEBD292BD2C43151A00FFB285 /* XCRemoteSwiftPackageReference \"Pow\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/EmergeTools/Pow.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 1.0.4;\n\t\t\t};\n\t\t};\n\t\tEBEF3C072C3BBEF80003477D /* XCRemoteSwiftPackageReference \"swift-log\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/apple/swift-log\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 1.6.1;\n\t\t\t};\n\t\t};\n/* End XCRemoteSwiftPackageReference section */\n\n/* Begin XCSwiftPackageProductDependency section */\n\t\tEB1003E62C4A7EFC009E61F2 /* PopupView */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = EB1003E52C4A7EEC009E61F2 /* XCRemoteSwiftPackageReference \"PopupView\" */;\n\t\t\tproductName = PopupView;\n\t\t};\n\t\tEBB1899C2C430AD00037A8F4 /* ComposableArchitecture */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = EB3BC5B92C430A6700C9920F /* XCRemoteSwiftPackageReference \"swift-composable-architecture\" */;\n\t\t\tproductName = ComposableArchitecture;\n\t\t};\n\t\tEBD292B92C430F9700FFB285 /* KeyboardShortcuts */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = EBD292B12C430D5800FFB285 /* XCRemoteSwiftPackageReference \"KeyboardShortcuts\" */;\n\t\t\tproductName = KeyboardShortcuts;\n\t\t};\n\t\tEBD292BE2C43168100FFB285 /* Pow */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = EBD292BD2C43151A00FFB285 /* XCRemoteSwiftPackageReference \"Pow\" */;\n\t\t\tproductName = Pow;\n\t\t};\n\t\tEBEF3C0A2C3BBF2A0003477D /* Logging */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = EBEF3C072C3BBEF80003477D /* XCRemoteSwiftPackageReference \"swift-log\" */;\n\t\t\tproductName = Logging;\n\t\t};\n/* End XCSwiftPackageProductDependency section */\n\t};\n\trootObject = EBEF3A162C3B255A0003477D /* Project object */;\n}\n"
  },
  {
    "path": "approf.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "approf.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": "approf.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved",
    "content": "{\n  \"originHash\" : \"bca11b0e59deddefb76aef5d49927075ef9e4a1238494b5a9858456b4fffe32b\",\n  \"pins\" : [\n    {\n      \"identity\" : \"combine-schedulers\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/combine-schedulers\",\n      \"state\" : {\n        \"revision\" : \"9fa31f4403da54855f1e2aeaeff478f4f0e40b13\",\n        \"version\" : \"1.0.2\"\n      }\n    },\n    {\n      \"identity\" : \"keyboardshortcuts\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/sindresorhus/KeyboardShortcuts\",\n      \"state\" : {\n        \"revision\" : \"2e5f15581fefb821d4b366e57d817be8bf12aa58\",\n        \"version\" : \"2.0.1\"\n      }\n    },\n    {\n      \"identity\" : \"popupview\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/exyte/PopupView.git\",\n      \"state\" : {\n        \"revision\" : \"21119b8dbb413e03b6036b788601e96806c83ed3\",\n        \"version\" : \"3.0.4\"\n      }\n    },\n    {\n      \"identity\" : \"pow\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/EmergeTools/Pow.git\",\n      \"state\" : {\n        \"revision\" : \"f0d0f3e72d42beaf2b01f1cb798e1b55902814eb\",\n        \"version\" : \"1.0.4\"\n      }\n    },\n    {\n      \"identity\" : \"swift-case-paths\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-case-paths\",\n      \"state\" : {\n        \"revision\" : \"642e6aab8e03e5f992d9c83e38c5be98cfad5078\",\n        \"version\" : \"1.5.5\"\n      }\n    },\n    {\n      \"identity\" : \"swift-clocks\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-clocks\",\n      \"state\" : {\n        \"revision\" : \"b9b24b69e2adda099a1fa381cda1eeec272d5b53\",\n        \"version\" : \"1.0.5\"\n      }\n    },\n    {\n      \"identity\" : \"swift-collections\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/apple/swift-collections\",\n      \"state\" : {\n        \"revision\" : \"3d2dc41a01f9e49d84f0a3925fb858bed64f702d\",\n        \"version\" : \"1.1.2\"\n      }\n    },\n    {\n      \"identity\" : \"swift-composable-architecture\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-composable-architecture\",\n      \"state\" : {\n        \"revision\" : \"0d8980f5bcc5fe6941f1788758667ff2b8c10f03\",\n        \"version\" : \"1.14.0\"\n      }\n    },\n    {\n      \"identity\" : \"swift-concurrency-extras\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-concurrency-extras\",\n      \"state\" : {\n        \"revision\" : \"bb5059bde9022d69ac516803f4f227d8ac967f71\",\n        \"version\" : \"1.1.0\"\n      }\n    },\n    {\n      \"identity\" : \"swift-custom-dump\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-custom-dump\",\n      \"state\" : {\n        \"revision\" : \"82645ec760917961cfa08c9c0c7104a57a0fa4b1\",\n        \"version\" : \"1.3.3\"\n      }\n    },\n    {\n      \"identity\" : \"swift-dependencies\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-dependencies\",\n      \"state\" : {\n        \"revision\" : \"3ef38bb702a1a2f39c7e19fc0578403b8ee52b17\",\n        \"version\" : \"1.3.9\"\n      }\n    },\n    {\n      \"identity\" : \"swift-identified-collections\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-identified-collections\",\n      \"state\" : {\n        \"revision\" : \"2f5ab6e091dd032b63dacbda052405756010dc3b\",\n        \"version\" : \"1.1.0\"\n      }\n    },\n    {\n      \"identity\" : \"swift-log\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/apple/swift-log\",\n      \"state\" : {\n        \"revision\" : \"9cb486020ebf03bfa5b5df985387a14a98744537\",\n        \"version\" : \"1.6.1\"\n      }\n    },\n    {\n      \"identity\" : \"swift-navigation\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-navigation\",\n      \"state\" : {\n        \"revision\" : \"e834b3760731160d7d448509ee6a1408c8582a6b\",\n        \"version\" : \"2.2.0\"\n      }\n    },\n    {\n      \"identity\" : \"swift-perception\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/swift-perception\",\n      \"state\" : {\n        \"revision\" : \"bc67aa8e461351c97282c2419153757a446ae1c9\",\n        \"version\" : \"1.3.5\"\n      }\n    },\n    {\n      \"identity\" : \"swift-syntax\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/swiftlang/swift-syntax\",\n      \"state\" : {\n        \"revision\" : \"4c6cc0a3b9e8f14b3ae2307c5ccae4de6167ac2c\",\n        \"version\" : \"600.0.0-prerelease-2024-06-12\"\n      }\n    },\n    {\n      \"identity\" : \"swiftui-introspect\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/siteline/swiftui-introspect\",\n      \"state\" : {\n        \"revision\" : \"807f73ce09a9b9723f12385e592b4e0aaebd3336\",\n        \"version\" : \"1.3.0\"\n      }\n    },\n    {\n      \"identity\" : \"xctest-dynamic-overlay\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/pointfreeco/xctest-dynamic-overlay\",\n      \"state\" : {\n        \"revision\" : \"bc2a151366f2cd0e347274544933bc2acb00c9fe\",\n        \"version\" : \"1.4.0\"\n      }\n    }\n  ],\n  \"version\" : 3\n}\n"
  },
  {
    "path": "approf.xcodeproj/xcshareddata/xcschemes/approf.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1600\"\n   version = \"1.7\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\"\n      buildArchitectures = \"Automatic\">\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 = \"EBEF3A1D2C3B255A0003477D\"\n               BuildableName = \"approf.app\"\n               BlueprintName = \"approf\"\n               ReferencedContainer = \"container:approf.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      <TestPlans>\n         <TestPlanReference\n            reference = \"container:approfTests/TestPlan.xctestplan\"\n            default = \"YES\">\n         </TestPlanReference>\n      </TestPlans>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\"\n            parallelizable = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"EBEF3A2E2C3B255B0003477D\"\n               BuildableName = \"approfTests.xctest\"\n               BlueprintName = \"approfTests\"\n               ReferencedContainer = \"container:approf.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\"\n            parallelizable = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"EBEF3A382C3B255B0003477D\"\n               BuildableName = \"approfUITests.xctest\"\n               BlueprintName = \"approfUITests\"\n               ReferencedContainer = \"container:approf.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 = \"EBEF3A1D2C3B255A0003477D\"\n            BuildableName = \"approf.app\"\n            BlueprintName = \"approf\"\n            ReferencedContainer = \"container:approf.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 = \"EBEF3A1D2C3B255A0003477D\"\n            BuildableName = \"approf.app\"\n            BlueprintName = \"approf\"\n            ReferencedContainer = \"container:approf.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": "approfTests/Files/Dummy.swift",
    "content": "//Created for approf in 2024\n\nimport Foundation\n\nclass Dummy{\n  \n}\n"
  },
  {
    "path": "approfTests/TestAppDropFiles.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport Foundation\nimport Testing\n\n@testable import approf\n\nstruct TestDropFiles2 {\n  @Test\n  @MainActor\n  func testAppDropFiles() async throws {\n    let urlA = Bundle(for: Dummy.self).url(forResource: \"a.pb\", withExtension: \"gz\")!\n    let urlB = Bundle(for: Dummy.self).url(forResource: \"b\", withExtension: \"pb\")!\n    \n    let clock = TestClock()\n    let dg = DateGenerator.constant(.distantPast)\n    \n    let store = TestStore(initialState: AppFeature.State()) {\n      AppFeature()\n    } withDependencies: {\n      $0.uuid = .incrementing\n      $0.continuousClock = clock\n      $0.date = dg\n    }\n    \n    await store.send(.onAppear) {\n      $0.synced = true\n      $0.pprofsSelectedId = nil\n    }\n    \n    let sharedBasic = PProfBasic(uuid: UUID(0), filePaths: [urlA.path(percentEncoded: false), urlB.path(percentEncoded: false)], createdAt: dg.now, presentation: .diff)\n        \n    await store.send(.drop(.onDropEnds([urlA, urlB]))) {\n      $0.drop.destination = .uth(UnderTheHood.State(basic: Shared(sharedBasic)))\n    }\n\n    await store.send(\\.drop.destination.uth.delegate.onConfirmImportButtonTapped) {\n      $0.drop.destination = nil\n    }\n\n    await clock.advance(by: .seconds(1))\n\n    var newBasic = sharedBasic\n    newBasic.id = UUID(1)\n    await store.receive(\\.drop.delegate.addNewBasic){\n      $0.basics = [newBasic]\n      $0.pprofs = [DetailFeature.State(basic: Shared(newBasic), period: .idle(IdleFeature.State()))]\n    }\n    \n    await store.receive(\\.onPprofsSelectedIdChanged){\n      $0.pprofsSelectedId = newBasic.id\n    }\n    \n  }\n}\n"
  },
  {
    "path": "approfTests/TestDropFiles.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport Testing\nimport Foundation\n\n@testable import approf\n\nstruct TestDropFiles {\n  @Test\n  @MainActor\n  func testDropFiles() async throws {\n    let urlA = Bundle(for: Dummy.self).url(forResource: \"a.pb\", withExtension: \"gz\")!\n    let urlB = Bundle(for: Dummy.self).url(forResource: \"b\", withExtension: \"pb\")!\n    \n    let clock = TestClock()\n    let dg = DateGenerator.constant(.distantPast)\n    \n    let store = TestStore(initialState: AppFeature.State()) {\n      AppFeature()\n    } withDependencies: {\n      $0.uuid = .incrementing\n      $0.continuousClock = clock\n      $0.date = dg\n    }\n\n    let dropStore = TestStore(initialState: DropAndImportFeature.State()) {\n      DropAndImportFeature()\n    } withDependencies: {\n      $0.uuid = .incrementing\n      $0.continuousClock = clock\n      $0.date = dg\n    }\n\n    await store.send(.onAppear) {\n      $0.synced = true\n    }\n\n    let sharedBasic = PProfBasic(uuid: UUID(0), filePaths: [urlA.path(percentEncoded: false), urlB.path(percentEncoded: false)], createdAt: dg.now, presentation: .diff)\n\n    await clock.advance(by: .seconds(1))\n    await dropStore.send(.onDropEnds([urlA, urlB])) {\n      $0.destination = .uth(UnderTheHood.State(basic: Shared(sharedBasic)))\n    }\n    \n    await store.send(.drop(.onDropEnds([urlA, urlB]))) {\n      $0.drop.destination = .uth(UnderTheHood.State(basic: Shared(sharedBasic)))\n    }\n  }\n}\n"
  },
  {
    "path": "approfTests/TestDropFilesLegacy.swift",
    "content": "// Created for approf in 2024\n\nimport ComposableArchitecture\nimport XCTest\n\n@testable import approf\n\nfinal class TestDropFilesLegacy: XCTestCase {\n  @MainActor\n  func testDropFiles() async throws {\n    let urlA = Bundle(for: Dummy.self).url(forResource: \"a.pb\", withExtension: \"gz\")!\n    let urlB = Bundle(for: Dummy.self).url(forResource: \"b\", withExtension: \"pb\")!\n    \n    let clock = TestClock()\n    let dg = DateGenerator.constant(.distantPast)\n    \n    let store = TestStore(initialState: AppFeature.State()) {\n      AppFeature()\n    } withDependencies: {\n      $0.uuid = .incrementing\n      $0.continuousClock = clock\n      $0.date = dg\n    }\n\n    let dropStore = TestStore(initialState: DropAndImportFeature.State()) {\n      DropAndImportFeature()\n    } withDependencies: {\n      $0.uuid = .incrementing\n      $0.continuousClock = clock\n      $0.date = dg\n    }\n\n    await store.send(.onAppear) {\n      $0.synced = true\n    }\n    \n    let sharedBasic = PProfBasic(uuid: UUID(0), filePaths: [urlA.path(percentEncoded: false), urlB.path(percentEncoded: false)], createdAt: dg.now, presentation: .diff)\n\n    await clock.advance(by: .seconds(1))\n    await dropStore.send(.onDropEnds([urlA, urlB])) {\n      $0.destination = .uth(UnderTheHood.State(basic: Shared(sharedBasic)))\n    }\n    \n    await store.send(.drop(.onDropEnds([urlA, urlB]))) {\n      $0.drop.destination = .uth(UnderTheHood.State(basic: Shared(sharedBasic)))\n    }\n  }\n}\n"
  },
  {
    "path": "approfTests/TestPlan.xctestplan",
    "content": "{\n  \"configurations\" : [\n    {\n      \"id\" : \"FD72B178-E2F5-4F38-9F74-ED8079928207\",\n      \"name\" : \"Configuration 1\",\n      \"options\" : {\n\n      }\n    }\n  ],\n  \"defaultOptions\" : {\n    \"testTimeoutsEnabled\" : true\n  },\n  \"testTargets\" : [\n    {\n      \"target\" : {\n        \"containerPath\" : \"container:approf.xcodeproj\",\n        \"identifier\" : \"EBEF3A2E2C3B255B0003477D\",\n        \"name\" : \"approfTests\"\n      }\n    }\n  ],\n  \"version\" : 1\n}\n"
  },
  {
    "path": "approfUITests/pprofUITests.swift",
    "content": "//\n//  pprofUITests.swift\n//  pprofUITests\n//\n//  Created by Clement on 08/07/2024.\n//\n\nimport XCTest\n\nfinal class pprofUITests: XCTestCase {\n\n    override func setUpWithError() throws {\n        // Put setup code here. This method is called before the invocation of each test method in the class.\n\n        // In UI tests it is usually best to stop immediately when a failure occurs.\n        continueAfterFailure = false\n\n        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.\n    }\n\n    override func tearDownWithError() throws {\n        // Put teardown code here. This method is called after the invocation of each test method in the class.\n    }\n\n    @MainActor\n    func testExample() throws {\n        // UI tests must launch the application that they test.\n        let app = XCUIApplication()\n        app.launch()\n\n        // Use XCTAssert and related functions to verify your tests produce the correct results.\n    }\n\n    @MainActor\n    func testLaunchPerformance() throws {\n        if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {\n            // This measures how long it takes to launch your application.\n            measure(metrics: [XCTApplicationLaunchMetric()]) {\n                XCUIApplication().launch()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "approfUITests/pprofUITestsLaunchTests.swift",
    "content": "//\n//  pprofUITestsLaunchTests.swift\n//  pprofUITests\n//\n//  Created by Clement on 08/07/2024.\n//\n\nimport XCTest\n\nfinal class pprofUITestsLaunchTests: XCTestCase {\n\n    override class var runsForEachTargetApplicationUIConfiguration: Bool {\n        true\n    }\n\n    override func setUpWithError() throws {\n        continueAfterFailure = false\n    }\n\n    @MainActor\n    func testLaunch() throws {\n        let app = XCUIApplication()\n        app.launch()\n\n        // Insert steps here to perform after app launch but before taking a screenshot,\n        // such as logging into a test account or navigating somewhere in the app\n\n        let attachment = XCTAttachment(screenshot: app.screenshot())\n        attachment.name = \"Launch Screen\"\n        attachment.lifetime = .keepAlways\n        add(attachment)\n    }\n}\n"
  },
  {
    "path": "ci_scripts/ci_post_clone.sh",
    "content": "#!/bin/bash\n\n#defaults write com.apple.dt.Xcode IDESkipMacroFingerprintValidation -bool YES\n\nmkdir -p ~/Library/org.swift.swiftpm/security/\ncp macros.json ~/Library/org.swift.swiftpm/security/\n"
  },
  {
    "path": "ci_scripts/macros.json",
    "content": "[\n  {\n    \"fingerprint\" : \"031704ba0634b45e02fe875b8ddddc7f30a07f49\",\n    \"packageIdentity\" : \"swift-case-paths\",\n    \"targetName\" : \"CasePathsMacros\"\n  },\n  {\n    \"fingerprint\" : \"d65f3c1b9332255a40002905b6787f765585d7fb\",\n    \"packageIdentity\" : \"swift-composable-architecture\",\n    \"targetName\" : \"ComposableArchitectureMacros\"\n  },\n  {\n    \"fingerprint\" : \"52018827ce21e482a36e3795bea2666b3898164c\",\n    \"packageIdentity\" : \"swift-dependencies\",\n    \"targetName\" : \"DependenciesMacrosPlugin\"\n  },\n  {\n    \"fingerprint\" : \"2c75ce556a6fc106721b0dadc2c7327244ad3999\",\n    \"packageIdentity\" : \"swift-perception\",\n    \"targetName\" : \"PerceptionMacros\"\n  }\n]"
  }
]