[
  {
    "path": ".gitignore",
    "content": "# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## Build generated\nbuild/\nDerivedData\n\n## Various settings\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n\n## Other\n*.xccheckout\n*.moved-aside\n*.xcuserstate\n*.xcscmblueprint\n\n## Obj-C/Swift specific\n*.hmap\n*.ipa\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.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# 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# fastlane\n#\n# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the \n# screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md\n\nfastlane/report.xml\nfastlane/screenshots\n.DS_Store\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: swift\nosx_image: xcode9.3\nscript: xcodebuild -project BuildTimeAnalyzer.xcodeproj -scheme BuildTimeAnalyzer build test\n"
  },
  {
    "path": "BuildTimeAnalyzer/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  BuildTimeAnalyzer\n//\n\nimport Cocoa\n\n@NSApplicationMain\nclass AppDelegate: NSObject, NSApplicationDelegate {\n    \n    @IBOutlet weak var projectSelectionMenuItem: NSMenuItem!\n    @IBOutlet weak var buildTimesMenuItem: NSMenuItem!\n    @IBOutlet weak var alwaysInFrontMenuItem: NSMenuItem!\n\n    @objc var canExport: Bool = false\n    \n    var viewController: ViewController? {\n        return NSApplication.shared.mainWindow?.contentViewController as? ViewController\n    }\n    \n    func applicationDidFinishLaunching(_ notification: Notification) {\n        alwaysInFrontMenuItem.state = UserSettings.windowShouldBeTopMost ? .on : .off\n    }\n    \n    func configureMenuItems(showBuildTimesMenuItem: Bool) {\n        projectSelectionMenuItem.isEnabled = !showBuildTimesMenuItem\n        buildTimesMenuItem.isEnabled = showBuildTimesMenuItem\n    }\n    \n    // MARK: Actions\n    \n    @IBAction func navigateToProjectSelection(_ sender: NSMenuItem) {\n        configureMenuItems(showBuildTimesMenuItem: true)\n        \n        viewController?.cancelProcessing()\n        viewController?.showInstructions(true)\n    }\n    \n    @IBAction func navigateToBuildTimes(_ sender: NSMenuItem) {\n        configureMenuItems(showBuildTimesMenuItem: false)\n        viewController?.showInstructions(false)\n    }\n    \n    @IBAction func visitGitHubPage(_ sender: AnyObject) {\n        let path = \"https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode\"\n        if let url = URL(string: path) {\n            NSWorkspace.shared.open(url)\n        }\n    }\n    \n    @IBAction func toggleAlwaysInFront(_ sender: NSMenuItem) {\n        let alwaysInFront = sender.state == .off\n        \n        sender.state = alwaysInFront ? .on : .off\n        UserSettings.windowShouldBeTopMost = alwaysInFront\n        \n        viewController?.makeWindowTopMost(topMost: alwaysInFront)\n    }\n}\n\n"
  },
  {
    "path": "BuildTimeAnalyzer/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo16.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo32-1.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo32.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo64.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo128.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo256-1.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo256.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo512-1.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo512.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"logo512@2x.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "BuildTimeAnalyzer/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "BuildTimeAnalyzer/Assets.xcassets/ScreenShot.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Screen Shot.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "BuildTimeAnalyzer/BuildManager.swift",
    "content": "//\n//  BuildManager.swift\n//  BuildTimeAnalyzer\n//\n\nimport Cocoa\n\nprotocol BuildManagerDelegate: AnyObject {\n    func derivedDataDidChange()\n    func buildManager(_ buildManager: BuildManager, shouldParseLogWithDatabase database: XcodeDatabase)\n}\n\nclass BuildManager: NSObject {\n    \n    weak var delegate: BuildManagerDelegate?\n    \n    private let derivedDataDirectoryMonitor = DirectoryMonitor(isDerivedData: true)\n    private let logFolderDirectoryMonitor = DirectoryMonitor(isDerivedData: false)\n    \n    private var currentDataBase: XcodeDatabase?\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        derivedDataDirectoryMonitor.delegate = self\n        logFolderDirectoryMonitor.delegate = self\n        \n        startMonitoring()\n    }\n    \n    func startMonitoring() {\n        stopMonitoring()\n        derivedDataDirectoryMonitor.startMonitoring(path: UserSettings.derivedDataLocation)\n    }\n    \n    func stopMonitoring() {\n        derivedDataDirectoryMonitor.stopMonitoring()\n    }\n    \n    func database(forFolder URL: URL) -> XcodeDatabase? {\n        let databaseURL = URL.appendingPathComponent(\"Cache.db\")\n        return XcodeDatabase(fromPath: databaseURL.path)\n    }\n    \n    func processDerivedData() {\n        guard let mostRecent = DerivedDataManager.derivedData().first else { return }\n        \n        let logFolder = mostRecent.url.appendingPathComponent(\"Logs/Build\").path\n        guard logFolderDirectoryMonitor.path != logFolder else { return }\n        \n        logFolderDirectoryMonitor.stopMonitoring()\n        logFolderDirectoryMonitor.startMonitoring(path: logFolder)\n    }\n    \n    func processLogFolder(with url: URL) {\n        guard let activeDatabase = database(forFolder: url),\n            activeDatabase.isBuildType,\n            activeDatabase != currentDataBase else { return }\n        \n        currentDataBase = activeDatabase\n        delegate?.buildManager(self, shouldParseLogWithDatabase: activeDatabase)\n    }\n}\n\nextension BuildManager: DirectoryMonitorDelegate {\n    func directoryMonitorDidObserveChange(_ directoryMonitor: DirectoryMonitor, isDerivedData: Bool) {\n        if isDerivedData {\n            delegate?.derivedDataDidChange()\n            processDerivedData()\n        } else if let path = directoryMonitor.path {\n            // TODO: If we don't dispatch, it seems it fires off too soon\n            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {\n                self.processLogFolder(with: URL(fileURLWithPath: path))\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/BuildTimeAnalyzer-Bridging-Header.h",
    "content": "//\n//  Use this file to import your target's public headers that you would like to expose to Swift.\n//\n\n#import \"NSData+GZIP.h\""
  },
  {
    "path": "BuildTimeAnalyzer/CSVExporter.swift",
    "content": "//\n//  CSVExporter.swift\n//  BuildTimeAnalyzer\n//\n//  Created by Bruno Resende on 16.01.19.\n//  Copyright © 2019 Cane Media Ltd. All rights reserved.\n//\n\nimport Foundation\n\nstruct CSVExporter {\n\n    static var filenameDateFormatter: DateFormatter = {\n        let formatter = DateFormatter()\n        formatter.dateFormat = \"yyyyMMdd-HHmmss\"\n        return formatter\n    }()\n\n    func filename(with prefix: String) -> String {\n        return \"\\(prefix)_\\(CSVExporter.filenameDateFormatter.string(from: Date())).csv\"\n    }\n\n    func export<T>(elements: [T], to url: URL) throws where T: CSVExportable {\n\n        guard let data = elements.joinedAsCSVString(delimiter: .doubleQuote).data(using: .utf8) else {\n            throw ExportErrors.couldNotParseStringAsUTF8\n        }\n\n        do {\n            try data.write(to: url, options: .atomic)\n        } catch {\n            throw ExportErrors.fileIO(error)\n        }\n    }\n\n    enum ExportErrors: Error {\n        case couldNotParseStringAsUTF8\n        case fileIO(Error)\n    }\n}\n\nenum CSVDelimiter: String {\n    case singleQuote = \"'\"\n    case doubleQuote = \"\\\"\"\n    case none = \"\"\n}\n\nprotocol CSVExportable {\n\n    static var csvHeaderLine: String { get }\n\n    var csvLine: String { get }\n}\n\nextension Array where Element: CSVExportable {\n\n    func joinedAsCSVString(delimiter: CSVDelimiter) -> String {\n\n        return ([Element.csvHeaderLine] + self.map({ $0.csvLine })).joined(separator: \"\\n\")\n    }\n}\n\nextension Array where Element == String {\n\n    func joinedAsCSVLine(delimiter: CSVDelimiter) -> String {\n\n        let formatter: (String) -> String\n\n        switch delimiter {\n        case .singleQuote:  formatter = { $0.replacingOccurrences(of: \"'\", with: \"\\\\'\") }\n        case .doubleQuote:  formatter = { $0.replacingOccurrences(of: \"\\\"\", with: \"\\\\\\\"\") }\n        case .none:         formatter = { $0 }\n        }\n\n        return self.map({ \"\\(delimiter.rawValue)\\(formatter($0))\\(delimiter.rawValue)\" }).joined(separator: \",\")\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/CompileMeasure.swift",
    "content": "//\n//  CompileMeasure.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\n\n@objcMembers class CompileMeasure: NSObject {\n    \n    dynamic var time: Double\n    var path: String\n    var code: String\n    dynamic var filename: String\n    var references: Int\n\n    private var locationArray: [Int]\n\n    public enum Order: String {\n        case filename\n        case time\n    }\n\n    var fileAndLine: String {\n        return \"\\(filename):\\(locationArray[0])\"\n    }\n\n    var fileInfo: String {\n        return \"\\(fileAndLine):\\(locationArray[1])\"\n    }\n\n\tvar fileRow: String {\n\t\t\"\\(locationArray[0])\"\n\t}\n\n\tvar fileColumn: String {\n\t\t\"\\(locationArray[1])\"\n\t}\n\n    var location: Int {\n        return locationArray[0]\n    }\n    \n    var timeString: String {\n        return String(format: \"%.f\", time)\n    }\n    \n    init?(time: Double, rawPath: String, code: String, references: Int) {\n        let untrimmedFilename = rawPath.split(separator: \"/\").map(String.init).last\n        \n        guard let filepath = rawPath.split(separator: \":\").map(String.init).first,\n            let filename = untrimmedFilename?.split(separator: \":\").map(String.init).first else { return nil }\n        \n        let locationString = String(rawPath[filepath.endIndex...].dropFirst())\n        let locations = locationString.split(separator: \":\").compactMap{ Int(String.init($0)) }\n        guard locations.count == 2 else { return nil }\n        \n        self.time = time\n        self.code = code\n        self.path = filepath\n        self.filename = filename\n        self.locationArray = locations\n        self.references = references\n    }\n\n    init?(rawPath: String, time: Double) {\n        let untrimmedFilename = rawPath.split(separator: \"/\").map(String.init).last\n\n        guard let filepath = rawPath.split(separator: \":\").map(String.init).first,\n            let filename = untrimmedFilename?.split(separator: \":\").map(String.init).first else { return nil }\n\n        self.time = time\n        self.code = \"\"\n        self.path = filepath\n        self.filename = filename\n        self.locationArray = [1,1]\n        self.references = 1\n    }\n\n    subscript(column: Int) -> String {\n        switch column {\n        case 0:\n            return timeString\n        case 1:\n            return fileInfo\n        case 2:\n            return \"\\(references)\"\n        default:\n            return code\n        }\n    }\n}\n\nextension CompileMeasure: CSVExportable {\n\n    static var csvHeaderLine: String = [\"time\", \"file\", \"row\", \"column\", \"references\", \"code\"].joinedAsCSVLine(delimiter: .doubleQuote)\n\n    var csvLine: String\n    {\n        return [timeString, filename, fileRow, fileColumn, \"\\(references)\", code].joinedAsCSVLine(delimiter: .doubleQuote)\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/DerivedDataManager.swift",
    "content": "//\n//  DerivedDataManager.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\n\nclass DerivedDataManager {\n    \n    static func derivedData() -> [File] {\n        let url = URL(fileURLWithPath: UserSettings.derivedDataLocation)\n        \n        let folders = DerivedDataManager.listFolders(at: url)\n        let fileManager = FileManager.default\n        \n        return folders.compactMap{ (url) -> File? in\n            if url.lastPathComponent != \"ModuleCache\",\n                let properties = try? fileManager.attributesOfItem(atPath: url.path),\n                let modificationDate = properties[FileAttributeKey.modificationDate] as? Date {\n                return File(date: modificationDate, url: url)\n            }\n            return nil\n        }.sorted{ $0.date > $1.date }\n    }\n    \n    static func listFolders(at url: URL) -> [URL] {\n        let fileManager = FileManager.default\n        let keys = [URLResourceKey.nameKey, URLResourceKey.isDirectoryKey]\n        let options: FileManager.DirectoryEnumerationOptions = [.skipsHiddenFiles, .skipsPackageDescendants, .skipsSubdirectoryDescendants]\n        \n        guard let enumerator = fileManager.enumerator(at: url, includingPropertiesForKeys: keys, options: options, errorHandler: nil) else { return [] }\n        \n        return enumerator.map{ $0 as! URL }\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/DirectoryMonitor.swift",
    "content": "//\n//  DirectoryMonitor.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\n\nprotocol DirectoryMonitorDelegate: AnyObject {\n    func directoryMonitorDidObserveChange(_ directoryMonitor: DirectoryMonitor, isDerivedData: Bool)\n}\n\nclass DirectoryMonitor {\n    var dispatchQueue: DispatchQueue\n    \n    weak var delegate: DirectoryMonitorDelegate?\n    \n    var fileDescriptor: Int32 = -1\n    var dispatchSource: DispatchSourceFileSystemObject?\n    var isDerivedData: Bool\n    var path: String?\n    var timer: Timer?\n    var lastDerivedDataDate = Date()\n    var isMonitoringDates = false\n    \n    init(isDerivedData: Bool) {\n        self.isDerivedData = isDerivedData\n        \n        let suffix = isDerivedData ? \"deriveddata\" : \"logfolder\"\n        dispatchQueue = DispatchQueue(label: \"uk.co.canemedia.directorymonitor.\\(suffix)\", attributes: .concurrent)\n    }\n    \n    func startMonitoring(path: String) {\n        self.path = path\n        \n        guard dispatchSource == nil && fileDescriptor == -1 else { return }\n        \n        fileDescriptor = open(path, O_EVTONLY)\n        guard fileDescriptor != -1 else { return }\n        \n        dispatchSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor, eventMask: .all, queue: dispatchQueue)\n        dispatchSource?.setEventHandler {\n            DispatchQueue.main.async {\n                self.delegate?.directoryMonitorDidObserveChange(self, isDerivedData: self.isDerivedData)\n            }\n        }\n        dispatchSource?.setCancelHandler {\n            close(self.fileDescriptor)\n            \n            self.fileDescriptor = -1\n            self.dispatchSource = nil\n            self.path = nil\n        }\n        dispatchSource?.resume()\n        \n        if isDerivedData && !isMonitoringDates {\n            isMonitoringDates = true\n            monitorModificationDates()\n        }\n    }\n    \n    func stopMonitoring() {\n        dispatchSource?.cancel()\n        path = nil\n    }\n    \n    func monitorModificationDates() {\n        if let date = DerivedDataManager.derivedData().first?.date, date > lastDerivedDataDate {\n            lastDerivedDataDate = date\n            self.delegate?.directoryMonitorDidObserveChange(self, isDerivedData: self.isDerivedData)\n        }\n        \n        if path != nil {\n            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {\n                self.monitorModificationDates()\n            }\n        } else {\n            isMonitoringDates = false\n        }\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/File.swift",
    "content": "//\n//  File.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\n\nstruct File {\n    let date: Date\n    let url: URL\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0.12</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSMinimumSystemVersion</key>\n\t<string>$(MACOSX_DEPLOYMENT_TARGET)</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2016 Cane Media Ltd. All rights reserved.</string>\n\t<key>NSMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>NSPrincipalClass</key>\n\t<string>NSApplication</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "BuildTimeAnalyzer/LogProcessor.swift",
    "content": "//\n//  LogProcessor.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\n\ntypealias CMUpdateClosure = (_ result: [CompileMeasure], _ didComplete: Bool, _ didCancel: Bool) -> ()\n\nprotocol LogProcessorProtocol: AnyObject {\n    var rawMeasures: [String: RawMeasure] { get set }\n    var updateHandler: CMUpdateClosure? { get set }\n    var shouldCancel: Bool { get set }\n    \n    func processingDidStart()\n    func processingDidFinish()\n}\n\nextension LogProcessorProtocol {\n    func processDatabase(database: XcodeDatabase, updateHandler: CMUpdateClosure?) {\n        guard let text = database.processLog() else {\n            updateHandler?([], true, false)\n            return\n        }\n        \n        self.updateHandler = updateHandler\n        DispatchQueue.global().async {\n            self.process(text: text)\n        }\n    }\n    \n    // MARK: Private methods\n    \n    private func process(text: String) {\n        let characterSet = CharacterSet(charactersIn:\"\\r\\\"\")\n        var remainingRange = text.startIndex..<text.endIndex\n        let regex = try! NSRegularExpression(pattern:  \"^\\\\d*\\\\.?\\\\d*ms\\\\t/\", options: [])\n        \n        rawMeasures.removeAll()\n        \n        processingDidStart()\n        \n        while let nextRange = text.rangeOfCharacter(from: characterSet, options: [], range: remainingRange) {\n            let text = String(text[remainingRange.lowerBound..<nextRange.upperBound])\n            \n            defer {\n                remainingRange = nextRange.upperBound..<remainingRange.upperBound\n            }\n            \n            // From LuizZak: (text as NSString).length improves the performance by about 2x compared to text.characters.count\n            let range = NSMakeRange(0, (text as NSString).length)\n            guard let match = regex.firstMatch(in: text, options: [], range: range) else { continue }\n            \n            let timeString = text[..<text.index(text.startIndex, offsetBy: match.range.length - 4)]\n            if let time = Double(timeString) {\n                let value = String(text[text.index(text.startIndex, offsetBy: match.range.length - 1)...])\n                if var rawMeasure = rawMeasures[value] {\n                    rawMeasure.time += time\n                    rawMeasure.references += 1\n                    rawMeasures[value] = rawMeasure\n                } else {\n                    rawMeasures[value] = RawMeasure(time: time, text: value)\n                }\n            }\n            guard !shouldCancel else { break }\n        }\n        processingDidFinish()\n    }\n    \n    fileprivate func updateResults(didComplete completed: Bool, didCancel: Bool) {\n        var filteredResults = rawMeasures.values.filter{ $0.time > 10 }\n        if filteredResults.count < 20 {\n            filteredResults = rawMeasures.values.filter{ $0.time > 0.1 }\n        }\n        \n        let sortedResults = filteredResults.sorted(by: { $0.time > $1.time })\n        updateHandler?(processResult(sortedResults), completed, didCancel)\n        \n        if completed {\n            rawMeasures.removeAll()\n        }\n    }\n    \n    private func processResult(_ unprocessedResult: [RawMeasure]) -> [CompileMeasure] {\n        let characterSet = CharacterSet(charactersIn:\"\\r\\\"\")\n        \n        var result: [CompileMeasure] = []\n        for entry in unprocessedResult {\n            let code = entry.text.split(separator: \"\\t\").map(String.init)\n            let method = code.count >= 2 ? trimPrefixes(code[1]) : \"-\"\n            \n            if let path = code.first?.trimmingCharacters(in: characterSet), let measure = CompileMeasure(time: entry.time, rawPath: path, code: method, references: entry.references) {\n                result.append(measure)\n            }\n        }\n        return result\n    }\n    \n    private func trimPrefixes(_ code: String) -> String {\n        var code = code\n        [\"@objc \", \"final \", \"@IBAction \"].forEach { (prefix) in\n            if code.hasPrefix(prefix) {\n                code = String(code[code.index(code.startIndex, offsetBy: prefix.count)...])\n            }\n        }\n        return code\n    }\n}\n\nclass LogProcessor: NSObject, LogProcessorProtocol {\n    \n    var rawMeasures: [String: RawMeasure] = [:]\n    var updateHandler: CMUpdateClosure?\n    var shouldCancel = false\n    var timer: Timer?\n    \n    func processingDidStart() {\n        DispatchQueue.main.async {\n            self.timer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(self.timerCallback(_:)), userInfo: nil, repeats: true)\n        }\n    }\n    \n    func processingDidFinish() {\n        DispatchQueue.main.async {\n            self.timer?.invalidate()\n            self.timer = nil\n            let didCancel = self.shouldCancel\n            self.shouldCancel = false\n            self.updateResults(didComplete: true, didCancel: didCancel)\n        }\n    }\n    \n    @objc func timerCallback(_ timer: Timer) {\n        updateResults(didComplete: false, didCancel: false)\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"24506\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" initialViewController=\"B8D-0N-5wS\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"24506\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Application-->\n        <scene sceneID=\"JPo-4y-FX3\">\n            <objects>\n                <application id=\"hnw-xV-0zn\" sceneMemberID=\"viewController\">\n                    <menu key=\"mainMenu\" title=\"Main Menu\" systemMenu=\"main\" id=\"AYu-sK-qS6\">\n                        <items>\n                            <menuItem title=\"Build Time Analyzer\" id=\"1Xt-HY-uBw\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Build Time Analyzer\" systemMenu=\"apple\" id=\"uQy-DD-JDr\">\n                                    <items>\n                                        <menuItem title=\"About Build Time Analyzer\" id=\"5kV-Vb-QxS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"orderFrontStandardAboutPanel:\" target=\"Ady-hI-5gd\" id=\"Exp-CZ-Vem\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"GitHub Page\" id=\"ZvE-gI-Jj2\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"visitGitHubPage:\" target=\"Voe-Tx-rLC\" id=\"OKx-FW-Ire\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"4je-JR-u6R\"/>\n                                        <menuItem title=\"Hide TestMenu\" keyEquivalent=\"h\" id=\"Olw-nP-bQN\">\n                                            <connections>\n                                                <action selector=\"hide:\" target=\"Ady-hI-5gd\" id=\"PnN-Uc-m68\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Hide Others\" keyEquivalent=\"h\" id=\"Vdr-fp-XzO\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"hideOtherApplications:\" target=\"Ady-hI-5gd\" id=\"VT4-aY-XCT\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Show All\" id=\"Kd2-mp-pUS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"unhideAllApplications:\" target=\"Ady-hI-5gd\" id=\"Dhg-Le-xox\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"kCx-OE-vgT\"/>\n                                        <menuItem title=\"Quit TestMenu\" keyEquivalent=\"q\" id=\"4sb-4s-VLi\">\n                                            <connections>\n                                                <action selector=\"terminate:\" target=\"Ady-hI-5gd\" id=\"Te7-pn-YzF\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"File\" id=\"dMs-cI-mzQ\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"File\" id=\"bib-Uj-vzu\">\n                                    <items>\n                                        <menuItem title=\"Close\" keyEquivalent=\"w\" id=\"DVo-aG-piG\">\n                                            <connections>\n                                                <action selector=\"performClose:\" target=\"Ady-hI-5gd\" id=\"HmO-Ls-i7Q\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"Kk2-Jz-LKd\"/>\n                                        <menuItem title=\"Export data as CSV…\" keyEquivalent=\"e\" id=\"3xt-bK-nQa\">\n                                            <connections>\n                                                <action selector=\"exportAsCSVClicked:\" target=\"Ady-hI-5gd\" id=\"kbQ-xo-OtY\"/>\n                                                <binding destination=\"Voe-Tx-rLC\" name=\"enabled\" keyPath=\"self.canExport\" id=\"nAf-82-Fb2\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Edit\" id=\"5QF-Oa-p0T\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Edit\" id=\"W48-6f-4Dl\">\n                                    <items>\n                                        <menuItem title=\"Undo\" keyEquivalent=\"z\" id=\"dRJ-4n-Yzg\">\n                                            <connections>\n                                                <action selector=\"undo:\" target=\"Ady-hI-5gd\" id=\"M6e-cu-g7V\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Redo\" keyEquivalent=\"Z\" id=\"6dh-zS-Vam\">\n                                            <connections>\n                                                <action selector=\"redo:\" target=\"Ady-hI-5gd\" id=\"oIA-Rs-6OD\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"WRV-NI-Exz\"/>\n                                        <menuItem title=\"Cut\" keyEquivalent=\"x\" id=\"uRl-iY-unG\">\n                                            <connections>\n                                                <action selector=\"cut:\" target=\"Ady-hI-5gd\" id=\"YJe-68-I9s\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Copy\" keyEquivalent=\"c\" id=\"x3v-GG-iWU\">\n                                            <connections>\n                                                <action selector=\"copy:\" target=\"Ady-hI-5gd\" id=\"G1f-GL-Joy\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste\" keyEquivalent=\"v\" id=\"gVA-U4-sdL\">\n                                            <connections>\n                                                <action selector=\"paste:\" target=\"Ady-hI-5gd\" id=\"UvS-8e-Qdg\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste and Match Style\" keyEquivalent=\"V\" id=\"WeT-3V-zwk\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"pasteAsPlainText:\" target=\"Ady-hI-5gd\" id=\"cEh-KX-wJQ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Delete\" id=\"pa3-QI-u2k\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"delete:\" target=\"Ady-hI-5gd\" id=\"0Mk-Ml-PaM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Select All\" keyEquivalent=\"a\" id=\"Ruw-6m-B2m\">\n                                            <connections>\n                                                <action selector=\"selectAll:\" target=\"Ady-hI-5gd\" id=\"VNm-Mi-diN\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"uyl-h8-XO2\"/>\n                                        <menuItem title=\"Speech\" id=\"xrE-MZ-jX0\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Speech\" id=\"3rS-ZA-NoH\">\n                                                <items>\n                                                    <menuItem title=\"Start Speaking\" id=\"Ynk-f8-cLZ\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"startSpeaking:\" target=\"Ady-hI-5gd\" id=\"654-Ng-kyl\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Stop Speaking\" id=\"Oyz-dy-DGm\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"stopSpeaking:\" target=\"Ady-hI-5gd\" id=\"dX8-6p-jy9\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Navigate\" id=\"dzK-lU-FKH\" userLabel=\"Navigate\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Navigate\" autoenablesItems=\"NO\" id=\"4cu-Mh-AKu\">\n                                    <items>\n                                        <menuItem title=\"Project Selection\" enabled=\"NO\" keyEquivalent=\"0\" id=\"JMA-rD-5Ql\">\n                                            <connections>\n                                                <action selector=\"navigateToProjectSelection:\" target=\"Voe-Tx-rLC\" id=\"DMt-ga-nyF\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Build Times\" enabled=\"NO\" keyEquivalent=\"1\" id=\"SfY-cQ-Dau\">\n                                            <connections>\n                                                <action selector=\"navigateToBuildTimes:\" target=\"Voe-Tx-rLC\" id=\"O18-0k-1fo\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Window\" id=\"aUF-d1-5bR\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Window\" systemMenu=\"window\" id=\"Td7-aD-5lo\">\n                                    <items>\n                                        <menuItem title=\"Minimize\" keyEquivalent=\"m\" id=\"OY7-WF-poV\">\n                                            <connections>\n                                                <action selector=\"performMiniaturize:\" target=\"Ady-hI-5gd\" id=\"VwT-WD-YPe\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Zoom\" id=\"R4o-n2-Eq4\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"performZoom:\" target=\"Ady-hI-5gd\" id=\"DIl-cC-cCs\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"eu3-7i-yIM\"/>\n                                        <menuItem title=\"Bring All to Front\" id=\"LE2-aR-0XJ\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"arrangeInFront:\" target=\"Ady-hI-5gd\" id=\"DRN-fu-gQh\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Always in Front\" state=\"on\" id=\"vT5-eJ-cMt\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAlwaysInFront:\" target=\"Voe-Tx-rLC\" id=\"a4N-d5-ic4\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                        </items>\n                    </menu>\n                    <connections>\n                        <outlet property=\"delegate\" destination=\"Voe-Tx-rLC\" id=\"Xt6-Qh-l1j\"/>\n                    </connections>\n                </application>\n                <customObject id=\"Voe-Tx-rLC\" customClass=\"AppDelegate\" customModule=\"BuildTimeAnalyzer\" customModuleProvider=\"target\">\n                    <connections>\n                        <outlet property=\"alwaysInFrontMenuItem\" destination=\"vT5-eJ-cMt\" id=\"hyc-ts-nzJ\"/>\n                        <outlet property=\"buildTimesMenuItem\" destination=\"SfY-cQ-Dau\" id=\"aXl-6m-zoY\"/>\n                        <outlet property=\"projectSelectionMenuItem\" destination=\"JMA-rD-5Ql\" id=\"ErS-4H-fO2\"/>\n                    </connections>\n                </customObject>\n                <customObject id=\"Ady-hI-5gd\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-33\" y=\"-217\"/>\n        </scene>\n        <!--Window Controller-->\n        <scene sceneID=\"R2V-B0-nI4\">\n            <objects>\n                <windowController id=\"B8D-0N-5wS\" sceneMemberID=\"viewController\">\n                    <window key=\"window\" title=\"Build Time Analyzer\" allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" releasedWhenClosed=\"NO\" visibleAtLaunch=\"NO\" animationBehavior=\"default\" id=\"IQv-IB-iLA\">\n                        <windowStyleMask key=\"styleMask\" titled=\"YES\" closable=\"YES\" miniaturizable=\"YES\" resizable=\"YES\"/>\n                        <rect key=\"contentRect\" x=\"196\" y=\"240\" width=\"999\" height=\"473\"/>\n                        <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"1440\" height=\"877\"/>\n                        <value key=\"minSize\" type=\"size\" width=\"900\" height=\"323\"/>\n                        <connections>\n                            <outlet property=\"delegate\" destination=\"B8D-0N-5wS\" id=\"Rb5-sO-360\"/>\n                        </connections>\n                    </window>\n                    <connections>\n                        <segue destination=\"XfG-lQ-9wD\" kind=\"relationship\" relationship=\"window.shadowedContentViewController\" id=\"cq2-FE-JQM\"/>\n                    </connections>\n                </windowController>\n                <customObject id=\"Oky-zY-oP4\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"258\" y=\"196\"/>\n        </scene>\n        <!--View Controller-->\n        <scene sceneID=\"hIz-AP-VOD\">\n            <objects>\n                <customObject id=\"rPt-NT-nkU\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n                <viewController id=\"XfG-lQ-9wD\" customClass=\"ViewController\" customModule=\"BuildTimeAnalyzer\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" misplaced=\"YES\" id=\"TUB-te-74g\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"994\" height=\"451\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"cll-Z4-M4w\">\n                                <rect key=\"frame\" x=\"20\" y=\"389\" width=\"34\" height=\"24\"/>\n                                <buttonCell key=\"cell\" type=\"push\" bezelStyle=\"rounded\" image=\"NSGoLeftTemplate\" imagePosition=\"only\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"YqD-Wn-Ga3\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"leftButtonClicked:\" target=\"XfG-lQ-9wD\" id=\"A8o-kz-ykA\"/>\n                                </connections>\n                            </button>\n                            <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"wGP-fY-d6m\">\n                                <rect key=\"frame\" x=\"62\" y=\"393\" width=\"51\" height=\"16\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Status: \" id=\"Mm0-J1-a5S\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"RvS-xK-GoL\">\n                                <rect key=\"frame\" x=\"109\" y=\"393\" width=\"83\" height=\"16\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Processing...\" id=\"9P7-Sg-abF\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <progressIndicator hidden=\"YES\" wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"xEn-wZ-b65\">\n                                <rect key=\"frame\" x=\"195\" y=\"393\" width=\"16\" height=\"16\"/>\n                            </progressIndicator>\n                            <button hidden=\"YES\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Phm-qp-QGE\">\n                                <rect key=\"frame\" x=\"221\" y=\"389\" width=\"66\" height=\"24\"/>\n                                <buttonCell key=\"cell\" type=\"push\" title=\"Cancel\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"eJH-bZ-4cr\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <string key=\"keyEquivalent\" base64-UTF8=\"YES\">\nGw\n</string>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"cancelButtonClicked:\" target=\"XfG-lQ-9wD\" id=\"pcf-gG-1AX\"/>\n                                </connections>\n                            </button>\n                            <searchField wantsLayer=\"YES\" focusRingType=\"none\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bBY-pQ-ugQ\">\n                                <rect key=\"frame\" x=\"231\" y=\"389\" width=\"567\" height=\"24\"/>\n                                <searchFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" borderStyle=\"bezel\" usesSingleLineMode=\"YES\" bezelStyle=\"round\" id=\"tSv-aC-SRU\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </searchFieldCell>\n                                <connections>\n                                    <outlet property=\"delegate\" destination=\"XfG-lQ-9wD\" id=\"b1G-WP-MAV\"/>\n                                </connections>\n                            </searchField>\n                            <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"N1E-R8-mNr\">\n                                <rect key=\"frame\" x=\"808\" y=\"394\" width=\"60\" height=\"14\"/>\n                                <buttonCell key=\"cell\" type=\"check\" title=\"per file\" bezelStyle=\"regularSquare\" imagePosition=\"left\" inset=\"2\" id=\"zIu-rY-2Qd\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"14\" id=\"Ev3-lW-a4O\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"60\" id=\"rhf-80-RU9\"/>\n                                </constraints>\n                                <connections>\n                                    <action selector=\"perFileCheckboxClicked:\" target=\"XfG-lQ-9wD\" id=\"Pxx-d4-CZO\"/>\n                                </connections>\n                            </button>\n                            <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Px1-f3-h0i\">\n                                <rect key=\"frame\" x=\"886\" y=\"394\" width=\"90\" height=\"16\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Build Time: 0s\" id=\"YXf-T1-4h3\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <scrollView hidden=\"YES\" autohidesScrollers=\"YES\" horizontalLineScroll=\"19\" horizontalPageScroll=\"10\" verticalLineScroll=\"19\" verticalPageScroll=\"10\" usesPredominantAxisScrolling=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"K1Q-qf-FZ3\">\n                                <rect key=\"frame\" x=\"20\" y=\"20\" width=\"954\" height=\"354\"/>\n                                <clipView key=\"contentView\" id=\"UfE-vR-QZu\">\n                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"952\" height=\"352\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <tableView verticalHuggingPriority=\"750\" allowsExpansionToolTips=\"YES\" columnAutoresizingStyle=\"lastColumnOnly\" columnSelection=\"YES\" multipleSelection=\"NO\" autosaveColumns=\"NO\" rowSizeStyle=\"automatic\" headerView=\"zp0-vs-Vct\" viewBased=\"YES\" id=\"Wag-HG-nHe\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"952\" height=\"329\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                            <size key=\"intercellSpacing\" width=\"3\" height=\"2\"/>\n                                            <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"gridColor\" name=\"gridColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <tableColumns>\n                                                <tableColumn width=\"90\" minWidth=\"40\" maxWidth=\"1000\" id=\"g67-YV-my9\">\n                                                    <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\" title=\"Cumulative time\">\n                                                        <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </tableHeaderCell>\n                                                    <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"FF6-Rn-rW6\">\n                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </textFieldCell>\n                                                    <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                    <prototypeCellViews>\n                                                        <tableCellView identifier=\"Cell0\" misplaced=\"YES\" id=\"8cX-uP-CmA\">\n                                                            <rect key=\"frame\" x=\"1\" y=\"1\" width=\"95\" height=\"17\"/>\n                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                            <subviews>\n                                                                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"JjP-9o-frO\">\n                                                                    <rect key=\"frame\" x=\"-2\" y=\"0.0\" width=\"99\" height=\"16\"/>\n                                                                    <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table \" id=\"suh-0M-gYO\">\n                                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                    </textFieldCell>\n                                                                </textField>\n                                                            </subviews>\n                                                            <constraints>\n                                                                <constraint firstAttribute=\"trailing\" secondItem=\"JjP-9o-frO\" secondAttribute=\"trailing\" id=\"6Eh-ns-FoN\"/>\n                                                                <constraint firstItem=\"JjP-9o-frO\" firstAttribute=\"top\" secondItem=\"8cX-uP-CmA\" secondAttribute=\"top\" id=\"N9I-Ay-0V3\"/>\n                                                                <constraint firstItem=\"JjP-9o-frO\" firstAttribute=\"leading\" secondItem=\"8cX-uP-CmA\" secondAttribute=\"leading\" id=\"nap-PT-9Xu\"/>\n                                                                <constraint firstAttribute=\"bottom\" secondItem=\"JjP-9o-frO\" secondAttribute=\"bottom\" id=\"tXV-IA-hXr\"/>\n                                                            </constraints>\n                                                            <connections>\n                                                                <outlet property=\"textField\" destination=\"JjP-9o-frO\" id=\"1b8-wn-HmW\"/>\n                                                            </connections>\n                                                        </tableCellView>\n                                                    </prototypeCellViews>\n                                                </tableColumn>\n                                                <tableColumn width=\"250\" minWidth=\"40\" maxWidth=\"1000\" id=\"I8k-1E-YFi\">\n                                                    <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\" title=\"Location\">\n                                                        <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </tableHeaderCell>\n                                                    <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"v7P-IT-kt6\">\n                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </textFieldCell>\n                                                    <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                    <prototypeCellViews>\n                                                        <tableCellView identifier=\"Cell1\" misplaced=\"YES\" id=\"rtd-z4-z3H\">\n                                                            <rect key=\"frame\" x=\"99\" y=\"1\" width=\"250\" height=\"17\"/>\n                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                            <subviews>\n                                                                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"gaM-Z3-6r5\">\n                                                                    <rect key=\"frame\" x=\"-2\" y=\"0.0\" width=\"254\" height=\"16\"/>\n                                                                    <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table View Cell\" id=\"ShZ-hG-2RX\">\n                                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                    </textFieldCell>\n                                                                </textField>\n                                                            </subviews>\n                                                            <constraints>\n                                                                <constraint firstAttribute=\"trailing\" secondItem=\"gaM-Z3-6r5\" secondAttribute=\"trailing\" id=\"CST-mz-Cev\"/>\n                                                                <constraint firstItem=\"gaM-Z3-6r5\" firstAttribute=\"top\" secondItem=\"rtd-z4-z3H\" secondAttribute=\"top\" id=\"Mhl-GM-DcR\"/>\n                                                                <constraint firstAttribute=\"bottom\" secondItem=\"gaM-Z3-6r5\" secondAttribute=\"bottom\" id=\"OfP-Vv-Oww\"/>\n                                                                <constraint firstItem=\"gaM-Z3-6r5\" firstAttribute=\"leading\" secondItem=\"rtd-z4-z3H\" secondAttribute=\"leading\" id=\"cWF-CT-nmB\"/>\n                                                            </constraints>\n                                                            <connections>\n                                                                <outlet property=\"textField\" destination=\"gaM-Z3-6r5\" id=\"VAL-7L-QYZ\"/>\n                                                            </connections>\n                                                        </tableCellView>\n                                                    </prototypeCellViews>\n                                                </tableColumn>\n                                                <tableColumn width=\"73\" minWidth=\"10\" maxWidth=\"3.4028234663852886e+38\" id=\"pNQ-e7-chu\">\n                                                    <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\" alignment=\"left\" title=\"Occurrences\">\n                                                        <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"calibratedWhite\"/>\n                                                    </tableHeaderCell>\n                                                    <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" alignment=\"left\" title=\"Text Cell\" id=\"2FU-BF-t5B\">\n                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </textFieldCell>\n                                                    <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                    <prototypeCellViews>\n                                                        <tableCellView identifier=\"Cell2\" id=\"Nfh-T6-pKh\">\n                                                            <rect key=\"frame\" x=\"352\" y=\"1\" width=\"73\" height=\"40\"/>\n                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                            <subviews>\n                                                                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"0iN-e0-gn8\">\n                                                                    <rect key=\"frame\" x=\"0.0\" y=\"12\" width=\"109\" height=\"16\"/>\n                                                                    <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table View Cell\" id=\"NrA-Gj-lWm\">\n                                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                    </textFieldCell>\n                                                                </textField>\n                                                            </subviews>\n                                                            <constraints>\n                                                                <constraint firstItem=\"0iN-e0-gn8\" firstAttribute=\"centerY\" secondItem=\"Nfh-T6-pKh\" secondAttribute=\"centerY\" id=\"IdL-Mf-JRi\"/>\n                                                                <constraint firstAttribute=\"trailing\" secondItem=\"0iN-e0-gn8\" secondAttribute=\"trailing\" constant=\"-34\" id=\"LwB-EE-cDe\"/>\n                                                                <constraint firstItem=\"0iN-e0-gn8\" firstAttribute=\"leading\" secondItem=\"Nfh-T6-pKh\" secondAttribute=\"leading\" constant=\"2\" id=\"qbx-Wq-paT\"/>\n                                                            </constraints>\n                                                            <connections>\n                                                                <outlet property=\"textField\" destination=\"0iN-e0-gn8\" id=\"hYB-5j-Xqa\"/>\n                                                            </connections>\n                                                        </tableCellView>\n                                                    </prototypeCellViews>\n                                                </tableColumn>\n                                                <tableColumn width=\"518\" minWidth=\"40\" maxWidth=\"1000\" id=\"Rka-lG-OGR\">\n                                                    <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\" title=\"Function\">\n                                                        <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </tableHeaderCell>\n                                                    <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"HHv-yh-Ikp\">\n                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </textFieldCell>\n                                                    <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                    <prototypeCellViews>\n                                                        <tableCellView identifier=\"Cell3\" misplaced=\"YES\" id=\"t5F-Tt-KtO\">\n                                                            <rect key=\"frame\" x=\"428\" y=\"1\" width=\"522\" height=\"17\"/>\n                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                            <subviews>\n                                                                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"MfB-eS-1vB\">\n                                                                    <rect key=\"frame\" x=\"-2\" y=\"0.0\" width=\"526\" height=\"16\"/>\n                                                                    <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table View Cell\" id=\"lez-yt-53a\">\n                                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                    </textFieldCell>\n                                                                </textField>\n                                                            </subviews>\n                                                            <constraints>\n                                                                <constraint firstItem=\"MfB-eS-1vB\" firstAttribute=\"top\" secondItem=\"t5F-Tt-KtO\" secondAttribute=\"top\" id=\"4aR-hk-T5b\"/>\n                                                                <constraint firstAttribute=\"trailing\" secondItem=\"MfB-eS-1vB\" secondAttribute=\"trailing\" id=\"5Kg-44-yUS\"/>\n                                                                <constraint firstAttribute=\"bottom\" secondItem=\"MfB-eS-1vB\" secondAttribute=\"bottom\" id=\"WWU-T4-LN2\"/>\n                                                                <constraint firstItem=\"MfB-eS-1vB\" firstAttribute=\"leading\" secondItem=\"t5F-Tt-KtO\" secondAttribute=\"leading\" id=\"hzi-Kk-Wyb\"/>\n                                                            </constraints>\n                                                            <connections>\n                                                                <outlet property=\"textField\" destination=\"MfB-eS-1vB\" id=\"ZWE-af-66X\"/>\n                                                            </connections>\n                                                        </tableCellView>\n                                                    </prototypeCellViews>\n                                                </tableColumn>\n                                            </tableColumns>\n                                            <connections>\n                                                <outlet property=\"dataSource\" destination=\"XfG-lQ-9wD\" id=\"gzU-SG-v2N\"/>\n                                                <outlet property=\"delegate\" destination=\"XfG-lQ-9wD\" id=\"kPR-hV-RmL\"/>\n                                            </connections>\n                                        </tableView>\n                                    </subviews>\n                                </clipView>\n                                <scroller key=\"horizontalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"QJr-l7-VY7\">\n                                    <rect key=\"frame\" x=\"1\" y=\"363\" width=\"952\" height=\"17\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </scroller>\n                                <scroller key=\"verticalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"NO\" id=\"7gW-pK-P4I\">\n                                    <rect key=\"frame\" x=\"224\" y=\"17\" width=\"15\" height=\"102\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </scroller>\n                                <tableHeaderView key=\"headerView\" wantsLayer=\"YES\" id=\"zp0-vs-Vct\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"952\" height=\"23\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </tableHeaderView>\n                            </scrollView>\n                            <customView translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"wyZ-eU-XEt\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"994\" height=\"424\"/>\n                                <subviews>\n                                    <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"x1K-8w-91Y\">\n                                        <rect key=\"frame\" x=\"18\" y=\"382\" width=\"97\" height=\"20\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Instructions\" id=\"9Ga-i4-eZ4\">\n                                            <font key=\"font\" metaFont=\"systemMedium\" size=\"17\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"c6J-cx-fi8\">\n                                        <rect key=\"frame\" x=\"189\" y=\"384\" width=\"404\" height=\"16\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"1) Ensure the below flags are added to your target's Build Settings\" id=\"R8V-zK-2ya\">\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"NbS-C3-WfY\">\n                                        <rect key=\"frame\" x=\"606\" y=\"380\" width=\"92\" height=\"24\"/>\n                                        <buttonCell key=\"cell\" type=\"push\" title=\"Copy flag 1\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"s9H-YB-qWq\">\n                                            <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                        </buttonCell>\n                                        <connections>\n                                            <action selector=\"clipboardButtonClicked:\" target=\"XfG-lQ-9wD\" id=\"xYh-dG-c8k\"/>\n                                        </connections>\n                                    </button>\n                                    <button verticalHuggingPriority=\"750\" misplaced=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"032-pL-jcU\">\n                                        <rect key=\"frame\" x=\"1200\" y=\"211\" width=\"132\" height=\"24\"/>\n                                        <buttonCell key=\"cell\" type=\"push\" title=\"Copy flag 2\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"ZfB-8n-cDW\">\n                                            <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                        </buttonCell>\n                                        <connections>\n                                            <action selector=\"clipboardButton2Clicked:\" target=\"XfG-lQ-9wD\" id=\"Fw6-Hi-c3r\"/>\n                                        </connections>\n                                    </button>\n                                    <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" ambiguous=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Um0-zQ-09O\">\n                                        <rect key=\"frame\" x=\"191\" y=\"307\" width=\"612\" height=\"69\"/>\n                                        <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"ScreenShot\" id=\"vJs-DY-m0y\"/>\n                                    </imageView>\n                                    <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" ambiguous=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Zkv-Tf-sdq\">\n                                        <rect key=\"frame\" x=\"189\" y=\"256\" width=\"224\" height=\"16\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"2) Clean your project (⌘ + Shift + K)\" id=\"eMR-lR-OuM\">\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" ambiguous=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"PV7-TD-diE\">\n                                        <rect key=\"frame\" x=\"189\" y=\"253\" width=\"339\" height=\"16\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"3) Build your project (⌘ + B) and wait for it to complete\" id=\"WcG-TO-qa4\">\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" ambiguous=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"O5K-4i-z6g\">\n                                        <rect key=\"frame\" x=\"189\" y=\"154\" width=\"245\" height=\"16\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Alternatively, choose an existing project\" id=\"j64-c6-4L7\">\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <scrollView wantsLayer=\"YES\" autohidesScrollers=\"YES\" horizontalLineScroll=\"27\" horizontalPageScroll=\"10\" verticalLineScroll=\"27\" verticalPageScroll=\"10\" usesPredominantAxisScrolling=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ddp-S7-yG2\">\n                                        <rect key=\"frame\" x=\"191\" y=\"77\" width=\"612\" height=\"120\"/>\n                                        <clipView key=\"contentView\" id=\"hf9-7R-VGA\">\n                                            <rect key=\"frame\" x=\"1\" y=\"1\" width=\"610\" height=\"118\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                            <subviews>\n                                                <tableView verticalHuggingPriority=\"750\" allowsExpansionToolTips=\"YES\" columnAutoresizingStyle=\"lastColumnOnly\" columnSelection=\"YES\" multipleSelection=\"NO\" autosaveColumns=\"NO\" rowHeight=\"25\" headerView=\"aAe-a7-ga6\" viewBased=\"YES\" id=\"vE3-G0-gZw\">\n                                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"610\" height=\"95\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                    <size key=\"intercellSpacing\" width=\"3\" height=\"2\"/>\n                                                    <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    <color key=\"gridColor\" name=\"gridColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    <tableColumns>\n                                                        <tableColumn width=\"380\" minWidth=\"40\" maxWidth=\"1000\" id=\"EHR-zb-SmS\">\n                                                            <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\" title=\"Name\">\n                                                                <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                            </tableHeaderCell>\n                                                            <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"5Pm-ZP-JFn\">\n                                                                <font key=\"font\" metaFont=\"system\"/>\n                                                                <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                            </textFieldCell>\n                                                            <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                            <prototypeCellViews>\n                                                                <tableCellView identifier=\"Cell0\" id=\"Od6-nA-b4s\">\n                                                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"385\" height=\"40\"/>\n                                                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                                    <subviews>\n                                                                        <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"eRA-xw-ZhX\">\n                                                                            <rect key=\"frame\" x=\"0.0\" y=\"23\" width=\"385\" height=\"17\"/>\n                                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMinY=\"YES\"/>\n                                                                            <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table View Cell\" id=\"vAr-Ew-aeF\">\n                                                                                <font key=\"font\" metaFont=\"system\"/>\n                                                                                <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                            </textFieldCell>\n                                                                        </textField>\n                                                                    </subviews>\n                                                                    <connections>\n                                                                        <outlet property=\"textField\" destination=\"eRA-xw-ZhX\" id=\"5lq-L9-C1L\"/>\n                                                                    </connections>\n                                                                </tableCellView>\n                                                            </prototypeCellViews>\n                                                        </tableColumn>\n                                                        <tableColumn width=\"215\" minWidth=\"40\" maxWidth=\"1000\" id=\"mpO-wX-dkq\">\n                                                            <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\" title=\"Date\">\n                                                                <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                            </tableHeaderCell>\n                                                            <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"suz-qG-dIq\">\n                                                                <font key=\"font\" metaFont=\"system\"/>\n                                                                <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                            </textFieldCell>\n                                                            <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                            <prototypeCellViews>\n                                                                <tableCellView identifier=\"Cell1\" id=\"rFj-Lv-vAO\">\n                                                                    <rect key=\"frame\" x=\"389\" y=\"1\" width=\"219\" height=\"40\"/>\n                                                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                                    <subviews>\n                                                                        <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ukd-Oi-mjC\">\n                                                                            <rect key=\"frame\" x=\"0.0\" y=\"23\" width=\"219\" height=\"17\"/>\n                                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMinY=\"YES\"/>\n                                                                            <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table View Cell\" id=\"7jY-Q2-1y9\">\n                                                                                <font key=\"font\" metaFont=\"system\"/>\n                                                                                <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                            </textFieldCell>\n                                                                        </textField>\n                                                                    </subviews>\n                                                                    <connections>\n                                                                        <outlet property=\"textField\" destination=\"Ukd-Oi-mjC\" id=\"adD-ul-2zd\"/>\n                                                                    </connections>\n                                                                </tableCellView>\n                                                            </prototypeCellViews>\n                                                        </tableColumn>\n                                                    </tableColumns>\n                                                    <connections>\n                                                        <action selector=\"didSelectCell:\" target=\"Ffg-BK-bSD\" id=\"l29-b7-dcK\"/>\n                                                        <outlet property=\"dataSource\" destination=\"Ffg-BK-bSD\" id=\"SjW-4d-Dgm\"/>\n                                                        <outlet property=\"delegate\" destination=\"Ffg-BK-bSD\" id=\"L1S-A9-dAn\"/>\n                                                    </connections>\n                                                </tableView>\n                                            </subviews>\n                                        </clipView>\n                                        <constraints>\n                                            <constraint firstAttribute=\"height\" relation=\"greaterThanOrEqual\" constant=\"120\" id=\"V1C-tO-aNA\"/>\n                                        </constraints>\n                                        <scroller key=\"horizontalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"YXc-0k-3G9\">\n                                            <rect key=\"frame\" x=\"1\" y=\"102\" width=\"610\" height=\"17\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                        </scroller>\n                                        <scroller key=\"verticalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" doubleValue=\"1\" horizontal=\"NO\" id=\"OkT-YA-gco\">\n                                            <rect key=\"frame\" x=\"224\" y=\"17\" width=\"15\" height=\"102\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                        </scroller>\n                                        <tableHeaderView key=\"headerView\" wantsLayer=\"YES\" id=\"aAe-a7-ga6\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"610\" height=\"23\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                        </tableHeaderView>\n                                    </scrollView>\n                                    <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"MtA-kf-7kN\">\n                                        <rect key=\"frame\" x=\"18\" y=\"31\" width=\"142\" height=\"16\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Derived Data Location:\" id=\"TXm-dt-Qp1\">\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                            <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                    </textField>\n                                    <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" verticalCompressionResistancePriority=\"751\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ptj-Cb-LDq\">\n                                        <rect key=\"frame\" x=\"191\" y=\"27\" width=\"612\" height=\"24\"/>\n                                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" drawsBackground=\"YES\" id=\"SDJ-mZ-FgV\">\n                                            <font key=\"font\" metaFont=\"system\"/>\n                                            <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                        </textFieldCell>\n                                        <connections>\n                                            <outlet property=\"delegate\" destination=\"XfG-lQ-9wD\" id=\"kcF-Uo-l1I\"/>\n                                        </connections>\n                                    </textField>\n                                    <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"coU-tR-Iyy\">\n                                        <rect key=\"frame\" x=\"811\" y=\"33\" width=\"22\" height=\"12\"/>\n                                        <buttonCell key=\"cell\" type=\"inline\" bezelStyle=\"inline\" image=\"NSFollowLinkFreestandingTemplate\" imagePosition=\"only\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"zPS-Vu-Noe\">\n                                            <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                            <font key=\"font\" metaFont=\"smallSystemBold\"/>\n                                        </buttonCell>\n                                        <connections>\n                                            <action selector=\"visitDerivedData:\" target=\"XfG-lQ-9wD\" id=\"HW7-Il-IM3\"/>\n                                        </connections>\n                                    </button>\n                                </subviews>\n                                <constraints>\n                                    <constraint firstItem=\"ddp-S7-yG2\" firstAttribute=\"trailing\" secondItem=\"Um0-zQ-09O\" secondAttribute=\"trailing\" id=\"7s6-Yg-1kY\"/>\n                                    <constraint firstItem=\"NbS-C3-WfY\" firstAttribute=\"leading\" secondItem=\"c6J-cx-fi8\" secondAttribute=\"trailing\" constant=\"15\" id=\"8SE-Qr-vIk\"/>\n                                    <constraint firstItem=\"x1K-8w-91Y\" firstAttribute=\"centerY\" secondItem=\"c6J-cx-fi8\" secondAttribute=\"centerY\" id=\"93U-LK-sEV\"/>\n                                    <constraint firstItem=\"ptj-Cb-LDq\" firstAttribute=\"leading\" secondItem=\"ddp-S7-yG2\" secondAttribute=\"leading\" id=\"9ZQ-n0-bEL\"/>\n                                    <constraint firstItem=\"PV7-TD-diE\" firstAttribute=\"top\" secondItem=\"Zkv-Tf-sdq\" secondAttribute=\"bottom\" constant=\"35\" id=\"BO5-sq-vNo\"/>\n                                    <constraint firstItem=\"Um0-zQ-09O\" firstAttribute=\"top\" secondItem=\"c6J-cx-fi8\" secondAttribute=\"bottom\" constant=\"8\" id=\"CCC-q5-86U\"/>\n                                    <constraint firstItem=\"O5K-4i-z6g\" firstAttribute=\"leading\" secondItem=\"PV7-TD-diE\" secondAttribute=\"leading\" id=\"Dpn-sp-Fni\"/>\n                                    <constraint firstItem=\"032-pL-jcU\" firstAttribute=\"leading\" secondItem=\"NbS-C3-WfY\" secondAttribute=\"trailing\" constant=\"6\" id=\"Ic5-61-Mq9\"/>\n                                    <constraint firstItem=\"c6J-cx-fi8\" firstAttribute=\"leading\" secondItem=\"Um0-zQ-09O\" secondAttribute=\"leading\" id=\"NIy-Q9-e38\"/>\n                                    <constraint firstItem=\"Um0-zQ-09O\" firstAttribute=\"centerX\" secondItem=\"wyZ-eU-XEt\" secondAttribute=\"centerX\" id=\"O4l-6w-kjo\"/>\n                                    <constraint firstItem=\"coU-tR-Iyy\" firstAttribute=\"leading\" secondItem=\"ptj-Cb-LDq\" secondAttribute=\"trailing\" constant=\"8\" id=\"Ou4-bQ-rT0\"/>\n                                    <constraint firstItem=\"ddp-S7-yG2\" firstAttribute=\"leading\" secondItem=\"Um0-zQ-09O\" secondAttribute=\"leading\" id=\"QZf-de-QEb\"/>\n                                    <constraint firstItem=\"ptj-Cb-LDq\" firstAttribute=\"trailing\" secondItem=\"ddp-S7-yG2\" secondAttribute=\"trailing\" id=\"QsI-Oh-lIn\"/>\n                                    <constraint firstItem=\"PV7-TD-diE\" firstAttribute=\"leading\" secondItem=\"Zkv-Tf-sdq\" secondAttribute=\"leading\" id=\"U3M-6g-IlA\"/>\n                                    <constraint firstItem=\"MtA-kf-7kN\" firstAttribute=\"top\" secondItem=\"ddp-S7-yG2\" secondAttribute=\"bottom\" constant=\"30\" id=\"Wsv-7h-dXk\"/>\n                                    <constraint firstItem=\"Zkv-Tf-sdq\" firstAttribute=\"leading\" secondItem=\"Um0-zQ-09O\" secondAttribute=\"leading\" id=\"dMc-8a-uJH\"/>\n                                    <constraint firstItem=\"032-pL-jcU\" firstAttribute=\"centerY\" secondItem=\"NbS-C3-WfY\" secondAttribute=\"centerY\" id=\"dgp-d4-cU5\"/>\n                                    <constraint firstItem=\"MtA-kf-7kN\" firstAttribute=\"leading\" secondItem=\"x1K-8w-91Y\" secondAttribute=\"leading\" id=\"doX-4F-aoa\"/>\n                                    <constraint firstItem=\"x1K-8w-91Y\" firstAttribute=\"leading\" secondItem=\"wyZ-eU-XEt\" secondAttribute=\"leading\" constant=\"20\" id=\"fYD-Gu-iO9\"/>\n                                    <constraint firstItem=\"ptj-Cb-LDq\" firstAttribute=\"centerY\" secondItem=\"MtA-kf-7kN\" secondAttribute=\"centerY\" id=\"hWs-e1-6dI\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"ddp-S7-yG2\" secondAttribute=\"trailing\" constant=\"191\" id=\"jvl-63-wCZ\"/>\n                                    <constraint firstItem=\"NbS-C3-WfY\" firstAttribute=\"centerY\" secondItem=\"c6J-cx-fi8\" secondAttribute=\"centerY\" id=\"lGh-3Z-UEi\"/>\n                                    <constraint firstAttribute=\"bottom\" secondItem=\"ptj-Cb-LDq\" secondAttribute=\"bottom\" constant=\"27\" id=\"nQn-b1-UO6\"/>\n                                    <constraint firstItem=\"ddp-S7-yG2\" firstAttribute=\"top\" secondItem=\"O5K-4i-z6g\" secondAttribute=\"bottom\" constant=\"5\" id=\"oCY-Ao-8bF\"/>\n                                    <constraint firstItem=\"Zkv-Tf-sdq\" firstAttribute=\"top\" secondItem=\"Um0-zQ-09O\" secondAttribute=\"bottom\" constant=\"35\" id=\"oan-Z5-mK3\"/>\n                                    <constraint firstItem=\"coU-tR-Iyy\" firstAttribute=\"centerY\" secondItem=\"ptj-Cb-LDq\" secondAttribute=\"centerY\" id=\"rN7-rQ-Q8B\"/>\n                                    <constraint firstItem=\"NbS-C3-WfY\" firstAttribute=\"top\" secondItem=\"wyZ-eU-XEt\" secondAttribute=\"top\" constant=\"20\" id=\"rsF-no-xAd\"/>\n                                    <constraint firstItem=\"O5K-4i-z6g\" firstAttribute=\"top\" secondItem=\"PV7-TD-diE\" secondAttribute=\"bottom\" constant=\"35\" id=\"wss-bT-SAy\"/>\n                                </constraints>\n                            </customView>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"cll-Z4-M4w\" firstAttribute=\"leading\" secondItem=\"TUB-te-74g\" secondAttribute=\"leading\" constant=\"20\" id=\"6I5-O1-qtA\"/>\n                            <constraint firstItem=\"Px1-f3-h0i\" firstAttribute=\"centerY\" secondItem=\"N1E-R8-mNr\" secondAttribute=\"centerY\" constant=\"-1\" id=\"6wl-rn-DSR\"/>\n                            <constraint firstItem=\"RvS-xK-GoL\" firstAttribute=\"leading\" secondItem=\"wGP-fY-d6m\" secondAttribute=\"trailing\" id=\"97q-Nd-g4K\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"wyZ-eU-XEt\" secondAttribute=\"bottom\" id=\"9Tx-hc-Cr8\"/>\n                            <constraint firstItem=\"wyZ-eU-XEt\" firstAttribute=\"leading\" secondItem=\"TUB-te-74g\" secondAttribute=\"leading\" id=\"9VV-Zf-ztM\"/>\n                            <constraint firstItem=\"N1E-R8-mNr\" firstAttribute=\"leading\" secondItem=\"bBY-pQ-ugQ\" secondAttribute=\"trailing\" constant=\"10\" id=\"9xK-9A-L8b\"/>\n                            <constraint firstItem=\"xEn-wZ-b65\" firstAttribute=\"leading\" secondItem=\"RvS-xK-GoL\" secondAttribute=\"trailing\" constant=\"5\" id=\"CWs-Zw-U9N\"/>\n                            <constraint firstItem=\"Phm-qp-QGE\" firstAttribute=\"leading\" secondItem=\"xEn-wZ-b65\" secondAttribute=\"trailing\" constant=\"10\" id=\"HCc-AM-YeT\"/>\n                            <constraint firstItem=\"Px1-f3-h0i\" firstAttribute=\"leading\" secondItem=\"N1E-R8-mNr\" secondAttribute=\"trailing\" constant=\"20\" id=\"IWD-nK-o2R\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"K1Q-qf-FZ3\" secondAttribute=\"trailing\" constant=\"20\" id=\"MHW-8Q-xwg\"/>\n                            <constraint firstItem=\"RvS-xK-GoL\" firstAttribute=\"centerY\" secondItem=\"wGP-fY-d6m\" secondAttribute=\"centerY\" id=\"QHM-Pg-2ag\"/>\n                            <constraint firstItem=\"K1Q-qf-FZ3\" firstAttribute=\"top\" secondItem=\"TUB-te-74g\" secondAttribute=\"top\" constant=\"50\" id=\"Qav-aG-fZq\"/>\n                            <constraint firstItem=\"bBY-pQ-ugQ\" firstAttribute=\"centerY\" secondItem=\"cll-Z4-M4w\" secondAttribute=\"centerY\" id=\"Roh-wf-zeZ\"/>\n                            <constraint firstItem=\"xEn-wZ-b65\" firstAttribute=\"centerY\" secondItem=\"RvS-xK-GoL\" secondAttribute=\"centerY\" id=\"UO8-dG-b6I\"/>\n                            <constraint firstItem=\"K1Q-qf-FZ3\" firstAttribute=\"leading\" secondItem=\"TUB-te-74g\" secondAttribute=\"leading\" constant=\"20\" id=\"W02-7b-1rF\"/>\n                            <constraint firstItem=\"bBY-pQ-ugQ\" firstAttribute=\"leading\" secondItem=\"Um0-zQ-09O\" secondAttribute=\"leading\" constant=\"40\" id=\"XGm-QC-YLA\"/>\n                            <constraint firstItem=\"N1E-R8-mNr\" firstAttribute=\"centerY\" secondItem=\"bBY-pQ-ugQ\" secondAttribute=\"centerY\" id=\"ec0-jZ-yN9\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Px1-f3-h0i\" secondAttribute=\"trailing\" constant=\"20\" id=\"ftF-AU-XEl\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"wyZ-eU-XEt\" secondAttribute=\"trailing\" id=\"fvn-gV-Dbr\"/>\n                            <constraint firstItem=\"wyZ-eU-XEt\" firstAttribute=\"top\" secondItem=\"TUB-te-74g\" secondAttribute=\"top\" id=\"gBL-BQ-VHN\"/>\n                            <constraint firstItem=\"wGP-fY-d6m\" firstAttribute=\"leading\" secondItem=\"cll-Z4-M4w\" secondAttribute=\"trailing\" constant=\"10\" id=\"slo-AQ-lkr\"/>\n                            <constraint firstItem=\"cll-Z4-M4w\" firstAttribute=\"centerY\" secondItem=\"wGP-fY-d6m\" secondAttribute=\"centerY\" id=\"tTb-24-hhh\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"K1Q-qf-FZ3\" secondAttribute=\"bottom\" constant=\"20\" id=\"tYg-T3-Agj\"/>\n                            <constraint firstItem=\"wGP-fY-d6m\" firstAttribute=\"top\" secondItem=\"TUB-te-74g\" secondAttribute=\"top\" constant=\"15\" id=\"xMr-bP-2jr\"/>\n                            <constraint firstItem=\"Phm-qp-QGE\" firstAttribute=\"centerY\" secondItem=\"xEn-wZ-b65\" secondAttribute=\"centerY\" id=\"zhM-OK-89S\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"buildManager\" destination=\"f4z-Qu-43g\" id=\"aek-kF-HmQ\"/>\n                        <outlet property=\"cancelButton\" destination=\"Phm-qp-QGE\" id=\"q44-19-Lli\"/>\n                        <outlet property=\"compileTimeTextField\" destination=\"Px1-f3-h0i\" id=\"XbZ-D3-wwe\"/>\n                        <outlet property=\"derivedDataTextField\" destination=\"ptj-Cb-LDq\" id=\"Hqz-Sh-zea\"/>\n                        <outlet property=\"instructionsView\" destination=\"wyZ-eU-XEt\" id=\"CSN-0u-vnQ\"/>\n                        <outlet property=\"leftButton\" destination=\"cll-Z4-M4w\" id=\"dZK-eZ-LHa\"/>\n                        <outlet property=\"perFileButton\" destination=\"N1E-R8-mNr\" id=\"CAb-hw-afy\"/>\n                        <outlet property=\"progressIndicator\" destination=\"xEn-wZ-b65\" id=\"ISf-c4-IX4\"/>\n                        <outlet property=\"projectSelection\" destination=\"Ffg-BK-bSD\" id=\"0N9-RU-Xyw\"/>\n                        <outlet property=\"searchField\" destination=\"bBY-pQ-ugQ\" id=\"Eqb-dJ-Eov\"/>\n                        <outlet property=\"statusLabel\" destination=\"wGP-fY-d6m\" id=\"ZJT-MH-vIf\"/>\n                        <outlet property=\"statusTextField\" destination=\"RvS-xK-GoL\" id=\"Vew-jo-Hex\"/>\n                        <outlet property=\"tableView\" destination=\"Wag-HG-nHe\" id=\"TKE-UK-M6w\"/>\n                        <outlet property=\"tableViewContainerView\" destination=\"K1Q-qf-FZ3\" id=\"ufv-Ah-QDA\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"Ffg-BK-bSD\" customClass=\"ProjectSelection\" customModule=\"BuildTimeAnalyzer\" customModuleProvider=\"target\">\n                    <connections>\n                        <outlet property=\"tableView\" destination=\"vE3-G0-gZw\" id=\"Mkh-Ri-cQN\"/>\n                    </connections>\n                </customObject>\n                <customObject id=\"f4z-Qu-43g\" customClass=\"BuildManager\" customModule=\"BuildTimeAnalyzer\" customModuleProvider=\"target\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"258\" y=\"933\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"NSFollowLinkFreestandingTemplate\" width=\"20\" height=\"20\"/>\n        <image name=\"NSGoLeftTemplate\" width=\"12\" height=\"17\"/>\n        <image name=\"ScreenShot\" width=\"616\" height=\"69\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "BuildTimeAnalyzer/NSAlert+Extensions.swift",
    "content": "//\n//  NSAlert+Extensions.swift\n//  BuildTimeAnalyzer\n//\n\nimport Cocoa\n\nextension NSAlert {\n    static func show(withMessage message: String, andInformativeText informativeText: String = \"\") {\n        let alert = NSAlert()\n        alert.messageText = message\n        alert.informativeText = informativeText\n        alert.alertStyle = .warning\n        alert.addButton(withTitle: \"OK\")\n        alert.runModal()\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/ProcessingState.swift",
    "content": "//\n//  ProcessingState.swift\n//  BuildTimeAnalyzer\n//\n\nenum ProcessingState {\n    case processing\n    case waiting\n    case completed(didSucceed: Bool, stateName: String)\n\n    static let cancelledString       = \"Cancelled\"\n    static let completedString       = \"Completed\"\n    static let failedString          = \"No valid logs found\"\n    static let processingString      = \"Processing log...\"\n    static let waitingForBuildString = \"Waiting...\"\n}\n\nextension ProcessingState : Equatable {}\n\nfunc ==(lhs: ProcessingState, rhs: ProcessingState) -> Bool {\n    switch (lhs, rhs) {\n    case (let .completed(didSucceed1, _), let .completed(didSucceed2, _)):\n        return didSucceed1 == didSucceed2\n        \n    case (.processing, .processing), (.waiting, .waiting):\n        return true\n        \n    default:\n        return false\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/ProjectSelection.swift",
    "content": "//\n//  ProjectSelection.swift\n//  BuildTimeAnalyzer\n//\n\nimport Cocoa\n\nprotocol ProjectSelectionDelegate: AnyObject {\n    func didSelectProject(with database: XcodeDatabase)\n}\n\nclass ProjectSelection: NSObject {\n    \n    @IBOutlet weak var tableView: NSTableView!\n    weak var delegate: ProjectSelectionDelegate?\n    \n    private var dataSource: [XcodeDatabase] = []\n    \n    static private let dateFormatter: DateFormatter = {\n        let dateFormatter = DateFormatter()\n        dateFormatter.timeStyle = .short\n        dateFormatter.dateStyle = .medium\n        return dateFormatter\n    }()\n    \n    func listFolders() {\n        dataSource = DerivedDataManager.derivedData().compactMap{\n            XcodeDatabase(fromPath: $0.url.appendingPathComponent(\"Logs/Build/LogStoreManifest.plist\").path)\n        }.sorted(by: { $0.modificationDate > $1.modificationDate })\n        \n        tableView.reloadData()\n    }\n    \n    // MARK: Actions\n    \n    @IBAction func didSelectCell(_ sender: NSTableView) {\n        guard sender.selectedRow != -1 else { return }\n        delegate?.didSelectProject(with: dataSource[sender.selectedRow])\n    }\n}\n\n// MARK: NSTableViewDataSource\n\nextension ProjectSelection: NSTableViewDataSource {\n    func numberOfRows(in tableView: NSTableView) -> Int {\n        return dataSource.count\n    }\n}\n\n// MARK: NSTableViewDelegate\n\nextension ProjectSelection: NSTableViewDelegate {\n    \n    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        guard let tableColumn = tableColumn, let columnIndex = tableView.tableColumns.firstIndex(of: tableColumn) else { return nil }\n        \n        let cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: \"Cell\\(columnIndex)\"), owner: self) as? NSTableCellView\n        \n        let source = dataSource[row]\n        var value = \"\"\n        \n        switch columnIndex {\n        case 0:\n            value = source.schemeName\n        default:\n            value = ProjectSelection.dateFormatter.string(from: source.modificationDate)\n        }\n        cellView?.textField?.stringValue = value\n        \n        return cellView\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/RawMeasure.swift",
    "content": "//\n//  RawMeasure.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\n\nstruct RawMeasure {\n    var time: Double\n    var text: String\n    var references: Int\n    \n    init(time: Double, text: String) {\n        self.time = time\n        self.text = text\n        self.references = 1\n    }\n}\n\n// MARK: Equatable\n\nextension RawMeasure: Equatable {}\n\nfunc ==(lhs: RawMeasure, rhs: RawMeasure) -> Bool {\n    return lhs.time == rhs.time && lhs.text == rhs.text\n}\n\n// MARK: Hashable\n\nextension RawMeasure: Hashable {\n    \n    func hash(into hasher: inout Hasher) {\n        hasher.combine(time)\n        hasher.combine(text)\n        hasher.combine(references)\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/UserSettings.swift",
    "content": "//\n//  UserCache.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\n\nclass UserSettings {\n    \n    static private let derivedDataLocationKey = \"derivedDataLocationKey\"\n    static private let windowLevelIsNormalKey = \"windowLevelIsNormalKey\"\n    \n    static private var _derivedDataLocation: String?\n    static private var _windowLevelIsNormal: Bool?\n    \n    static var derivedDataLocation: String {\n        get {\n            if _derivedDataLocation == nil {\n                _derivedDataLocation = UserDefaults.standard.string(forKey: derivedDataLocationKey)\n            }\n            if _derivedDataLocation == nil, let libraryFolder = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first {\n                _derivedDataLocation = \"\\(libraryFolder)/Developer/Xcode/DerivedData\"\n            }\n            return _derivedDataLocation ?? \"\"\n        }\n        set {\n            _derivedDataLocation = newValue\n            UserDefaults.standard.set(newValue, forKey: derivedDataLocationKey)\n            UserDefaults.standard.synchronize()\n        }\n    }\n    \n    static var windowShouldBeTopMost: Bool {\n        get {\n            if _windowLevelIsNormal == nil {\n                _windowLevelIsNormal = UserDefaults.standard.bool(forKey: windowLevelIsNormalKey)\n            }\n            return !(_windowLevelIsNormal ?? false)\n        }\n        set {\n            _windowLevelIsNormal = !newValue\n            UserDefaults.standard.set(_windowLevelIsNormal, forKey: windowLevelIsNormalKey)\n            UserDefaults.standard.synchronize()\n        }\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  BuildTimeAnalyzer\n//\n\nimport Cocoa\n\nclass ViewController: NSViewController {\n    \n    @IBOutlet var buildManager: BuildManager!\n    @IBOutlet weak var cancelButton: NSButton!\n    @IBOutlet weak var compileTimeTextField: NSTextField!\n    @IBOutlet weak var derivedDataTextField: NSTextField!\n    @IBOutlet weak var instructionsView: NSView!\n    @IBOutlet weak var leftButton: NSButton!\n    @IBOutlet weak var perFileButton: NSButton!\n    @IBOutlet weak var progressIndicator: NSProgressIndicator!\n    @IBOutlet weak var projectSelection: ProjectSelection!\n    @IBOutlet weak var searchField: NSSearchField!\n    @IBOutlet weak var statusLabel: NSTextField!\n    @IBOutlet weak var statusTextField: NSTextField!\n    @IBOutlet weak var tableView: NSTableView!\n    @IBOutlet weak var tableViewContainerView: NSScrollView!\n\n    private let dataSource = ViewControllerDataSource()\n    \n    private var currentKey: String?\n    private var nextDatabase: XcodeDatabase?\n\n    private(set) var lastProcessedDatabaseSchemeName: String? = nil\n    {\n        didSet\n        {\n            (NSApp.delegate as? AppDelegate)?.canExport = lastProcessedDatabaseSchemeName != nil\n        }\n    }\n    \n    private var processor = LogProcessor()\n    \n    var processingState: ProcessingState = .waiting {\n        didSet {\n            updateViewForState()\n        }\n    }\n    \n    // MARK: Lifecycle\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        configureLayout()\n        \n        buildManager.delegate = self\n        projectSelection.delegate = self\n        projectSelection.listFolders()\n\n        tableView.tableColumns[0].sortDescriptorPrototype = NSSortDescriptor(key: CompileMeasure.Order.time.rawValue, ascending: true)\n        tableView.tableColumns[1].sortDescriptorPrototype = NSSortDescriptor(key: CompileMeasure.Order.filename.rawValue, ascending: true)\n\n        NotificationCenter.default.addObserver(self, selector: #selector(windowWillClose(notification:)), name: NSWindow.willCloseNotification, object: nil)\n    }\n    \n    override func viewWillAppear() {\n        super.viewWillAppear()\n        \n        // Set window level before view is displayed\n        makeWindowTopMost(topMost: UserSettings.windowShouldBeTopMost)\n    }\n    \n    override func viewWillDisappear() {\n        super.viewWillDisappear()\n\n        // Reset window level before view is hidden\n        // Reference: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/WinPanel/Concepts/WindowLevel.html\n        makeWindowTopMost(topMost: false)\n    }\n    \n    @objc func windowWillClose(notification: NSNotification) {\n        guard let object = notification.object, !(object is NSPanel) else { return }\n        NotificationCenter.default.removeObserver(self)\n        \n        processor.shouldCancel = true\n        NSApp.terminate(self)\n    }\n    \n    // MARK: Layout\n    \n    func configureLayout() {\n        updateTotalLabel(with: 0)\n        updateViewForState()\n        showInstructions(true)\n        \n        derivedDataTextField.stringValue = UserSettings.derivedDataLocation\n        makeWindowTopMost(topMost: UserSettings.windowShouldBeTopMost)\n    }\n    \n    func showInstructions(_ show: Bool) {\n        instructionsView.isHidden = !show\n        \n        let views: [NSView] = [compileTimeTextField, leftButton, perFileButton, searchField, statusLabel, statusTextField, tableViewContainerView]\n        views.forEach{ $0.isHidden = show }\n        \n        if show && processingState == .processing {\n            processor.shouldCancel = true\n            cancelButton.isHidden = true\n            progressIndicator.isHidden = true\n        }\n    }\n    \n    func updateViewForState() {\n        switch processingState {\n        case .processing:\n            showInstructions(false)\n            progressIndicator.isHidden = false\n            progressIndicator.startAnimation(self)\n            statusTextField.stringValue = ProcessingState.processingString\n            cancelButton.isHidden = false\n            \n        case .completed(_, let stateName):\n            progressIndicator.isHidden = true\n            progressIndicator.stopAnimation(self)\n            statusTextField.stringValue = stateName\n            cancelButton.isHidden = true\n            \n        case .waiting:\n            progressIndicator.isHidden = true\n            progressIndicator.stopAnimation(self)\n            statusTextField.stringValue = ProcessingState.waitingForBuildString\n            cancelButton.isHidden = true\n        }\n        \n        if instructionsView.isHidden {\n            searchField.isHidden = !cancelButton.isHidden\n        }\n    }\n    \n    func makeWindowTopMost(topMost: Bool) {\n        if let window = NSApplication.shared.windows.first {\n            let level: CGWindowLevelKey = topMost ? .floatingWindow : .normalWindow\n            window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(level)))\n        }\n    }\n    \n    // MARK: Actions\n    \n    @IBAction func perFileCheckboxClicked(_ sender: NSButton) {\n        dataSource.aggregateByFile = (sender.state.rawValue == 1)\n        tableView.reloadData()\n    }\n    \n    @IBAction func clipboardButtonClicked(_ sender: AnyObject) {\n        NSPasteboard.general.clearContents()\n        NSPasteboard.general.writeObjects([\"-Xfrontend\" as NSPasteboardWriting])\n    }\n    \n    @IBAction func clipboardButton2Clicked(_ sender: AnyObject) {\n        NSPasteboard.general.clearContents()\n        NSPasteboard.general.writeObjects([\"-debug-time-function-bodies\" as NSPasteboardWriting])\n    }\n    \n    @IBAction func visitDerivedData(_ sender: AnyObject) {\n        let url = URL(fileURLWithPath: derivedDataTextField.stringValue, isDirectory: true)\n        NSWorkspace.shared.open(url)\n    }\n    \n    \n    @IBAction func cancelButtonClicked(_ sender: AnyObject) {\n        processor.shouldCancel = true\n    }\n    \n    @IBAction func leftButtonClicked(_ sender: NSButton) {\n        configureMenuItems(showBuildTimesMenuItem: true)\n        \n        cancelProcessing()\n        showInstructions(true)\n        projectSelection.listFolders()\n    }\n\n    @IBAction func exportAsCSVClicked(_ sender: Any?) {\n        guard let keyWindow = NSApp.keyWindow, let scheme = lastProcessedDatabaseSchemeName else {\n            return\n        }\n\n        let exporter = CSVExporter()\n\n        let savePanel = NSSavePanel()\n        savePanel.title = \"Exporting data as CSV…\"\n        savePanel.message = \"Pick location for CSV file to be exported:\"\n        savePanel.prompt = \"Export\"\n        savePanel.allowedFileTypes = [\"csv\"]\n        savePanel.nameFieldStringValue = exporter.filename(with: scheme)\n\n        savePanel.beginSheetModal(for: keyWindow) { [dataSource] (response) in\n            guard response == NSApplication.ModalResponse.OK, let fileUrl = savePanel.url else {\n                return\n            }\n\n            do\n            {\n                try dataSource.exportProcessedData(using: exporter, to: fileUrl)\n            }\n            catch\n            {\n                NSAlert(error: error).runModal()\n            }\n        }\n    }\n    \n    func controlTextDidChange(_ obj: Notification) {\n        if let field = obj.object as? NSSearchField, field == searchField {\n            dataSource.filter = searchField.stringValue\n            tableView.reloadData()\n        } else if let field = obj.object as? NSTextField, field == derivedDataTextField {\n            buildManager.stopMonitoring()\n            UserSettings.derivedDataLocation = field.stringValue\n\n            projectSelection.listFolders()\n            buildManager.startMonitoring()\n        }\n    }\n    \n    // MARK: Utilities\n    \n    func cancelProcessing() {\n        guard processingState == .processing else { return }\n        \n        processor.shouldCancel = true\n        cancelButton.isHidden = true\n    }\n    \n    func configureMenuItems(showBuildTimesMenuItem: Bool) {\n        if let appDelegate = NSApp.delegate as? AppDelegate {\n            appDelegate.configureMenuItems(showBuildTimesMenuItem: showBuildTimesMenuItem)\n        }\n    }\n    \n    func processLog(with database: XcodeDatabase) {\n        guard processingState != .processing else {\n            if let currentKey = currentKey, currentKey != database.key {\n                nextDatabase = database\n                processor.shouldCancel = true\n            }\n            return\n        }\n        \n        configureMenuItems(showBuildTimesMenuItem: false)\n        \n        processingState = .processing\n        currentKey = database.key\n        lastProcessedDatabaseSchemeName = database.schemeName\n        \n        updateTotalLabel(with: database.buildTime)\n        \n        processor.processDatabase(database: database) { [weak self] (result, didComplete, didCancel) in\n            self?.handleProcessorUpdate(result: result, didComplete: didComplete, didCancel: didCancel)\n        }\n    }\n    \n    func handleProcessorUpdate(result: [CompileMeasure], didComplete: Bool, didCancel: Bool) {\n        dataSource.resetSourceData(newSourceData: result)\n        tableView.reloadData()\n        \n        if didComplete {\n            completeProcessorUpdate(didCancel: didCancel)\n        }\n    }\n    \n    func completeProcessorUpdate(didCancel: Bool) {\n        let didSucceed = !dataSource.isEmpty()\n        \n        var stateName = ProcessingState.failedString\n        if didCancel {\n            stateName = ProcessingState.cancelledString\n        } else if didSucceed {\n            stateName = ProcessingState.completedString\n        }\n        \n        processingState = .completed(didSucceed: didSucceed, stateName: stateName)\n        currentKey = nil\n        \n        if let nextDatabase = nextDatabase {\n            self.nextDatabase = nil\n            processLog(with: nextDatabase)\n        }\n        \n        if !didSucceed {\n            let text = \"Ensure the Swift compiler flags has been added.\"\n            NSAlert.show(withMessage: ProcessingState.failedString, andInformativeText: text)\n            \n            showInstructions(true)\n            configureMenuItems(showBuildTimesMenuItem: true)\n        }\n    }\n    \n    func updateTotalLabel(with buildTime: Int) {\n        let text = \"Build duration: \" + (buildTime < 60 ? \"\\(buildTime)s\" : \"\\(buildTime / 60)m \\(buildTime % 60)s\")\n        compileTimeTextField.stringValue = text\n    }\n}\n\n// MARK: NSTableViewDataSource\n\nextension ViewController: NSTableViewDataSource {\n    func numberOfRows(in tableView: NSTableView) -> Int {\n        return dataSource.count()\n    }\n    \n    func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {\n        guard let item = dataSource.measure(index: row) else { return false }\n        let url = URL(fileURLWithPath: item.path, isDirectory: true)\n        NSWorkspace.shared.open(url)\n\n        let gotoLineScript =\n            \"tell application \\\"Xcode\\\"\\n\" +\n            \"  activate\\n\" +\n            \"end tell\\n\" +\n            \"tell application \\\"System Events\\\"\\n\" +\n            \"  keystroke \\\"l\\\" using command down\\n\" +\n            \"  keystroke \\\"\\(item.location)\\\"\\n\" +\n            \"  keystroke return\\n\" +\n            \"end tell\"\n\n        DispatchQueue.global().async {\n            if let script = NSAppleScript(source: gotoLineScript) {\n                script.executeAndReturnError(nil)\n            }\n        }\n        \n        return true\n    }\n}\n\n// MARK: NSTableViewDelegate\n\nextension ViewController: NSTableViewDelegate {\n    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        guard let tableColumn = tableColumn, let columnIndex = tableView.tableColumns.firstIndex(of: tableColumn) else { return nil }\n        guard let item = dataSource.measure(index: row) else { return nil }\n\n        let result = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: \"Cell\\(columnIndex)\"), owner: self) as? NSTableCellView\n        result?.textField?.stringValue = item[columnIndex]\n        \n        return result\n    }\n\n    func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {\n        dataSource.sortDescriptors = tableView.sortDescriptors\n        tableView.reloadData()\n    }\n}\n\n// MARK: BuildManagerDelegate \n\nextension ViewController: BuildManagerDelegate {\n    func buildManager(_ buildManager: BuildManager, shouldParseLogWithDatabase database: XcodeDatabase) {\n        processLog(with: database)\n    }\n    \n    func derivedDataDidChange() {\n        projectSelection.listFolders()\n    }\n}\n\n// MARK: ProjectSelectionDelegate\n\nextension ViewController: ProjectSelectionDelegate {\n    func didSelectProject(with database: XcodeDatabase) {\n        processLog(with: database)\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/ViewControllerDataSource.swift",
    "content": "//\n//  ViewControllerDataSource.swift\n//  BuildTimeAnalyzer\n//\n//  Created by Dmitrii on 02/12/2017.\n//  Copyright © 2017 Cane Media Ltd. All rights reserved.\n//\n\nimport Foundation\n\nclass ViewControllerDataSource {\n\n    var aggregateByFile = false {\n        didSet {\n            processData()\n        }\n    }\n\n    var filter = \"\" {\n        didSet {\n            processData()\n        }\n    }\n\n    var sortDescriptors = [NSSortDescriptor]() {\n        didSet {\n            processData()\n        }\n    }\n\n    private var originalData = [CompileMeasure]()\n    private var processedData = [CompileMeasure]()\n\n    func resetSourceData(newSourceData: [CompileMeasure]) {\n        originalData = newSourceData\n        processData()\n    }\n\n    func isEmpty() -> Bool {\n        return processedData.isEmpty\n    }\n\n    func count() -> Int {\n        return processedData.count\n    }\n\n    func measure(index: Int) -> CompileMeasure? {\n        guard index < processedData.count && index >= 0 else { return nil }\n        return processedData[index]\n    }\n\n    func exportProcessedData(using exporter: CSVExporter, to url: URL) throws {\n        try exporter.export(elements: processedData, to: url)\n    }\n\n    // MARK: - Private methods\n\n    private func processData() {\n        var newProcessedData = aggregateIfNeeded(originalData)\n        newProcessedData = applySortingIfNeeded(newProcessedData)\n        newProcessedData = applyFilteringIfNeeded(newProcessedData)\n\n        processedData = newProcessedData\n    }\n\n    private func aggregateIfNeeded(_ input: [CompileMeasure]) -> [CompileMeasure] {\n        guard aggregateByFile else { return input }\n        var fileTimes: [String: CompileMeasure] = [:]\n        for measure in input {\n            if let fileMeasure = fileTimes[measure.path] {\n                fileMeasure.time += measure.time\n                fileTimes[measure.path] = fileMeasure\n            } else {\n                let newFileMeasure = CompileMeasure(rawPath: measure.path, time: measure.time)\n                fileTimes[measure.path] = newFileMeasure\n            }\n        }\n        return Array(fileTimes.values)\n    }\n\n    private func applySortingIfNeeded(_ input: [CompileMeasure]) -> [CompileMeasure] {\n        if sortDescriptors.isEmpty { return input }\n        return (input as NSArray).sortedArray(using: sortDescriptors) as! Array\n    }\n\n    private func applyFilteringIfNeeded(_ input: [CompileMeasure]) -> [CompileMeasure] {\n        guard !filter.isEmpty else { return input }\n        return input.filter{ textContains($0.code, pattern: filter) || textContains($0.filename, pattern: filter) }\n    }\n\n    private func textContains(_ text: String, pattern: String) -> Bool {\n        return text.lowercased().contains(pattern.lowercased())\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer/XcodeDatabase.swift",
    "content": "//\n//  XcodeDatabase.swift\n//  BuildTimeAnalyzer\n//\n\nimport Foundation\nimport Compression\n\nstruct XcodeDatabase {\n    var path: String\n    var modificationDate: Date\n    \n    var key: String\n    var schemeName: String\n    var title: String\n    var timeStartedRecording: Int\n    var timeStoppedRecording: Int\n    \n    var isBuildType: Bool {\n        return title.hasPrefix(\"Build \") ||  title.hasPrefix(\"Compile \")\n    }\n    \n    var url: URL {\n        return URL(fileURLWithPath: path)\n    }\n    \n    var logUrl: URL {\n        return folderPath.appendingPathComponent(\"\\(key).xcactivitylog\")\n    }\n    \n    var folderPath: URL {\n        return url.deletingLastPathComponent()\n    }\n    \n    var buildTime: Int {\n        return timeStoppedRecording - timeStartedRecording\n    }\n    \n    init?(fromPath path: String) {\n        guard let data = NSDictionary(contentsOfFile: path)?[\"logs\"] as? [String: AnyObject],\n            let key = XcodeDatabase.sortKeys(usingData: data).last?.key,\n            let value = data[key] as? [String : AnyObject],\n            let schemeName = value[\"schemeIdentifier-schemeName\"] as? String,\n            let title = value[\"title\"] as? String,\n            let timeStartedRecording = value[\"timeStartedRecording\"] as? NSNumber,\n            let timeStoppedRecording = value[\"timeStoppedRecording\"] as? NSNumber,\n            let fileAttributes = try? FileManager.default.attributesOfItem(atPath: path),\n            let modificationDate = fileAttributes[FileAttributeKey.modificationDate] as? Date\n            else { return nil }\n        \n        self.modificationDate = modificationDate\n        self.path = path\n        self.key = key\n        self.schemeName = schemeName\n        self.title = title\n        self.timeStartedRecording = timeStartedRecording.intValue\n        self.timeStoppedRecording = timeStoppedRecording.intValue\n    }\n    \n    func processLog() -> String? {\n        guard let rawData = try? Data(contentsOf: URL(fileURLWithPath: logUrl.path)),\n              let data = rawData.gunzipped() else { return nil }\n        return String(data: data, encoding: .utf8)\n    }\n    \n    private static let gzipHeaderSize = 10\n    \n    static func gunzip(_ data: Data) -> Data? {\n        guard data.count > gzipHeaderSize else { return nil }\n        \n        // Skip the gzip header (10 bytes) to get raw deflate data\n        let deflateData = data.dropFirst(gzipHeaderSize)\n        \n        let bufferSize = data.count * 4\n        let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)\n        defer { buffer.deallocate() }\n        \n        var result = Data()\n        deflateData.withUnsafeBytes { rawBuffer in\n            guard let sourcePointer = rawBuffer.baseAddress?.bindMemory(to: UInt8.self, capacity: deflateData.count) else { return }\n            let stream = UnsafeMutablePointer<compression_stream>.allocate(capacity: 1)\n            defer { stream.deallocate() }\n            \n            var status = compression_stream_init(stream, COMPRESSION_STREAM_DECODE, COMPRESSION_ZLIB)\n            guard status == COMPRESSION_STATUS_OK else { return }\n            defer { compression_stream_destroy(stream) }\n            \n            stream.pointee.src_ptr = sourcePointer\n            stream.pointee.src_size = deflateData.count\n            stream.pointee.dst_ptr = buffer\n            stream.pointee.dst_size = bufferSize\n            \n            repeat {\n                status = compression_stream_process(stream, 0)\n                if stream.pointee.dst_size == 0 || status == COMPRESSION_STATUS_END {\n                    let outputSize = bufferSize - stream.pointee.dst_size\n                    result.append(buffer, count: outputSize)\n                    stream.pointee.dst_ptr = buffer\n                    stream.pointee.dst_size = bufferSize\n                }\n            } while status == COMPRESSION_STATUS_OK\n        }\n        return result.isEmpty ? nil : result\n    }\n    \n    static private func sortKeys(usingData data: [String: AnyObject]) -> [(Int, key: String)] {\n        var sortedKeys: [(Int, key: String)] = []\n        for key in data.keys {\n            if let value = data[key] as? [String: AnyObject],\n                let timeStoppedRecording = value[\"timeStoppedRecording\"] as? NSNumber {\n                sortedKeys.append((timeStoppedRecording.intValue, key))\n            }\n        }\n        return sortedKeys.sorted{ $0.0 < $1.0 }\n    }\n}\n\nprivate extension Data {\n    func gunzipped() -> Data? {\n        return XcodeDatabase.gunzip(self)\n    }\n}\n\nextension XcodeDatabase : Equatable {}\n\nfunc ==(lhs: XcodeDatabase, rhs: XcodeDatabase) -> Bool {\n    return lhs.path == rhs.path && lhs.modificationDate == rhs.modificationDate\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t2839B8691FD2896F004C075C /* ViewControllerDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2839B8681FD2896F004C075C /* ViewControllerDataSource.swift */; };\n\t\t2839B86B1FD32766004C075C /* ViewControllerDataSourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2839B86A1FD32766004C075C /* ViewControllerDataSourceTest.swift */; };\n\t\t2A3164C81D21D73F00064045 /* CompileMeasure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3164C01D21D73F00064045 /* CompileMeasure.swift */; };\n\t\t2A3164C91D21D73F00064045 /* LogProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3164C11D21D73F00064045 /* LogProcessor.swift */; };\n\t\t2A3164CB1D21D73F00064045 /* ProcessingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3164C31D21D73F00064045 /* ProcessingState.swift */; };\n\t\t2A3164CC1D21D73F00064045 /* RawMeasure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3164C41D21D73F00064045 /* RawMeasure.swift */; };\n\t\t2A3164D01D21D74A00064045 /* CompileMeasureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3164CF1D21D74A00064045 /* CompileMeasureTests.swift */; };\n\t\t2A3698AA1D80A1AC002C5CDA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A3698A91D80A1AC002C5CDA /* Main.storyboard */; };\n\t\t2A3698AC1D80A33B002C5CDA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3698AB1D80A33B002C5CDA /* ViewController.swift */; };\n\t\t2A5404011D86D01700DBD44C /* BuildManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5404001D86D01700DBD44C /* BuildManager.swift */; };\n\t\t2A5404031D86DE0C00DBD44C /* XcodeDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5404021D86DE0C00DBD44C /* XcodeDatabase.swift */; };\n\t\t2A5404051D86F3C700DBD44C /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5404041D86F3C700DBD44C /* File.swift */; };\n\t\t2A9807DD1D7C71F900B9232C /* DirectoryMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A9807DC1D7C71F900B9232C /* DirectoryMonitor.swift */; };\n\t\t2A9807DF1D7C76FD00B9232C /* ProjectSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A9807DE1D7C76FD00B9232C /* ProjectSelection.swift */; };\n\t\t2ABFB6CE1D81F2DE00D060BF /* NSAlert+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABFB6CD1D81F2DE00D060BF /* NSAlert+Extensions.swift */; };\n\t\t2ACBFD0C1D8835E60009567E /* UserSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ACBFD0B1D8835E60009567E /* UserSettings.swift */; };\n\t\t2AE775121D225D5D00D1A744 /* DerivedDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE775111D225D5D00D1A744 /* DerivedDataManager.swift */; };\n\t\t2AF821441D21D6B900D65186 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF821431D21D6B900D65186 /* AppDelegate.swift */; };\n\t\t2AF821461D21D6B900D65186 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AF821451D21D6B900D65186 /* Assets.xcassets */; };\n\t\t5603EB6221EF93E90013D77B /* CSVExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5603EB6121EF93E90013D77B /* CSVExporter.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t2AF821501D21D6B900D65186 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 2AF821381D21D6B900D65186 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2AF8213F1D21D6B900D65186;\n\t\t\tremoteInfo = BuildTimeAnalyzer;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t2839B8681FD2896F004C075C /* ViewControllerDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerDataSource.swift; sourceTree = \"<group>\"; };\n\t\t2839B86A1FD32766004C075C /* ViewControllerDataSourceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerDataSourceTest.swift; sourceTree = \"<group>\"; };\n\t\t2A3164C01D21D73F00064045 /* CompileMeasure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompileMeasure.swift; sourceTree = \"<group>\"; };\n\t\t2A3164C11D21D73F00064045 /* LogProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogProcessor.swift; sourceTree = \"<group>\"; };\n\t\t2A3164C31D21D73F00064045 /* ProcessingState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProcessingState.swift; sourceTree = \"<group>\"; };\n\t\t2A3164C41D21D73F00064045 /* RawMeasure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawMeasure.swift; sourceTree = \"<group>\"; };\n\t\t2A3164CF1D21D74A00064045 /* CompileMeasureTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompileMeasureTests.swift; sourceTree = \"<group>\"; };\n\t\t2A3698A91D80A1AC002C5CDA /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = \"<group>\"; };\n\t\t2A3698AB1D80A33B002C5CDA /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t2A5404001D86D01700DBD44C /* BuildManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuildManager.swift; sourceTree = \"<group>\"; };\n\t\t2A5404021D86DE0C00DBD44C /* XcodeDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodeDatabase.swift; sourceTree = \"<group>\"; };\n\t\t2A5404041D86F3C700DBD44C /* File.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = \"<group>\"; };\n\t\t2A9807DC1D7C71F900B9232C /* DirectoryMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirectoryMonitor.swift; sourceTree = \"<group>\"; };\n\t\t2A9807DE1D7C76FD00B9232C /* ProjectSelection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProjectSelection.swift; sourceTree = \"<group>\"; };\n\t\t2ABFB6CD1D81F2DE00D060BF /* NSAlert+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"NSAlert+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\t2ACBFD0B1D8835E60009567E /* UserSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserSettings.swift; sourceTree = \"<group>\"; };\n\t\t2AE775111D225D5D00D1A744 /* DerivedDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DerivedDataManager.swift; sourceTree = \"<group>\"; };\n\t\t2AF821401D21D6B900D65186 /* BuildTimeAnalyzer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BuildTimeAnalyzer.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2AF821431D21D6B900D65186 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t2AF821451D21D6B900D65186 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = BuildTimeAnalyzer/Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t2AF8214A1D21D6B900D65186 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t2AF8214F1D21D6B900D65186 /* BuildTimeAnalyzerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BuildTimeAnalyzerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2AF821551D21D6B900D65186 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t5603EB6121EF93E90013D77B /* CSVExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CSVExporter.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t2AF8213D1D21D6B900D65186 /* 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\t2AF8214C1D21D6B900D65186 /* 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\t2A3164D11D21D74F00064045 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2AF8214A1D21D6B900D65186 /* Info.plist */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2A3164D71D21D7A800064045 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2AF821551D21D6B900D65186 /* Info.plist */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2ABFB6CF1D81F34300D060BF /* Extensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2ABFB6CD1D81F2DE00D060BF /* NSAlert+Extensions.swift */,\n\t\t\t);\n\t\t\tname = Extensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2ABFB6D01D81F35400D060BF /* Application */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2AF821431D21D6B900D65186 /* AppDelegate.swift */,\n\t\t\t\t2A3698A91D80A1AC002C5CDA /* Main.storyboard */,\n\t\t\t);\n\t\t\tname = Application;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2ABFB6D11D81F37300D060BF /* Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2A3164C01D21D73F00064045 /* CompileMeasure.swift */,\n\t\t\t\t2A5404041D86F3C700DBD44C /* File.swift */,\n\t\t\t\t2A3164C31D21D73F00064045 /* ProcessingState.swift */,\n\t\t\t\t2A3164C41D21D73F00064045 /* RawMeasure.swift */,\n\t\t\t\t2839B8681FD2896F004C075C /* ViewControllerDataSource.swift */,\n\t\t\t\t2A5404021D86DE0C00DBD44C /* XcodeDatabase.swift */,\n\t\t\t);\n\t\t\tname = Models;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2ABFB6D21D81F81400D060BF /* ViewControllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2A3698AB1D80A33B002C5CDA /* ViewController.swift */,\n\t\t\t);\n\t\t\tname = ViewControllers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2ABFB6D31D81F82600D060BF /* Utilities */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2A5404001D86D01700DBD44C /* BuildManager.swift */,\n\t\t\t\t2AE775111D225D5D00D1A744 /* DerivedDataManager.swift */,\n\t\t\t\t2A9807DC1D7C71F900B9232C /* DirectoryMonitor.swift */,\n\t\t\t\t2A3164C11D21D73F00064045 /* LogProcessor.swift */,\n\t\t\t\t2A9807DE1D7C76FD00B9232C /* ProjectSelection.swift */,\n\t\t\t\t2ACBFD0B1D8835E60009567E /* UserSettings.swift */,\n\t\t\t\t5603EB6121EF93E90013D77B /* CSVExporter.swift */,\n\t\t\t);\n\t\t\tname = Utilities;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2AF821371D21D6B900D65186 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2AF821421D21D6B900D65186 /* BuildTimeAnalyzer */,\n\t\t\t\t2AF821451D21D6B900D65186 /* Assets.xcassets */,\n\t\t\t\t2AF821521D21D6B900D65186 /* BuildTimeAnalyzerTests */,\n\t\t\t\t2AF821411D21D6B900D65186 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2AF821411D21D6B900D65186 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2AF821401D21D6B900D65186 /* BuildTimeAnalyzer.app */,\n\t\t\t\t2AF8214F1D21D6B900D65186 /* BuildTimeAnalyzerTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2AF821421D21D6B900D65186 /* BuildTimeAnalyzer */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2ABFB6D01D81F35400D060BF /* Application */,\n\t\t\t\t2ABFB6CF1D81F34300D060BF /* Extensions */,\n\t\t\t\t2ABFB6D11D81F37300D060BF /* Models */,\n\t\t\t\t2A3164D11D21D74F00064045 /* Supporting Files */,\n\t\t\t\t2ABFB6D31D81F82600D060BF /* Utilities */,\n\t\t\t\t2ABFB6D21D81F81400D060BF /* ViewControllers */,\n\t\t\t);\n\t\t\tpath = BuildTimeAnalyzer;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2AF821521D21D6B900D65186 /* BuildTimeAnalyzerTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2A3164CF1D21D74A00064045 /* CompileMeasureTests.swift */,\n\t\t\t\t2839B86A1FD32766004C075C /* ViewControllerDataSourceTest.swift */,\n\t\t\t\t2A3164D71D21D7A800064045 /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = BuildTimeAnalyzerTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t2AF8213F1D21D6B900D65186 /* BuildTimeAnalyzer */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2AF821581D21D6B900D65186 /* Build configuration list for PBXNativeTarget \"BuildTimeAnalyzer\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2AF8213C1D21D6B900D65186 /* Sources */,\n\t\t\t\t2AF8213D1D21D6B900D65186 /* Frameworks */,\n\t\t\t\t2AF8213E1D21D6B900D65186 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = BuildTimeAnalyzer;\n\t\t\tproductName = BuildTimeAnalyzer;\n\t\t\tproductReference = 2AF821401D21D6B900D65186 /* BuildTimeAnalyzer.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t2AF8214E1D21D6B900D65186 /* BuildTimeAnalyzerTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2AF8215B1D21D6B900D65186 /* Build configuration list for PBXNativeTarget \"BuildTimeAnalyzerTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2AF8214B1D21D6B900D65186 /* Sources */,\n\t\t\t\t2AF8214C1D21D6B900D65186 /* Frameworks */,\n\t\t\t\t2AF8214D1D21D6B900D65186 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t2AF821511D21D6B900D65186 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = BuildTimeAnalyzerTests;\n\t\t\tproductName = BuildTimeAnalyzerTests;\n\t\t\tproductReference = 2AF8214F1D21D6B900D65186 /* BuildTimeAnalyzerTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t2AF821381D21D6B900D65186 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = YES;\n\t\t\t\tLastSwiftUpdateCheck = 0730;\n\t\t\t\tLastUpgradeCheck = 2630;\n\t\t\t\tORGANIZATIONNAME = \"Cane Media Ltd\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t2AF8213F1D21D6B900D65186 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.3.1;\n\t\t\t\t\t\tLastSwiftMigration = 1250;\n\t\t\t\t\t};\n\t\t\t\t\t2AF8214E1D21D6B900D65186 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.3.1;\n\t\t\t\t\t\tLastSwiftMigration = 1250;\n\t\t\t\t\t\tTestTargetID = 2AF8213F1D21D6B900D65186;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 2AF8213B1D21D6B900D65186 /* Build configuration list for PBXProject \"BuildTimeAnalyzer\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\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 = 2AF821371D21D6B900D65186;\n\t\t\tproductRefGroup = 2AF821411D21D6B900D65186 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t2AF8213F1D21D6B900D65186 /* BuildTimeAnalyzer */,\n\t\t\t\t2AF8214E1D21D6B900D65186 /* BuildTimeAnalyzerTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t2AF8213E1D21D6B900D65186 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2A3698AA1D80A1AC002C5CDA /* Main.storyboard in Resources */,\n\t\t\t\t2AF821461D21D6B900D65186 /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2AF8214D1D21D6B900D65186 /* 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\t2AF8213C1D21D6B900D65186 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2A9807DD1D7C71F900B9232C /* DirectoryMonitor.swift in Sources */,\n\t\t\t\t2A3164C91D21D73F00064045 /* LogProcessor.swift in Sources */,\n\t\t\t\t2839B8691FD2896F004C075C /* ViewControllerDataSource.swift in Sources */,\n\t\t\t\t2A5404011D86D01700DBD44C /* BuildManager.swift in Sources */,\n\t\t\t\t5603EB6221EF93E90013D77B /* CSVExporter.swift in Sources */,\n\t\t\t\t2A5404051D86F3C700DBD44C /* File.swift in Sources */,\n\t\t\t\t2ABFB6CE1D81F2DE00D060BF /* NSAlert+Extensions.swift in Sources */,\n\t\t\t\t2A5404031D86DE0C00DBD44C /* XcodeDatabase.swift in Sources */,\n\t\t\t\t2A3164CB1D21D73F00064045 /* ProcessingState.swift in Sources */,\n\t\t\t\t2AF821441D21D6B900D65186 /* AppDelegate.swift in Sources */,\n\t\t\t\t2AE775121D225D5D00D1A744 /* DerivedDataManager.swift in Sources */,\n\t\t\t\t2A3698AC1D80A33B002C5CDA /* ViewController.swift in Sources */,\n\t\t\t\t2A3164CC1D21D73F00064045 /* RawMeasure.swift in Sources */,\n\t\t\t\t2ACBFD0C1D8835E60009567E /* UserSettings.swift in Sources */,\n\t\t\t\t2A3164C81D21D73F00064045 /* CompileMeasure.swift in Sources */,\n\t\t\t\t2A9807DF1D7C76FD00B9232C /* ProjectSelection.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2AF8214B1D21D6B900D65186 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2A3164D01D21D74A00064045 /* CompileMeasureTests.swift in Sources */,\n\t\t\t\t2839B86B1FD32766004C075C /* ViewControllerDataSourceTest.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\t2AF821511D21D6B900D65186 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 2AF8213F1D21D6B900D65186 /* BuildTimeAnalyzer */;\n\t\t\ttargetProxy = 2AF821501D21D6B900D65186 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t2AF821561D21D6B900D65186 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\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 = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_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\tMACOSX_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2AF821571D21D6B900D65186 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\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 = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2AF821591D21D6B900D65186 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tINFOPLIST_FILE = BuildTimeAnalyzer/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 26.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = uk.co.canemedia.BuildTimeAnalyzer;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2AF8215A1D21D6B900D65186 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tINFOPLIST_FILE = BuildTimeAnalyzer/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 26.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = uk.co.canemedia.BuildTimeAnalyzer;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2AF8215C1D21D6B900D65186 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tINFOPLIST_FILE = BuildTimeAnalyzerTests/Info.plist;\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\t\"@loader_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 26.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = uk.co.canemedia.BuildTimeAnalyzerTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/BuildTimeAnalyzer.app/Contents/MacOS/BuildTimeAnalyzer\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2AF8215D1D21D6B900D65186 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tINFOPLIST_FILE = BuildTimeAnalyzerTests/Info.plist;\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\t\"@loader_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 26.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = uk.co.canemedia.BuildTimeAnalyzerTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/BuildTimeAnalyzer.app/Contents/MacOS/BuildTimeAnalyzer\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t2AF8213B1D21D6B900D65186 /* Build configuration list for PBXProject \"BuildTimeAnalyzer\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2AF821561D21D6B900D65186 /* Debug */,\n\t\t\t\t2AF821571D21D6B900D65186 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2AF821581D21D6B900D65186 /* Build configuration list for PBXNativeTarget \"BuildTimeAnalyzer\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2AF821591D21D6B900D65186 /* Debug */,\n\t\t\t\t2AF8215A1D21D6B900D65186 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2AF8215B1D21D6B900D65186 /* Build configuration list for PBXNativeTarget \"BuildTimeAnalyzerTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2AF8215C1D21D6B900D65186 /* Debug */,\n\t\t\t\t2AF8215D1D21D6B900D65186 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 2AF821381D21D6B900D65186 /* Project object */;\n}\n"
  },
  {
    "path": "BuildTimeAnalyzer.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:BuildTimeAnalyzer.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "BuildTimeAnalyzer.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": "BuildTimeAnalyzer.xcodeproj/xcshareddata/xcschemes/BuildTimeAnalyzer.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"2630\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2AF8213F1D21D6B900D65186\"\n               BuildableName = \"BuildTimeAnalyzer.app\"\n               BlueprintName = \"BuildTimeAnalyzer\"\n               ReferencedContainer = \"container:BuildTimeAnalyzer.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2AF8213F1D21D6B900D65186\"\n            BuildableName = \"BuildTimeAnalyzer.app\"\n            BlueprintName = \"BuildTimeAnalyzer\"\n            ReferencedContainer = \"container:BuildTimeAnalyzer.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2AF8214E1D21D6B900D65186\"\n               BuildableName = \"BuildTimeAnalyzerTests.xctest\"\n               BlueprintName = \"BuildTimeAnalyzerTests\"\n               ReferencedContainer = \"container:BuildTimeAnalyzer.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 = \"2AF8213F1D21D6B900D65186\"\n            BuildableName = \"BuildTimeAnalyzer.app\"\n            BlueprintName = \"BuildTimeAnalyzer\"\n            ReferencedContainer = \"container:BuildTimeAnalyzer.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 = \"2AF8213F1D21D6B900D65186\"\n            BuildableName = \"BuildTimeAnalyzer.app\"\n            BlueprintName = \"BuildTimeAnalyzer\"\n            ReferencedContainer = \"container:BuildTimeAnalyzer.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": "BuildTimeAnalyzerTests/CompileMeasureTests.swift",
    "content": "//\n//  CompileMeasureTests.swift\n//  CMBuildTimeAnalyzerTests\n//\n\nimport XCTest\n\n@testable import BuildTimeAnalyzer\n\nclass BuildTimeAnalyzerTests: XCTestCase {\n    \n    func testInit() {\n        // Given\n        let time = 25.3\n        let timeString = \"\\(time)ms\"\n        let filename = \"Code.Swift\"\n        let fileInfo = \"\\(filename):10:23\"\n        let location = 10\n        let folder = \"/User/JohnAppleseed/\"\n        let path = \"\\(folder)\\(filename)\"\n        let rawPath = \"\\(folder)\\(fileInfo)\"\n        let code = \"some code\"\n        let references = 2\n        \n        // When\n        let resultOptional = CompileMeasure(time: time, rawPath: rawPath, code: code, references: references)\n        \n        // Then \n        XCTAssertNotNil(resultOptional)\n        guard let result = resultOptional else { return }\n        \n        XCTAssertEqual(result.time, time)\n        XCTAssertEqual(result.code, code)\n        XCTAssertEqual(result.path, path)\n        XCTAssertEqual(result.fileInfo, fileInfo)\n        XCTAssertEqual(result.filename, filename)\n        XCTAssertEqual(result.location, location)\n        XCTAssertEqual(result.timeString, timeString)\n        XCTAssertEqual(result.references, references)\n    }\n}\n"
  },
  {
    "path": "BuildTimeAnalyzerTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "BuildTimeAnalyzerTests/ViewControllerDataSourceTest.swift",
    "content": "//\n//  ViewControllerDataSourceTest.swift\n//  BuildTimeAnalyzerTests\n//\n//  Created by Dmitrii on 02/12/2017.\n//  Copyright © 2017 Cane Media Ltd. All rights reserved.\n//\n\nimport XCTest\n@testable import BuildTimeAnalyzer\n\nclass ViewControllerDataSourceTest: XCTestCase {\n\n    var measArray: [CompileMeasure]!\n\n    override func setUp() {\n        super.setUp()\n        let meas1 = CompileMeasure(rawPath: \"FileName1.swift:1:1\", time: 10)\n        let meas2 = CompileMeasure(rawPath: \"FileName2.swift:2:2\", time: 2)\n        let meas3 = CompileMeasure(rawPath: \"FileName3.swift:3:3\", time: 8)\n        let meas4 = CompileMeasure(rawPath: \"FileName3.swift:4:4\", time: 0)\n        let meas5 = CompileMeasure(rawPath: \"FileName1.swift:5:5\", time: 2)\n        measArray = [meas4!, meas5!, meas2!, meas3!, meas1!]\n    }\n\n    func testInit() {\n        let dataSource = ViewControllerDataSource()\n\n        XCTAssertFalse(dataSource.aggregateByFile)\n        XCTAssertEqual(dataSource.filter, \"\")\n        XCTAssertNotNil(dataSource.sortDescriptors)\n        XCTAssertEqual(dataSource.sortDescriptors.count, 0)\n        XCTAssertTrue(dataSource.isEmpty())\n    }\n\n    func testAggregate() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        dataSource.aggregateByFile = true\n\n        XCTAssertEqual(dataSource.count(), 3)\n        XCTAssertFalse(dataSource.isEmpty())\n    }\n\n    func testFilter_1() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        dataSource.filter = \"1\"\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 2)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName1.swift\")\n        XCTAssertEqual(dataSource.measure(index: 1)!.filename, \"FileName1.swift\")\n    }\n\n    func testFilter_2() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        dataSource.filter = \"2\"\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 1)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName2.swift\")\n    }\n\n    func testFilter_noMatch() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        dataSource.filter = \"noMatch\"\n\n        XCTAssertTrue(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 0)\n    }\n\n    func testSortTimeAscending() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        let desc = NSSortDescriptor(key: \"time\", ascending: true)\n        dataSource.sortDescriptors = [desc]\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 5)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 1)!.filename, \"FileName1.swift\")\n        XCTAssertEqual(dataSource.measure(index: 2)!.filename, \"FileName2.swift\")\n        XCTAssertEqual(dataSource.measure(index: 3)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 4)!.filename, \"FileName1.swift\")\n    }\n\n    func testSortFilenameDescending() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        let desc = NSSortDescriptor(key: \"filename\", ascending: false)\n        dataSource.sortDescriptors = [desc]\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 5)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 1)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 2)!.filename, \"FileName2.swift\")\n        XCTAssertEqual(dataSource.measure(index: 3)!.filename, \"FileName1.swift\")\n        XCTAssertEqual(dataSource.measure(index: 4)!.filename, \"FileName1.swift\")\n    }\n\n    func testSortFilenameAscending_TimeAscending() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        let descFilename = NSSortDescriptor(key: \"filename\", ascending: true)\n        let descTime = NSSortDescriptor(key: \"time\", ascending: true)\n        dataSource.sortDescriptors = [descFilename, descTime]\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 5)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName1.swift\")\n        XCTAssertEqual(dataSource.measure(index: 0)!.time, 2)\n        XCTAssertEqual(dataSource.measure(index: 1)!.filename, \"FileName1.swift\")\n        XCTAssertEqual(dataSource.measure(index: 1)!.time, 10)\n        XCTAssertEqual(dataSource.measure(index: 2)!.filename, \"FileName2.swift\")\n        XCTAssertEqual(dataSource.measure(index: 3)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 3)!.time, 0)\n        XCTAssertEqual(dataSource.measure(index: 4)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 4)!.time, 8)\n    }\n\n    func testSortTimeAscending_FilenameDescending() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        let descTime = NSSortDescriptor(key: \"time\", ascending: true)\n        let descFilename = NSSortDescriptor(key: \"filename\", ascending: false)\n        dataSource.sortDescriptors = [descTime, descFilename]\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 5)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 0)!.time, 0)\n        XCTAssertEqual(dataSource.measure(index: 1)!.filename, \"FileName2.swift\")\n        XCTAssertEqual(dataSource.measure(index: 1)!.time, 2)\n        XCTAssertEqual(dataSource.measure(index: 2)!.filename, \"FileName1.swift\")\n        XCTAssertEqual(dataSource.measure(index: 2)!.time, 2)\n        XCTAssertEqual(dataSource.measure(index: 3)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 3)!.time, 8)\n        XCTAssertEqual(dataSource.measure(index: 4)!.filename, \"FileName1.swift\")\n        XCTAssertEqual(dataSource.measure(index: 4)!.time, 10)\n    }\n\n    func testSortTimeAscending_Filter3() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        let descTime = NSSortDescriptor(key: \"time\", ascending: true)\n        dataSource.sortDescriptors = [descTime]\n        dataSource.filter = \"3\"\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 2)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 0)!.time, 0)\n        XCTAssertEqual(dataSource.measure(index: 1)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 1)!.time, 8)\n    }\n\n    func testFilter3_Aggregate() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        dataSource.filter = \"3\"\n        dataSource.aggregateByFile = true\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 1)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName3.swift\")\n    }\n\n    func testSortFilenameDescending_FilterCanceled_Aggregate() {\n        let dataSource = ViewControllerDataSource()\n        dataSource.resetSourceData(newSourceData: measArray)\n        let descFilename = NSSortDescriptor(key: \"filename\", ascending: false)\n        dataSource.sortDescriptors = [descFilename]\n        dataSource.filter = \"2\"\n        dataSource.aggregateByFile = true\n        dataSource.filter = \"\"\n\n        XCTAssertFalse(dataSource.isEmpty())\n        XCTAssertEqual(dataSource.count(), 3)\n        XCTAssertEqual(dataSource.measure(index: 0)!.filename, \"FileName3.swift\")\n        XCTAssertEqual(dataSource.measure(index: 1)!.filename, \"FileName2.swift\")\n        XCTAssertEqual(dataSource.measure(index: 2)!.filename, \"FileName1.swift\")\n\n    }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Robert Gummesson\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": "Build Time Analyzer for Xcode\n======================\n\n[![GitHub release](https://img.shields.io/github/release/RobertGummesson/BuildTimeAnalyzer-for-Xcode.svg)](https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode/releases/latest)\n[![Swift](https://img.shields.io/badge/Swift-5-orange.svg)](https://swift.org)\n[![Platform](https://img.shields.io/badge/platform-macOS-blue.svg)](https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode)\n[![MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n## Overview\n\nBuild Time Analyzer is a macOS app that shows you a break down of Swift build times. See [this post]( https://medium.com/p/fc92cdd91e31) and [this post](https://medium.com/p/37b0a7514cbe) on Medium for context. \n\n## Usage\n\nOpen up the app and follow the instructions.\n\n![screenshot.png](https://raw.githubusercontent.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode/master/Screenshots/screenshot.png)\n\n## Installation\n\nDownload the code and open it in Xcode, archive the project and export the build. Easy, right?\n\n## Contributions\n\nIf you encounter any issues or have ideas for improvement, I am open to code contributions.\n\n## License\n\n    Copyright (c) 2016-2026, Robert Gummesson\n    All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice, this\n      list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimer in the documentation\n      and/or other materials provided with the distribution.\n\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  }
]