├── .gitignore
├── images
├── demo.gif
├── icon.png
└── preference.png
├── Scre
├── Assets.xcassets
│ ├── Contents.json
│ └── AppIcon.appiconset
│ │ ├── Icon-128.png
│ │ ├── Icon-16.png
│ │ ├── Icon-256.png
│ │ ├── Icon-257.png
│ │ ├── Icon-32.png
│ │ ├── Icon-33.png
│ │ ├── Icon-512.png
│ │ ├── Icon-513.png
│ │ ├── Icon-64.png
│ │ ├── Icon-1024.png
│ │ └── Contents.json
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
├── Scre.entitlements
├── Application.swift
├── Model
│ ├── FrameRate.swift
│ ├── TimerHolder.swift
│ ├── PixelSize.swift
│ ├── GIFConveter.swift
│ └── ScreenRecorder.swift
├── Util
│ ├── Utils.swift
│ ├── Config.swift
│ ├── NSWindow+Extensions.swift
│ └── WindowServer.swift
├── Info.plist
├── View
│ ├── SettingsView.swift
│ └── MainView.swift
└── AppDelegate.swift
├── Podfile
├── Scre.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── shintaro.katafuchi.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── shintaro.katafuchi.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── xcshareddata
│ └── xcschemes
│ │ └── Scre.xcscheme
└── project.pbxproj
├── Scre.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── Podfile.lock
├── CHANGELOG.md
├── ScreTests
├── Info.plist
└── ScreTests.swift
├── ScreUITests
├── Info.plist
└── ScreUITests.swift
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | Pods/
2 | Scre.xcworkspace/xcuserdata/
3 | .DS_Store
--------------------------------------------------------------------------------
/images/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/images/demo.gif
--------------------------------------------------------------------------------
/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/images/icon.png
--------------------------------------------------------------------------------
/images/preference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/images/preference.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Scre/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-128.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-16.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-256.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-257.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-257.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-32.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-33.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-512.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-513.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-513.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-64.png
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-1024.png
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | target 'Scre' do
2 | use_frameworks!
3 | pod "Regift"
4 |
5 | target 'ScreTests' do
6 | inherit! :search_paths
7 | end
8 |
9 | target 'ScreUITests' do
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/Scre.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Scre.xcodeproj/xcuserdata/shintaro.katafuchi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/Scre.xcodeproj/project.xcworkspace/xcuserdata/shintaro.katafuchi.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre.xcodeproj/project.xcworkspace/xcuserdata/shintaro.katafuchi.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Scre.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Regift (1.6.0)
3 |
4 | DEPENDENCIES:
5 | - Regift
6 |
7 | SPEC REPOS:
8 | trunk:
9 | - Regift
10 |
11 | SPEC CHECKSUMS:
12 | Regift: a7c1a7e377c60bfc34301d6f532e099e5ae109a8
13 |
14 | PODFILE CHECKSUM: 399285fd0af35a126e4a9881ad289a493b33cc90
15 |
16 | COCOAPODS: 1.10.0
17 |
--------------------------------------------------------------------------------
/Scre.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Scre.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # ChangeLog
2 |
3 | - 0.2 2021/03/13
4 | - Update: [FPS support](https://github.com/hotchemi/Scre/commit/5a535e91b20b401b746026315e5ced10e0afb1da)
5 | - Fix: [disable record button during start and stop](https://github.com/hotchemi/Scre/pull/5)
6 | - Fix: [initial frame could be zero](https://github.com/hotchemi/Scre/pull/4)
7 | - 0.1 2021/03/11
8 | - Initial release!
--------------------------------------------------------------------------------
/Scre/Scre.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.assets.movies.read-write
8 |
9 | com.apple.security.files.user-selected.read-write
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Scre/Application.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | @main
4 | struct Application: App {
5 | @NSApplicationDelegateAdaptor(AppDelegate.self) private var delegate
6 |
7 | var body: some Scene {
8 | WindowGroup {
9 | MainView()
10 | }
11 | Settings {
12 | SettingsView()
13 | }
14 | .commands {
15 | // disable creating new window
16 | CommandGroup(replacing: CommandGroupPlacement.newItem) {
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Scre/Model/FrameRate.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | enum FrameRate: Int, CaseIterable {
4 | case high
5 | case medium
6 | case low
7 |
8 | var frameRate: Int {
9 | switch self {
10 | case .high:
11 | return 30
12 | case .medium:
13 | return 15
14 | case .low:
15 | return 8
16 | }
17 | }
18 |
19 | var label: String {
20 | switch self {
21 | case .high:
22 | return "High(\(frameRate))"
23 | case .medium:
24 | return "Middle(\(frameRate))"
25 | case .low:
26 | return "Low(\(frameRate))"
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ScreTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ScreUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Scre/Util/Utils.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 |
3 | struct Utils {
4 | static let formatter: DateFormatter = {
5 | let formatter = DateFormatter()
6 | formatter.dateFormat = "yyyy-MM-dd HH.mm.ss"
7 | return formatter
8 | }()
9 |
10 | static func recordFrame(window: NSWindow?) -> CGRect {
11 | guard let window = window else {
12 | return CGRect.zero
13 | }
14 | let lineWidth: CGFloat = 2
15 | let titleHeight: CGFloat = 12
16 | let someValue: CGFloat = 20
17 | return CGRect(x: window.frame.origin.x + lineWidth,
18 | y: window.frame.origin.y + titleHeight + someValue + lineWidth,
19 | width: window.frame.size.width - lineWidth * 2,
20 | height: window.frame.size.height - 40 - someValue - lineWidth)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Scre/Model/TimerHolder.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 | import Combine
3 |
4 | class TimerHolder : ObservableObject {
5 | @Published var navigationTitle = ""
6 | private var timer : Timer?
7 | private var count = 0
8 | private var startDate: Date?
9 |
10 | func start() {
11 | timer?.invalidate()
12 | count = 0
13 | timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [self] _ in
14 | self.count += 1
15 | self.navigationTitle = self.createTimeString(count)
16 | }
17 | }
18 |
19 | private func createTimeString(_ seconds: Int) -> String {
20 | let m = (seconds / 60) % 60
21 | let s = seconds % 60
22 | return String(format: "%02u:%02u", m, s)
23 | }
24 |
25 | func stop() {
26 | timer?.invalidate()
27 | count = 0
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Scre/Model/PixelSize.swift:
--------------------------------------------------------------------------------
1 | import AVFoundation
2 |
3 | enum PixelSize: Int, CaseIterable {
4 | case original
5 | case high
6 | case medium
7 | case low
8 |
9 | var preset: AVCaptureSession.Preset? {
10 | switch self {
11 | case .original:
12 | return nil
13 | case .high:
14 | return AVCaptureSession.Preset.high
15 | case .medium:
16 | return AVCaptureSession.Preset.medium
17 | case .low:
18 | return AVCaptureSession.Preset.low
19 | }
20 | }
21 |
22 | var label: String {
23 | switch self {
24 | case .original:
25 | return "Original"
26 | case .high:
27 | return "High"
28 | case .medium:
29 | return "Middle"
30 | case .low:
31 | return "Low"
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Scre.xcodeproj/xcuserdata/shintaro.katafuchi.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Scre.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 4
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 9F3B5F6825E28DB80084A6B9
16 |
17 | primary
18 |
19 |
20 | 9F3B5F7A25E28DB90084A6B9
21 |
22 | primary
23 |
24 |
25 | 9F3B5F8525E28DB90084A6B9
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Scre/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 0.1
19 | CFBundleVersion
20 | 1
21 | LSMinimumSystemVersion
22 | $(MACOSX_DEPLOYMENT_TARGET)
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ScreTests/ScreTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScreTests.swift
3 | // ScreTests
4 | //
5 | // Created by Shintaro Katafuchi on 2021/02/21.
6 | //
7 |
8 | import XCTest
9 | @testable import Scre
10 |
11 | class ScreTests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 | }
16 |
17 | override func tearDownWithError() throws {
18 | // Put teardown code here. This method is called after the invocation of each test method in the class.
19 | }
20 |
21 | func testExample() throws {
22 | // This is an example of a functional test case.
23 | // Use XCTAssert and related functions to verify your tests produce the correct results.
24 | }
25 |
26 | func testPerformanceExample() throws {
27 | // This is an example of a performance test case.
28 | self.measure {
29 | // Put the code you want to measure the time of here.
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Shintaro Katafuchi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Scre
2 |
3 |
4 |
5 |
6 |
7 | A lightweight screen recorder macOS application written in SwiftUI.
8 |
9 | ## Demo
10 |
11 |
12 |
13 |
14 |
15 | ## Install
16 |
17 | You can use [homebrew-cask](https://github.com/Homebrew/homebrew-cask) or download from [release](https://github.com/hotchemi/Scre/releases) page.
18 |
19 | ```sh
20 | brew tap hotchemi/tap
21 | brew install scre
22 | ```
23 |
24 | ## Keyboard Shortcuts
25 |
26 | - `Command + s`: record/stop button
27 | - `Command + l`: Show other windows
28 | - `Command + ,`: Settings
29 |
30 | ## Settings
31 |
32 | - Always ask file path
33 | - if the option is false, we automatically save GIF file under `Movies` folder.
34 | - Mouse button press
35 | - You can capture your mouse and its press event.
36 | - Repeat
37 | - You can choose whether the GIF file supports repeat or not
38 | - Pixel Size
39 | - Original, High, Middle, Low
40 | - Frame Rate
41 | - High, Middle, Low
42 |
43 |
44 |
46 |
47 | ## Build
48 |
49 | You need CocoaPods to resolve dependencies.
50 |
51 | ```sh
52 | pod install
53 | ```
54 |
55 | And open `Scre.xcworkspace` on XCode and here you go!
--------------------------------------------------------------------------------
/Scre/Util/Config.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import AVFoundation
3 |
4 | struct Config {
5 | enum Key: String {
6 | case alwaysAskFilePath
7 | case mouseButtonPress
8 | case repeatAllowed
9 | case pixelSize
10 | case frameRate
11 | case location
12 | case windowFrame
13 | }
14 |
15 | static let shared = Config()
16 | let userDefaults: UserDefaults
17 |
18 | init(userDefaults: UserDefaults = UserDefaults.standard) {
19 | self.userDefaults = userDefaults
20 | }
21 |
22 | var location: String {
23 | userDefaults.string(forKey: Key.location.rawValue) ?? NSSearchPathForDirectoriesInDomains(.moviesDirectory, .userDomainMask, true).first ?? ""
24 | }
25 |
26 | var alwaysAskFilePath: Bool {
27 | userDefaults.bool(forKey: Key.alwaysAskFilePath.rawValue)
28 | }
29 |
30 | var mouseButtonPress: Bool {
31 | userDefaults.bool(forKey: Key.mouseButtonPress.rawValue)
32 | }
33 |
34 | var repeatAllowed: Int {
35 | userDefaults.bool(forKey: Key.repeatAllowed.rawValue) ? 0 : 1
36 | }
37 |
38 | var sessionPreset: AVCaptureSession.Preset? {
39 | PixelSize(rawValue: userDefaults.integer(forKey: Key.pixelSize.rawValue))?.preset
40 | }
41 |
42 | var frameRate: Int {
43 | FrameRate(rawValue: userDefaults.integer(forKey: Key.frameRate.rawValue))?.frameRate ?? FrameRate.medium.frameRate
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Scre/Model/GIFConveter.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Regift
3 |
4 | final class GIFConverter {
5 | typealias Completion = (URL?) -> Void
6 | private let config = Config.shared
7 |
8 | private var gifUrl: URL {
9 | if config.alwaysAskFilePath {
10 | return URL(fileURLWithPath: Config.shared.location)
11 | } else {
12 | let url = NSSearchPathForDirectoriesInDomains(.moviesDirectory, .userDomainMask, true).first ?? ""
13 | return URL(fileURLWithPath: url).appendingPathComponent(Utils.formatter.string(from: Date())).appendingPathExtension("gif")
14 | }
15 | }
16 |
17 | func save(videoUrl: URL, duration: Float, completion: @escaping Completion) {
18 | Regift.createGIFFromSource(videoUrl, startTime: 0, duration: duration, frameRate: config.frameRate, loopCount: config.repeatAllowed) { url in
19 | self.copy(url: url, completion: completion)
20 | }
21 | }
22 |
23 | private func copy(url: URL?, completion: @escaping Completion) {
24 | guard let url = url else {
25 | completion(nil)
26 | return
27 | }
28 | defer {
29 | try? FileManager.default.removeItem(at: url)
30 | }
31 | do {
32 | let gifUrl = self.gifUrl
33 | try FileManager.default.copyItem(at: url, to: gifUrl)
34 | completion(gifUrl)
35 | } catch {
36 | completion(nil)
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Scre/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Icon-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "Icon-33.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "Icon-32.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "Icon-64.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "Icon-128.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "Icon-257.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "Icon-256.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "Icon-513.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "Icon-512.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "Icon-1024.png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/ScreUITests/ScreUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScreUITests.swift
3 | // ScreUITests
4 | //
5 | // Created by Shintaro Katafuchi on 2021/02/21.
6 | //
7 |
8 | import XCTest
9 |
10 | class ScreUITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use recording to get started writing UI tests.
31 | // Use XCTAssert and related functions to verify your tests produce the correct results.
32 | }
33 |
34 | func testLaunchPerformance() throws {
35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
36 | // This measures how long it takes to launch your application.
37 | measure(metrics: [XCTApplicationLaunchMetric()]) {
38 | XCUIApplication().launch()
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Scre/Util/NSWindow+Extensions.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import SwiftUI
3 |
4 | extension NSWindow {
5 | func toggleMoving(enabled: Bool) {
6 | if enabled {
7 | styleMask.update(with: .resizable)
8 | isMovable = true
9 | isMovableByWindowBackground = true
10 | level = NSWindow.Level(Int(CGWindowLevelForKey(.normalWindow)))
11 | } else {
12 | styleMask.remove(.resizable)
13 | isMovable = false
14 | isMovableByWindowBackground = false
15 | level = NSWindow.Level(Int(CGWindowLevelForKey(.floatingWindow)))
16 | }
17 | }
18 |
19 | func setSizeAsTitle() {
20 | title = sizeAsTitle()
21 | }
22 |
23 | func sizeAsTitle() -> String {
24 | return "Size: \(frame.size.width.description) × \(frame.size.height.description)"
25 | }
26 |
27 | func setInitialFrame(prevRect: CGRect) {
28 | if prevRect == .zero, let screenSize = screen?.visibleFrame.size {
29 | let width: CGFloat = 400
30 | let height: CGFloat = 600
31 | let x = (screenSize.width - prevRect.size.width) / 2 - (width / 2)
32 | let y = (screenSize.height - prevRect.size.height) / 2 - (height / 2)
33 | setFrame(CGRect(x: x, y: y, width: width, height: height), display: true)
34 | } else {
35 | setFrame(frame, display: true)
36 | }
37 | }
38 | }
39 |
40 | extension View {
41 | @ViewBuilder func isHidden(_ hidden: Bool) -> some View {
42 | if hidden {
43 | self.hidden()
44 | } else {
45 | self
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Scre/Util/WindowServer.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct WindowServer {
4 | struct Window {
5 | let pid: Int
6 | let x: Int
7 | let y: Int
8 | let width: Int
9 | let height: Int
10 | }
11 |
12 | static func getWindows() -> [Window] {
13 | var windows: [Window] = []
14 | let options = CGWindowListOption(arrayLiteral: .excludeDesktopElements, .optionOnScreenOnly)
15 | guard let windowList: NSArray = CGWindowListCopyWindowInfo(options, kCGNullWindowID) else {
16 | return windows
17 | }
18 | for window in windowList {
19 | let dict = window as! NSDictionary
20 | if ((dict.value(forKey: "kCGWindowAlpha") as! Double) == 0) {
21 | continue
22 | }
23 | var ownerName = ""
24 | if (dict.value(forKey: "kCGWindowOwnerName") != nil) {
25 | ownerName = dict.value(forKey: "kCGWindowOwnerName") as! String
26 | }
27 | let bundleName = Bundle.main.infoDictionary![kCFBundleNameKey as String] as! String
28 | if (bundleName == ownerName) {
29 | continue
30 | }
31 | let bounds = dict.value(forKey: "kCGWindowBounds") as! NSDictionary
32 | let x = bounds.value(forKey: "X")! as! Int
33 | let y = bounds.value(forKey: "Y")! as! Int
34 | let width = bounds.value(forKey: "Width")! as! Int
35 | let height = bounds.value(forKey: "Height")! as! Int
36 | let pid = dict.value(forKey: "kCGWindowOwnerPID") as! Int
37 | windows.append(Window(pid: pid, x: x, y: y, width: width, height: height))
38 | }
39 | return windows
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Scre/View/SettingsView.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | struct SettingsView: View {
4 | var body: some View {
5 | GeneralSettingsView()
6 | }
7 | }
8 |
9 | struct GeneralSettingsView: View {
10 | // TODO: move to ViewModel
11 | @AppStorage(Config.Key.alwaysAskFilePath.rawValue) private var alwaysAskFilePath = false
12 | @AppStorage(Config.Key.mouseButtonPress.rawValue) private var mouseButtonPress = true
13 | @AppStorage(Config.Key.repeatAllowed.rawValue) private var repeatAllowed = true
14 | @AppStorage(Config.Key.pixelSize.rawValue) private var pixelSize = PixelSize.original.rawValue
15 | @AppStorage(Config.Key.frameRate.rawValue) private var frameRate = FrameRate.medium.rawValue
16 | @AppStorage(Config.Key.location.rawValue) private var location = ""
17 |
18 | var body: some View {
19 | Form {
20 | Toggle("Always ask file path", isOn: $alwaysAskFilePath)
21 | .toggleStyle(SwitchToggleStyle())
22 | Toggle("Mouse button press", isOn: $mouseButtonPress)
23 | .toggleStyle(SwitchToggleStyle())
24 | Toggle("Repeat", isOn: $repeatAllowed)
25 | .toggleStyle(SwitchToggleStyle())
26 | Picker(selection: $pixelSize, label: Text("Pixel Size")) {
27 | ForEach(PixelSize.allCases, id: \.self) { size in
28 | Text(size.label).tag(size.rawValue)
29 | }
30 | }
31 | .frame(width: 160)
32 | Picker(selection: $frameRate, label: Text("Frame Rate")) {
33 | ForEach(FrameRate.allCases, id: \.self) {rate in
34 | Text(rate.label).tag(rate.rawValue)
35 | }
36 | }
37 | .frame(width: 170)
38 | }
39 | .navigationTitle("Preferences")
40 | .frame(width: 350)
41 | .padding()
42 | }
43 | }
44 |
45 | struct SettingsView_Previews: PreviewProvider {
46 | static var previews: some View {
47 | SettingsView()
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Scre/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | final class AppDelegate: NSObject, NSApplicationDelegate {
4 | @AppStorage(Config.Key.windowFrame.rawValue) private var windowFrame = ""
5 |
6 | var window: NSWindow? {
7 | NSApplication.shared.windows.first
8 | }
9 |
10 | func applicationDidFinishLaunching(_ notification: Notification) {
11 | guard let window = window else {
12 | return
13 | }
14 | window.setInitialFrame(prevRect: NSRectFromString(windowFrame))
15 | window.setSizeAsTitle()
16 | window.tabbingMode = .disallowed
17 | window.isOpaque = false
18 | window.backgroundColor = NSColor.clear
19 | window.contentView?.wantsLayer = true
20 | window.contentView?.layer?.borderColor = NSColor.windowBackgroundColor.cgColor
21 | window.contentView?.layer?.borderWidth = 2
22 | window.contentView?.layer?.allowsEdgeAntialiasing = true
23 | window.delegate = self
24 | window.makeKeyAndOrderFront(nil)
25 | window.toggleMoving(enabled: true)
26 |
27 | NotificationCenter.default.addObserver(self, selector: #selector(didResizeNotification(notification:)), name: NSWindow.didResizeNotification, object: nil)
28 | }
29 |
30 | func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
31 | true
32 | }
33 | }
34 |
35 | // MARK: - Command Menu
36 | extension AppDelegate {
37 | @IBAction func showHelp(_ sender: Any) {
38 | guard let url = URL(string: "https://github.com/hotchemi/Scre") else {
39 | return
40 | }
41 | NSWorkspace.shared.open(url)
42 | }
43 | }
44 |
45 | // MARK: - NSWindow.didResizeNotification
46 | extension AppDelegate {
47 | @objc func didResizeNotification(notification: Notification) {
48 | window?.setSizeAsTitle()
49 | }
50 | }
51 |
52 | // MARK: - NSWindowDelegate
53 | extension AppDelegate : NSWindowDelegate {
54 | func windowWillClose(_ notification: Notification) {
55 | NotificationCenter.default.removeObserver(self)
56 | if let frame = window?.frame {
57 | windowFrame = NSStringFromRect(frame)
58 | }
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/Scre/Model/ScreenRecorder.swift:
--------------------------------------------------------------------------------
1 | import AVFoundation
2 | import Cocoa
3 |
4 | protocol ScreenRecorderDelegate {
5 | func screenRecorder(recorder: ScreenRecorder, didStateChange state: MainView.ViewState)
6 | }
7 |
8 | final class ScreenRecorder: NSObject {
9 | private let input = AVCaptureScreenInput(displayID: CGMainDisplayID())
10 | private let output = AVCaptureMovieFileOutput()
11 | private let session = AVCaptureSession()
12 | private let gifConveter = GIFConverter()
13 | private let config = Config.shared
14 |
15 | var delegate: ScreenRecorderDelegate?
16 |
17 | override init() {}
18 |
19 | func record(rect: CGRect) {
20 | guard let input = input else {
21 | debugPrint("failed to initialize AVCaptureScreenInput")
22 | return
23 | }
24 | if let preset = config.sessionPreset {
25 | input.scaleFactor = 1.0
26 | session.sessionPreset = preset
27 | } else {
28 | input.scaleFactor = 0.505
29 | }
30 | input.cropRect = rect
31 | input.capturesCursor = config.mouseButtonPress
32 | input.capturesMouseClicks = config.mouseButtonPress
33 | if session.canAddInput(input) {
34 | session.addInput(input)
35 | }
36 | if session.canAddOutput(output) {
37 | session.addOutput(output)
38 | }
39 | let tempVideoUrl = URL(fileURLWithPath: NSTemporaryDirectory())
40 | .appendingPathComponent(UUID().uuidString)
41 | .appendingPathExtension("mov")
42 | session.startRunning()
43 | output.startRecording(to: tempVideoUrl, recordingDelegate: self)
44 | }
45 |
46 | func stop() {
47 | output.stopRecording()
48 | session.stopRunning()
49 | session.removeOutput(output)
50 | if let input = input {
51 | session.removeInput(input)
52 | }
53 | }
54 | }
55 |
56 | // MARK: - AVCaptureFileOutputRecordingDelegate
57 | extension ScreenRecorder: AVCaptureFileOutputRecordingDelegate {
58 | func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
59 | delegate?.screenRecorder(recorder: self, didStateChange: .recording)
60 | }
61 |
62 | func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
63 | delegate?.screenRecorder(recorder: self, didStateChange: .stop)
64 | let duration = CMTimeGetSeconds(output.recordedDuration)
65 | gifConveter.save(videoUrl: outputFileURL, duration: Float(duration)) { [weak self] url in
66 | guard let self = self else {
67 | return
68 | }
69 | let state: MainView.ViewState = url == nil ? .error : .finish
70 | self.delegate?.screenRecorder(recorder: self, didStateChange: state)
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Scre.xcodeproj/xcshareddata/xcschemes/Scre.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/Scre/View/MainView.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | struct MainView: View {
4 | enum ViewState {
5 | case idle
6 | case start
7 | case recording
8 | case stop
9 | case finish
10 | case error
11 | }
12 | // TODO: move to ViewModel
13 | private let screenRecorder = ScreenRecorder()
14 | @AppStorage(Config.Key.location.rawValue) private var location = ""
15 | @AppStorage(Config.Key.alwaysAskFilePath.rawValue) private var alwaysAskFilePath = false
16 |
17 | @NSApplicationDelegateAdaptor(AppDelegate.self) private var delegate
18 | @ObservedObject private var timerHolder = TimerHolder()
19 | @State private var recordButtonText = "play.fill"
20 | @State private var isActionButtonDisabled = false
21 | @State private var isProgressHidden = true
22 | @State private var showPopover = false
23 | @State private var showAlert = false
24 | @State var state: ViewState = .idle {
25 | didSet {
26 | DispatchQueue.main.async {
27 | self.handleStateChanged()
28 | }
29 | }
30 | }
31 |
32 | var body: some View {
33 | ZStack {
34 | VStack {
35 | Spacer()
36 | HStack {
37 | Button(action: {
38 | NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil)
39 | }, label: {
40 | Image(systemName: "gear")
41 | })
42 | Spacer()
43 | Button(action: {
44 | switch state {
45 | case .idle:
46 | state = .start
47 | case .start, .recording:
48 | state = .stop
49 | default:
50 | break
51 | }
52 | }, label: {
53 | Image(systemName: recordButtonText)
54 | })
55 | .keyboardShortcut("s", modifiers: [.command])
56 | .disabled(isActionButtonDisabled)
57 | Spacer()
58 | Button(action: {
59 | showPopover.toggle()
60 | }, label: {
61 | Image(systemName: "macwindow")
62 | })
63 | .keyboardShortcut("l", modifiers: [.command])
64 | .popover(
65 | isPresented: self.$showPopover,
66 | arrowEdge: .bottom
67 | ) {
68 | // TODO: separate view
69 | let windows = WindowServer.getWindows()
70 | let apps = windows.map { NSRunningApplication(processIdentifier: pid_t($0.pid)) }
71 | List {
72 | ForEach(0 ..< windows.count, id: \.self) { index in
73 | Button(action: {
74 | showPopover.toggle()
75 | guard let screen = NSScreen.main?.frame else {
76 | return
77 | }
78 | let width = windows[index].width
79 | let height = windows[index].height
80 | let x = windows[index].x
81 | let y = Int(screen.size.height) - windows[index].y - height
82 | let rect = CGRect(x: x, y: y, width: width, height: height)
83 | delegate.window?.setFrame(rect, display: true, animate: true)
84 | }) {
85 | Image(nsImage: (apps[index]?.icon)!)
86 | Text(apps[index]?.localizedName ?? "")
87 | }
88 | .buttonStyle(PlainButtonStyle())
89 | }
90 | }
91 | }
92 | }
93 | .padding(8)
94 | .background(Color(NSColor.windowBackgroundColor))
95 | .alert(isPresented: $showAlert) {
96 | Alert(title: Text("Error"),
97 | message: Text("Sorry, something wrong has happenned.")
98 | )
99 | }
100 | }
101 | ProgressView().isHidden(isProgressHidden)
102 | }.navigationTitle(timerHolder.navigationTitle)
103 | }
104 |
105 | private func openSavePanel(successHandler: @escaping () -> Void, errorHandler: @escaping () -> Void) {
106 | let panel = NSSavePanel()
107 | panel.nameFieldStringValue = "\(Utils.formatter.string(from: Date())).gif"
108 | panel.showsTagField = true
109 | panel.canCreateDirectories = true
110 | panel.allowedFileTypes = ["gif"]
111 | panel.begin { response in
112 | if response == .OK, let url = panel.url {
113 | location = url.path
114 | successHandler()
115 | } else {
116 | errorHandler()
117 | }
118 | }
119 | }
120 |
121 | private func handleStateChanged() {
122 | switch state {
123 | case .idle:
124 | recordButtonText = "play.fill"
125 | delegate.window?.toggleMoving(enabled: true)
126 | isProgressHidden = true
127 | timerHolder.navigationTitle = delegate.window?.sizeAsTitle() ?? ""
128 | isActionButtonDisabled = false
129 | case .start:
130 | let closure = {
131 | screenRecorder.delegate = self
132 | screenRecorder.record(rect: Utils.recordFrame(window: delegate.window))
133 | recordButtonText = "stop.fill"
134 | isProgressHidden = true
135 | delegate.window?.toggleMoving(enabled: false)
136 | timerHolder.navigationTitle = "Record will start..."
137 | isActionButtonDisabled = true
138 | }
139 | if alwaysAskFilePath {
140 | openSavePanel(successHandler: closure) {
141 | state = .idle
142 | }
143 | } else {
144 | closure()
145 | }
146 | case .recording:
147 | recordButtonText = "stop.fill"
148 | isProgressHidden = true
149 | timerHolder.start()
150 | isActionButtonDisabled = false
151 | case .stop:
152 | screenRecorder.stop()
153 | isProgressHidden = false
154 | timerHolder.navigationTitle = "Converting to GIF..."
155 | timerHolder.stop()
156 | isActionButtonDisabled = true
157 | case .finish:
158 | state = .idle
159 | isProgressHidden = false
160 | isActionButtonDisabled = false
161 | case .error:
162 | state = .idle
163 | showAlert = true
164 | }
165 | }
166 | }
167 |
168 | extension MainView: ScreenRecorderDelegate {
169 | func screenRecorder(recorder: ScreenRecorder, didStateChange state: ViewState) {
170 | self.state = state
171 | }
172 | }
173 |
174 | struct MainView_Previews: PreviewProvider {
175 | static var previews: some View {
176 | MainView()
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/Scre.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 51;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 7414E07E22D8A9092307001C /* Pods_ScreTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E01C68ECF755905402BBC828 /* Pods_ScreTests.framework */; };
11 | 9F26FE3425E3AE710081BE31 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F26FE3325E3AE710081BE31 /* AppDelegate.swift */; };
12 | 9F3B5F6D25E28DB80084A6B9 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F6C25E28DB80084A6B9 /* Application.swift */; };
13 | 9F3B5F6F25E28DB80084A6B9 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F6E25E28DB80084A6B9 /* MainView.swift */; };
14 | 9F3B5F7125E28DB90084A6B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F3B5F7025E28DB90084A6B9 /* Assets.xcassets */; };
15 | 9F3B5F7425E28DB90084A6B9 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F3B5F7325E28DB90084A6B9 /* Preview Assets.xcassets */; };
16 | 9F3B5F8025E28DB90084A6B9 /* ScreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F7F25E28DB90084A6B9 /* ScreTests.swift */; };
17 | 9F3B5F8B25E28DB90084A6B9 /* ScreUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F8A25E28DB90084A6B9 /* ScreUITests.swift */; };
18 | 9F6037E025E4A7FB00CFA708 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6037DF25E4A7FB00CFA708 /* Config.swift */; };
19 | 9F6037E825E4A81A00CFA708 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6037E725E4A81A00CFA708 /* Utils.swift */; };
20 | 9F85967E25EBA86200A51B43 /* NSWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F85967D25EBA86200A51B43 /* NSWindow+Extensions.swift */; };
21 | 9F93E6C425F2AE8D00B26C7E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F93E6C325F2AE8D00B26C7E /* SettingsView.swift */; };
22 | 9F9AD9C325F4CD6200F48B58 /* PixelSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9AD9C225F4CD6200F48B58 /* PixelSize.swift */; };
23 | 9F9AD9C825F4D33700F48B58 /* FrameRate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9AD9C725F4D33700F48B58 /* FrameRate.swift */; };
24 | 9F9AD9DA25F50EC600F48B58 /* WindowServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9AD9D925F50EC600F48B58 /* WindowServer.swift */; };
25 | 9F9EDC2725F737C400EAFB35 /* TimerHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9EDC2625F737C400EAFB35 /* TimerHolder.swift */; };
26 | 9FB3EF9425E4023500E88335 /* ScreenRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB3EF9325E4023500E88335 /* ScreenRecorder.swift */; };
27 | 9FB3EF9E25E4033700E88335 /* GIFConveter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB3EF9D25E4033700E88335 /* GIFConveter.swift */; };
28 | BD1FDFFDB68D3C03475CDF49 /* Pods_Scre_ScreUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA2220A2A757812E276A7305 /* Pods_Scre_ScreUITests.framework */; };
29 | CEECA6E9DB548459019290C4 /* Pods_Scre.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03E9D5724D7131A8543D5C2C /* Pods_Scre.framework */; };
30 | /* End PBXBuildFile section */
31 |
32 | /* Begin PBXContainerItemProxy section */
33 | 9F3B5F7C25E28DB90084A6B9 /* PBXContainerItemProxy */ = {
34 | isa = PBXContainerItemProxy;
35 | containerPortal = 9F3B5F6125E28DB80084A6B9 /* Project object */;
36 | proxyType = 1;
37 | remoteGlobalIDString = 9F3B5F6825E28DB80084A6B9;
38 | remoteInfo = Scre;
39 | };
40 | 9F3B5F8725E28DB90084A6B9 /* PBXContainerItemProxy */ = {
41 | isa = PBXContainerItemProxy;
42 | containerPortal = 9F3B5F6125E28DB80084A6B9 /* Project object */;
43 | proxyType = 1;
44 | remoteGlobalIDString = 9F3B5F6825E28DB80084A6B9;
45 | remoteInfo = Scre;
46 | };
47 | /* End PBXContainerItemProxy section */
48 |
49 | /* Begin PBXFileReference section */
50 | 03E9D5724D7131A8543D5C2C /* Pods_Scre.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Scre.framework; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 0F8B03146FD21BF6DCD03EB2 /* Pods-Scre.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre.debug.xcconfig"; path = "Target Support Files/Pods-Scre/Pods-Scre.debug.xcconfig"; sourceTree = ""; };
52 | 1195994B4F14D667AD726394 /* Pods-Scre-ScreUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre-ScreUITests.debug.xcconfig"; path = "Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests.debug.xcconfig"; sourceTree = ""; };
53 | 4667D51D990932C8CEF4AD43 /* Pods-Scre-ScreUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre-ScreUITests.release.xcconfig"; path = "Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests.release.xcconfig"; sourceTree = ""; };
54 | 877258A9C45840F1682F8875 /* Pods-ScreTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreTests.release.xcconfig"; path = "Target Support Files/Pods-ScreTests/Pods-ScreTests.release.xcconfig"; sourceTree = ""; };
55 | 9F26FE3325E3AE710081BE31 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
56 | 9F3B5F6925E28DB80084A6B9 /* Scre.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Scre.app; sourceTree = BUILT_PRODUCTS_DIR; };
57 | 9F3B5F6C25E28DB80084A6B9 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = ""; };
58 | 9F3B5F6E25E28DB80084A6B9 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; };
59 | 9F3B5F7025E28DB90084A6B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
60 | 9F3B5F7325E28DB90084A6B9 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
61 | 9F3B5F7525E28DB90084A6B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
62 | 9F3B5F7625E28DB90084A6B9 /* Scre.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Scre.entitlements; sourceTree = ""; };
63 | 9F3B5F7B25E28DB90084A6B9 /* ScreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
64 | 9F3B5F7F25E28DB90084A6B9 /* ScreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreTests.swift; sourceTree = ""; };
65 | 9F3B5F8125E28DB90084A6B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
66 | 9F3B5F8625E28DB90084A6B9 /* ScreUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
67 | 9F3B5F8A25E28DB90084A6B9 /* ScreUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreUITests.swift; sourceTree = ""; };
68 | 9F3B5F8C25E28DB90084A6B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
69 | 9F6037DF25E4A7FB00CFA708 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; };
70 | 9F6037E725E4A81A00CFA708 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; };
71 | 9F85967D25EBA86200A51B43 /* NSWindow+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSWindow+Extensions.swift"; sourceTree = ""; };
72 | 9F93E6C325F2AE8D00B26C7E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; };
73 | 9F9AD9C225F4CD6200F48B58 /* PixelSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelSize.swift; sourceTree = ""; };
74 | 9F9AD9C725F4D33700F48B58 /* FrameRate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameRate.swift; sourceTree = ""; };
75 | 9F9AD9D925F50EC600F48B58 /* WindowServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowServer.swift; sourceTree = ""; };
76 | 9F9EDC2625F737C400EAFB35 /* TimerHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerHolder.swift; sourceTree = ""; };
77 | 9FB3EF9325E4023500E88335 /* ScreenRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenRecorder.swift; sourceTree = ""; };
78 | 9FB3EF9D25E4033700E88335 /* GIFConveter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GIFConveter.swift; sourceTree = ""; };
79 | AA2220A2A757812E276A7305 /* Pods_Scre_ScreUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Scre_ScreUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
80 | C1083585DB6297624A614B7F /* Pods-ScreTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreTests.debug.xcconfig"; path = "Target Support Files/Pods-ScreTests/Pods-ScreTests.debug.xcconfig"; sourceTree = ""; };
81 | E01C68ECF755905402BBC828 /* Pods_ScreTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ScreTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
82 | EA0E19E1E1906A0A9A5764EF /* Pods-Scre.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre.release.xcconfig"; path = "Target Support Files/Pods-Scre/Pods-Scre.release.xcconfig"; sourceTree = ""; };
83 | /* End PBXFileReference section */
84 |
85 | /* Begin PBXFrameworksBuildPhase section */
86 | 9F3B5F6625E28DB80084A6B9 /* Frameworks */ = {
87 | isa = PBXFrameworksBuildPhase;
88 | buildActionMask = 2147483647;
89 | files = (
90 | CEECA6E9DB548459019290C4 /* Pods_Scre.framework in Frameworks */,
91 | );
92 | runOnlyForDeploymentPostprocessing = 0;
93 | };
94 | 9F3B5F7825E28DB90084A6B9 /* Frameworks */ = {
95 | isa = PBXFrameworksBuildPhase;
96 | buildActionMask = 2147483647;
97 | files = (
98 | 7414E07E22D8A9092307001C /* Pods_ScreTests.framework in Frameworks */,
99 | );
100 | runOnlyForDeploymentPostprocessing = 0;
101 | };
102 | 9F3B5F8325E28DB90084A6B9 /* Frameworks */ = {
103 | isa = PBXFrameworksBuildPhase;
104 | buildActionMask = 2147483647;
105 | files = (
106 | BD1FDFFDB68D3C03475CDF49 /* Pods_Scre_ScreUITests.framework in Frameworks */,
107 | );
108 | runOnlyForDeploymentPostprocessing = 0;
109 | };
110 | /* End PBXFrameworksBuildPhase section */
111 |
112 | /* Begin PBXGroup section */
113 | 9F26FE2C25E3ADEB0081BE31 /* View */ = {
114 | isa = PBXGroup;
115 | children = (
116 | 9F3B5F6E25E28DB80084A6B9 /* MainView.swift */,
117 | 9F93E6C325F2AE8D00B26C7E /* SettingsView.swift */,
118 | );
119 | path = View;
120 | sourceTree = "";
121 | };
122 | 9F3B5F6025E28DB80084A6B9 = {
123 | isa = PBXGroup;
124 | children = (
125 | 9F3B5F6B25E28DB80084A6B9 /* Scre */,
126 | 9F3B5F7E25E28DB90084A6B9 /* ScreTests */,
127 | 9F3B5F8925E28DB90084A6B9 /* ScreUITests */,
128 | 9F3B5F6A25E28DB80084A6B9 /* Products */,
129 | B488C141B5517547C2CFF575 /* Pods */,
130 | E1A5780A4E70365F7356EC1B /* Frameworks */,
131 | );
132 | sourceTree = "";
133 | };
134 | 9F3B5F6A25E28DB80084A6B9 /* Products */ = {
135 | isa = PBXGroup;
136 | children = (
137 | 9F3B5F6925E28DB80084A6B9 /* Scre.app */,
138 | 9F3B5F7B25E28DB90084A6B9 /* ScreTests.xctest */,
139 | 9F3B5F8625E28DB90084A6B9 /* ScreUITests.xctest */,
140 | );
141 | name = Products;
142 | sourceTree = "";
143 | };
144 | 9F3B5F6B25E28DB80084A6B9 /* Scre */ = {
145 | isa = PBXGroup;
146 | children = (
147 | 9F6037DE25E4A7ED00CFA708 /* Util */,
148 | 9FB3EF9125E4021B00E88335 /* Model */,
149 | 9F26FE2C25E3ADEB0081BE31 /* View */,
150 | 9F26FE3325E3AE710081BE31 /* AppDelegate.swift */,
151 | 9F3B5F6C25E28DB80084A6B9 /* Application.swift */,
152 | 9F3B5F7025E28DB90084A6B9 /* Assets.xcassets */,
153 | 9F3B5F7525E28DB90084A6B9 /* Info.plist */,
154 | 9F3B5F7625E28DB90084A6B9 /* Scre.entitlements */,
155 | 9F3B5F7225E28DB90084A6B9 /* Preview Content */,
156 | );
157 | path = Scre;
158 | sourceTree = "";
159 | };
160 | 9F3B5F7225E28DB90084A6B9 /* Preview Content */ = {
161 | isa = PBXGroup;
162 | children = (
163 | 9F3B5F7325E28DB90084A6B9 /* Preview Assets.xcassets */,
164 | );
165 | path = "Preview Content";
166 | sourceTree = "";
167 | };
168 | 9F3B5F7E25E28DB90084A6B9 /* ScreTests */ = {
169 | isa = PBXGroup;
170 | children = (
171 | 9F3B5F7F25E28DB90084A6B9 /* ScreTests.swift */,
172 | 9F3B5F8125E28DB90084A6B9 /* Info.plist */,
173 | );
174 | path = ScreTests;
175 | sourceTree = "";
176 | };
177 | 9F3B5F8925E28DB90084A6B9 /* ScreUITests */ = {
178 | isa = PBXGroup;
179 | children = (
180 | 9F3B5F8A25E28DB90084A6B9 /* ScreUITests.swift */,
181 | 9F3B5F8C25E28DB90084A6B9 /* Info.plist */,
182 | );
183 | path = ScreUITests;
184 | sourceTree = "";
185 | };
186 | 9F6037DE25E4A7ED00CFA708 /* Util */ = {
187 | isa = PBXGroup;
188 | children = (
189 | 9F6037DF25E4A7FB00CFA708 /* Config.swift */,
190 | 9F6037E725E4A81A00CFA708 /* Utils.swift */,
191 | 9F85967D25EBA86200A51B43 /* NSWindow+Extensions.swift */,
192 | 9F9AD9D925F50EC600F48B58 /* WindowServer.swift */,
193 | );
194 | path = Util;
195 | sourceTree = "";
196 | };
197 | 9FB3EF9125E4021B00E88335 /* Model */ = {
198 | isa = PBXGroup;
199 | children = (
200 | 9FB3EF9325E4023500E88335 /* ScreenRecorder.swift */,
201 | 9FB3EF9D25E4033700E88335 /* GIFConveter.swift */,
202 | 9F9AD9C225F4CD6200F48B58 /* PixelSize.swift */,
203 | 9F9AD9C725F4D33700F48B58 /* FrameRate.swift */,
204 | 9F9EDC2625F737C400EAFB35 /* TimerHolder.swift */,
205 | );
206 | path = Model;
207 | sourceTree = "";
208 | };
209 | B488C141B5517547C2CFF575 /* Pods */ = {
210 | isa = PBXGroup;
211 | children = (
212 | 0F8B03146FD21BF6DCD03EB2 /* Pods-Scre.debug.xcconfig */,
213 | EA0E19E1E1906A0A9A5764EF /* Pods-Scre.release.xcconfig */,
214 | 1195994B4F14D667AD726394 /* Pods-Scre-ScreUITests.debug.xcconfig */,
215 | 4667D51D990932C8CEF4AD43 /* Pods-Scre-ScreUITests.release.xcconfig */,
216 | C1083585DB6297624A614B7F /* Pods-ScreTests.debug.xcconfig */,
217 | 877258A9C45840F1682F8875 /* Pods-ScreTests.release.xcconfig */,
218 | );
219 | path = Pods;
220 | sourceTree = "";
221 | };
222 | E1A5780A4E70365F7356EC1B /* Frameworks */ = {
223 | isa = PBXGroup;
224 | children = (
225 | 03E9D5724D7131A8543D5C2C /* Pods_Scre.framework */,
226 | AA2220A2A757812E276A7305 /* Pods_Scre_ScreUITests.framework */,
227 | E01C68ECF755905402BBC828 /* Pods_ScreTests.framework */,
228 | );
229 | name = Frameworks;
230 | sourceTree = "";
231 | };
232 | /* End PBXGroup section */
233 |
234 | /* Begin PBXNativeTarget section */
235 | 9F3B5F6825E28DB80084A6B9 /* Scre */ = {
236 | isa = PBXNativeTarget;
237 | buildConfigurationList = 9F3B5F8F25E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "Scre" */;
238 | buildPhases = (
239 | D07BDB164334E5B2CA9A3246 /* [CP] Check Pods Manifest.lock */,
240 | 9F3B5F6525E28DB80084A6B9 /* Sources */,
241 | 9F3B5F6625E28DB80084A6B9 /* Frameworks */,
242 | 9F3B5F6725E28DB80084A6B9 /* Resources */,
243 | 2BF3D8796D13DB59DF1CB22D /* [CP] Embed Pods Frameworks */,
244 | );
245 | buildRules = (
246 | );
247 | dependencies = (
248 | );
249 | name = Scre;
250 | productName = Scre;
251 | productReference = 9F3B5F6925E28DB80084A6B9 /* Scre.app */;
252 | productType = "com.apple.product-type.application";
253 | };
254 | 9F3B5F7A25E28DB90084A6B9 /* ScreTests */ = {
255 | isa = PBXNativeTarget;
256 | buildConfigurationList = 9F3B5F9225E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreTests" */;
257 | buildPhases = (
258 | FD0D607E3A67EA76E1A96E08 /* [CP] Check Pods Manifest.lock */,
259 | 9F3B5F7725E28DB90084A6B9 /* Sources */,
260 | 9F3B5F7825E28DB90084A6B9 /* Frameworks */,
261 | 9F3B5F7925E28DB90084A6B9 /* Resources */,
262 | );
263 | buildRules = (
264 | );
265 | dependencies = (
266 | 9F3B5F7D25E28DB90084A6B9 /* PBXTargetDependency */,
267 | );
268 | name = ScreTests;
269 | productName = ScreTests;
270 | productReference = 9F3B5F7B25E28DB90084A6B9 /* ScreTests.xctest */;
271 | productType = "com.apple.product-type.bundle.unit-test";
272 | };
273 | 9F3B5F8525E28DB90084A6B9 /* ScreUITests */ = {
274 | isa = PBXNativeTarget;
275 | buildConfigurationList = 9F3B5F9525E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreUITests" */;
276 | buildPhases = (
277 | B908A311D8D6EE087CBEAA35 /* [CP] Check Pods Manifest.lock */,
278 | 9F3B5F8225E28DB90084A6B9 /* Sources */,
279 | 9F3B5F8325E28DB90084A6B9 /* Frameworks */,
280 | 9F3B5F8425E28DB90084A6B9 /* Resources */,
281 | 14E6693ADE3ADE729BD6A3AA /* [CP] Embed Pods Frameworks */,
282 | );
283 | buildRules = (
284 | );
285 | dependencies = (
286 | 9F3B5F8825E28DB90084A6B9 /* PBXTargetDependency */,
287 | );
288 | name = ScreUITests;
289 | productName = ScreUITests;
290 | productReference = 9F3B5F8625E28DB90084A6B9 /* ScreUITests.xctest */;
291 | productType = "com.apple.product-type.bundle.ui-testing";
292 | };
293 | /* End PBXNativeTarget section */
294 |
295 | /* Begin PBXProject section */
296 | 9F3B5F6125E28DB80084A6B9 /* Project object */ = {
297 | isa = PBXProject;
298 | attributes = {
299 | LastSwiftUpdateCheck = 1240;
300 | LastUpgradeCheck = 1240;
301 | TargetAttributes = {
302 | 9F3B5F6825E28DB80084A6B9 = {
303 | CreatedOnToolsVersion = 12.4;
304 | };
305 | 9F3B5F7A25E28DB90084A6B9 = {
306 | CreatedOnToolsVersion = 12.4;
307 | TestTargetID = 9F3B5F6825E28DB80084A6B9;
308 | };
309 | 9F3B5F8525E28DB90084A6B9 = {
310 | CreatedOnToolsVersion = 12.4;
311 | TestTargetID = 9F3B5F6825E28DB80084A6B9;
312 | };
313 | };
314 | };
315 | buildConfigurationList = 9F3B5F6425E28DB80084A6B9 /* Build configuration list for PBXProject "Scre" */;
316 | compatibilityVersion = "Xcode 9.3";
317 | developmentRegion = en;
318 | hasScannedForEncodings = 0;
319 | knownRegions = (
320 | en,
321 | Base,
322 | );
323 | mainGroup = 9F3B5F6025E28DB80084A6B9;
324 | productRefGroup = 9F3B5F6A25E28DB80084A6B9 /* Products */;
325 | projectDirPath = "";
326 | projectRoot = "";
327 | targets = (
328 | 9F3B5F6825E28DB80084A6B9 /* Scre */,
329 | 9F3B5F7A25E28DB90084A6B9 /* ScreTests */,
330 | 9F3B5F8525E28DB90084A6B9 /* ScreUITests */,
331 | );
332 | };
333 | /* End PBXProject section */
334 |
335 | /* Begin PBXResourcesBuildPhase section */
336 | 9F3B5F6725E28DB80084A6B9 /* Resources */ = {
337 | isa = PBXResourcesBuildPhase;
338 | buildActionMask = 2147483647;
339 | files = (
340 | 9F3B5F7425E28DB90084A6B9 /* Preview Assets.xcassets in Resources */,
341 | 9F3B5F7125E28DB90084A6B9 /* Assets.xcassets in Resources */,
342 | );
343 | runOnlyForDeploymentPostprocessing = 0;
344 | };
345 | 9F3B5F7925E28DB90084A6B9 /* Resources */ = {
346 | isa = PBXResourcesBuildPhase;
347 | buildActionMask = 2147483647;
348 | files = (
349 | );
350 | runOnlyForDeploymentPostprocessing = 0;
351 | };
352 | 9F3B5F8425E28DB90084A6B9 /* Resources */ = {
353 | isa = PBXResourcesBuildPhase;
354 | buildActionMask = 2147483647;
355 | files = (
356 | );
357 | runOnlyForDeploymentPostprocessing = 0;
358 | };
359 | /* End PBXResourcesBuildPhase section */
360 |
361 | /* Begin PBXShellScriptBuildPhase section */
362 | 14E6693ADE3ADE729BD6A3AA /* [CP] Embed Pods Frameworks */ = {
363 | isa = PBXShellScriptBuildPhase;
364 | buildActionMask = 2147483647;
365 | files = (
366 | );
367 | inputFileListPaths = (
368 | "${PODS_ROOT}/Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
369 | );
370 | name = "[CP] Embed Pods Frameworks";
371 | outputFileListPaths = (
372 | "${PODS_ROOT}/Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
373 | );
374 | runOnlyForDeploymentPostprocessing = 0;
375 | shellPath = /bin/sh;
376 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests-frameworks.sh\"\n";
377 | showEnvVarsInLog = 0;
378 | };
379 | 2BF3D8796D13DB59DF1CB22D /* [CP] Embed Pods Frameworks */ = {
380 | isa = PBXShellScriptBuildPhase;
381 | buildActionMask = 2147483647;
382 | files = (
383 | );
384 | inputFileListPaths = (
385 | "${PODS_ROOT}/Target Support Files/Pods-Scre/Pods-Scre-frameworks-${CONFIGURATION}-input-files.xcfilelist",
386 | );
387 | name = "[CP] Embed Pods Frameworks";
388 | outputFileListPaths = (
389 | "${PODS_ROOT}/Target Support Files/Pods-Scre/Pods-Scre-frameworks-${CONFIGURATION}-output-files.xcfilelist",
390 | );
391 | runOnlyForDeploymentPostprocessing = 0;
392 | shellPath = /bin/sh;
393 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Scre/Pods-Scre-frameworks.sh\"\n";
394 | showEnvVarsInLog = 0;
395 | };
396 | B908A311D8D6EE087CBEAA35 /* [CP] Check Pods Manifest.lock */ = {
397 | isa = PBXShellScriptBuildPhase;
398 | buildActionMask = 2147483647;
399 | files = (
400 | );
401 | inputFileListPaths = (
402 | );
403 | inputPaths = (
404 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
405 | "${PODS_ROOT}/Manifest.lock",
406 | );
407 | name = "[CP] Check Pods Manifest.lock";
408 | outputFileListPaths = (
409 | );
410 | outputPaths = (
411 | "$(DERIVED_FILE_DIR)/Pods-Scre-ScreUITests-checkManifestLockResult.txt",
412 | );
413 | runOnlyForDeploymentPostprocessing = 0;
414 | shellPath = /bin/sh;
415 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
416 | showEnvVarsInLog = 0;
417 | };
418 | D07BDB164334E5B2CA9A3246 /* [CP] Check Pods Manifest.lock */ = {
419 | isa = PBXShellScriptBuildPhase;
420 | buildActionMask = 2147483647;
421 | files = (
422 | );
423 | inputFileListPaths = (
424 | );
425 | inputPaths = (
426 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
427 | "${PODS_ROOT}/Manifest.lock",
428 | );
429 | name = "[CP] Check Pods Manifest.lock";
430 | outputFileListPaths = (
431 | );
432 | outputPaths = (
433 | "$(DERIVED_FILE_DIR)/Pods-Scre-checkManifestLockResult.txt",
434 | );
435 | runOnlyForDeploymentPostprocessing = 0;
436 | shellPath = /bin/sh;
437 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
438 | showEnvVarsInLog = 0;
439 | };
440 | FD0D607E3A67EA76E1A96E08 /* [CP] Check Pods Manifest.lock */ = {
441 | isa = PBXShellScriptBuildPhase;
442 | buildActionMask = 2147483647;
443 | files = (
444 | );
445 | inputFileListPaths = (
446 | );
447 | inputPaths = (
448 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
449 | "${PODS_ROOT}/Manifest.lock",
450 | );
451 | name = "[CP] Check Pods Manifest.lock";
452 | outputFileListPaths = (
453 | );
454 | outputPaths = (
455 | "$(DERIVED_FILE_DIR)/Pods-ScreTests-checkManifestLockResult.txt",
456 | );
457 | runOnlyForDeploymentPostprocessing = 0;
458 | shellPath = /bin/sh;
459 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
460 | showEnvVarsInLog = 0;
461 | };
462 | /* End PBXShellScriptBuildPhase section */
463 |
464 | /* Begin PBXSourcesBuildPhase section */
465 | 9F3B5F6525E28DB80084A6B9 /* Sources */ = {
466 | isa = PBXSourcesBuildPhase;
467 | buildActionMask = 2147483647;
468 | files = (
469 | 9F9AD9C825F4D33700F48B58 /* FrameRate.swift in Sources */,
470 | 9F26FE3425E3AE710081BE31 /* AppDelegate.swift in Sources */,
471 | 9F9AD9DA25F50EC600F48B58 /* WindowServer.swift in Sources */,
472 | 9F3B5F6F25E28DB80084A6B9 /* MainView.swift in Sources */,
473 | 9F85967E25EBA86200A51B43 /* NSWindow+Extensions.swift in Sources */,
474 | 9F93E6C425F2AE8D00B26C7E /* SettingsView.swift in Sources */,
475 | 9F9EDC2725F737C400EAFB35 /* TimerHolder.swift in Sources */,
476 | 9F3B5F6D25E28DB80084A6B9 /* Application.swift in Sources */,
477 | 9F9AD9C325F4CD6200F48B58 /* PixelSize.swift in Sources */,
478 | 9F6037E025E4A7FB00CFA708 /* Config.swift in Sources */,
479 | 9FB3EF9425E4023500E88335 /* ScreenRecorder.swift in Sources */,
480 | 9FB3EF9E25E4033700E88335 /* GIFConveter.swift in Sources */,
481 | 9F6037E825E4A81A00CFA708 /* Utils.swift in Sources */,
482 | );
483 | runOnlyForDeploymentPostprocessing = 0;
484 | };
485 | 9F3B5F7725E28DB90084A6B9 /* Sources */ = {
486 | isa = PBXSourcesBuildPhase;
487 | buildActionMask = 2147483647;
488 | files = (
489 | 9F3B5F8025E28DB90084A6B9 /* ScreTests.swift in Sources */,
490 | );
491 | runOnlyForDeploymentPostprocessing = 0;
492 | };
493 | 9F3B5F8225E28DB90084A6B9 /* Sources */ = {
494 | isa = PBXSourcesBuildPhase;
495 | buildActionMask = 2147483647;
496 | files = (
497 | 9F3B5F8B25E28DB90084A6B9 /* ScreUITests.swift in Sources */,
498 | );
499 | runOnlyForDeploymentPostprocessing = 0;
500 | };
501 | /* End PBXSourcesBuildPhase section */
502 |
503 | /* Begin PBXTargetDependency section */
504 | 9F3B5F7D25E28DB90084A6B9 /* PBXTargetDependency */ = {
505 | isa = PBXTargetDependency;
506 | target = 9F3B5F6825E28DB80084A6B9 /* Scre */;
507 | targetProxy = 9F3B5F7C25E28DB90084A6B9 /* PBXContainerItemProxy */;
508 | };
509 | 9F3B5F8825E28DB90084A6B9 /* PBXTargetDependency */ = {
510 | isa = PBXTargetDependency;
511 | target = 9F3B5F6825E28DB80084A6B9 /* Scre */;
512 | targetProxy = 9F3B5F8725E28DB90084A6B9 /* PBXContainerItemProxy */;
513 | };
514 | /* End PBXTargetDependency section */
515 |
516 | /* Begin XCBuildConfiguration section */
517 | 9F3B5F8D25E28DB90084A6B9 /* Debug */ = {
518 | isa = XCBuildConfiguration;
519 | buildSettings = {
520 | ALWAYS_SEARCH_USER_PATHS = NO;
521 | CLANG_ANALYZER_NONNULL = YES;
522 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
523 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
524 | CLANG_CXX_LIBRARY = "libc++";
525 | CLANG_ENABLE_MODULES = YES;
526 | CLANG_ENABLE_OBJC_ARC = YES;
527 | CLANG_ENABLE_OBJC_WEAK = YES;
528 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
529 | CLANG_WARN_BOOL_CONVERSION = YES;
530 | CLANG_WARN_COMMA = YES;
531 | CLANG_WARN_CONSTANT_CONVERSION = YES;
532 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
533 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
534 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
535 | CLANG_WARN_EMPTY_BODY = YES;
536 | CLANG_WARN_ENUM_CONVERSION = YES;
537 | CLANG_WARN_INFINITE_RECURSION = YES;
538 | CLANG_WARN_INT_CONVERSION = YES;
539 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
540 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
541 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
542 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
543 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
544 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
545 | CLANG_WARN_STRICT_PROTOTYPES = YES;
546 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
547 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
548 | CLANG_WARN_UNREACHABLE_CODE = YES;
549 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
550 | COPY_PHASE_STRIP = NO;
551 | DEBUG_INFORMATION_FORMAT = dwarf;
552 | ENABLE_STRICT_OBJC_MSGSEND = YES;
553 | ENABLE_TESTABILITY = YES;
554 | GCC_C_LANGUAGE_STANDARD = gnu11;
555 | GCC_DYNAMIC_NO_PIC = NO;
556 | GCC_NO_COMMON_BLOCKS = YES;
557 | GCC_OPTIMIZATION_LEVEL = 0;
558 | GCC_PREPROCESSOR_DEFINITIONS = (
559 | "DEBUG=1",
560 | "$(inherited)",
561 | );
562 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
563 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
564 | GCC_WARN_UNDECLARED_SELECTOR = YES;
565 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
566 | GCC_WARN_UNUSED_FUNCTION = YES;
567 | GCC_WARN_UNUSED_VARIABLE = YES;
568 | MACOSX_DEPLOYMENT_TARGET = 11.1;
569 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
570 | MTL_FAST_MATH = YES;
571 | ONLY_ACTIVE_ARCH = YES;
572 | SDKROOT = macosx;
573 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
574 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
575 | };
576 | name = Debug;
577 | };
578 | 9F3B5F8E25E28DB90084A6B9 /* Release */ = {
579 | isa = XCBuildConfiguration;
580 | buildSettings = {
581 | ALWAYS_SEARCH_USER_PATHS = NO;
582 | CLANG_ANALYZER_NONNULL = YES;
583 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
584 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
585 | CLANG_CXX_LIBRARY = "libc++";
586 | CLANG_ENABLE_MODULES = YES;
587 | CLANG_ENABLE_OBJC_ARC = YES;
588 | CLANG_ENABLE_OBJC_WEAK = YES;
589 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
590 | CLANG_WARN_BOOL_CONVERSION = YES;
591 | CLANG_WARN_COMMA = YES;
592 | CLANG_WARN_CONSTANT_CONVERSION = YES;
593 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
594 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
595 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
596 | CLANG_WARN_EMPTY_BODY = YES;
597 | CLANG_WARN_ENUM_CONVERSION = YES;
598 | CLANG_WARN_INFINITE_RECURSION = YES;
599 | CLANG_WARN_INT_CONVERSION = YES;
600 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
601 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
602 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
603 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
604 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
605 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
606 | CLANG_WARN_STRICT_PROTOTYPES = YES;
607 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
608 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
609 | CLANG_WARN_UNREACHABLE_CODE = YES;
610 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
611 | COPY_PHASE_STRIP = NO;
612 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
613 | ENABLE_NS_ASSERTIONS = NO;
614 | ENABLE_STRICT_OBJC_MSGSEND = YES;
615 | GCC_C_LANGUAGE_STANDARD = gnu11;
616 | GCC_NO_COMMON_BLOCKS = YES;
617 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
618 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
619 | GCC_WARN_UNDECLARED_SELECTOR = YES;
620 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
621 | GCC_WARN_UNUSED_FUNCTION = YES;
622 | GCC_WARN_UNUSED_VARIABLE = YES;
623 | MACOSX_DEPLOYMENT_TARGET = 11.1;
624 | MTL_ENABLE_DEBUG_INFO = NO;
625 | MTL_FAST_MATH = YES;
626 | SDKROOT = macosx;
627 | SWIFT_COMPILATION_MODE = wholemodule;
628 | SWIFT_OPTIMIZATION_LEVEL = "-O";
629 | };
630 | name = Release;
631 | };
632 | 9F3B5F9025E28DB90084A6B9 /* Debug */ = {
633 | isa = XCBuildConfiguration;
634 | baseConfigurationReference = 0F8B03146FD21BF6DCD03EB2 /* Pods-Scre.debug.xcconfig */;
635 | buildSettings = {
636 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
637 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
638 | CODE_SIGN_ENTITLEMENTS = Scre/Scre.entitlements;
639 | CODE_SIGN_STYLE = Automatic;
640 | COMBINE_HIDPI_IMAGES = YES;
641 | DEVELOPMENT_ASSET_PATHS = "\"Scre/Preview Content\"";
642 | ENABLE_PREVIEWS = YES;
643 | INFOPLIST_FILE = Scre/Info.plist;
644 | LD_RUNPATH_SEARCH_PATHS = (
645 | "$(inherited)",
646 | "@executable_path/../Frameworks",
647 | );
648 | MACOSX_DEPLOYMENT_TARGET = 11.0;
649 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.Scre;
650 | PRODUCT_NAME = "$(TARGET_NAME)";
651 | SWIFT_VERSION = 5.0;
652 | };
653 | name = Debug;
654 | };
655 | 9F3B5F9125E28DB90084A6B9 /* Release */ = {
656 | isa = XCBuildConfiguration;
657 | baseConfigurationReference = EA0E19E1E1906A0A9A5764EF /* Pods-Scre.release.xcconfig */;
658 | buildSettings = {
659 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
660 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
661 | CODE_SIGN_ENTITLEMENTS = Scre/Scre.entitlements;
662 | CODE_SIGN_STYLE = Automatic;
663 | COMBINE_HIDPI_IMAGES = YES;
664 | DEVELOPMENT_ASSET_PATHS = "\"Scre/Preview Content\"";
665 | ENABLE_PREVIEWS = YES;
666 | INFOPLIST_FILE = Scre/Info.plist;
667 | LD_RUNPATH_SEARCH_PATHS = (
668 | "$(inherited)",
669 | "@executable_path/../Frameworks",
670 | );
671 | MACOSX_DEPLOYMENT_TARGET = 11.0;
672 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.Scre;
673 | PRODUCT_NAME = "$(TARGET_NAME)";
674 | SWIFT_VERSION = 5.0;
675 | };
676 | name = Release;
677 | };
678 | 9F3B5F9325E28DB90084A6B9 /* Debug */ = {
679 | isa = XCBuildConfiguration;
680 | baseConfigurationReference = C1083585DB6297624A614B7F /* Pods-ScreTests.debug.xcconfig */;
681 | buildSettings = {
682 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
683 | BUNDLE_LOADER = "$(TEST_HOST)";
684 | CODE_SIGN_STYLE = Automatic;
685 | COMBINE_HIDPI_IMAGES = YES;
686 | INFOPLIST_FILE = ScreTests/Info.plist;
687 | LD_RUNPATH_SEARCH_PATHS = (
688 | "$(inherited)",
689 | "@executable_path/../Frameworks",
690 | "@loader_path/../Frameworks",
691 | );
692 | MACOSX_DEPLOYMENT_TARGET = 11.0;
693 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreTests;
694 | PRODUCT_NAME = "$(TARGET_NAME)";
695 | SWIFT_VERSION = 5.0;
696 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Scre.app/Contents/MacOS/Scre";
697 | };
698 | name = Debug;
699 | };
700 | 9F3B5F9425E28DB90084A6B9 /* Release */ = {
701 | isa = XCBuildConfiguration;
702 | baseConfigurationReference = 877258A9C45840F1682F8875 /* Pods-ScreTests.release.xcconfig */;
703 | buildSettings = {
704 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
705 | BUNDLE_LOADER = "$(TEST_HOST)";
706 | CODE_SIGN_STYLE = Automatic;
707 | COMBINE_HIDPI_IMAGES = YES;
708 | INFOPLIST_FILE = ScreTests/Info.plist;
709 | LD_RUNPATH_SEARCH_PATHS = (
710 | "$(inherited)",
711 | "@executable_path/../Frameworks",
712 | "@loader_path/../Frameworks",
713 | );
714 | MACOSX_DEPLOYMENT_TARGET = 11.0;
715 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreTests;
716 | PRODUCT_NAME = "$(TARGET_NAME)";
717 | SWIFT_VERSION = 5.0;
718 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Scre.app/Contents/MacOS/Scre";
719 | };
720 | name = Release;
721 | };
722 | 9F3B5F9625E28DB90084A6B9 /* Debug */ = {
723 | isa = XCBuildConfiguration;
724 | baseConfigurationReference = 1195994B4F14D667AD726394 /* Pods-Scre-ScreUITests.debug.xcconfig */;
725 | buildSettings = {
726 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
727 | CODE_SIGN_STYLE = Automatic;
728 | COMBINE_HIDPI_IMAGES = YES;
729 | INFOPLIST_FILE = ScreUITests/Info.plist;
730 | LD_RUNPATH_SEARCH_PATHS = (
731 | "$(inherited)",
732 | "@executable_path/../Frameworks",
733 | "@loader_path/../Frameworks",
734 | );
735 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreUITests;
736 | PRODUCT_NAME = "$(TARGET_NAME)";
737 | SWIFT_VERSION = 5.0;
738 | TEST_TARGET_NAME = Scre;
739 | };
740 | name = Debug;
741 | };
742 | 9F3B5F9725E28DB90084A6B9 /* Release */ = {
743 | isa = XCBuildConfiguration;
744 | baseConfigurationReference = 4667D51D990932C8CEF4AD43 /* Pods-Scre-ScreUITests.release.xcconfig */;
745 | buildSettings = {
746 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
747 | CODE_SIGN_STYLE = Automatic;
748 | COMBINE_HIDPI_IMAGES = YES;
749 | INFOPLIST_FILE = ScreUITests/Info.plist;
750 | LD_RUNPATH_SEARCH_PATHS = (
751 | "$(inherited)",
752 | "@executable_path/../Frameworks",
753 | "@loader_path/../Frameworks",
754 | );
755 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreUITests;
756 | PRODUCT_NAME = "$(TARGET_NAME)";
757 | SWIFT_VERSION = 5.0;
758 | TEST_TARGET_NAME = Scre;
759 | };
760 | name = Release;
761 | };
762 | /* End XCBuildConfiguration section */
763 |
764 | /* Begin XCConfigurationList section */
765 | 9F3B5F6425E28DB80084A6B9 /* Build configuration list for PBXProject "Scre" */ = {
766 | isa = XCConfigurationList;
767 | buildConfigurations = (
768 | 9F3B5F8D25E28DB90084A6B9 /* Debug */,
769 | 9F3B5F8E25E28DB90084A6B9 /* Release */,
770 | );
771 | defaultConfigurationIsVisible = 0;
772 | defaultConfigurationName = Release;
773 | };
774 | 9F3B5F8F25E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "Scre" */ = {
775 | isa = XCConfigurationList;
776 | buildConfigurations = (
777 | 9F3B5F9025E28DB90084A6B9 /* Debug */,
778 | 9F3B5F9125E28DB90084A6B9 /* Release */,
779 | );
780 | defaultConfigurationIsVisible = 0;
781 | defaultConfigurationName = Release;
782 | };
783 | 9F3B5F9225E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreTests" */ = {
784 | isa = XCConfigurationList;
785 | buildConfigurations = (
786 | 9F3B5F9325E28DB90084A6B9 /* Debug */,
787 | 9F3B5F9425E28DB90084A6B9 /* Release */,
788 | );
789 | defaultConfigurationIsVisible = 0;
790 | defaultConfigurationName = Release;
791 | };
792 | 9F3B5F9525E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreUITests" */ = {
793 | isa = XCConfigurationList;
794 | buildConfigurations = (
795 | 9F3B5F9625E28DB90084A6B9 /* Debug */,
796 | 9F3B5F9725E28DB90084A6B9 /* Release */,
797 | );
798 | defaultConfigurationIsVisible = 0;
799 | defaultConfigurationName = Release;
800 | };
801 | /* End XCConfigurationList section */
802 | };
803 | rootObject = 9F3B5F6125E28DB80084A6B9 /* Project object */;
804 | }
805 |
--------------------------------------------------------------------------------