[
  {
    "path": ".gitignore",
    "content": "# Mac\n.DS_Store\n\n# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## User settings\nxcuserdata/\n\n## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)\n*.xcscmblueprint\n*.xccheckout\n\n## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)\nbuild/\nDerivedData/\n*.moved-aside\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\n\n## Obj-C/Swift specific\n*.hmap\n\n## App packaging\n*.ipa\n*.dSYM.zip\n*.dSYM\n\n## Playgrounds\ntimeline.xctimeline\nplayground.xcworkspace\n\n# Swift Package Manager\n#\n# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.\n# Packages/\n# Package.pins\n# Package.resolved\n# *.xcodeproj\n#\n# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata\n# hence it is not needed unless you have added a package configuration file to your project\n# .swiftpm\n\n.build/\n\n# CocoaPods\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\n# Pods/\n#\n# Add this line if you want to avoid checking in source code from the Xcode workspace\n# *.xcworkspace\n\n# Carthage\n#\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\nCarthage/Build/\n\n# Accio dependency management\nDependencies/\n.accio/\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo.\n# Instead, use fastlane to re-generate the screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/#source-control\n\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots/**/*.png\nfastlane/test_output\n\n# Code Injection\n#\n# After new code Injection tools there's a generated folder /iOSInjectionProject\n# https://github.com/johnno1962/injectionforxcode\n\niOSInjectionProject/\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Action.swift",
    "content": "//\n//  Action.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/16.\n//  Copyright © 2022 yuki. All rights reserved.\n//\n\npublic struct Action {\n    public let title: String\n    public let action: () -> ()\n    \n    public init(title: String, action: @escaping () -> ()) {\n        self.title = title\n        self.action = action\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Delta.swift",
    "content": "//\n//  Delta.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/05/14.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\npublic enum Delta<Value> {\n    case to(Value)\n    case by(Value)\n}\n\nextension Delta {\n    @inlinable public func map<T>(_ tranceform: (Value) throws -> T) rethrows -> Delta<T> {\n        switch self {\n        case .to(let value): return .to(try tranceform(value))\n        case .by(let value): return .by(try tranceform(value))\n        }\n    }\n    \n    @inlinable public func reduce(_ initialValue: Value, _ tranceform: (Value, Value) throws -> Value) rethrows -> Value {\n        switch self {\n        case .to(let value): return value\n        case .by(let value): return try tranceform(initialValue, value)\n        }\n    }\n    \n    @inlinable public func takeValue() -> Value {\n        switch self {\n        case .to(let value): return value\n        case .by(let value): return value\n        }\n    }\n    \n    @inlinable public func apply(_ initialValue: inout Value, _ tranceform: (Value, Value) throws -> Value) rethrows {\n        initialValue = try reduce(initialValue, tranceform)\n    }\n}\n\nextension Delta where Value: AdditiveArithmetic {\n    @inlinable public func reduce(_ initialValue: Value) -> Value {\n        reduce(initialValue, +)\n    }\n    @inlinable public func apply(_ initialValue: inout Value) {\n        apply(&initialValue, +)\n    }\n    \n    @inlinable public static func += (_ initialValue: inout Value, delta: Delta<Value>) {\n        delta.apply(&initialValue)\n    }\n}\n\nextension Delta where Value: RangeReplaceableCollection {\n    @inlinable public func reduce(_ initialValue: Value) -> Value {\n        reduce(initialValue, +)\n    }\n    @inlinable public func apply(_ initialValue: inout Value) {\n        apply(&initialValue, +)\n    }\n    \n    @inlinable public static func += (_ initialValue: inout Value, delta: Delta<Value>) {\n        delta.apply(&initialValue)\n    }\n}\n\nextension Delta: Encodable where Value: Encodable {\n    public func encode(to encoder: Encoder) throws {\n        var container = encoder.singleValueContainer()\n        switch self {\n        case .by(let value): try container.encode([\"by\": value])\n        case .to(let value): try container.encode([\"to\": value])\n        }\n    }\n}\n\nextension Delta: Decodable where Value: Decodable {\n    public init(from decoder: Decoder) throws {\n        let container = try decoder.singleValueContainer()\n        let content = try container.decode([String: Value].self)\n        \n        guard let (key, value) = content.first else {\n            throw DecodingError.dataCorruptedError(in: container, debugDescription: \"Empty container\")\n        }\n        \n        switch key {\n        case \"by\": self = .by(value)\n        case \"to\": self = .to(value)\n        default: throw DecodingError.dataCorruptedError(in: container, debugDescription: \"Unkown key '\\(key)'\")\n        }\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NS+OnAwake.swift",
    "content": "//\n//  NSLoadView.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/08/31.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nopen class NSLoadView: NSView {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadTextView: NSTextView {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadTableRowView: NSTableRowView {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\n\nopen class NSLoadVisualEffectView: NSVisualEffectView {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\n\nopen class NSLoadImageView: NSImageView {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadStackView: NSStackView {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadTextField: NSTextField {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadTokenField: NSTokenField {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadSearchField: NSSearchField {\n\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadScrollView: NSScrollView {\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadTableView: NSTableView {\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadSplitView: NSSplitView {\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadControl: NSControl {\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadButton: NSButton {\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class NSLoadCollectionView: NSCollectionView {\n    open func onAwake() {}\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n}\n\nopen class CALoadLayer: CALayer {\n\n    open func onAwake() {}\n    \n    public override init() {\n        super.init()\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n    public override init(layer: Any) {\n        super.init(layer: layer)\n        onAwake()\n    }\n}\n\nopen class CALoadShapeLayer: CAShapeLayer {\n\n    open func onAwake() {}\n\n    public override init() {\n        super.init()\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n    public override init(layer: Any) {\n        super.init(layer: layer)\n        onAwake()\n    }\n}\n\nopen class CALoadTextLayer: CATextLayer {\n\n    open func onAwake() {}\n\n    public override init() {\n        super.init()\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n    public override init(layer: Any) {\n        super.init(layer: layer)\n        onAwake()\n    }\n}\n\nopen class CALoadGradientLayer: CAGradientLayer {\n\n    open func onAwake() {}\n\n    public override init() {\n        super.init()\n        onAwake()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        onAwake()\n    }\n    public override init(layer: Any) {\n        super.init(layer: layer)\n        onAwake()\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NSColorView.swift",
    "content": "//\n//  NSColorView.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/10/05.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nopen class NSColorView: NSLoadView {\n    open var borderWidth: CGFloat = 1 { didSet { setNeedsDisplay(bounds) } }\n    open var borderColor: NSColor? { didSet { setNeedsDisplay(bounds) } }\n    open var backgroundColor: NSColor? { didSet { setNeedsDisplay(bounds) } }\n    \n    open override func draw(_ dirtyRect: NSRect) {\n        if let backgroundColor = self.backgroundColor {\n            backgroundColor.setFill()\n            dirtyRect.fill()\n        }\n        if let borderColor = self.borderColor {\n            borderColor.setStroke()\n            let path = NSBezierPath(rect: dirtyRect)\n            path.lineWidth = borderWidth\n            path.stroke()\n        }\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NSViewController+ChainObject.swift",
    "content": "//\n//  NSViewController.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/07/19.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nprivate var chainObjectKey = 0\nprivate var chainObjectFlagKey = 0\n\nextension NSViewController {\n    public var isChainObjectLoaded: Bool {\n        get { objc_getAssociatedObject(self, &chainObjectFlagKey) as? Bool ?? false }\n        set { objc_setAssociatedObject(self, &chainObjectFlagKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }\n    }\n    \n    public var chainObject: Any? {\n        get { objc_getAssociatedObject(self, &chainObjectKey) }\n        set {\n            guard let chainObject = newValue else { return }\n            if self.isChainObjectLoaded { return }; self.isChainObjectLoaded = true\n            objc_setAssociatedObject(self, &chainObjectKey, chainObject, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)\n            Self.activateObjectChain\n            for child in children { child.chainObject = chainObject }\n            self.chainObjectDidLoad()\n        }\n    }\n    \n    @objc open func chainObjectDidLoad() {}\n    \n    static let activateObjectChain: () = method_exchangeImplementations(\n        class_getInstanceMethod(NSViewController.self, #selector(addChild))!,\n        class_getInstanceMethod(NSViewController.self, #selector(chain_addChild))!\n    )\n    \n    @objc private dynamic func chain_addChild(_ childViewController: NSViewController) {\n        childViewController.chainObject = chainObject\n        self.chain_addChild(childViewController)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/NSViewController+StateObject.swift",
    "content": "//\n//  NSViewController+StateObject.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/24.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport Combine\n\npublic struct StateChannel<Value> {\n    let rawValue: String\n    \n    public init(_ rawValue: String) {\n        self.rawValue = rawValue\n    }\n}\n\nextension NSViewController {\n    public func getState<Value>(for channel: StateChannel<Value?>) -> Value? {\n        getState(for: channel).flatMap{ $0 }\n    }\n    public func getState<Value>(for channel: StateChannel<Value>) -> Value? {\n        publisher(for: channel.rawValue).value as? Value\n    }\n\n    public func setState<Value>(_ value: Value?, for channel: StateChannel<Value>) {\n        Self.activateStateObject()\n        _setState(value, for: channel.rawValue)\n    }\n    \n    public func getStatePublisher<Value>(for channel: StateChannel<Value>) -> AnyPublisher<Value?, Never> {\n        publisher(for: channel.rawValue).map{ $0 as? Value }.eraseToAnyPublisher()\n    }\n    public func getStatePublisher<Value>(for channel: StateChannel<Value>) -> AnyPublisher<Value?, Never> where Value: AnyObject {\n        publisher(for: channel.rawValue).map{ $0 as? Value }.removeDuplicates(by: ===).eraseToAnyPublisher()\n    }\n    public func getStatePublisher<Value>(for channel: StateChannel<Value?>) -> AnyPublisher<Value?, Never> where Value: AnyObject {\n        publisher(for: channel.rawValue).map{ $0 as? Value }.removeDuplicates(by: ===).eraseToAnyPublisher()\n    }\n    \n    public func linkState<Value>(for channel: StateChannel<Value>, to viewController: NSViewController) {\n        getStatePublisher(for: channel).sink{ viewController.setState($0, for: channel) }.store(in: &self.objectBag)\n    }\n}\n\nextension NSViewController {\n    private static func activateStateObject() {\n        enum __ {\n            static let __: () = method_exchangeImplementations(\n                class_getInstanceMethod(NSViewController.self, #selector(addChild))!,\n                class_getInstanceMethod(NSViewController.self, #selector(_addChild))!\n            )\n        }\n        __.__\n    }\n    \n    private func _setState(_ value: Any?, for channel: String) {\n        publisher(for: channel).send(value)\n        \n        for child in children {\n            child._setState(value, for: channel)\n        }\n    }\n    \n    private static var envContainerKey = 0\n    \n    private var envContainer: [String: CurrentValueSubject<Any?, Never>] {\n        get { objc_getAssociatedObject(self, &Self.envContainerKey) as? [String: CurrentValueSubject<Any?, Never>] ?? [:] }\n        set { objc_setAssociatedObject(self, &Self.envContainerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }\n    }\n    \n    private func publisher(for channel: String) -> CurrentValueSubject<Any?, Never> {\n        return envContainer[channel] ?? CurrentValueSubject(nil) => { envContainer[channel] = $0 }\n    }\n    \n    @objc private dynamic func _addChild(_ childViewController: NSViewController) {\n        for channel in envContainer.keys {\n            guard let value = publisher(for: channel).value else { continue }\n            \n            childViewController._setState(value, for: channel)\n        }\n                \n        self._addChild(childViewController)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Observable.swift",
    "content": "//\n//  Property.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/07/06.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Combine\n\n/// Publishedの10倍軽いPropertyWrapper\n@propertyWrapper\npublic struct Observable<Value> {\n\n    public struct Publisher: Combine.Publisher {\n        public typealias Output = Value\n        public typealias Failure = Never\n        \n        @usableFromInline let subject: CurrentValueSubject<Value, Never>\n        \n        @inlinable init(_ value: Value) { self.subject = CurrentValueSubject(value) }\n        \n        @inlinable public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {\n            self.subject.receive(subscriber: subscriber)\n        }\n    }\n    \n    public let projectedValue: Publisher\n    \n    @inlinable public var wrappedValue: Value {\n        @inlinable get { projectedValue.subject.value }\n        @inlinable set { projectedValue.subject.send(newValue) }\n    }\n    @inlinable public init(wrappedValue value: Value) {\n        self.projectedValue = Publisher(value)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/PipeOperator.swift",
    "content": "//\n//  +Functions.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/10/01.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nprecedencegroup PipePrecedence {\n    higherThan: NilCoalescingPrecedence\n    associativity: left\n}\n\ninfix operator =>: PipePrecedence\ninfix operator |>: PipePrecedence\ninfix operator <=>: PipePrecedence\n\n@discardableResult\n@inlinable public func => <T>(lhs: T, rhs: (T) throws -> Void) rethrows -> T {\n    try rhs(lhs)\n    return lhs\n}\n\n@discardableResult\n@inlinable public func |> <T, U>(lhs: T, rhs: (T) throws -> U) rethrows -> U {\n    try rhs(lhs)\n}\n\n@discardableResult\n@inlinable public func <=> <T>(lhs: T, rhs: (inout T) throws -> Void) rethrows -> T {\n    var lhs = lhs\n    try rhs(&lhs)\n    return lhs\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Query.swift",
    "content": "//\n//  Query.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/01/13.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\n/// 検索時のクエリを表す。検索時の処理を一般化することが目的\n///\n/// # 大まかな仕様\n/// - 空クエリは全てにマッチ\n/// - 大文字小文字を考慮せずに検索を行う\n/// - 空白文字で区切った文字の全てにマッチするときにマッチする\n///\n/// # サンプル\n/// ```\n/// let query = Query(\"Hello World\")\n///\n/// query.matches(to: \"\") // true\n/// query.matches(to: \"Hello whole new world.\") // true\n/// query.matches(to: \"Hello swift.\") // false\n/// ```\npublic struct Query {\n    \n    /// 検索を行う要素\n    let components: [String]\n    \n    /// 文字列で初期化\n    public init(_ query: String) {\n        self.components = query.components(separatedBy: .whitespaces)\n            .map{ $0.lowercased() }\n            .filter{ !$0.isEmpty }\n    }\n    /// 空クエリで初期化\n    public init() {\n        self.components = []\n    }\n    \n    public var isEmpty: Bool { self.components.isEmpty }\n    \n    /// マッチ判定を行う。詳細は`Query`のDiscussionを参照。\n    public func matches(to contents: String...) -> Bool {\n        if self.components.isEmpty { return true }\n        \n        let contents = contents.map{ $0.lowercased() }\n        \n        return components.allSatisfy{ component in\n            contents.contains{ $0.contains(component) }\n        }\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Reachability+Publisher.swift",
    "content": "//\n//  Reachability+Ex.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/09/14.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Foundation\nimport Combine\n\nextension Reachability {\n    public struct Publisher: Combine.Publisher {\n        public typealias Output = Reachability\n        public typealias Failure = Never\n        \n        let subject: CurrentValueSubject<Reachability, Never>\n        \n        init(_ reachability: Reachability) {\n            self.subject = CurrentValueSubject(reachability)\n            reachability.whenReachable = {[subject] in subject.send($0) }\n            reachability.whenUnreachable = {[subject] in subject.send($0) }\n            try? reachability.startNotifier()\n        }\n        \n        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {\n            self.subject.receive(subscriber: subscriber)\n        }\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Reachability.swift",
    "content": "/*\nCopyright (c) 2014, Ashley Mills\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n*/\n\nimport SystemConfiguration\nimport Foundation\n\npublic enum ReachabilityError: Error {\n    case failedToCreateWithAddress(sockaddr, Int32)\n    case failedToCreateWithHostname(String, Int32)\n    case unableToSetCallback(Int32)\n    case unableToSetDispatchQueue(Int32)\n    case unableToGetFlags(Int32)\n}\n\n@available(*, unavailable, renamed: \"Notification.Name.reachabilityChanged\")\npublic let ReachabilityChangedNotification = NSNotification.Name(\"ReachabilityChangedNotification\")\n\npublic extension Notification.Name {\n    static let reachabilityChanged = Notification.Name(\"reachabilityChanged\")\n}\n\npublic class Reachability {\n\n    public typealias NetworkReachable = (Reachability) -> ()\n    public typealias NetworkUnreachable = (Reachability) -> ()\n    \n    public private(set) lazy var publisher = Publisher(self)\n\n    public enum Connection: CustomStringConvertible {\n        case unavailable, wifi, cellular\n        public var description: String {\n            switch self {\n            case .cellular: return \"Cellular\"\n            case .wifi: return \"WiFi\"\n            case .unavailable: return \"No Connection\"\n            }\n        }\n    }\n\n    public var whenReachable: NetworkReachable?\n    public var whenUnreachable: NetworkUnreachable?\n\n    /// Set to `false` to force Reachability.connection to .none when on cellular connection (default value `true`)\n    public var allowsCellularConnection: Bool\n\n    // The notification center on which \"reachability changed\" events are being posted\n    public var notificationCenter: NotificationCenter = NotificationCenter.default\n\n    public var connection: Connection {\n        if flags == nil {\n            try? setReachabilityFlags()\n        }\n        \n        switch flags?.connection {\n        case .unavailable?, nil: return .unavailable\n        case .cellular?: return allowsCellularConnection ? .cellular : .unavailable\n        case .wifi?: return .wifi\n        }\n    }\n\n    fileprivate var isRunningOnDevice: Bool = {\n        #if targetEnvironment(simulator)\n            return false\n        #else\n            return true\n        #endif\n    }()\n\n    fileprivate(set) var notifierRunning = false\n    fileprivate let reachabilityRef: SCNetworkReachability\n    fileprivate let reachabilitySerialQueue: DispatchQueue\n    fileprivate let notificationQueue: DispatchQueue?\n    fileprivate(set) var flags: SCNetworkReachabilityFlags? {\n        didSet {\n            guard flags != oldValue else { return }\n            notifyReachabilityChanged()\n        }\n    }\n\n    required public init(reachabilityRef: SCNetworkReachability,\n                         queueQoS: DispatchQoS = .default,\n                         targetQueue: DispatchQueue? = nil,\n                         notificationQueue: DispatchQueue? = .main) {\n        self.allowsCellularConnection = true\n        self.reachabilityRef = reachabilityRef\n        self.reachabilitySerialQueue = DispatchQueue(label: \"uk.co.ashleymills.reachability\", qos: queueQoS, target: targetQueue)\n        self.notificationQueue = notificationQueue\n    }\n\n    public convenience init(hostname: String,\n                            queueQoS: DispatchQoS = .default,\n                            targetQueue: DispatchQueue? = nil,\n                            notificationQueue: DispatchQueue? = .main) throws {\n        guard let ref = SCNetworkReachabilityCreateWithName(nil, hostname) else {\n            throw ReachabilityError.failedToCreateWithHostname(hostname, SCError())\n        }\n        self.init(reachabilityRef: ref, queueQoS: queueQoS, targetQueue: targetQueue, notificationQueue: notificationQueue)\n    }\n\n    public convenience init(queueQoS: DispatchQoS = .default,\n                            targetQueue: DispatchQueue? = nil,\n                            notificationQueue: DispatchQueue? = .main) throws {\n        var zeroAddress = sockaddr()\n        zeroAddress.sa_len = UInt8(MemoryLayout<sockaddr>.size)\n        zeroAddress.sa_family = sa_family_t(AF_INET)\n\n        guard let ref = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress) else {\n            throw ReachabilityError.failedToCreateWithAddress(zeroAddress, SCError())\n        }\n\n        self.init(reachabilityRef: ref, queueQoS: queueQoS, targetQueue: targetQueue, notificationQueue: notificationQueue)\n    }\n\n    deinit {\n        stopNotifier()\n    }\n}\n\npublic extension Reachability {\n\n    // MARK: - *** Notifier methods ***\n    func startNotifier() throws {\n        guard !notifierRunning else { return }\n\n        let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in\n            guard let info = info else { return }\n\n            // `weakifiedReachability` is guaranteed to exist by virtue of our\n            // retain/release callbacks which we provided to the `SCNetworkReachabilityContext`.\n            let weakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info).takeUnretainedValue()\n\n            // The weak `reachability` _may_ no longer exist if the `Reachability`\n            // object has since been deallocated but a callback was already in flight.\n            weakifiedReachability.reachability?.flags = flags\n        }\n\n        let weakifiedReachability = ReachabilityWeakifier(reachability: self)\n        let opaqueWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.passUnretained(weakifiedReachability).toOpaque()\n\n        var context = SCNetworkReachabilityContext(\n            version: 0,\n            info: UnsafeMutableRawPointer(opaqueWeakifiedReachability),\n            retain: { (info: UnsafeRawPointer) -> UnsafeRawPointer in\n                let unmanagedWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info)\n                _ = unmanagedWeakifiedReachability.retain()\n                return UnsafeRawPointer(unmanagedWeakifiedReachability.toOpaque())\n            },\n            release: { (info: UnsafeRawPointer) -> Void in\n                let unmanagedWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info)\n                unmanagedWeakifiedReachability.release()\n            },\n            copyDescription: { (info: UnsafeRawPointer) -> Unmanaged<CFString> in\n                let unmanagedWeakifiedReachability = Unmanaged<ReachabilityWeakifier>.fromOpaque(info)\n                let weakifiedReachability = unmanagedWeakifiedReachability.takeUnretainedValue()\n                let description = weakifiedReachability.reachability?.description ?? \"nil\"\n                return Unmanaged.passRetained(description as CFString)\n            }\n        )\n\n        if !SCNetworkReachabilitySetCallback(reachabilityRef, callback, &context) {\n            stopNotifier()\n            throw ReachabilityError.unableToSetCallback(SCError())\n        }\n\n        if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef, reachabilitySerialQueue) {\n            stopNotifier()\n            throw ReachabilityError.unableToSetDispatchQueue(SCError())\n        }\n\n        // Perform an initial check\n        try setReachabilityFlags()\n\n        notifierRunning = true\n    }\n\n    func stopNotifier() {\n        defer { notifierRunning = false }\n\n        SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil)\n        SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)\n    }\n\n    var description: String {\n        return flags?.description ?? \"unavailable flags\"\n    }\n}\n\nfileprivate extension Reachability {\n\n    func setReachabilityFlags() throws {\n        try reachabilitySerialQueue.sync { [unowned self] in\n            var flags = SCNetworkReachabilityFlags()\n            if !SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags) {\n                self.stopNotifier()\n                throw ReachabilityError.unableToGetFlags(SCError())\n            }\n            \n            self.flags = flags\n        }\n    }\n    \n\n    func notifyReachabilityChanged() {\n        let notify = { [weak self] in\n            guard let self = self else { return }\n            self.connection != .unavailable ? self.whenReachable?(self) : self.whenUnreachable?(self)\n            self.notificationCenter.post(name: .reachabilityChanged, object: self)\n        }\n\n        // notify on the configured `notificationQueue`, or the caller's (i.e. `reachabilitySerialQueue`)\n        notificationQueue?.async(execute: notify) ?? notify()\n    }\n}\n\nextension SCNetworkReachabilityFlags {\n\n    typealias Connection = Reachability.Connection\n\n    var connection: Connection {\n        guard isReachableFlagSet else { return .unavailable }\n\n        // If we're reachable, but not on an iOS device (i.e. simulator), we must be on WiFi\n        #if targetEnvironment(simulator)\n        return .wifi\n        #else\n        var connection = Connection.unavailable\n\n        if !isConnectionRequiredFlagSet {\n            connection = .wifi\n        }\n\n        if isConnectionOnTrafficOrDemandFlagSet {\n            if !isInterventionRequiredFlagSet {\n                connection = .wifi\n            }\n        }\n\n        if isOnWWANFlagSet {\n            connection = .cellular\n        }\n\n        return connection\n        #endif\n    }\n\n    var isOnWWANFlagSet: Bool {\n        #if os(iOS)\n        return contains(.isWWAN)\n        #else\n        return false\n        #endif\n    }\n    var isReachableFlagSet: Bool {\n        return contains(.reachable)\n    }\n    var isConnectionRequiredFlagSet: Bool {\n        return contains(.connectionRequired)\n    }\n    var isInterventionRequiredFlagSet: Bool {\n        return contains(.interventionRequired)\n    }\n    var isConnectionOnTrafficFlagSet: Bool {\n        return contains(.connectionOnTraffic)\n    }\n    var isConnectionOnDemandFlagSet: Bool {\n        return contains(.connectionOnDemand)\n    }\n    var isConnectionOnTrafficOrDemandFlagSet: Bool {\n        return !intersection([.connectionOnTraffic, .connectionOnDemand]).isEmpty\n    }\n    var isTransientConnectionFlagSet: Bool {\n        return contains(.transientConnection)\n    }\n    var isLocalAddressFlagSet: Bool {\n        return contains(.isLocalAddress)\n    }\n    var isDirectFlagSet: Bool {\n        return contains(.isDirect)\n    }\n    var isConnectionRequiredAndTransientFlagSet: Bool {\n        return intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]\n    }\n\n    var description: String {\n        let W = isOnWWANFlagSet ? \"W\" : \"-\"\n        let R = isReachableFlagSet ? \"R\" : \"-\"\n        let c = isConnectionRequiredFlagSet ? \"c\" : \"-\"\n        let t = isTransientConnectionFlagSet ? \"t\" : \"-\"\n        let i = isInterventionRequiredFlagSet ? \"i\" : \"-\"\n        let C = isConnectionOnTrafficFlagSet ? \"C\" : \"-\"\n        let D = isConnectionOnDemandFlagSet ? \"D\" : \"-\"\n        let l = isLocalAddressFlagSet ? \"l\" : \"-\"\n        let d = isDirectFlagSet ? \"d\" : \"-\"\n\n        return \"\\(W)\\(R) \\(c)\\(t)\\(i)\\(C)\\(D)\\(l)\\(d)\"\n    }\n}\n\n/**\n `ReachabilityWeakifier` weakly wraps the `Reachability` class\n in order to break retain cycles when interacting with CoreFoundation.\n\n CoreFoundation callbacks expect a pair of retain/release whenever an\n opaque `info` parameter is provided. These callbacks exist to guard\n against memory management race conditions when invoking the callbacks.\n\n #### Race Condition\n\n If we passed `SCNetworkReachabilitySetCallback` a direct reference to our\n `Reachability` class without also providing corresponding retain/release\n callbacks, then a race condition can lead to crashes when:\n - `Reachability` is deallocated on thread X\n - A `SCNetworkReachability` callback(s) is already in flight on thread Y\n\n #### Retain Cycle\n\n If we pass `Reachability` to CoreFoundtion while also providing retain/\n release callbacks, we would create a retain cycle once CoreFoundation\n retains our `Reachability` class. This fixes the crashes and his how\n CoreFoundation expects the API to be used, but doesn't play nicely with\n Swift/ARC. This cycle would only be broken after manually calling\n `stopNotifier()` — `deinit` would never be called.\n\n #### ReachabilityWeakifier\n\n By providing both retain/release callbacks and wrapping `Reachability` in\n a weak wrapper, we:\n - interact correctly with CoreFoundation, thereby avoiding a crash.\n See \"Memory Management Programming Guide for Core Foundation\".\n - don't alter the public API of `Reachability.swift` in any way\n - still allow for automatic stopping of the notifier on `deinit`.\n */\nprivate class ReachabilityWeakifier {\n    weak var reachability: Reachability?\n    init(reachability: Reachability) {\n        self.reachability = reachability\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/RestorableData.swift",
    "content": "//\n//  RestorableData.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport Cocoa\n\nextension FileManager {\n    public static let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(Bundle.main.bundleIdentifier ?? \"com.noname.app\")\n}\n\nprivate let encoder = JSONEncoder()\nprivate let decoder = JSONDecoder()\nprivate let restorableDataURL = FileManager.temporaryDirectoryURL.appendingPathComponent(\"RestorableData\") => {\n    try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)\n}\n\n@propertyWrapper\npublic struct RestorableData<Value: Codable> {\n    public struct Publisher: Combine.Publisher {\n        public typealias Output = Value\n        public typealias Failure = Never\n        \n        let subject: CurrentValueSubject<Value, Never>\n        \n        init(_ value: Value) { self.subject = CurrentValueSubject(value) }\n        \n        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {\n            self.subject.receive(subscriber: subscriber)\n        }\n    }\n    \n    public let projectedValue: Publisher\n    public let key: String\n    public let fileURL: URL\n    \n    public var wrappedValue: Value {\n        get { projectedValue.subject.value }\n        set {\n            projectedValue.subject.send(newValue)\n            do { try encoder.encode(newValue).write(to: fileURL) } catch {}\n        }\n    }\n    public init(wrappedValue initialValue: Value, _ key: String) {\n        self.key = key\n        self.fileURL = restorableDataURL.appendingPathComponent(key + \".json\")\n        \n        let wrappedValue: Value\n        do {\n            wrappedValue = try decoder.decode(Value.self, from: Data(contentsOf: fileURL))\n        } catch {\n            wrappedValue = initialValue\n        }\n        \n        self.projectedValue = Publisher(wrappedValue)\n    }\n}\n\nfinal public class NSImageContainer: Codable {\n    static let dataDirectoryURL = FileManager.temporaryDirectoryURL.appendingPathComponent(\"NSImageContainer\") => {\n        try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)\n    }\n    \n    public let image: NSImage\n    public let id: String\n    public init(_ image: NSImage) {\n        self.image = image\n        self.id = UUID().uuidString\n    }\n    \n    public static func wrap(_ image: NSImage) -> NSImageContainer { NSImageContainer(image) }\n    \n    public func encode(to encoder: Encoder) throws {\n        var container = encoder.singleValueContainer()\n        try container.encode(id)\n        let fileURL = NSImageContainer.dataDirectoryURL.appendingPathComponent(id)\n        if !FileManager.default.fileExists(atPath: fileURL.path) {\n            try image.tiffRepresentation?.write(to: fileURL)\n        }\n    }\n    public init(from decoder: Decoder) throws {\n        let container = try decoder.singleValueContainer()\n        let id = try container.decode(String.self)\n        let fileURL = NSImageContainer.dataDirectoryURL.appendingPathComponent(id)\n        guard let image = NSImage(contentsOf: fileURL) else {\n            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: \"No image\"))\n        }\n        self.image = image\n        self.id = id\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/RestorableState.swift",
    "content": "//\n//  RestorableState.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport Foundation\n\n@propertyWrapper\npublic struct RestorableState<Value: RawRepresentable> {\n    public struct Publisher: Combine.Publisher {\n        public typealias Output = Value\n        public typealias Failure = Never\n        \n        let subject: CurrentValueSubject<Value, Never>\n        \n        init(_ value: Value) { self.subject = CurrentValueSubject(value) }\n        \n        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Self.Failure, S.Input == Self.Output {\n            self.subject.receive(subscriber: subscriber)\n        }\n    }\n    \n    public let projectedValue: Publisher\n    public let key: String\n    \n    public var wrappedValue: Value {\n        get { projectedValue.subject.value }\n        set {\n            projectedValue.subject.send(newValue)\n            UserDefaults.standard.set(newValue.rawValue, forKey: key)\n        }\n    }\n    public init(wrappedValue initialValue: Value, _ key: String) {\n        let wrappedValue: Value\n        \n        if let rawValue = UserDefaults.standard.object(forKey: key) as? Value.RawValue, let value = Value(rawValue: rawValue) {\n            wrappedValue = value\n        } else {\n            wrappedValue = initialValue\n        }\n        \n        self.projectedValue = Publisher(wrappedValue)\n        self.key = key\n    }\n}\n\nextension String: RawRepresentable {\n    public var rawValue: Self { self }\n    public init(rawValue: Self) { self = rawValue }\n}\n\nextension Bool: RawRepresentable {\n    public var rawValue: Self { self }\n    public init(rawValue: Self) { self = rawValue }\n}\n\nextension Optional: RawRepresentable {\n    public var rawValue: Self { self }\n    public init(rawValue: Self) { self = rawValue }\n}\n\nextension Int: RawRepresentable {\n    public var rawValue: Self { self }\n    public init(rawValue: Self) { self = rawValue }\n}\n\nextension CGFloat: RawRepresentable {\n    public var rawValue: Self { self }\n    public init(rawValue: Self) { self = rawValue }\n}\n\nextension Double: RawRepresentable {\n    public var rawValue: Self { self }\n    public init(rawValue: Self) { self = rawValue }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Terminal.swift",
    "content": "//\n//  Terminal.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/11.\n//\n\nimport Foundation\n\npublic enum TerminalError: Error, CustomStringConvertible {\n    case nonZeroExit(String)\n    \n    public var description: String {\n        switch self {\n        case .nonZeroExit(let string): return string\n        }\n    }\n}\n\npublic enum Terminal {\n    public struct ExecuteOption: OptionSet {\n        public let rawValue: UInt64\n        \n        public init(rawValue: UInt64) { self.rawValue = rawValue }\n        \n        public static let standardOutput = ExecuteOption(rawValue: 1 << 0)\n        public static let standardError = ExecuteOption(rawValue: 1 << 1)\n    }\n    \n    public static func run(_ executableURL: URL, arguments: [String], queue: DispatchQueue = .global(), options: ExecuteOption = .all) -> Promise<String, Error> {\n        let task = Process()\n        let outputPipe = Pipe()\n        let errorPipe = Pipe()\n        \n        task.executableURL = executableURL\n        task.arguments = arguments\n        \n        if options.contains(.standardOutput) {\n            task.standardOutput = outputPipe\n        }\n        if options.contains(.standardError) {\n            task.standardError = errorPipe\n        }\n        \n        return Promise<String, Error>.tryAsync(on: queue) { resolve, reject in\n            try task.run()\n            task.waitUntilExit()\n            \n            if task.terminationStatus != 0 {\n                reject(TerminalError.nonZeroExit(errorPipe.readStringToEndOfFile ?? \"[binary]\"))\n            } else {\n                resolve(outputPipe.readStringToEndOfFile ?? \"[binary]\")\n            }\n        }\n    }\n}\n\nextension Pipe {\n    public var readStringToEndOfFile: String? {\n        String(data: self.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/ViewPlaceholder.swift",
    "content": "//\n//  ViewPlaceholder.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/03.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport Combine\n\nopen class NSPlaceholderView<View: NSView>: NSLoadView {\n    public var contentView: View? {\n        didSet {\n            oldValue?.removeFromSuperview()\n            if let contentView = contentView {\n                self.addSubview(contentView)\n                contentView.translatesAutoresizingMaskIntoConstraints = false\n                NSLayoutConstraint.activate([\n                    contentView.rightAnchor.constraint(equalTo: self.rightAnchor),\n                    contentView.leftAnchor.constraint(equalTo: self.leftAnchor),\n                    contentView.topAnchor.constraint(equalTo: self.topAnchor),\n                    contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor),\n                ])\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Class/Zip3Sequence.swift",
    "content": "//\n//  Zip3Sequence.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/22.\n//  Copyright © 2022 yuki. All rights reserved.\n//\n\npublic func zip<A: Sequence, B: Sequence, C: Sequence>(_ a: A, _ b: B, _ c: C) -> Zip3Sequence<A, B, C> {\n    Zip3Sequence(a, b, c)\n}\npublic func zip<A: Sequence, B: Sequence, C: Sequence, D: Sequence>(_ a: A, _ b: B, _ c: C, _ d: D) -> Zip4Sequence<A, B, C, D> {\n    Zip4Sequence(a, b, c, d)\n}\n\npublic struct Zip3Sequence<A: Sequence, B: Sequence, C: Sequence>: Sequence {\n    public typealias Element = (A.Element, B.Element, C.Element)\n    \n    public let a: A\n    public let b: B\n    public let c: C\n    \n    public struct Iterator: IteratorProtocol {\n        var a: A.Iterator\n        var b: B.Iterator\n        var c: C.Iterator\n        \n        mutating public func next() -> Element? {\n            if let a = a.next(), let b = b.next(), let c = c.next() { return (a, b, c) }; return nil\n        }\n    }\n    \n    public func makeIterator() -> Iterator { Iterator(a: a.makeIterator(), b: b.makeIterator(), c: c.makeIterator()) }\n    \n    init(_ a: A, _ b: B, _ c: C) {\n        self.a = a\n        self.b = b\n        self.c = c\n    }\n}\n\npublic struct Zip4Sequence<A: Sequence, B: Sequence, C: Sequence, D: Sequence>: Sequence {\n    public typealias Element = (A.Element, B.Element, C.Element, D.Element)\n    \n    public let a: A\n    public let b: B\n    public let c: C\n    public let d: D\n    \n    public struct Iterator: IteratorProtocol {\n        var a: A.Iterator\n        var b: B.Iterator\n        var c: C.Iterator\n        var d: D.Iterator\n        \n        mutating public func next() -> Element? {\n            if let a = a.next(), let b = b.next(), let c = c.next(), let d = d.next() { return (a, b, c, d) }; return nil\n        }\n    }\n    \n    public func makeIterator() -> Iterator { Iterator(a: a.makeIterator(), b: b.makeIterator(), c: c.makeIterator(), d: d.makeIterator()) }\n    \n    init(_ a: A, _ b: B, _ c: C, _ d: D) {\n        self.a = a\n        self.b = b\n        self.c = c\n        self.d = d\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/CoreUtil.h",
    "content": "//\n//  CoreUtil.h\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\n#import <Foundation/Foundation.h>\n#import \"ExceptionHanlder.h\"\n\n//! Project version number for CoreUtil.\nFOUNDATION_EXPORT double CoreUtilVersionNumber;\n\n//! Project version string for CoreUtil.\nFOUNDATION_EXPORT const unsigned char CoreUtilVersionString[];\n\n// In this header, you should import all the public headers of your framework using statements like #import <CoreUtil/PublicHeader.h>\n"
  },
  {
    "path": "CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHandler.swift",
    "content": "//\n//  ExceptionHandler.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/26.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\n@inlinable public func objc_try(_ tryBlock: () -> ()) throws {\n    var error: NSError?\n    _ExceptionHandler.objc_try(tryBlock, objc_catch: {\n        error = NSError(domain: \"NSException\", code: 999, userInfo: $0.userInfo?.reduce(into: [:]) { $0[\"\\($1.key)\"] = $1.value })\n    }, objc_finally: {})\n    if let error = error { throw error }\n}\n\n@inlinable public func objc_try<T>(_ tryBlock: () -> T) throws -> T {\n    var value: T?\n    var error: NSError?\n    _ExceptionHandler.objc_try({\n        value = tryBlock()\n    }, objc_catch: {\n        error = NSError(domain: \"NSException\", code: 999, userInfo: $0.userInfo?.reduce(into: [:]) { $0[\"\\($1.key)\"] = $1.value })\n    }, objc_finally: {})\n    if let error = error { throw error }\n    return value!\n}\n\n@inlinable public func objc_try(_ tryBlock: () -> (), catch catchBlock: (NSException) -> (), finally finallyBlock: () -> () = {}) {\n    _ExceptionHandler.objc_try(tryBlock, objc_catch: catchBlock, objc_finally: finallyBlock)\n}\n\n@inlinable public func objc_try<T>(_ tryBlock: () -> T, catch catchBlock: (NSException) -> T, finally finallyBlock: () -> () = {}) -> T {\n    var value: T!\n    \n    _ExceptionHandler.objc_try({\n        value = tryBlock()\n    }, objc_catch: {\n        value = catchBlock($0)\n    }, objc_finally: finallyBlock)\n    \n    return value\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHanlder.h",
    "content": "//\n//  ExceptionHanlder.h\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/26.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@interface _ExceptionHandler : NSObject\n+ (void)objc_try: (nonnull __attribute__((noescape)) void(^)(void))objc_try\n      objc_catch: (nonnull __attribute__((noescape)) void(^)(NSException* _Nonnull))objc_catch\n    objc_finally: (nullable __attribute__((noescape)) void(^)(void))objc_finally;\n@end\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/ExceptionHanlder/ExceptionHanlder.m",
    "content": "//\n//  ExceptionHanlder.m\n//  CoreUtil\n//\n//  Created by yuki on 2021/06/26.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import <ExceptionHanlder.h>\n\n@implementation _ExceptionHandler : NSObject \n+ (void)objc_try: (nonnull __attribute__((noescape)) void(^)(void)) objc_try\n      objc_catch: (nonnull __attribute__((noescape)) void(^)(NSException* _Nonnull)) objc_catch\n    objc_finally: (nullable __attribute__((noescape)) void(^)(void)) objc_finally {\n    @try {\n        objc_try();\n    } @catch (NSException* exception) {\n        objc_catch(exception);\n    } @finally {\n        if (objc_finally) { objc_finally(); }\n    }\n}\n@end\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Export.swift",
    "content": "//\n//  Export.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\n@_exported import Promise\n@_exported import SnapKit\n@_exported import Cocoa\n@_exported import Combine\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/Combine+ObjectBag.swift",
    "content": "//\n//  NSObject+Combine.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/05/22.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Foundation\nimport Combine\n\nprivate var bagKey: UInt8 = 0\n\nextension NSObject {\n    public var objectBag: Set<AnyCancellable> {\n        get { bagContainer.value } set { bagContainer.value = newValue }\n    }\n    \n    private class BagContainer {\n        var value = Set<AnyCancellable>()\n    }\n    \n    private var bagContainer: BagContainer {\n        if let container = objc_getAssociatedObject(self, &bagKey) as? BagContainer { return container }\n        let container = BagContainer()\n        objc_setAssociatedObject(self, &bagKey, container, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)\n        return container\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/Combine+Peek.swift",
    "content": "//\n//  Combine+Peek.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport Combine\n\nextension Publisher {\n    public func peekError(_ block: @escaping (Failure) -> Void) -> Publishers.MapError<Self, Failure> {\n        self.mapError { f -> Failure in block(f); return f }\n    }\n    public func peek(_ block: @escaping (Output) -> Void) -> Publishers.Map<Self, Output> {\n        self.map { block($0); return $0 }\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/NSControl+Combine.swift",
    "content": "//\n//  NSButton+Combine.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/07/23.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport Combine\n\nprivate var actionPublisherKey = 0\n\nextension NSControl {\n    \n    final public class Publisher: Combine.Publisher {\n        public typealias Output = Void\n        public typealias Failure = Never\n        \n        final class Target: NSObject {\n            let subject = PassthroughSubject<Void, Never>()\n            @objc func action(_ sender: NSControl) { self.subject.send() }\n        }\n        \n        let target: Target\n        \n        init(control: NSControl) {\n            let target = Target()\n            control.target = target\n            control.action = #selector(Target.action)\n            self.target = target\n        }\n        \n        public func receive<S: Subscriber>(subscriber: S) where S.Failure == Failure, S.Input == Output {\n            self.target.subject.receive(subscriber: subscriber)\n        }\n    }\n    \n    // actionとtargetを設定してpublisherとして出力できるようにします。\n    public var actionPublisher: Publisher {\n        if let publisher = objc_getAssociatedObject(self, &actionPublisherKey) as? Publisher { return publisher }\n        let publisher = Publisher(control: self)\n        objc_setAssociatedObject(self, &actionPublisherKey, publisher, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)\n        return publisher\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Combine/NSTextField+Combine.swift",
    "content": "//\n//  Combine+TextField.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/01/03.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport Combine\n\nprivate var delegateKey = 0\n\nextension NSTextField {\n    \n    public var endEditingStringPublisher: AnyPublisher<String, Never> { pubilsherDelegate.endEditingPublisher.map{ $0.stringValue }.eraseToAnyPublisher() }\n    public var changeStringPublisher: AnyPublisher<String, Never> { pubilsherDelegate.changePublisher.map{ $0.stringValue }.eraseToAnyPublisher() }\n    public var beginEditingStringPublisher: AnyPublisher<String, Never> { pubilsherDelegate.beginEditingPublisher.map{ $0.stringValue }.eraseToAnyPublisher() }\n    \n    public var endEditingPublisher: AnyPublisher<NSTextField, Never> { pubilsherDelegate.endEditingPublisher.eraseToAnyPublisher() }\n    public var changePublisher: AnyPublisher<NSTextField, Never> { pubilsherDelegate.changePublisher.eraseToAnyPublisher() }\n    public var beginEditingPublisher: AnyPublisher<NSTextField, Never> { pubilsherDelegate.beginEditingPublisher.eraseToAnyPublisher() }\n    \n    final private class PublisherDelegate: NSObject, NSTextFieldDelegate {\n        let endEditingPublisher = PassthroughSubject<NSTextField, Never>()\n        let changePublisher = PassthroughSubject<NSTextField, Never>()\n        let beginEditingPublisher = PassthroughSubject<NSTextField, Never>()\n        \n        func controlTextDidBeginEditing(_ obj: Notification) {\n            guard let textField = obj.object as? NSTextField else { return }\n            beginEditingPublisher.send(textField)\n        }\n        func controlTextDidChange(_ obj: Notification) {\n            guard let textField = obj.object as? NSTextField else { return }\n            changePublisher.send(textField)\n        }\n        func controlTextDidEndEditing(_ obj: Notification) {\n            guard let textField = obj.object as? NSTextField else { return }\n            endEditingPublisher.send(textField)\n        }\n    }\n    \n    private var pubilsherDelegate: PublisherDelegate {\n        if let delegate = objc_getAssociatedObject(self, &delegateKey) as? PublisherDelegate { return delegate }\n        let delegate = PublisherDelegate()\n        objc_setAssociatedObject(self, &delegateKey, delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)\n        assert(self.delegate == nil, \"Publisher delegate is not averable. \\(delegate)\")\n        self.delegate = delegate\n        return delegate\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGPoint.swift",
    "content": "//\n//  Ex+CGPoint.swift\n//  Topica\n//\n//  Created by yuki on 2019/10/27.\n//  Copyright © 2019 yuki. All rights reserved.\n//\n\nimport CoreGraphics\n\n@inlinable public func round(_ point: CGPoint) -> CGPoint {\n    CGPoint(x: round(point.x), y: round(point.y))\n}\n\n@inlinable public func ceil(_ point: CGPoint) -> CGPoint {\n    CGPoint(x: ceil(point.x), y: ceil(point.y))\n}\n\n@inlinable public func floor(_ point: CGPoint) -> CGPoint {\n    CGPoint(x: floor(point.x), y: floor(point.y))\n}\n\n@inlinable public func sign(_ point: CGPoint) -> CGPoint {\n    CGPoint(x: sign(point.x), y: sign(point.y))\n}\n\n@inlinable public func min(_ point0: CGPoint, _ point1: CGPoint) -> CGPoint {\n    CGPoint(x: min(point0.x, point1.x), y: min(point0.y, point1.y))\n}\n\n@inlinable public func max(_ point0: CGPoint, _ point1: CGPoint) -> CGPoint {\n    CGPoint(x: max(point0.x, point1.x), y: max(point0.y, point1.y))\n}\n\n@inlinable public func abs(_ point: CGPoint) -> CGFloat {\n    sqrt(point.x * point.x + point.y * point.y)\n}\n\n@inlinable public func abs2(_ point: CGPoint) -> CGFloat {\n    point.x * point.x + point.y * point.y\n}\n\n@inlinable public func clamp(_ point: CGPoint, in rect: CGRect) -> CGPoint {\n    CGPoint(x: clamp(point.x, into: rect.minX...rect.maxX), y: clamp(point.y, into: rect.minY...rect.maxY))\n}\n\n@inlinable public func dot(_ point0: CGPoint, _ point1: CGPoint) -> CGFloat {\n    point0.x * point1.x + point0.y * point1.y\n}\n\nextension CGPoint {\n    public static let infinity = CGSize(width: CGFloat.infinity, height: .infinity)\n    \n    @inlinable public func convertToSize() -> CGSize {\n        CGSize(width: x, height: y)\n    }\n\n    @inlinable public var unitVector: CGPoint {\n        let absValue = abs(self)\n        if absValue == 0 { return .zero }\n        return self / absValue\n    }\n    \n    @inlinable public var isFinite: Bool {\n        x.isFinite && y.isFinite\n    }\n}\n\nextension CGPoint {\n    @inlinable public func map(_ tranceform: (CGFloat) -> (CGFloat)) -> CGPoint {\n        mapX(tranceform).mapY(tranceform)\n    }\n    @inlinable public func mapX(_ tranceform: (CGFloat) -> (CGFloat)) -> CGPoint {\n        CGPoint(x: tranceform(x), y: y)\n    }\n    @inlinable public func mapY(_ tranceform: (CGFloat) -> (CGFloat)) -> CGPoint {\n        CGPoint(x: x, y: tranceform(y))\n    }\n}\n\nextension CGPoint: ExpressibleByArrayLiteral {\n    @inlinable public init(arrayLiteral elements: CGFloat...) {\n        assert(elements.count == 2)\n        self.init(x: elements[0], y: elements[1])\n    }\n}\n\nextension CGPoint: Hashable {\n    @inlinable public func hash(into hasher: inout Hasher) {\n        hasher.combine(x)\n        hasher.combine(y)\n    }\n}\n\nextension CGPoint: AdditiveArithmetic {\n    @inlinable public static func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint {\n        CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)\n    }\n    @inlinable public static func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint {\n        CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)\n    }\n    @inlinable public static prefix func - (lhs: CGPoint) -> CGPoint {\n        CGPoint(x: -lhs.x, y: -lhs.y)\n    }\n    @inlinable public static func += (lhs: inout CGPoint, rhs: CGPoint) {\n        lhs = CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)\n    }\n    @inlinable public static func -= (lhs: inout CGPoint, rhs: CGPoint) {\n        lhs = CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)\n    }\n}\n\nextension CGPoint {\n    @inlinable public static func * (lhs: CGPoint, rhs: CGFloat) -> CGPoint {\n        return CGPoint(x: lhs.x * rhs, y: lhs.y * rhs)\n    }\n    @inlinable public static func * (lhs: CGPoint, rhs: CGPoint) -> CGPoint {\n        return CGPoint(x: lhs.x * rhs.x, y: lhs.y * rhs.y)\n    }\n    @inlinable public static func / (lhs: CGPoint, rhs: CGFloat) -> CGPoint {\n        return CGPoint(x: lhs.x / rhs, y: lhs.y / rhs)\n    }\n    @inlinable public static func / (lhs: CGPoint, rhs: CGPoint) -> CGPoint {\n        return CGPoint(x: lhs.x / rhs.x, y: lhs.y / rhs.y)\n    }\n    @inlinable public static func *= (lhs: inout CGPoint, rhs: CGFloat) {\n        lhs = CGPoint(x: lhs.x * rhs, y: lhs.y * rhs)\n    }\n    @inlinable public static func /= (lhs: inout CGPoint, rhs: CGFloat) {\n        lhs = CGPoint(x: lhs.x / rhs, y: lhs.y / rhs)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGRect.swift",
    "content": "//\n//  Ex+CGRect.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/02/03.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Foundation\n\n@inlinable public func round(_ rect: CGRect) -> CGRect {\n    CGRect(origin: round(rect.origin), end: round(rect.end))\n}\n\nextension CGRect {\n    @inlinable public var center: CGPoint {\n        @inlinable get { CGPoint(x: midX, y: midY) }\n        @inlinable set { self.origin = CGPoint(x: newValue.x - width/2, y: newValue.y - height/2) }\n    }\n\n    @inlinable public var end: CGPoint {\n        @inlinable get { CGPoint(x: maxX, y: maxY) }\n        @inlinable set { self.origin = CGPoint(x: newValue.x - width, y: newValue.y - height) }\n    }\n\n    @inlinable public func fattened(by inset: CGFloat) -> CGRect {\n        CGRect(origin: self.origin - [inset, inset], size: self.size + [inset, inset]*2)\n    }\n\n    @inlinable public func slimmed(by inset: CGFloat) -> CGRect {\n        CGRect(origin: self.origin + [inset, inset], size: self.size - [inset, inset]*2)\n    }\n\n    @inlinable public func fattened(by edgeInsets: NSEdgeInsets) -> CGRect {\n        CGRect(origin: self.origin - [edgeInsets.left, edgeInsets.bottom],\n               size: self.size + [edgeInsets.left + edgeInsets.right, edgeInsets.top + edgeInsets.bottom])\n    }\n\n    @inlinable public func slimmed(by edgeInsets: NSEdgeInsets) -> CGRect {\n        CGRect(origin: self.origin + [edgeInsets.left, edgeInsets.bottom],\n               size: self.size - [edgeInsets.left + edgeInsets.right, edgeInsets.top + edgeInsets.bottom])\n    }\n}\n\nextension CGRect {\n    @inlinable public func mapOrigin(_ tranceform: (CGPoint) -> (CGPoint)) -> CGRect {\n        CGRect(origin: tranceform(origin), size: size)\n    }\n    @inlinable public func mapCenter(_ tranceform: (CGPoint) -> (CGPoint)) -> CGRect {\n        CGRect(center: tranceform(center), size: size)\n    }\n    @inlinable public func mapEnd(_ tranceform: (CGPoint) -> (CGPoint)) -> CGRect {\n        CGRect(end: tranceform(end), size: size)\n    }\n    @inlinable public func mapSizePreservingOrigin(_ tranceform: (CGSize) -> (CGSize)) -> CGRect {\n        CGRect(origin: origin, size: tranceform(size))\n    }\n    @inlinable public func mapSizePreservingCenter(_ tranceform: (CGSize) -> (CGSize)) -> CGRect {\n        CGRect(center: center, size: tranceform(size))\n    }\n    @inlinable public func mapSizePreservingEnd(_ tranceform: (CGSize) -> (CGSize)) -> CGRect {\n        CGRect(end: end, size: tranceform(size))\n    }\n}\n\nextension CGRect {\n    @inlinable public init(origin: CGPoint) {\n        self.init(origin: origin, size: .zero)\n    }\n    @inlinable public init(size: CGSize) {\n        self.init(origin: .zero, size: size)\n    }\n    @inlinable public init(origin: CGPoint, end: CGPoint) {\n        self.init(origin: origin, size: (end - origin).convertToSize())\n    }\n    @inlinable public init(center: CGPoint, size: CGSize) {\n        self.init(origin: center - size.convertToPoint() / 2, size: size)\n    }\n    @inlinable public init(end: CGPoint, size: CGSize) {\n        self.init(origin: end - size.convertToPoint(), size: size)\n    }\n    @inlinable public init(originX: CGFloat, centerY: CGFloat, size: CGSize) {\n        self.init(origin: [originX, centerY - size.height/2], size: size)\n    }\n    @inlinable public init(centerX: CGFloat, originY: CGFloat, size: CGSize) {\n        self.init(origin: [centerX - size.width/2, originY], size: size)\n    }\n    \n    @inlinable public var isFinite: Bool {\n        size.isFinite && origin.isFinite\n    }\n}\n\nextension CGRect {\n    @inlinable public static func + (lhs: CGRect, rhs: CGRect) -> CGRect {\n        CGRect(origin: lhs.origin + rhs.origin, size: lhs.size + rhs.size)\n    }\n    @inlinable public static func - (lhs: CGRect, rhs: CGRect) -> CGRect {\n        CGRect(origin: lhs.origin - rhs.origin, size: lhs.size - rhs.size)\n    }\n}\n\nextension CGRect: Hashable {\n    @inlinable public func hash(into hasher: inout Hasher) {\n        hasher.combine(size)\n        hasher.combine(origin)\n    }\n}\n\nextension Collection where Element == CGRect {\n    @inlinable public var enclosingRect: CGRect {\n        if self.isEmpty { return .zero }\n        \n        var minX: CGFloat = .infinity\n        var minY: CGFloat = .infinity\n        var maxX: CGFloat = -.infinity\n        var maxY: CGFloat = -.infinity\n        \n        for rect in self {\n            if minX > rect.origin.x { minX = rect.origin.x }\n            if minY > rect.origin.y { minY = rect.origin.y }\n            let _maxX = rect.origin.x + rect.size.width\n            if maxX < _maxX { maxX = _maxX }\n            let _maxY = rect.origin.y + rect.size.height\n            if maxY < _maxY { maxY = _maxY }\n        }\n        \n        let rect = CGRect(origin: [minX, minY], end: [maxX, maxY])\n        return rect\n    }\n}\n\nextension FloatingPoint {\n    @inlinable public func isFiniteOrZero() -> Self { isFinite ? self : .zero }\n}\nextension CGPoint {\n    @inlinable public func isFiniteOrZero() -> CGPoint { isFinite ? self : .zero }\n}\nextension CGSize {\n    @inlinable public func isFiniteOrZero() -> CGSize { isFinite ? self : .zero }\n}\nextension CGRect {\n    @inlinable public func isFiniteOrZero() -> CGRect { isFinite ? self : .zero }\n}\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/CoreGraphics/Ex+CGSize.swift",
    "content": "import CoreGraphics\n\n\n@inlinable public func round(_ size: CGSize) -> CGSize {\n    CGSize(width: round(size.width), height: round(size.height))\n}\n\n@inlinable public func abs(_ size: CGSize) -> CGSize {\n    CGSize(width: abs(size.width), height: abs(size.height))\n}\n\n@inlinable public func sign(_ size: CGSize) -> CGSize {\n    CGSize(width: sign(size.width), height: sign(size.height))\n}\n\n@inlinable public func min(_ size0: CGSize, _ size1: CGSize) -> CGSize {\n    CGSize(width: min(size0.width, size1.width), height: min(size0.height, size1.height))\n}\n\n@inlinable public func max(_ size0: CGSize, _ size1: CGSize) -> CGSize {\n    CGSize(width: max(size0.width, size1.width), height: max(size0.height, size1.height))\n}\n\nextension CGSize {\n    @inlinable public func convertToPoint() -> CGPoint {\n        CGPoint(x: width, y: height)\n    }\n    \n    @inlinable public var minElement: CGFloat {\n        min(abs(self.width), abs(self.height))\n    }\n    @inlinable public var maxElement: CGFloat {\n        max(abs(self.width), abs(self.height))\n    }\n    @inlinable public var isFinite: Bool {\n        width.isFinite && height.isFinite\n    }\n    \n    public static let infinity = CGSize(width: CGFloat.infinity, height: .infinity)\n}\n\nextension CGSize {\n    @inlinable public func mapWidth(_ tranceform: (CGFloat) -> (CGFloat)) -> CGSize {\n        CGSize(width: tranceform(width), height: height)\n    }\n    @inlinable public func mapHeight(_ tranceform: (CGFloat) -> (CGFloat)) -> CGSize {\n        CGSize(width: width, height: tranceform(height))\n    }\n}\n\nextension CGSize: ExpressibleByArrayLiteral {\n    public init(arrayLiteral elements: CGFloat...) {\n        assert(elements.count == 2)\n        self.init(width: elements[0], height: elements[1])\n    }\n}\n\nextension CGSize: AdditiveArithmetic {\n    @inlinable public static func + (lhs: CGSize, rhs: CGSize) -> CGSize {\n        CGSize(width: lhs.width + rhs.width, height: lhs.height + rhs.height)\n    }\n    @inlinable public static func - (lhs: CGSize, rhs: CGSize) -> CGSize {\n        CGSize(width: lhs.width - rhs.width, height: lhs.height - rhs.height)\n    }\n    @inlinable public static prefix func - (lhs: CGSize) -> CGSize {\n        CGSize(width: -lhs.width, height: -lhs.height)\n    }\n}\n\nextension CGSize {\n    @inlinable public static func * (lhs: CGSize, rhs: CGFloat) -> CGSize {\n        return CGSize(width: lhs.width * rhs, height: lhs.height * rhs)\n    }\n    @inlinable public static func * (lhs: CGSize, rhs: CGSize) -> CGSize {\n        return CGSize(width: lhs.width * rhs.width, height: lhs.height * rhs.height)\n    }\n    @inlinable public static func / (lhs: CGSize, rhs: CGFloat) -> CGSize {\n        return CGSize(width: lhs.width / rhs, height: lhs.height / rhs)\n    }\n    @inlinable public static func / (lhs: CGSize, rhs: CGSize) -> CGSize {\n        return CGSize(width: lhs.width / rhs.width, height: lhs.height / rhs.height)\n    }\n    @inlinable public static func *= (lhs: inout CGSize, rhs: CGFloat) {\n        lhs.width *= rhs\n        lhs.height *= rhs\n    }\n    @inlinable public static func /= (lhs: inout CGSize, rhs: CGFloat) {\n        lhs.width /= rhs\n        lhs.height /= rhs\n    }\n}\n\nextension CGSize: Hashable {\n    @inlinable public func hash(into hasher: inout Hasher) {\n        hasher.combine(width)\n        hasher.combine(height)\n    }\n}\n\nextension CGSize {\n    /// boundingBoxにアスペクトフィットするのに必要な変換レートを返します。\n    @inlinable public func aspectFitRatio(fitInside boundingBox: CGSize) -> CGFloat {\n        let mW = boundingBox.width / self.width\n        let mH = boundingBox.height / self.height\n\n        if mH > mW {\n            return boundingBox.width / self.width\n        } else {\n            return boundingBox.height / self.height\n        }\n    }\n\n    /// boundingBoxにアスペクトフィルするのに必要な変換レートを返します。\n    @inlinable public func aspectFillRatio(fillInside boundingBox: CGSize) -> CGFloat {\n        let mW = boundingBox.width / self.width\n        let mH = boundingBox.height / self.height\n\n        if mH < mW {\n            return boundingBox.width / self.width\n        } else {\n            return boundingBox.height / self.height\n        }\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Array.swift",
    "content": "//\n//  Extensions.swift\n//  DANMAKER\n//\n//  Created by yuki on 2015/06/24.\n//  Copyright © 2015 yuki. All rights reserved.\n//\n\nextension RandomAccessCollection {\n    @inlinable public func at(_ index: Self.Index) -> Element? {\n        self.indices.contains(index) ? self[index] : nil\n    }\n}\n\nextension Sequence {\n    @inlinable public func count(where condition: (Element) throws -> Bool) rethrows -> Int {\n        try self.lazy.filter(condition).count\n    }\n    @inlinable public func count(while condition: (Element) throws -> Bool) rethrows -> Int {\n        var count = 0\n        for element in self {\n            if try !condition(element) { return count }\n            count += 1\n        }\n        return count\n    }\n    \n    @inlinable public func firstSome<T>(where condition: (Element) throws -> T?) rethrows -> T? {\n        try self.lazy.compactMap(condition).first\n    }\n    \n    @inlinable public func allSome<T>(_ tranceform: (Element) throws -> T?) rethrows -> [T]? {\n        var values = [T]()\n        for element in self {\n            guard let element = try tranceform(element) else { return nil }\n            values.append(element)\n        }\n        return values\n    }\n}\n\nextension Array {\n    public mutating func move(fromIndex: Int, toIndex: Int) {\n        assert(indices.contains(fromIndex), \"fromIndex '\\(fromIndex)' is out of bounds.\")\n        \n        if fromIndex == toIndex { return }\n        let removed = self.remove(at: fromIndex)\n        \n        if fromIndex < toIndex {\n            self.insert(removed, at: toIndex - 1)\n        } else {\n            self.insert(removed, at: toIndex)\n        }\n    }\n    \n    public mutating func move<Range: RangeExpression>(fromRange: Range, toIndex: Int) where Range.Bound == Int {\n        assert(indices.contains(toIndex), \"toIndex '\\(toIndex)' is out of bounds.\")\n        let range = fromRange.relative(to: self)\n        \n        if range.contains(toIndex) { return }\n        \n        let removed = self[range]\n        self.removeSubrange(range)\n        \n        if range.upperBound < toIndex + range.count - 1 {\n            self.insert(contentsOf: removed, at: toIndex - range.count + 1)\n        } else {\n            self.insert(contentsOf: removed, at: toIndex)\n        }\n    }\n}\n\nextension Array {\n    @discardableResult\n    @inlinable public mutating func removeFirst(where condition: (Element) throws -> Bool) rethrows -> Element? {\n        for i in 0..<self.count {\n            if try condition(self[i]) { return remove(at: i) }\n        }\n        return nil\n    }\n}\n\n// MARK: - Equatable Array Extensions\nextension Array where Element: Equatable {\n    @inlinable @discardableResult public mutating func removeFirst(_ element: Element) -> Element? {\n        for index in 0..<count where self[index] == element {\n            return remove(at: index)\n        }\n\n        return nil\n    }\n}\n\nextension Sequence where Element: Comparable {\n    @inlinable public func max(_ replace: Element) -> Element {  self.max() ?? replace }\n    @inlinable public func min(_ replace: Element) -> Element { self.min() ?? replace }\n}\n\nextension Dictionary {\n    public mutating func arrayAppend<T>(_ value: T, forKey key: Key) where Self.Value == Array<T> {\n        if self[key] == nil { self[key] = [] }\n        self[key]!.append(value)\n    }\n    public mutating func arrayAppend<T, S: Sequence>(contentsOf newElements: S, forKey key: Key) where Self.Value == Array<T>, S.Element == T {\n        if self[key] == nil { self[key] = [] }\n        self[key]!.append(contentsOf: newElements)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Clamp.swift",
    "content": "//\n//  Ex+Comparable.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/04/01.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\npublic func clamp<Target: Comparable>(_ x: Target, into range: ClosedRange<Target>) -> Target {\n    max(range.lowerBound, min(x, range.upperBound))\n}\n\npublic func clamp<Target: Comparable>(_ x: Target, into range: PartialRangeFrom<Target>) -> Target {\n    max(range.lowerBound, x)\n}\n\npublic func clamp<Target: Comparable>(_ x: Target, into range: PartialRangeThrough<Target>) -> Target {\n    min(range.upperBound, x)\n}\n\nextension Strideable {\n    public func clamped(_ range: Range<Self>) -> Self {\n        max(range.lowerBound, min(self, range.upperBound.advanced(by: -1)))\n    }\n}\n\nextension Comparable {\n    public func clamped(_ range: ClosedRange<Self>) -> Self {\n        clamp(self, into: range)\n    }\n    public func clamped(_ range: PartialRangeFrom<Self>) -> Self {\n        clamp(self, into: range)\n    }\n    public func clamped(_ range: PartialRangeThrough<Self>) -> Self {\n        clamp(self, into: range)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Localize.swift",
    "content": "//\n//  Ex+Localize.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/02/13.\n//\n\nimport Foundation\n\nextension String {\n    public func localized() -> String {\n        NSLocalizedString(self, comment: self)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+Number.swift",
    "content": "//\n//  Ex+NUmber.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/06/24.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\n/// Returns `1` when the value greater than or equals to `0`. And returns `-1` when the value smaller than `0`\n@inlinable public func sign<T: SignedNumeric & Comparable>(_ value: T) -> T {\n    if value >= T.zero {\n        return 1\n    } else {\n        return -1\n    }\n}\n\nextension Double {\n    @inlinable public func rounded(toDecimal fractionDigits: Int) -> Self {\n        let multiplier = pow(10, Self(fractionDigits))\n        return Darwin.round(self * multiplier) / multiplier\n    }\n}\n\nextension Float {\n    @inlinable public func rounded(toDecimal fractionDigits: Int) -> Self {\n        let multiplier = pow(10, Self(fractionDigits))\n        return Darwin.round(self * multiplier) / multiplier\n    }\n}\n\nextension CGFloat {\n    @inlinable public func rounded(toDecimal fractionDigits: Int) -> Self {\n        let multiplier = pow(10, Self(fractionDigits))\n        return Darwin.round(self * multiplier) / multiplier\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/Swift/Ex+OptionSet.swift",
    "content": "//\n//  Ex+OptionSet.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/04/13.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nextension OptionSet where RawValue: FixedWidthInteger {\n    public static var all: Self { Self(rawValue: RawValue.max) }\n    public static var none: Self { [] }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+CALayer.swift",
    "content": "//\n//  Ex+CALayer.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/06/23.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nextension CALayer {\n    public static func animationDisabled() -> Self {\n        let layer = Self.init()\n        layer.areAnimationsEnabled = false\n        return layer\n    }\n}\n\nextension CALayer {\n    @objc public var areAnimationsEnabled: Bool {\n        get { delegate === CALayerAnimationsDisablingDelegate.shared }\n        set { delegate = newValue ? nil : CALayerAnimationsDisablingDelegate.shared }\n    }\n}\n\nprivate class CALayerAnimationsDisablingDelegate: NSObject, CALayerDelegate {\n    public static let shared = CALayerAnimationsDisablingDelegate()\n    let null = NSNull()\n\n    func action(for layer: CALayer, forKey event: String) -> CAAction? { null }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+Image.swift",
    "content": "//\n//  Ex+Image.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/03/10.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nextension NSImage {\n    public var cgImage: CGImage? {\n        var imageRect = CGRect(size: self.size)\n        return cgImage(forProposedRect: &imageRect, context: nil, hints: nil)\n    }\n}\n\n\nextension CGImage {\n    public func convertToGrayscale() -> CGImage {\n        let imageRect = CGRect(size: CGSize(width: width, height: height))\n        let context = CGContext(\n            data: nil, width: self.width, height: self.height,\n            bitsPerComponent: 8, bytesPerRow: 0,\n            space: CGColorSpaceCreateDeviceGray(), bitmapInfo: CGImageAlphaInfo.none.rawValue\n        )!\n        context.draw(self, in: imageRect)\n        return context.makeImage()!\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSColor.swift",
    "content": "import Cocoa\n\n// MARK: - Extension for Color\nextension NSColor {\n    public convenience init(colorSpace: NSColorSpace = .current, hex: Int, alpha: CGFloat = 1.0) {\n        let red = CGFloat((hex & 0xff_00_00) >> 16) / 255\n        let green = CGFloat((hex & 0x00_ff_00) >> 8) / 255\n        let blue = CGFloat((hex & 0x00_00_ff) >> 0) / 255\n\n        self.init(colorSpace: colorSpace, red: red, green: green, blue: blue, alpha: alpha)\n    }\n\n    public convenience init(colorSpace: NSColorSpace = .current, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {\n        var rgba = [red, green, blue, alpha]\n        self.init(colorSpace: colorSpace, components: &rgba, count: rgba.count)\n    }\n}\n\nextension NSColorSpace {\n    public static let current: NSColorSpace = NSScreen.main?.colorSpace ?? NSColorSpace.deviceRGB\n}\n\nextension CGColorSpace {\n    public static let current: CGColorSpace = NSColorSpace.current.cgColorSpace ?? CGColorSpaceCreateDeviceRGB()\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSControl.swift",
    "content": "//\n//  Ex+NSControl.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/10/28.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nextension NSControl {\n    public func setTarget(_ target: AnyObject, action: Selector) {\n        self.target = target\n        self.action = action\n    }\n    \n    public func executeAction() {\n        guard let object = (target as? NSObject), let action = self.action else { return NSSound.beep() }\n        \n        if object.responds(to: action) {\n            object.perform(action, with: self)\n        }\n    }\n}\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSEdgeInsets.swift",
    "content": "//\n//  Ex+NSEdgeInsets.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\n\nextension NSEdgeInsets: Equatable {\n    public static let zero = NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)\n    \n    public static func == (lhs: NSEdgeInsets, rhs: NSEdgeInsets) -> Bool {\n        lhs.top == rhs.top && lhs.left == rhs.left && lhs.bottom == rhs.bottom && lhs.right == rhs.right\n    }\n    \n    public static func each(top: CGFloat = 0, left: CGFloat = 0, bottom: CGFloat = 0, right: CGFloat = 0) -> NSEdgeInsets {\n        NSEdgeInsets(top: top, left: left, bottom: bottom, right: right)\n    }\n    \n    public init(repeating element: CGFloat) {\n        self.init(top: element, left: element, bottom: element, right: element)\n    }\n    \n    public init(x: CGFloat=0, y: CGFloat=0) {\n        self.init(top: y, left: x, bottom: y, right: x)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSEvent.swift",
    "content": "//\n//  NSEvent+Location.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/11/11.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nextension NSEvent {\n    @inlinable public func location(in view: NSView) -> CGPoint {\n        view.convert(self.locationInWindow, from: nil)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSMenuItem.swift",
    "content": "//\n//  Ex+NSMenuItem.swift\n//  CoreUtil\n//\n//  Created by yuki on 2020/08/20.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport Combine\n\nprivate var actionHandlerKey = 0\nprivate var actionPublisherKey = 0\n\nextension NSMenuItem {\n    public convenience init(title: String, image: NSImage? = nil, isSelected: Bool = false, isEnabled: Bool = true, action: (() -> Void)? = nil) {\n        self.init()\n        self.title = title\n        self.image = image\n        self.isSelected = isSelected\n        if let action = action { self.setAction(action) } \n    }\n    \n    public var isSelected: Bool {\n        get { self.state == .on } set { self.state = newValue ? .on : .off }\n    }\n    \n    public func setAction(_ block: @escaping () -> ()) {\n        self.actionHandler.action = block\n    }\n    \n    private var actionHandler: ActionHandler {\n        if let handler = objc_getAssociatedObject(self, &actionHandlerKey) as? ActionHandler { return handler }\n        let handler = ActionHandler()\n        self.target = handler\n        self.action = #selector(ActionHandler.run)\n        objc_setAssociatedObject(self, &actionHandlerKey, handler, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)\n        return handler\n    }\n    \n    final private class ActionHandler {\n        var action: (() -> ())?\n        @objc func run(_ sender: Any?) { self.action?() }\n    }\n}\n\nextension NSMenu {\n    public func addItem(title: String, image: NSImage? = nil, isSelected: Bool = false, isEnabled: Bool = true, action: (() -> Void)?) {\n        let item = NSMenuItem(title: title, image: image, isSelected: isSelected, isEnabled: isEnabled, action: action)\n        self.addItem(item)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSPopover.swift",
    "content": "//\n//  Ex+NSPopover.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/05/31.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport Combine\n\nextension NSPopover {\n    public var willClosePublisher: AnyPublisher<Void, Never> { publisherDelegate.willClosePublisher.eraseToAnyPublisher() }\n    public var willShowPublisher: AnyPublisher<Void, Never> { publisherDelegate.willShowPublisher.eraseToAnyPublisher() }\n    public var didClosePublisher: AnyPublisher<Void, Never> { publisherDelegate.didClosePublisher.eraseToAnyPublisher() }\n    public var didShowPublisher: AnyPublisher<Void, Never> { publisherDelegate.didShowPublisher.eraseToAnyPublisher() }\n    public var didDetachPublisher: AnyPublisher<Void, Never> { publisherDelegate.didDetachPublisher.eraseToAnyPublisher() }\n    \n    private static var delegateKey = 0\n    private var publisherDelegate: PublisherDelegate {\n        if let delegate = objc_getAssociatedObject(self, &Self.delegateKey) as? PublisherDelegate { return delegate }\n        \n        let delegate = PublisherDelegate()\n        self.delegate = delegate\n        objc_setAssociatedObject(self, &Self.delegateKey, delegate, .OBJC_ASSOCIATION_RETAIN)\n        return delegate\n    }\n    \n    final private class PublisherDelegate: NSObject, NSPopoverDelegate {\n        let willClosePublisher = PassthroughSubject<Void, Never>()\n        let willShowPublisher = PassthroughSubject<Void, Never>()\n        let didClosePublisher = PassthroughSubject<Void, Never>()\n        let didShowPublisher = PassthroughSubject<Void, Never>()\n        let didDetachPublisher = PassthroughSubject<Void, Never>()\n        \n        func popoverWillClose(_ notification: Notification) { willClosePublisher.send() }\n        func popoverWillShow(_ notification: Notification) { willShowPublisher.send() }\n        func popoverDidDetach(_ popover: NSPopover) { didDetachPublisher.send() }\n        func popoverDidShow(_ notification: Notification) { didShowPublisher.send() }\n        func popoverDidClose(_ notification: Notification) { didClosePublisher.send() }\n    }\n}\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+NSTableView.swift",
    "content": "//\n//  Ex+NSTableView.swift\n//  CoreUtil\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\n\nextension NSTableView {\n    public static let listColumnIdentifier = NSUserInterfaceItemIdentifier(\"$_column\")\n        \n    public func becomeListStyle() {\n        let column = NSTableColumn(identifier: Self.listColumnIdentifier)\n        column.resizingMask = .autoresizingMask\n\n        // column\n        self.addTableColumn(column)\n        self.columnAutoresizingStyle = .firstColumnOnlyAutoresizingStyle\n        self.allowsColumnResizing = false\n        self.allowsColumnSelection = false\n\n        // appearance\n        self.headerView = nil\n        self.intercellSpacing = .zero\n        self.focusRingType = .none\n\n        // behavior\n        self.allowsEmptySelection = true\n        self.allowsMultipleSelection = false\n        self.backgroundColor = .clear\n        \n        if #available(OSX 11.0, *) { self.style = .plain }\n    }\n    \n    /// 1コラムのみのTableView\n    public static func list() -> Self {\n        let tableView = Self()\n        tableView.becomeListStyle()\n        return tableView\n    }\n}\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/Extensions/UI/Ex+UI.swift",
    "content": "import Cocoa\n\npublic let NSOutlineViewNotificationItemKey = \"NSObject\"\n\nextension NSView {\n    #if DEBUG\n    public func __setBackgroundColor(_ color: NSColor) {\n        self.wantsLayer = true\n        self.layer?.backgroundColor = color.cgColor\n    }\n    #endif\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/HotKey/HotKey.swift",
    "content": "//\n//  KeyboardShortcut.swift\n//  ListView\n//\n//  Created by yuki on 2021/06/28.\n//\n\nimport Carbon\nimport Cocoa\n\npublic struct HotKey: Hashable {\n    public let key: Key?\n    public let modifiers: NSEvent.ModifierFlags\n    \n    public init(_ key: Key?, _ modifiers: NSEvent.ModifierFlags = []) {\n        self.key = key\n        self.modifiers = modifiers\n    }\n}\n\nextension HotKey {\n    public static let open = HotKey(.o, .command)\n    public static let copy = HotKey(.c, .command)\n    public static let paste = HotKey(.v, .command)\n    public static let cut = HotKey(.x, .command)\n    public static let duplicate = HotKey(.d, .command)\n    public static let save = HotKey(.s, .command)\n    public static let undo = HotKey(.z, .command)\n    public static let selectAll = HotKey(.a, .command)\n    public static let redo = HotKey(.z, [.command, .shift])\n    public static let go = HotKey(.rightBracket, .command)\n    public static let back = HotKey(.leftBracket, .command)\n    public static let print = HotKey(.p, .command)\n    public static let delete = HotKey(.delete)\n    public static let tab = HotKey(.tab)\n    public static let backtab = HotKey(.tab, .shift)\n    public static let escape = HotKey(.escape)\n    public static let enter = HotKey(.keypadEnter)\n    public static let space = HotKey(.space)\n    public static let `return` = HotKey(.return)\n    public static let leftArrow = HotKey(.leftArrow, [.numericPad, .function])\n    public static let rightArrow = HotKey(.rightArrow, [.numericPad, .function])\n    public static let upArrow = HotKey(.upArrow, [.numericPad, .function])\n    public static let downArrow = HotKey(.downArrow, [.numericPad, .function])\n    public static let leftShiftArrow = HotKey(.leftArrow, [.numericPad, .function, .shift])\n    public static let rightShiftArrow = HotKey(.rightArrow, [.numericPad, .function, .shift])\n    public static let upShiftArrow = HotKey(.upArrow, [.numericPad, .function, .shift])\n    public static let downShiftArrow = HotKey(.downArrow, [.numericPad, .function, .shift])\n}\n\nextension HotKey: CustomStringConvertible {\n    public var description: String {\n        var output = modifiers.description\n        if let key = key {\n            output += key.description\n        }\n        return output\n    }\n}\n\nextension NSEvent.ModifierFlags: Hashable {\n    public func hash(into hasher: inout Hasher) {\n        hasher.combine(rawValue)\n    }\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil/HotKey/Key.swift",
    "content": "//\n//  Key.swift\n//  ListView\n//\n//  Created by yuki on 2021/06/28.\n//\n\nimport Carbon\n\npublic enum Key {\n    // MARK: - Letters -\n    case a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z\n\n    // MARK: - Numbers -\n    case zero, one, two, three, four, five, six, seven, eight, nine\n\n    // MARK: - Symbols -\n    case period, quote, rightBracket, semicolon, slash, backslash, comma, equal, grave, leftBracket, minus\n\n    // MARK: - White Spaces -\n    case space, tab, `return`\n\n    // MARK: - Modifiers -\n    case command, rightCommand, option, rightOption, control, rightControl, shift, rightShift, function, capsLock\n\n    // MARK: - Navigation\n    case pageUp, pageDown, home, end, upArrow, rightArrow, downArrow, leftArrow\n\n    // MARK: - Functions\n    case f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20\n\n    // MARK: - Keypad\n    case keypad0, keypad1, keypad2, keypad3, keypad4, keypad5, keypad6, keypad7, keypad8, keypad9, keypadClear, keypadDecimal, keypadDivide, keypadEnter, keypadEquals, keypadMinus, keypadMultiply, keypadPlus\n\n    // MARK: - Misc\n    case escape, delete, forwardDelete, help, volumeUp, volumeDown, mute\n\n    public init?(keyCode: Int) {\n        switch keyCode {\n        case kVK_ANSI_A: self = .a\n        case kVK_ANSI_S: self = .s\n        case kVK_ANSI_D: self = .d\n        case kVK_ANSI_F: self = .f\n        case kVK_ANSI_H: self = .h\n        case kVK_ANSI_G: self = .g\n        case kVK_ANSI_Z: self = .z\n        case kVK_ANSI_X: self = .x\n        case kVK_ANSI_C: self = .c\n        case kVK_ANSI_V: self = .v\n        case kVK_ANSI_B: self = .b\n        case kVK_ANSI_Q: self = .q\n        case kVK_ANSI_W: self = .w\n        case kVK_ANSI_E: self = .e\n        case kVK_ANSI_R: self = .r\n        case kVK_ANSI_Y: self = .y\n        case kVK_ANSI_T: self = .t\n        case kVK_ANSI_1: self = .one\n        case kVK_ANSI_2: self = .two\n        case kVK_ANSI_3: self = .three\n        case kVK_ANSI_4: self = .four\n        case kVK_ANSI_6: self = .six\n        case kVK_ANSI_5: self = .five\n        case kVK_ANSI_Equal: self = .equal\n        case kVK_ANSI_9: self = .nine\n        case kVK_ANSI_7: self = .seven\n        case kVK_ANSI_Minus: self = .minus\n        case kVK_ANSI_8: self = .eight\n        case kVK_ANSI_0: self = .zero\n        case kVK_ANSI_RightBracket: self = .rightBracket\n        case kVK_ANSI_O: self = .o\n        case kVK_ANSI_U: self = .u\n        case kVK_ANSI_LeftBracket: self = .leftBracket\n        case kVK_ANSI_I: self = .i\n        case kVK_ANSI_P: self = .p\n        case kVK_ANSI_L: self = .l\n        case kVK_ANSI_J: self = .j\n        case kVK_ANSI_Quote: self = .quote\n        case kVK_ANSI_K: self = .k\n        case kVK_ANSI_Semicolon: self = .semicolon\n        case kVK_ANSI_Backslash: self = .backslash\n        case kVK_ANSI_Comma: self = .comma\n        case kVK_ANSI_Slash: self = .slash\n        case kVK_ANSI_N: self = .n\n        case kVK_ANSI_M: self = .m\n        case kVK_ANSI_Period: self = .period\n        case kVK_ANSI_Grave: self = .grave\n        case kVK_ANSI_KeypadDecimal: self = .keypadDecimal\n        case kVK_ANSI_KeypadMultiply: self = .keypadMultiply\n        case kVK_ANSI_KeypadPlus: self = .keypadPlus\n        case kVK_ANSI_KeypadClear: self = .keypadClear\n        case kVK_ANSI_KeypadDivide: self = .keypadDivide\n        case kVK_ANSI_KeypadEnter: self = .keypadEnter\n        case kVK_ANSI_KeypadMinus: self = .keypadMinus\n        case kVK_ANSI_KeypadEquals: self = .keypadEquals\n        case kVK_ANSI_Keypad0: self = .keypad0\n        case kVK_ANSI_Keypad1: self = .keypad1\n        case kVK_ANSI_Keypad2: self = .keypad2\n        case kVK_ANSI_Keypad3: self = .keypad3\n        case kVK_ANSI_Keypad4: self = .keypad4\n        case kVK_ANSI_Keypad5: self = .keypad5\n        case kVK_ANSI_Keypad6: self = .keypad6\n        case kVK_ANSI_Keypad7: self = .keypad7\n        case kVK_ANSI_Keypad8: self = .keypad8\n        case kVK_ANSI_Keypad9: self = .keypad9\n        case kVK_Return: self = .`return`\n        case kVK_Tab: self = .tab\n        case kVK_Space: self = .space\n        case kVK_Delete: self = .delete\n        case kVK_Escape: self = .escape\n        case kVK_Command: self = .command\n        case kVK_Shift: self = .shift\n        case kVK_CapsLock: self = .capsLock\n        case kVK_Option: self = .option\n        case kVK_Control: self = .control\n        case kVK_RightCommand: self = .rightCommand\n        case kVK_RightShift: self = .rightShift\n        case kVK_RightOption: self = .rightOption\n        case kVK_RightControl: self = .rightControl\n        case kVK_Function: self = .function\n        case kVK_F17: self = .f17\n        case kVK_VolumeUp: self = .volumeUp\n        case kVK_VolumeDown: self = .volumeDown\n        case kVK_Mute: self = .mute\n        case kVK_F18: self = .f18\n        case kVK_F19: self = .f19\n        case kVK_F20: self = .f20\n        case kVK_F5: self = .f5\n        case kVK_F6: self = .f6\n        case kVK_F7: self = .f7\n        case kVK_F3: self = .f3\n        case kVK_F8: self = .f8\n        case kVK_F9: self = .f9\n        case kVK_F11: self = .f11\n        case kVK_F13: self = .f13\n        case kVK_F16: self = .f16\n        case kVK_F14: self = .f14\n        case kVK_F10: self = .f10\n        case kVK_F12: self = .f12\n        case kVK_F15: self = .f15\n        case kVK_Help: self = .help\n        case kVK_Home: self = .home\n        case kVK_PageUp: self = .pageUp\n        case kVK_ForwardDelete: self = .forwardDelete\n        case kVK_F4: self = .f4\n        case kVK_End: self = .end\n        case kVK_F2: self = .f2\n        case kVK_PageDown: self = .pageDown\n        case kVK_F1: self = .f1\n        case kVK_LeftArrow: self = .leftArrow\n        case kVK_RightArrow: self = .rightArrow\n        case kVK_DownArrow: self = .downArrow\n        case kVK_UpArrow: self = .upArrow\n        default: return nil\n        }\n    }\n    \n    public var keyCode: Int {\n        switch self {\n        case .a: return kVK_ANSI_A\n        case .s: return kVK_ANSI_S\n        case .d: return kVK_ANSI_D\n        case .f: return kVK_ANSI_F\n        case .h: return kVK_ANSI_H\n        case .g: return kVK_ANSI_G\n        case .z: return kVK_ANSI_Z\n        case .x: return kVK_ANSI_X\n        case .c: return kVK_ANSI_C\n        case .v: return kVK_ANSI_V\n        case .b: return kVK_ANSI_B\n        case .q: return kVK_ANSI_Q\n        case .w: return kVK_ANSI_W\n        case .e: return kVK_ANSI_E\n        case .r: return kVK_ANSI_R\n        case .y: return kVK_ANSI_Y\n        case .t: return kVK_ANSI_T\n        case .one: return kVK_ANSI_1\n        case .two: return kVK_ANSI_2\n        case .three: return kVK_ANSI_3\n        case .four: return kVK_ANSI_4\n        case .six: return kVK_ANSI_6\n        case .five: return kVK_ANSI_5\n        case .equal: return kVK_ANSI_Equal\n        case .nine: return kVK_ANSI_9\n        case .seven: return kVK_ANSI_7\n        case .minus: return kVK_ANSI_Minus\n        case .eight: return kVK_ANSI_8\n        case .zero: return kVK_ANSI_0\n        case .rightBracket: return kVK_ANSI_RightBracket\n        case .o: return kVK_ANSI_O\n        case .u: return kVK_ANSI_U\n        case .leftBracket: return kVK_ANSI_LeftBracket\n        case .i: return kVK_ANSI_I\n        case .p: return kVK_ANSI_P\n        case .l: return kVK_ANSI_L\n        case .j: return kVK_ANSI_J\n        case .quote: return kVK_ANSI_Quote\n        case .k: return kVK_ANSI_K\n        case .semicolon: return kVK_ANSI_Semicolon\n        case .backslash: return kVK_ANSI_Backslash\n        case .comma: return kVK_ANSI_Comma\n        case .slash: return kVK_ANSI_Slash\n        case .n: return kVK_ANSI_N\n        case .m: return kVK_ANSI_M\n        case .period: return kVK_ANSI_Period\n        case .grave: return kVK_ANSI_Grave\n        case .keypadDecimal: return kVK_ANSI_KeypadDecimal\n        case .keypadMultiply: return kVK_ANSI_KeypadMultiply\n        case .keypadPlus: return kVK_ANSI_KeypadPlus\n        case .keypadClear: return kVK_ANSI_KeypadClear\n        case .keypadDivide: return kVK_ANSI_KeypadDivide\n        case .keypadEnter: return kVK_ANSI_KeypadEnter\n        case .keypadMinus: return kVK_ANSI_KeypadMinus\n        case .keypadEquals: return kVK_ANSI_KeypadEquals\n        case .keypad0: return kVK_ANSI_Keypad0\n        case .keypad1: return kVK_ANSI_Keypad1\n        case .keypad2: return kVK_ANSI_Keypad2\n        case .keypad3: return kVK_ANSI_Keypad3\n        case .keypad4: return kVK_ANSI_Keypad4\n        case .keypad5: return kVK_ANSI_Keypad5\n        case .keypad6: return kVK_ANSI_Keypad6\n        case .keypad7: return kVK_ANSI_Keypad7\n        case .keypad8: return kVK_ANSI_Keypad8\n        case .keypad9: return kVK_ANSI_Keypad9\n        case .`return`: return kVK_Return\n        case .tab: return kVK_Tab\n        case .space: return kVK_Space\n        case .delete: return kVK_Delete\n        case .escape: return kVK_Escape\n        case .command: return kVK_Command\n        case .shift: return kVK_Shift\n        case .capsLock: return kVK_CapsLock\n        case .option: return kVK_Option\n        case .control: return kVK_Control\n        case .rightCommand: return kVK_RightCommand\n        case .rightShift: return kVK_RightShift\n        case .rightOption: return kVK_RightOption\n        case .rightControl: return kVK_RightControl\n        case .function: return kVK_Function\n        case .f17: return kVK_F17\n        case .volumeUp: return kVK_VolumeUp\n        case .volumeDown: return kVK_VolumeDown\n        case .mute: return kVK_Mute\n        case .f18: return kVK_F18\n        case .f19: return kVK_F19\n        case .f20: return kVK_F20\n        case .f5: return kVK_F5\n        case .f6: return kVK_F6\n        case .f7: return kVK_F7\n        case .f3: return kVK_F3\n        case .f8: return kVK_F8\n        case .f9: return kVK_F9\n        case .f11: return kVK_F11\n        case .f13: return kVK_F13\n        case .f16: return kVK_F16\n        case .f14: return kVK_F14\n        case .f10: return kVK_F10\n        case .f12: return kVK_F12\n        case .f15: return kVK_F15\n        case .help: return kVK_Help\n        case .home: return kVK_Home\n        case .pageUp: return kVK_PageUp\n        case .forwardDelete: return kVK_ForwardDelete\n        case .f4: return kVK_F4\n        case .end: return kVK_End\n        case .f2: return kVK_F2\n        case .pageDown: return kVK_PageDown\n        case .f1: return kVK_F1\n        case .leftArrow: return kVK_LeftArrow\n        case .rightArrow: return kVK_RightArrow\n        case .downArrow: return kVK_DownArrow\n        case .upArrow: return kVK_UpArrow\n        }\n    }\n}\n\nextension Key: CustomStringConvertible {\n    public var description: String {\n        switch  self {\n        case .a: return \"A\"\n        case .s: return \"S\"\n        case .d: return \"D\"\n        case .f: return \"F\"\n        case .h: return \"H\"\n        case .g: return \"G\"\n        case .z: return \"Z\"\n        case .x: return \"X\"\n        case .c: return \"C\"\n        case .v: return \"V\"\n        case .b: return \"B\"\n        case .q: return \"Q\"\n        case .w: return \"W\"\n        case .e: return \"E\"\n        case .r: return \"R\"\n        case .y: return \"Y\"\n        case .t: return \"T\"\n        case .one, .keypad1: return \"1\"\n        case .two, .keypad2: return \"2\"\n        case .three, .keypad3: return \"3\"\n        case .four, .keypad4: return \"4\"\n        case .six, .keypad6: return \"6\"\n        case .five, .keypad5: return \"5\"\n        case .equal: return \"=\"\n        case .nine, .keypad9: return \"9\"\n        case .seven, .keypad7: return \"7\"\n        case .minus: return \"-\"\n        case .eight, .keypad8: return \"8\"\n        case .zero, .keypad0: return \"0\"\n        case .rightBracket: return \"]\"\n        case .o: return \"O\"\n        case .u: return \"U\"\n        case .leftBracket: return \"[\"\n        case .i: return \"I\"\n        case .p: return \"P\"\n        case .l: return \"L\"\n        case .j: return \"J\"\n        case .quote: return \"\\\"\"\n        case .k: return \"K\"\n        case .semicolon: return \";\"\n        case .backslash: return \"\\\\\"\n        case .comma: return \",\"\n        case .slash: return \"/\"\n        case .n: return \"N\"\n        case .m: return \"M\"\n        case .period: return \".\"\n        case .grave: return \"`\"\n        case .keypadDecimal: return \".\"\n        case .keypadMultiply: return \"𝗑\"\n        case .keypadPlus: return \"+\"\n        case .keypadClear: return \"⌧\"\n        case .keypadDivide: return \"/\"\n        case .keypadEnter: return \"↩︎\"\n        case .keypadMinus: return \"-\"\n        case .keypadEquals: return \"=\"\n        case .`return`: return \"↩︎\"\n        case .tab: return \"⇥\"\n        case .space: return \"␣\"\n        case .delete: return \"⌫\"\n        case .escape: return \"⎋\"\n        case .command, .rightCommand: return \"⌘\"\n        case .shift, .rightShift: return \"⇧\"\n        case .capsLock: return \"⇪\"\n        case .option, .rightOption: return \"⌥\"\n        case .control, .rightControl: return \"⌃\"\n        case .function: return \"fn\"\n        case .f17: return \"F17\"\n        case .volumeUp: return \"🔊\"\n        case .volumeDown: return \"🔉\"\n        case .mute: return \"🔇\"\n        case .f18: return \"F18\"\n        case .f19: return \"F19\"\n        case .f20: return \"F20\"\n        case .f5: return \"F5\"\n        case .f6: return \"F6\"\n        case .f7: return \"F7\"\n        case .f3: return \"F3\"\n        case .f8: return \"F8\"\n        case .f9: return \"F9\"\n        case .f11: return \"F11\"\n        case .f13: return \"F13\"\n        case .f16: return \"F16\"\n        case .f14: return \"F14\"\n        case .f10: return \"F10\"\n        case .f12: return \"F12\"\n        case .f15: return \"F15\"\n        case .help: return \"?⃝\"\n        case .home: return \"↖\"\n        case .pageUp: return \"⇞\"\n        case .forwardDelete: return \"⌦\"\n        case .f4: return \"F4\"\n        case .end: return \"↘\"\n        case .f2: return \"F2\"\n        case .pageDown: return \"⇟\"\n        case .f1: return \"F1\"\n        case .leftArrow: return \"←\"\n        case .rightArrow: return \"→\"\n        case .downArrow: return \"↓\"\n        case .upArrow: return \"↑\"\n        }\n    }\n}\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/HotKey/NSEvent+HotKey.swift",
    "content": "//\n//  NSEvent+HotKey.swift\n//  ListView\n//\n//  Created by yuki on 2021/06/28.\n//\n\nimport Cocoa\n\nextension NSEvent {\n    public var hotKey: HotKey {\n        HotKey(Key(keyCode: Int(self.keyCode)), self.modifierFlags.intersection(.deviceIndependentFlagsMask))\n    }\n}\n\nextension NSEvent.ModifierFlags: CustomStringConvertible {\n    public var description: String {\n        var output = \"\"\n        \n        if self.contains(.capsLock) { output += Key.capsLock.description }\n        if self.contains(.shift) { output += Key.shift.description }\n        if self.contains(.control) { output += Key.control.description }\n        if self.contains(.option) { output += Key.option.description }\n        if self.contains(.command) { output += Key.command.description }\n        if self.contains(.numericPad) { output += \"Np\" }\n        if self.contains(.help) { output += Key.help.description }\n        if self.contains(.function) { output += Key.function.description }\n\n        return output\n    }\n}\n\n\n"
  },
  {
    "path": "CoreUtil/CoreUtil/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>$(DEVELOPMENT_LANGUAGE)</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>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "CoreUtil/CoreUtil.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 52;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tB608540827A66635003BF243 /* NSControl+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = B608540727A66635003BF243 /* NSControl+Combine.swift */; };\n\t\tB62013E927A9147600AF5386 /* Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62013E827A9147600AF5386 /* Delta.swift */; };\n\t\tB64B1E9427A4F67000AC2601 /* CoreUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = B64B1E9227A4F67000AC2601 /* CoreUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tB64B1ED027A4F71200AC2601 /* ViewPlaceholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ECF27A4F71200AC2601 /* ViewPlaceholder.swift */; };\n\t\tB64B1ED327A4F71F00AC2601 /* NS+OnAwake.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ED227A4F71F00AC2601 /* NS+OnAwake.swift */; };\n\t\tB64B1ED627A4F72D00AC2601 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ED527A4F72D00AC2601 /* Query.swift */; };\n\t\tB64B1ED927A4F73700AC2601 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1ED827A4F73700AC2601 /* Observable.swift */; };\n\t\tB64B1EDC27A4F75600AC2601 /* PipeOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EDB27A4F75600AC2601 /* PipeOperator.swift */; };\n\t\tB64B1EE327A4F79100AC2601 /* NSEvent+HotKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE027A4F79100AC2601 /* NSEvent+HotKey.swift */; };\n\t\tB64B1EE427A4F79100AC2601 /* Key.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE127A4F79100AC2601 /* Key.swift */; };\n\t\tB64B1EE527A4F79100AC2601 /* HotKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE227A4F79100AC2601 /* HotKey.swift */; };\n\t\tB64B1EF727A4F7AA00AC2601 /* Ex+Number.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EE927A4F7AA00AC2601 /* Ex+Number.swift */; };\n\t\tB64B1EFA27A4F7AA00AC2601 /* Ex+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EEC27A4F7AA00AC2601 /* Ex+Array.swift */; };\n\t\tB64B1F0027A4F7AA00AC2601 /* Ex+OptionSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EF227A4F7AA00AC2601 /* Ex+OptionSet.swift */; };\n\t\tB64B1F0127A4F7AA00AC2601 /* Ex+Clamp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1EF327A4F7AA00AC2601 /* Ex+Clamp.swift */; };\n\t\tB64B1F1627A4F80800AC2601 /* Ex+CGSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1127A4F80800AC2601 /* Ex+CGSize.swift */; };\n\t\tB64B1F1827A4F80800AC2601 /* Ex+CGPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1327A4F80800AC2601 /* Ex+CGPoint.swift */; };\n\t\tB64B1F1A27A4F80800AC2601 /* Ex+CGRect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1527A4F80800AC2601 /* Ex+CGRect.swift */; };\n\t\tB64B1F2B27A4F83500AC2601 /* Ex+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F1F27A4F83500AC2601 /* Ex+UI.swift */; };\n\t\tB64B1F2E27A4F83500AC2601 /* Ex+NSControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2227A4F83500AC2601 /* Ex+NSControl.swift */; };\n\t\tB64B1F3027A4F83500AC2601 /* Ex+NSPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2427A4F83500AC2601 /* Ex+NSPopover.swift */; };\n\t\tB64B1F3127A4F83500AC2601 /* Ex+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2527A4F83500AC2601 /* Ex+Image.swift */; };\n\t\tB64B1F3327A4F83500AC2601 /* Ex+NSEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2727A4F83500AC2601 /* Ex+NSEvent.swift */; };\n\t\tB64B1F3427A4F83500AC2601 /* Ex+NSMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2827A4F83500AC2601 /* Ex+NSMenuItem.swift */; };\n\t\tB64B1F3627A4F83500AC2601 /* Ex+NSColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F2A27A4F83500AC2601 /* Ex+NSColor.swift */; };\n\t\tB64B1F3927A4F8AD00AC2601 /* Ex+NSTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F3827A4F8AD00AC2601 /* Ex+NSTableView.swift */; };\n\t\tB64B1F3C27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F3B27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift */; };\n\t\tB64B1F6327A4FC5100AC2601 /* Promise in Frameworks */ = {isa = PBXBuildFile; productRef = B64B1F6227A4FC5100AC2601 /* Promise */; };\n\t\tB64B1F6827A4FC8A00AC2601 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = B64B1F6727A4FC8A00AC2601 /* SnapKit */; };\n\t\tB64B1F6B27A4FC8F00AC2601 /* Export.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F6A27A4FC8F00AC2601 /* Export.swift */; };\n\t\tB64B201127A50E5200AC2601 /* NSColorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B201027A50E5200AC2601 /* NSColorView.swift */; };\n\t\tB64B201A27A5103100AC2601 /* Ex+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B201927A5103100AC2601 /* Ex+CALayer.swift */; };\n\t\tB64B205927A530D700AC2601 /* NSViewController+ChainObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B205827A530D700AC2601 /* NSViewController+ChainObject.swift */; };\n\t\tB64B205C27A530E800AC2601 /* NSViewController+StateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B205B27A530E800AC2601 /* NSViewController+StateObject.swift */; };\n\t\tB64B209527A5323A00AC2601 /* Combine+ObjectBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B209427A5323A00AC2601 /* Combine+ObjectBag.swift */; };\n\t\tB66F0D4C27B6176A00DC812D /* Terminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66F0D4B27B6176A00DC812D /* Terminal.swift */; };\n\t\tB680A79127A681F8007CB707 /* NSTextField+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A79027A681F8007CB707 /* NSTextField+Combine.swift */; };\n\t\tB680A86527A8C58C007CB707 /* Combine+Peek.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A86427A8C58C007CB707 /* Combine+Peek.swift */; };\n\t\tB680A89C27A8DA16007CB707 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A89B27A8DA16007CB707 /* Action.swift */; };\n\t\tB680A8A027A8DA78007CB707 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = B680A89F27A8DA78007CB707 /* OrderedCollections */; };\n\t\tB680A8A227A8DA78007CB707 /* DequeModule in Frameworks */ = {isa = PBXBuildFile; productRef = B680A8A127A8DA78007CB707 /* DequeModule */; };\n\t\tB680A8A427A8DA78007CB707 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = B680A8A327A8DA78007CB707 /* Collections */; };\n\t\tB6A93D2B27CBA2EB003A6D7F /* Zip3Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A93D2A27CBA2EB003A6D7F /* Zip3Sequence.swift */; };\n\t\tB6AC27A327AA6F5C000FD713 /* Reachability+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AC27A127AA6F5B000FD713 /* Reachability+Publisher.swift */; };\n\t\tB6AC27A427AA6F5C000FD713 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AC27A227AA6F5C000FD713 /* Reachability.swift */; };\n\t\tB6B5727A27AC223A0069DBA7 /* RestorableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5727927AC223A0069DBA7 /* RestorableState.swift */; };\n\t\tB6B5727D27AC22480069DBA7 /* RestorableData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5727C27AC22480069DBA7 /* RestorableData.swift */; };\n\t\tB6BD80FA27B8B06900152AB9 /* Ex+Localize.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BD80F927B8B06900152AB9 /* Ex+Localize.swift */; };\n\t\tB6D1AF3D27A60A210022FED2 /* ExceptionHanlder.m in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AF3A27A60A210022FED2 /* ExceptionHanlder.m */; };\n\t\tB6D1AF3E27A60A210022FED2 /* ExceptionHanlder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6D1AF3B27A60A210022FED2 /* ExceptionHanlder.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tB6D1AF3F27A60A210022FED2 /* ExceptionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AF3C27A60A210022FED2 /* ExceptionHandler.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\tB608540727A66635003BF243 /* NSControl+Combine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"NSControl+Combine.swift\"; sourceTree = \"<group>\"; };\n\t\tB62013E827A9147600AF5386 /* Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Delta.swift; sourceTree = \"<group>\"; };\n\t\tB64B1E8F27A4F67000AC2601 /* CoreUtil.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreUtil.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tB64B1E9227A4F67000AC2601 /* CoreUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreUtil.h; sourceTree = \"<group>\"; };\n\t\tB64B1E9327A4F67000AC2601 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tB64B1ECF27A4F71200AC2601 /* ViewPlaceholder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewPlaceholder.swift; sourceTree = \"<group>\"; };\n\t\tB64B1ED227A4F71F00AC2601 /* NS+OnAwake.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"NS+OnAwake.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1ED527A4F72D00AC2601 /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = \"<group>\"; };\n\t\tB64B1ED827A4F73700AC2601 /* Observable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = \"<group>\"; };\n\t\tB64B1EDB27A4F75600AC2601 /* PipeOperator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PipeOperator.swift; sourceTree = \"<group>\"; };\n\t\tB64B1EE027A4F79100AC2601 /* NSEvent+HotKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"NSEvent+HotKey.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1EE127A4F79100AC2601 /* Key.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Key.swift; sourceTree = \"<group>\"; };\n\t\tB64B1EE227A4F79100AC2601 /* HotKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HotKey.swift; sourceTree = \"<group>\"; };\n\t\tB64B1EE927A4F7AA00AC2601 /* Ex+Number.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+Number.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1EEC27A4F7AA00AC2601 /* Ex+Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+Array.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1EF227A4F7AA00AC2601 /* Ex+OptionSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+OptionSet.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1EF327A4F7AA00AC2601 /* Ex+Clamp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+Clamp.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F1127A4F80800AC2601 /* Ex+CGSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+CGSize.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F1327A4F80800AC2601 /* Ex+CGPoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+CGPoint.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F1527A4F80800AC2601 /* Ex+CGRect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+CGRect.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F1F27A4F83500AC2601 /* Ex+UI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+UI.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F2227A4F83500AC2601 /* Ex+NSControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+NSControl.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F2427A4F83500AC2601 /* Ex+NSPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+NSPopover.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F2527A4F83500AC2601 /* Ex+Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+Image.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F2727A4F83500AC2601 /* Ex+NSEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+NSEvent.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F2827A4F83500AC2601 /* Ex+NSMenuItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+NSMenuItem.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F2A27A4F83500AC2601 /* Ex+NSColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+NSColor.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F3827A4F8AD00AC2601 /* Ex+NSTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Ex+NSTableView.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F3B27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Ex+NSEdgeInsets.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1F6A27A4FC8F00AC2601 /* Export.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Export.swift; sourceTree = \"<group>\"; };\n\t\tB64B201027A50E5200AC2601 /* NSColorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSColorView.swift; sourceTree = \"<group>\"; };\n\t\tB64B201927A5103100AC2601 /* Ex+CALayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+CALayer.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B205827A530D700AC2601 /* NSViewController+ChainObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"NSViewController+ChainObject.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B205B27A530E800AC2601 /* NSViewController+StateObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"NSViewController+StateObject.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B209427A5323A00AC2601 /* Combine+ObjectBag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Combine+ObjectBag.swift\"; sourceTree = \"<group>\"; };\n\t\tB66F0D4B27B6176A00DC812D /* Terminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Terminal.swift; sourceTree = \"<group>\"; };\n\t\tB680A79027A681F8007CB707 /* NSTextField+Combine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"NSTextField+Combine.swift\"; sourceTree = \"<group>\"; };\n\t\tB680A86427A8C58C007CB707 /* Combine+Peek.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Combine+Peek.swift\"; sourceTree = \"<group>\"; };\n\t\tB680A89B27A8DA16007CB707 /* Action.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = \"<group>\"; };\n\t\tB6A93D2A27CBA2EB003A6D7F /* Zip3Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zip3Sequence.swift; sourceTree = \"<group>\"; };\n\t\tB6AC27A127AA6F5B000FD713 /* Reachability+Publisher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Reachability+Publisher.swift\"; sourceTree = \"<group>\"; };\n\t\tB6AC27A227AA6F5C000FD713 /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = \"<group>\"; };\n\t\tB6B5727927AC223A0069DBA7 /* RestorableState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorableState.swift; sourceTree = \"<group>\"; };\n\t\tB6B5727C27AC22480069DBA7 /* RestorableData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorableData.swift; sourceTree = \"<group>\"; };\n\t\tB6BD80F927B8B06900152AB9 /* Ex+Localize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Ex+Localize.swift\"; sourceTree = \"<group>\"; };\n\t\tB6D1AF3A27A60A210022FED2 /* ExceptionHanlder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExceptionHanlder.m; sourceTree = \"<group>\"; };\n\t\tB6D1AF3B27A60A210022FED2 /* ExceptionHanlder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionHanlder.h; sourceTree = \"<group>\"; };\n\t\tB6D1AF3C27A60A210022FED2 /* ExceptionHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExceptionHandler.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tB64B1E8C27A4F67000AC2601 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB64B1F6327A4FC5100AC2601 /* Promise in Frameworks */,\n\t\t\t\tB680A8A227A8DA78007CB707 /* DequeModule in Frameworks */,\n\t\t\t\tB680A8A427A8DA78007CB707 /* Collections in Frameworks */,\n\t\t\t\tB64B1F6827A4FC8A00AC2601 /* SnapKit in Frameworks */,\n\t\t\t\tB680A8A027A8DA78007CB707 /* OrderedCollections in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tB64B1E8527A4F67000AC2601 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1E9127A4F67000AC2601 /* CoreUtil */,\n\t\t\t\tB64B1E9027A4F67000AC2601 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1E9027A4F67000AC2601 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1E8F27A4F67000AC2601 /* CoreUtil.framework */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1E9127A4F67000AC2601 /* CoreUtil */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1E9227A4F67000AC2601 /* CoreUtil.h */,\n\t\t\t\tB64B1E9327A4F67000AC2601 /* Info.plist */,\n\t\t\t\tB64B1F6A27A4FC8F00AC2601 /* Export.swift */,\n\t\t\t\tB6D1AF3927A60A210022FED2 /* ExceptionHanlder */,\n\t\t\t\tB64B1F6D27A4FC9100AC2601 /* Class */,\n\t\t\t\tB64B1EE727A4F79800AC2601 /* Extensions */,\n\t\t\t\tB64B1EDF27A4F79100AC2601 /* HotKey */,\n\t\t\t);\n\t\t\tpath = CoreUtil;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1EDF27A4F79100AC2601 /* HotKey */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1EE027A4F79100AC2601 /* NSEvent+HotKey.swift */,\n\t\t\t\tB64B1EE127A4F79100AC2601 /* Key.swift */,\n\t\t\t\tB64B1EE227A4F79100AC2601 /* HotKey.swift */,\n\t\t\t);\n\t\t\tpath = HotKey;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1EE727A4F79800AC2601 /* Extensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B208E27A5322A00AC2601 /* Combine */,\n\t\t\t\tB64B1F1E27A4F83500AC2601 /* UI */,\n\t\t\t\tB64B1F1027A4F80800AC2601 /* CoreGraphics */,\n\t\t\t\tB64B1EE827A4F7AA00AC2601 /* Swift */,\n\t\t\t);\n\t\t\tpath = Extensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1EE827A4F7AA00AC2601 /* Swift */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1EE927A4F7AA00AC2601 /* Ex+Number.swift */,\n\t\t\t\tB64B1EEC27A4F7AA00AC2601 /* Ex+Array.swift */,\n\t\t\t\tB64B1EF227A4F7AA00AC2601 /* Ex+OptionSet.swift */,\n\t\t\t\tB64B1EF327A4F7AA00AC2601 /* Ex+Clamp.swift */,\n\t\t\t\tB6BD80F927B8B06900152AB9 /* Ex+Localize.swift */,\n\t\t\t);\n\t\t\tpath = Swift;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1F1027A4F80800AC2601 /* CoreGraphics */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1F1127A4F80800AC2601 /* Ex+CGSize.swift */,\n\t\t\t\tB64B1F1327A4F80800AC2601 /* Ex+CGPoint.swift */,\n\t\t\t\tB64B1F1527A4F80800AC2601 /* Ex+CGRect.swift */,\n\t\t\t);\n\t\t\tpath = CoreGraphics;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1F1E27A4F83500AC2601 /* UI */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B201927A5103100AC2601 /* Ex+CALayer.swift */,\n\t\t\t\tB64B1F1F27A4F83500AC2601 /* Ex+UI.swift */,\n\t\t\t\tB64B1F2227A4F83500AC2601 /* Ex+NSControl.swift */,\n\t\t\t\tB64B1F2427A4F83500AC2601 /* Ex+NSPopover.swift */,\n\t\t\t\tB64B1F2527A4F83500AC2601 /* Ex+Image.swift */,\n\t\t\t\tB64B1F2727A4F83500AC2601 /* Ex+NSEvent.swift */,\n\t\t\t\tB64B1F2827A4F83500AC2601 /* Ex+NSMenuItem.swift */,\n\t\t\t\tB64B1F2A27A4F83500AC2601 /* Ex+NSColor.swift */,\n\t\t\t\tB64B1F3827A4F8AD00AC2601 /* Ex+NSTableView.swift */,\n\t\t\t\tB64B1F3B27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift */,\n\t\t\t);\n\t\t\tpath = UI;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1F6D27A4FC9100AC2601 /* Class */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6A93D2A27CBA2EB003A6D7F /* Zip3Sequence.swift */,\n\t\t\t\tB6AC27A227AA6F5C000FD713 /* Reachability.swift */,\n\t\t\t\tB6AC27A127AA6F5B000FD713 /* Reachability+Publisher.swift */,\n\t\t\t\tB64B201027A50E5200AC2601 /* NSColorView.swift */,\n\t\t\t\tB64B1ECF27A4F71200AC2601 /* ViewPlaceholder.swift */,\n\t\t\t\tB64B1ED527A4F72D00AC2601 /* Query.swift */,\n\t\t\t\tB680A89B27A8DA16007CB707 /* Action.swift */,\n\t\t\t\tB64B205827A530D700AC2601 /* NSViewController+ChainObject.swift */,\n\t\t\t\tB64B205B27A530E800AC2601 /* NSViewController+StateObject.swift */,\n\t\t\t\tB62013E827A9147600AF5386 /* Delta.swift */,\n\t\t\t\tB64B1ED827A4F73700AC2601 /* Observable.swift */,\n\t\t\t\tB64B1EDB27A4F75600AC2601 /* PipeOperator.swift */,\n\t\t\t\tB64B1ED227A4F71F00AC2601 /* NS+OnAwake.swift */,\n\t\t\t\tB6B5727927AC223A0069DBA7 /* RestorableState.swift */,\n\t\t\t\tB6B5727C27AC22480069DBA7 /* RestorableData.swift */,\n\t\t\t\tB66F0D4B27B6176A00DC812D /* Terminal.swift */,\n\t\t\t);\n\t\t\tpath = Class;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B208E27A5322A00AC2601 /* Combine */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB608540727A66635003BF243 /* NSControl+Combine.swift */,\n\t\t\t\tB680A79027A681F8007CB707 /* NSTextField+Combine.swift */,\n\t\t\t\tB64B209427A5323A00AC2601 /* Combine+ObjectBag.swift */,\n\t\t\t\tB680A86427A8C58C007CB707 /* Combine+Peek.swift */,\n\t\t\t);\n\t\t\tpath = Combine;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6D1AF3927A60A210022FED2 /* ExceptionHanlder */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6D1AF3A27A60A210022FED2 /* ExceptionHanlder.m */,\n\t\t\t\tB6D1AF3B27A60A210022FED2 /* ExceptionHanlder.h */,\n\t\t\t\tB6D1AF3C27A60A210022FED2 /* ExceptionHandler.swift */,\n\t\t\t);\n\t\t\tpath = ExceptionHanlder;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\tB64B1E8A27A4F67000AC2601 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB64B1E9427A4F67000AC2601 /* CoreUtil.h in Headers */,\n\t\t\t\tB6D1AF3E27A60A210022FED2 /* ExceptionHanlder.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\tB64B1E8E27A4F67000AC2601 /* CoreUtil */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = B64B1E9727A4F67000AC2601 /* Build configuration list for PBXNativeTarget \"CoreUtil\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tB64B1E8A27A4F67000AC2601 /* Headers */,\n\t\t\t\tB64B1E8B27A4F67000AC2601 /* Sources */,\n\t\t\t\tB64B1E8C27A4F67000AC2601 /* Frameworks */,\n\t\t\t\tB64B1E8D27A4F67000AC2601 /* 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 = CoreUtil;\n\t\t\tpackageProductDependencies = (\n\t\t\t\tB64B1F6227A4FC5100AC2601 /* Promise */,\n\t\t\t\tB64B1F6727A4FC8A00AC2601 /* SnapKit */,\n\t\t\t\tB680A89F27A8DA78007CB707 /* OrderedCollections */,\n\t\t\t\tB680A8A127A8DA78007CB707 /* DequeModule */,\n\t\t\t\tB680A8A327A8DA78007CB707 /* Collections */,\n\t\t\t);\n\t\t\tproductName = CoreUtil;\n\t\t\tproductReference = B64B1E8F27A4F67000AC2601 /* CoreUtil.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tB64B1E8627A4F67000AC2601 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1240;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tB64B1E8E27A4F67000AC2601 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 12.4;\n\t\t\t\t\t\tLastSwiftMigration = 1240;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = B64B1E8927A4F67000AC2601 /* Build configuration list for PBXProject \"CoreUtil\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\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 = B64B1E8527A4F67000AC2601;\n\t\t\tpackageReferences = (\n\t\t\t\tB64B1F6127A4FC5100AC2601 /* XCRemoteSwiftPackageReference \"Promise\" */,\n\t\t\t\tB64B1F6627A4FC8A00AC2601 /* XCRemoteSwiftPackageReference \"SnapKit\" */,\n\t\t\t\tB680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference \"swift-collections\" */,\n\t\t\t);\n\t\t\tproductRefGroup = B64B1E9027A4F67000AC2601 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tB64B1E8E27A4F67000AC2601 /* CoreUtil */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tB64B1E8D27A4F67000AC2601 /* 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\tB64B1E8B27A4F67000AC2601 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB6D1AF3D27A60A210022FED2 /* ExceptionHanlder.m in Sources */,\n\t\t\t\tB680A89C27A8DA16007CB707 /* Action.swift in Sources */,\n\t\t\t\tB64B1F6B27A4FC8F00AC2601 /* Export.swift in Sources */,\n\t\t\t\tB64B205C27A530E800AC2601 /* NSViewController+StateObject.swift in Sources */,\n\t\t\t\tB608540827A66635003BF243 /* NSControl+Combine.swift in Sources */,\n\t\t\t\tB64B1F3327A4F83500AC2601 /* Ex+NSEvent.swift in Sources */,\n\t\t\t\tB64B205927A530D700AC2601 /* NSViewController+ChainObject.swift in Sources */,\n\t\t\t\tB66F0D4C27B6176A00DC812D /* Terminal.swift in Sources */,\n\t\t\t\tB64B1EE427A4F79100AC2601 /* Key.swift in Sources */,\n\t\t\t\tB64B1F0027A4F7AA00AC2601 /* Ex+OptionSet.swift in Sources */,\n\t\t\t\tB6AC27A327AA6F5C000FD713 /* Reachability+Publisher.swift in Sources */,\n\t\t\t\tB64B1F2E27A4F83500AC2601 /* Ex+NSControl.swift in Sources */,\n\t\t\t\tB64B1F1627A4F80800AC2601 /* Ex+CGSize.swift in Sources */,\n\t\t\t\tB6B5727A27AC223A0069DBA7 /* RestorableState.swift in Sources */,\n\t\t\t\tB64B1ED927A4F73700AC2601 /* Observable.swift in Sources */,\n\t\t\t\tB64B201127A50E5200AC2601 /* NSColorView.swift in Sources */,\n\t\t\t\tB64B1EE327A4F79100AC2601 /* NSEvent+HotKey.swift in Sources */,\n\t\t\t\tB64B201A27A5103100AC2601 /* Ex+CALayer.swift in Sources */,\n\t\t\t\tB680A79127A681F8007CB707 /* NSTextField+Combine.swift in Sources */,\n\t\t\t\tB64B1EFA27A4F7AA00AC2601 /* Ex+Array.swift in Sources */,\n\t\t\t\tB64B1F1A27A4F80800AC2601 /* Ex+CGRect.swift in Sources */,\n\t\t\t\tB64B1F3C27A4F8C400AC2601 /* Ex+NSEdgeInsets.swift in Sources */,\n\t\t\t\tB64B1F3427A4F83500AC2601 /* Ex+NSMenuItem.swift in Sources */,\n\t\t\t\tB64B1F3027A4F83500AC2601 /* Ex+NSPopover.swift in Sources */,\n\t\t\t\tB64B1EE527A4F79100AC2601 /* HotKey.swift in Sources */,\n\t\t\t\tB64B1F3627A4F83500AC2601 /* Ex+NSColor.swift in Sources */,\n\t\t\t\tB64B209527A5323A00AC2601 /* Combine+ObjectBag.swift in Sources */,\n\t\t\t\tB64B1EDC27A4F75600AC2601 /* PipeOperator.swift in Sources */,\n\t\t\t\tB6BD80FA27B8B06900152AB9 /* Ex+Localize.swift in Sources */,\n\t\t\t\tB64B1F1827A4F80800AC2601 /* Ex+CGPoint.swift in Sources */,\n\t\t\t\tB680A86527A8C58C007CB707 /* Combine+Peek.swift in Sources */,\n\t\t\t\tB64B1ED027A4F71200AC2601 /* ViewPlaceholder.swift in Sources */,\n\t\t\t\tB6A93D2B27CBA2EB003A6D7F /* Zip3Sequence.swift in Sources */,\n\t\t\t\tB64B1F3127A4F83500AC2601 /* Ex+Image.swift in Sources */,\n\t\t\t\tB64B1ED627A4F72D00AC2601 /* Query.swift in Sources */,\n\t\t\t\tB64B1F2B27A4F83500AC2601 /* Ex+UI.swift in Sources */,\n\t\t\t\tB64B1F3927A4F8AD00AC2601 /* Ex+NSTableView.swift in Sources */,\n\t\t\t\tB64B1F0127A4F7AA00AC2601 /* Ex+Clamp.swift in Sources */,\n\t\t\t\tB64B1EF727A4F7AA00AC2601 /* Ex+Number.swift in Sources */,\n\t\t\t\tB62013E927A9147600AF5386 /* Delta.swift in Sources */,\n\t\t\t\tB6D1AF3F27A60A210022FED2 /* ExceptionHandler.swift in Sources */,\n\t\t\t\tB64B1ED327A4F71F00AC2601 /* NS+OnAwake.swift in Sources */,\n\t\t\t\tB6AC27A427AA6F5C000FD713 /* Reachability.swift in Sources */,\n\t\t\t\tB6B5727D27AC22480069DBA7 /* RestorableData.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\tB64B1E9527A4F67000AC2601 /* 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_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\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_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\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\tGCC_C_LANGUAGE_STANDARD = gnu11;\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.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tB64B1E9627A4F67000AC2601 /* 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_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\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_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\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\tGCC_C_LANGUAGE_STANDARD = gnu11;\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.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tB64B1E9827A4F67000AC2601 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDEVELOPMENT_TEAM = T5HMUWWK5R;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = CoreUtil/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\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 = 10.15;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.yuki.CoreUtil;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ENFORCE_EXCLUSIVE_ACCESS = off;\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\tB64B1E9927A4F67000AC2601 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDEVELOPMENT_TEAM = T5HMUWWK5R;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = CoreUtil/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\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 = 10.15;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.yuki.CoreUtil;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_ENFORCE_EXCLUSIVE_ACCESS = off;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tB64B1E8927A4F67000AC2601 /* Build configuration list for PBXProject \"CoreUtil\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tB64B1E9527A4F67000AC2601 /* Debug */,\n\t\t\t\tB64B1E9627A4F67000AC2601 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tB64B1E9727A4F67000AC2601 /* Build configuration list for PBXNativeTarget \"CoreUtil\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tB64B1E9827A4F67000AC2601 /* Debug */,\n\t\t\t\tB64B1E9927A4F67000AC2601 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\n/* Begin XCRemoteSwiftPackageReference section */\n\t\tB64B1F6127A4FC5100AC2601 /* XCRemoteSwiftPackageReference \"Promise\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/ObuchiYuki/Promise.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 1.0.9;\n\t\t\t};\n\t\t};\n\t\tB64B1F6627A4FC8A00AC2601 /* XCRemoteSwiftPackageReference \"SnapKit\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/SnapKit/SnapKit.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 5.0.1;\n\t\t\t};\n\t\t};\n\t\tB680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference \"swift-collections\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/apple/swift-collections\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 1.0.2;\n\t\t\t};\n\t\t};\n/* End XCRemoteSwiftPackageReference section */\n\n/* Begin XCSwiftPackageProductDependency section */\n\t\tB64B1F6227A4FC5100AC2601 /* Promise */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B64B1F6127A4FC5100AC2601 /* XCRemoteSwiftPackageReference \"Promise\" */;\n\t\t\tproductName = Promise;\n\t\t};\n\t\tB64B1F6727A4FC8A00AC2601 /* SnapKit */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B64B1F6627A4FC8A00AC2601 /* XCRemoteSwiftPackageReference \"SnapKit\" */;\n\t\t\tproductName = SnapKit;\n\t\t};\n\t\tB680A89F27A8DA78007CB707 /* OrderedCollections */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference \"swift-collections\" */;\n\t\t\tproductName = OrderedCollections;\n\t\t};\n\t\tB680A8A127A8DA78007CB707 /* DequeModule */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference \"swift-collections\" */;\n\t\t\tproductName = DequeModule;\n\t\t};\n\t\tB680A8A327A8DA78007CB707 /* Collections */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B680A89E27A8DA78007CB707 /* XCRemoteSwiftPackageReference \"swift-collections\" */;\n\t\t\tproductName = Collections;\n\t\t};\n/* End XCSwiftPackageProductDependency section */\n\t};\n\trootObject = B64B1E8627A4F67000AC2601 /* Project object */;\n}\n"
  },
  {
    "path": "CoreUtil/CoreUtil.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "CoreUtil/CoreUtil.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": "DevToys/DevToys/App/AppViewController.swift",
    "content": "//\n//  ViewController.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\nimport CoreUtil\n\nfinal class AppViewController: NSSplitViewController {\n    private let sidebarController = SidebarViewController()\n    private let bodyController = BodyViewController()\n    \n    override func chainObjectDidLoad() {\n        // The object chain will be broken on `addSplitViewItem`. So call the manual chain.\n        self.sidebarController.chainObject = chainObject\n        self.bodyController.chainObject = chainObject\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        let sidebarItem = NSSplitViewItem(sidebarWithViewController: sidebarController)\n        sidebarItem.minimumThickness = 200\n        sidebarItem.canCollapse = false\n        self.addSplitViewItem(sidebarItem)\n        \n        let bodyItem = NSSplitViewItem(viewController: bodyController)\n        bodyItem.minimumThickness = 480\n        bodyItem.canCollapse = false\n        self.addSplitViewItem(bodyItem)\n        \n        splitView.setPosition(220, ofDividerAt: 0)\n        \n        self.splitView.autosaveName = \"app.splitv\"\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/App/AppWindowController.swift",
    "content": "//\n//  AppWindowController.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\nimport Darwin\nimport AppKit\n\nfinal class AppWindowController: NSWindowController {\n    private let appModel = AppModel()\n    \n    private lazy var separatorItem = NSTrackingSeparatorToolbarItem(\n        identifier: AppWindowController.separatorItemIdentifier, splitView: splitViewController.splitView, dividerIndex: 0\n    )\n    private lazy var disclosureItem = NSToolbarItem(\n        itemIdentifier: AppWindowController.disclosureItemIdentifier\n    )\n    private var splitViewController: NSSplitViewController {\n        self.window?.contentViewController as! NSSplitViewController\n    }\n    \n    @objc private func toggleSidebar() {\n        splitViewController.splitViewItems[0].animator().isCollapsed.toggle()\n    }\n    \n    override func windowDidLoad() {        \n        self.contentViewController?.chainObject = appModel\n        \n        self.appModel.settings.$appearanceType\n            .sink{\n                switch $0 {\n                case .useSystemSettings: self.window?.appearance = nil\n                case .darkMode: self.window?.appearance = NSAppearance(named: .darkAqua)\n                case .lightMode: self.window?.appearance = NSAppearance(named: .aqua)\n                }\n            }\n            .store(in: &objectBag)\n        self.appModel.$tool\n            .sink{[unowned self] in self.window?.title = $0.title }.store(in: &objectBag)\n        \n        guard let toolbar = self.window?.toolbar else { return assertionFailure() }\n        toolbar.delegate = self\n        toolbar.allowsUserCustomization = true\n\n        disclosureItem.view = NSButton(title: \"Sidebar\", image: R.Image.sidebarDisclosure) => {\n            $0.bezelStyle = .texturedRounded\n            $0.actionPublisher.sink{[unowned self] in toggleSidebar() }.store(in: &objectBag)\n        }\n    }\n}\n\nextension AppWindowController: NSToolbarDelegate {\n    \n    static let separatorItemIdentifier = NSToolbarItem.Identifier(\"separator\")\n    static let disclosureItemIdentifier = NSToolbarItem.Identifier(\"disclosure\")\n    \n    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {\n        if #available(macOS 11.0, *) {\n            return [AppWindowController.disclosureItemIdentifier, AppWindowController.separatorItemIdentifier]\n        } else {\n            return [AppWindowController.disclosureItemIdentifier]\n        }\n    }\n    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {\n        self.toolbarDefaultItemIdentifiers(toolbar)\n    }\n    func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {\n        []\n    }\n    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {\n        if #available(macOS 11.0, *) {\n            if itemIdentifier == AppWindowController.separatorItemIdentifier {\n                return self.separatorItem\n            }\n        }\n        if itemIdentifier == AppWindowController.disclosureItemIdentifier {\n            return self.disclosureItem\n        }\n        return nil\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\n\n@main\nclass AppDelegate: NSObject, NSApplicationDelegate { \n    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { true }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/BodyViewController.swift",
    "content": "//\n//  BodyViewController.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class BodyViewController: NSViewController {\n    private let placeholderView = NSPlaceholderView()\n    private var contentViewController: NSViewController?\n    \n    override func loadView() { self.view = placeholderView }\n    \n    override func chainObjectDidLoad() {\n        self.appModel.$tool\n            .sink{[unowned self] in replaceTool($0) }.store(in: &objectBag)\n        self.appModel.$searchQuery\n            .sink{[unowned self] in handleQuery($0) }.store(in: &objectBag)\n    }\n    \n    private func handleQuery(_ query: String) {\n        if query.isEmpty {\n            self.replaceTool(appModel.tool)\n        } else {\n            self.replaceTool(.search)\n        }\n    }\n    \n    private func replaceTool(_ tool: Tool) {\n        self.contentViewController?.removeFromParent()\n        self.addChild(tool.viewController)\n        self.contentViewController = tool.viewController\n        self.placeholderView.contentView = tool.viewController.view\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/Base64DecoderView+.swift",
    "content": "//\n//  Base64Decoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class Base64DecoderViewController: NSViewController {\n    private let cell = Base64DecoderView()\n    \n    @RestorableState(\"base64.sourceType\") private var sourceType = SourceType.text\n    @RestorableState(\"base64.rawString\") private var rawString = defaultRawString\n    @Observable private var formattedString = defaultBase64String\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.cell.inputTextSection.stringPublisher\n            .sink{[unowned self] in self.rawString = $0; self.formattedString = encode($0) }.store(in: &objectBag)\n        self.cell.encodeTextSection.stringPublisher\n            .sink{[unowned self] in self.formattedString = $0; self.rawString = decode($0) }.store(in: &objectBag)\n        self.cell.sourceTypePicker.itemPublisher\n            .sink{[unowned self] in self.sourceType = $0 }.store(in: &objectBag)\n        self.cell.fileDrop.urlsPublisher.compactMap{ $0.first }\n            .sink{[unowned self] in self.formattedString = self.encodeFile($0) }.store(in: &objectBag)\n        self.cell.exportButton.actionPublisher\n            .sink{[unowned self] in self.exportFile() }.store(in: &objectBag)\n        \n        self.$sourceType\n            .sink{[unowned self] in self.cell.sourceTypePicker.selectedItem = $0; updateEncodeView($0) }.store(in: &objectBag)\n        self.$rawString\n            .sink{[unowned self] in self.cell.inputTextSection.string = $0 }.store(in: &objectBag)\n        self.$formattedString\n            .sink{[unowned self] in self.cell.encodeTextSection.string = $0 }.store(in: &objectBag)\n    }\n    \n    private func updateEncodeView(_ sourceType: SourceType) {\n        switch sourceType {\n        case .file:\n            self.cell.inputSectionContainer.contentView = cell.fileDropSection\n        case .text:\n            self.cell.inputSectionContainer.contentView = cell.inputTextSection\n            self.formattedString = self.encode(rawString)\n        }\n    }\n    \n    private func exportFile() {\n        let panel = NSSavePanel()\n        guard let data = Data(base64Encoded: formattedString), panel.runModal() == .OK, let url = panel.url else { return }\n        \n        do {\n            try data.write(to: url)\n        } catch {\n            NSSound.beep()\n        }\n    }\n    private func encodeFile(_ url: URL) -> String {\n        (try? Data(contentsOf: url).base64EncodedString()) ?? \"[Encode Failed]\"\n    }\n    private func encode(_ string: String) -> String {\n        string.data(using: .utf8)!.base64EncodedString()\n    }\n    private func decode(_ string: String) -> String {\n        String(data: Data(base64Encoded: string) ?? Data(), encoding: .utf8) ?? \"Not String\"\n    }\n}\n\nprivate enum SourceType: String, TextItem {\n    case text = \"Text Source\"\n    case file = \"File Source\"\n    var title: String { rawValue.localized() }\n}\n\nfinal private class Base64DecoderView: Page {\n    let sourceTypePicker = EnumPopupButton<SourceType>()\n    \n    let fileDrop = FileDrop()\n    let exportButton = SectionButton(title: \"Export\".localized(), image: R.Image.export)\n    let inputSectionContainer = NSPlaceholderView()\n    let inputTextSection = TextViewSection(title: \"Text\".localized(), options: [.all])\n    lazy var fileDropSection = Section(title: \"File\".localized(), items: [fileDrop], toolbarItems: [exportButton])\n    \n    let encodeTextSection = TextViewSection(title: \"Encoded\".localized(), options: [.all])\n    \n    override func layout() {\n        super.layout()\n        let halfHeight = max(200, (self.frame.height - 190) / 2)\n        \n        self.fileDropSection.snp.remakeConstraints{ make in\n            make.height.equalTo(halfHeight)\n        }\n        self.inputTextSection.snp.remakeConstraints{ make in\n            make.height.equalTo(halfHeight)\n        }\n        self.encodeTextSection.snp.remakeConstraints{ make in\n            make.height.equalTo(halfHeight)\n        }\n    }\n    \n    override func onAwake() {            \n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.convert, title: \"Source Type\".localized(), control: sourceTypePicker)\n        ]))\n        self.inputSectionContainer.contentView = inputTextSection\n        self.addSection(inputSectionContainer)\n        self.addSection(inputTextSection)\n        self.addSection(encodeTextSection)\n    }\n}\n\nprivate let defaultRawString = \"An Open-Source Swiss Army knife for developers. DevToys helps in everyday tasks like formatting JSON, comparing text, testing RegExp. No need to use many untruthful websites to do simple tasks with your data. With Smart Detection, DevToys is able to detect the best tool that can treat the data you copied in the clipboard of your Windows. Compact overlay lets you keep the app in small and on top of other windows. Multiple instances of the app can be used at once.\"\n\nprivate let defaultBase64String = \"QW4gT3Blbi1Tb3VyY2UgU3dpc3MgQXJteSBrbmlmZSBmb3IgZGV2ZWxvcGVycy4KRGV2VG95cyBoZWxwcyBpbiBldmVyeWRheSB0YXNrcyBsaWtlIGZvcm1hdHRpbmcgSlNPTiwgY29tcGFyaW5nIHRleHQsIHRlc3RpbmcgUmVnRXhwLiBObyBuZWVkIHRvIHVzZSBtYW55IHVudHJ1dGhmdWwgd2Vic2l0ZXMgdG8gZG8gc2ltcGxlIHRhc2tzIHdpdGggeW91ciBkYXRhLiBXaXRoIFNtYXJ0IERldGVjdGlvbiwgRGV2VG95cyBpcyBhYmxlIHRvIGRldGVjdCB0aGUgYmVzdCB0b29sIHRoYXQgY2FuIHRyZWF0IHRoZSBkYXRhIHlvdSBjb3BpZWQgaW4gdGhlIGNsaXBib2FyZCBvZiB5b3VyIFdpbmRvd3MuIENvbXBhY3Qgb3ZlcmxheSBsZXRzIHlvdSBrZWVwIHRoZSBhcHAgaW4gc21hbGwgYW5kIG9uIHRvcCBvZiBvdGhlciB3aW5kb3dzLiBNdWx0aXBsZSBpbnN0YW5jZXMgb2YgdGhlIGFwcCBjYW4gYmUgdXNlZCBhdCBvbmNlLg==\"\n"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/HTMLDecoderView+.swift",
    "content": "//\n//  HTMLDecoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\nimport HTMLEntities\n\nfinal class HTMLDecoderViewController: NSViewController {\n    private let cell = HTMLDecoderView()\n    \n    @RestorableState(\"html.rawString\") var rawString = \"<script>alert(\\\"abc\\\")</script>\"\n    @RestorableState(\"html.formattedString\") var formattedString = \"&#x3C;script&#x3E;alert(&#x22;abc&#x22;)&#x3C;/script&#x3E;\"\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.cell.decodeTextSection.stringPublisher\n            .sink{[unowned self] in self.rawString = $0; self.formattedString = $0.htmlEscape() }.store(in: &objectBag)\n        self.cell.encodeTextSection.stringPublisher\n            .sink{[unowned self] in self.formattedString = $0; self.rawString = $0.htmlUnescape() }.store(in: &objectBag)\n        \n        self.$rawString\n            .sink{[unowned self] in self.cell.decodeTextSection.string = $0 }.store(in: &objectBag)\n        self.$formattedString\n            .sink{[unowned self] in self.cell.encodeTextSection.string = $0 }.store(in: &objectBag)\n    }\n}\n\nfinal private class HTMLDecoderView: Page {\n    let decodeTextSection = CodeViewSection(title: \"Decoded\".localized(), options: [.all], language: .xml)\n    let encodeTextSection = TextViewSection(title: \"Encoded\".localized(), options: [.all])\n    \n    override func layout() {\n        super.layout()\n        let halfHeight = max(200, (self.frame.height - 100) / 2)\n        \n        self.decodeTextSection.snp.remakeConstraints{ make in\n            make.height.equalTo(halfHeight)\n        }\n        self.encodeTextSection.snp.remakeConstraints{ make in\n            make.height.equalTo(halfHeight)\n        }\n    }\n    \n    override func onAwake() {        \n        self.addSection(decodeTextSection)\n        self.addSection(encodeTextSection)\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/JWTDecoderView+.swift",
    "content": "//\n//  JWTDecoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class JWTDecoderViewController: NSViewController {\n    private let cell = JWTDecoderView()\n    \n    @RestorableState(\"jwt.token\") var token = defaultToken\n    @RestorableState(\"jwt.header\") var header = defaultHeader\n    @RestorableState(\"jwt.payload\") var payload = defaultPayload\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$token\n            .sink{[unowned self] in self.cell.tokenTextSection.string = $0 }.store(in: &objectBag)\n        self.$header\n            .sink{[unowned self] in self.cell.headerCodeSection.string = $0 }.store(in: &objectBag)\n        self.$payload\n            .sink{[unowned self] in self.cell.payloadCodeSection.string = $0 }.store(in: &objectBag)\n        \n        self.cell.tokenTextSection.stringPublisher\n            .sink{[unowned self] in\n                self.token = $0\n                guard let (header, payload) = self.decodeJWT($0) else {\n                    self.header = \"[Decode Failed]\"\n                    self.payload = \"[Decode Failed]\"\n                    return\n                }\n                \n                self.header = header\n                self.payload = payload\n            }\n            .store(in: &objectBag)\n    }\n    \n    private func decodeJWT(_ token: String) -> (header: String, payload: String)? {\n        let components = token.split(separator: \".\").map{ String($0) }\n        \n        guard components.count == 3 else { print(\"not3\"); return nil }\n        guard let header = self.decodeBase64ToJson(components[0]) else { print(\"he\"); return nil }\n        guard let payload = self.decodeBase64ToJson(components[1]) else { print(\"pa\"); return nil }\n        \n        return (header, payload)\n    }\n    \n    private func decodeBase64ToJson(_ string: String) -> String? {\n        guard let data = Data(base64Encoded: string) ?? Data(base64Encoded: string + \"=\") ?? Data(base64Encoded: string + \"==\") else { return nil }\n        guard let object = try? JSONSerialization.jsonObject(with: data, options: []) else { return nil }\n        guard let json = try? JSONSerialization.data(withJSONObject: object, options: .prettyPrinted) else { return nil }\n        \n        return String(data: json, encoding: .utf8)\n    }\n}\n\nfinal private class JWTDecoderView: Page {\n        \n    let tokenTextSection = TextViewSection(title: \"JWT Token\".localized(), options: .defaultInput)\n    let headerCodeSection = CodeViewSection(title: \"Header\".localized(), options: .defaultOutput, language: .javascript)\n    let payloadCodeSection = CodeViewSection(title: \"Payload\".localized(), options: .defaultOutput, language: .javascript)\n    \n    override func layout() {\n        super.layout()\n        \n        let contentHeight = max(100, (self.frame.height - 100) / 3)\n        \n        self.tokenTextSection.snp.remakeConstraints{ make in\n            make.height.equalTo(contentHeight)\n        }\n        self.headerCodeSection.snp.remakeConstraints{ make in\n            make.height.equalTo(contentHeight)\n        }\n        self.payloadCodeSection.snp.remakeConstraints{ make in\n            make.height.equalTo(contentHeight)\n        }\n    }\n    \n    override func onAwake() {        \n        self.addSection(tokenTextSection)\n        self.tokenTextSection.textView.snp.remakeConstraints{ make in\n            make.height.equalTo(85)\n        }\n        self.addSection(headerCodeSection)\n        self.headerCodeSection.textView.snp.remakeConstraints{ make in\n            make.height.equalTo(100)\n        }\n        self.addSection(payloadCodeSection)\n        self.payloadCodeSection.textView.snp.remakeConstraints{ make in\n            make.height.equalTo(100)\n        }\n    }\n}\n\nprivate let defaultToken = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiYWdlIjoxNn0.Ir_wyzMjqDXeeaGWJVgdysutJ6C9E3MX11t38LD2K60\"\n\nprivate let defaultPayload = \"\"\"\n{\n  \"sub\": \"1234567890\",\n  \"name\": \"Alice\",\n  \"age\": 16\n}\n\"\"\"\n\nprivate let defaultHeader = \"\"\"\n{\n  \"alg\": \"HS256\",\n  \"typ\": \"JWT\"\n}\n\"\"\"\n"
  },
  {
    "path": "DevToys/DevToys/Body/Coder/URLDecoderView+.swift",
    "content": "//\n//  URLDecoder.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class URLDecoderViewController: NSViewController {\n    private let cell = URLDecoderView()\n    \n    @RestorableState(\"url.rawString\") var rawString = \"https://www.microsoft.com/ja-jp/p/devtoys/9pgcv4v3bk4w?rtc=1#activetab=pivot:overviewtab\"\n    @RestorableState(\"url.formattedString\") var formattedString = \"https%3A%2F%2Fwww.microsoft.com%2Fja-jp%2Fp%2Fdevtoys%2F9pgcv4v3bk4w%3Frtc%3D1%23activetab%3Dpivot%3Aoverviewtab\"\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.cell.decodeTextSection.stringPublisher\n            .sink{[unowned self] in self.rawString = $0; self.formattedString = encodeToURL($0) }.store(in: &objectBag)\n        self.cell.encodeTextSection.stringPublisher\n            .sink{[unowned self] in self.formattedString = $0; if let s = $0.removingPercentEncoding { self.rawString = s } }.store(in: &objectBag)\n        \n        self.$rawString\n            .sink{[unowned self] in self.cell.decodeTextSection.string = $0 }.store(in: &objectBag)\n        self.$formattedString\n            .sink{[unowned self] in self.cell.encodeTextSection.string = $0 }.store(in: &objectBag)\n    }\n    \n    private func encodeToURL(_ string: String) -> String {\n        let allowedCharacters = NSCharacterSet.alphanumerics.union(.init(charactersIn: \"-._~\"))\n        return string.addingPercentEncoding(withAllowedCharacters: allowedCharacters) ?? \"???\"\n    }\n}\n\nfinal private class URLDecoderView: Page {\n    let decodeTextSection = TextViewSection(title: \"Decoded\".localized(), options: [.all])\n    let encodeTextSection = TextViewSection(title: \"Encoded\".localized(), options: [.all])\n    \n    override func layout() {\n        super.layout()\n        let halfHeight = max(200, (self.frame.height - 100) / 2)\n        \n        self.decodeTextSection.snp.remakeConstraints{ make in\n            make.height.equalTo(halfHeight)\n        }\n        self.encodeTextSection.snp.remakeConstraints{ make in\n            make.height.equalTo(halfHeight)\n        }\n    }\n    \n    override func onAwake() {        \n        self.addSection(decodeTextSection)\n        self.addSection(encodeTextSection)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Convert/DateConverterView+.swift",
    "content": "//\n//  DateConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class DateConverterViewController: NSViewController {\n    private let cell = DateConverterView()\n    \n    @Observable var date = Date()\n    \n    private let isoFormatter = ISO8601DateFormatter()\n    private let gmtFormatter = DateFormatter() => {\n        $0.locale = Locale(identifier: \"en_US_POSIX\")\n        $0.timeZone = TimeZone(abbreviation: \"GMT\")\n    }\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$date\n            .sink{[unowned self] in\n                self.cell.datePicker.date = $0\n                self.cell.unixTimeField.value = $0.timeIntervalSince1970.rounded()\n                self.cell.isoDateField.string = isoFormatter.string(from: $0)\n                self.cell.graphicDatePicker.dateValue = $0\n            }\n            .store(in: &objectBag)\n        \n        self.cell.graphicDatePicker.actionPublisher\n            .sink{[unowned self] in self.date = cell.graphicDatePicker.dateValue }.store(in: &objectBag)\n        self.cell.nowButton.actionPublisher\n            .sink{[unowned self] in self.date = Date() }.store(in: &objectBag)\n        self.cell.datePicker.datePublisher\n            .sink{[unowned self] in self.date = $0 }.store(in: &objectBag)\n        self.cell.unixTimeField.valuePublisher\n            .sink{[unowned self] in self.date = Date(timeIntervalSince1970: $0.reduce(self.date.timeIntervalSince1970)) }.store(in: &objectBag)\n        self.cell.isoDateField.changeStringPublisher.compactMap{[unowned self] in isoFormatter.date(from: $0) }\n            .sink{[unowned self] in self.date = $0 }.store(in: &objectBag)\n    }\n}\n\nfinal private class DateConverterView: Page {\n    \n    let datePicker = DatePicker()\n    let utcDatePicker = DatePicker()\n    let nowButton = Button(title: \"Now\")\n    let unixTimeField = NumberField()\n    let isoDateField = TextField(showCopyButton: false)\n    let timestampDateField = TextField(showCopyButton: false)\n    let graphicDatePicker = NSDatePicker()\n    \n    override func onAwake() {        \n        self.addSection(Section(title: \"Date\".localized(), items: [\n            NSStackView() => {\n                $0.distribution = .equalSpacing\n                $0.addArrangedSubview(datePicker)\n                $0.addArrangedSubview(nowButton)\n            }\n        ]))\n        self.datePicker.snp.remakeConstraints{ make in\n            make.right.equalTo(nowButton.snp.left).inset(-8)\n        }\n        \n        self.addSection(Section(title: \"Unix Time\".localized(), items: [unixTimeField]))\n        self.unixTimeField.showStepper = false\n        self.unixTimeField.snp.remakeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.addSection(Section(title: \"ISO 8601\".localized(), items: [isoDateField]))\n        self.addSection(Section(title: \"Timestamp\".localized(), items: [timestampDateField]))\n        \n        self.addSection(Section(title: \"Calender\".localized(), items: [graphicDatePicker]))\n        self.graphicDatePicker.datePickerStyle = .clockAndCalendar\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Convert/JSONYamlConverterView+.swift",
    "content": "//\n//  JSONYamlConverter+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\nimport Yams\nimport SwiftJSONFormatter\n\nfinal class JSONYamlConverterViewController: NSViewController {\n    private let cell = JSONYamlConverterView()\n    \n    @RestorableState(\"jy.format\") private var formatStyle: FormatStyle = .pretty\n    @RestorableState(\"jy.json\") private var jsonCode = defaultJsonCode\n    @RestorableState(\"jy.yaml\") private var yamlCode = defaultYamlCode\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$jsonCode\n            .sink{[unowned self] in self.cell.jsonSection.string = $0 }.store(in: &objectBag)\n        self.$yamlCode\n            .sink{[unowned self] in self.cell.yamlSection.string = $0 }.store(in: &objectBag)\n        self.$formatStyle\n            .sink{[unowned self] in self.cell.formatStylePicker.selectedItem = $0 }.store(in: &objectBag)\n     \n        self.cell.formatStylePicker.itemPublisher\n            .sink{[unowned self] in self.formatStyle = $0 }.store(in: &objectBag)\n        self.cell.jsonSection.stringPublisher\n            .sink{[unowned self] in\n                self.jsonCode = $0\n                if let yamlCode = convertJsonToYaml(code: $0, formatStyle: self.formatStyle) {\n                    self.yamlCode = yamlCode\n                }\n            }\n            .store(in: &objectBag)\n        self.cell.yamlSection.stringPublisher\n            .sink{[unowned self] in\n                self.yamlCode = $0\n                if let jsonCode = convertYamlToJson(code: $0, formatStyle: self.formatStyle) { self.jsonCode = jsonCode }\n            }\n            .store(in: &objectBag)\n    }\n    \n    private func convertYamlToJson(code: String, formatStyle: FormatStyle) -> String? {\n        if code.isEmpty { return \"\" }\n        guard let object = try? Yams.load(yaml: code) else { return nil }\n        \n        var options = JSONSerialization.WritingOptions()\n        options.insert(.sortedKeys)\n        if formatStyle == .pretty { options.insert(.prettyPrinted) }\n        return try? objc_try {\n            guard let data = try? JSONSerialization.data(withJSONObject: object, options: options) else { return nil }\n            let json = String(data: data, encoding: .utf8)!\n            \n            return SwiftJSONFormatter.beautify(json, indent: \"    \")\n        }\n    }\n    \n    private func convertJsonToYaml(code: String, formatStyle: FormatStyle) -> String? {\n        if code.isEmpty { return \"\" }\n        return objc_try({\n            guard let object = try? JSONSerialization.jsonObject(with: code.data(using: .utf8)!) else {\n                return nil\n            }\n            \n            let swiftObject = convertNSObject(object)\n            \n            return try? Yams.dump(object: swiftObject)\n        }, catch: {_ in\n            return nil\n        })\n    }\n    \n    private func convertNSObject(_ object: Any) -> Any {\n        if let object = object as? NSDictionary {\n            return (object as! [String: Any]).mapValues{ convertNSObject($0) }\n        }\n        if let object = object as? NSArray { return (object as! [Any]).map{ convertNSObject($0) } }\n        if let object = object as? NSString { return object as String }\n        if let object = object as? NSNumber {\n            switch CFNumberGetType(object) {\n            case .cgFloatType, .floatType, .doubleType, .float32Type, .float64Type: return object.doubleValue\n            case .longLongType, .longType, .shortType, .intType, .sInt8Type, .sInt16Type, .sInt32Type, .sInt64Type, .cfIndexType, .nsIntegerType: return object.intValue\n            case .charType: return object.boolValue\n            @unknown default: return object.intValue\n            }\n        }\n        \n        return object\n    }\n}\n\nprivate enum FormatStyle: String, TextItem {\n    case pretty = \"Pretty\"\n    case minified = \"Minified\"\n    \n    var title: String { rawValue.localized() }\n}\n\nfinal private class JSONYamlConverterView: Page {\n    \n    let formatStylePicker = EnumPopupButton<FormatStyle>()\n    \n    let jsonSection = CodeViewSection(title: \"JSON\", options: .all, language: .javascript)\n    let yamlSection = CodeViewSection(title: \"Yaml\", options: .all, language: .yaml)\n    \n    private lazy var ioStack = self.addSection2(jsonSection, yamlSection)\n    \n    override func layout() {\n        super.layout()\n        \n        self.ioStack.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 170))\n        }\n    }\n    \n    override func onAwake() {\n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.format, title: \"Format\".localized(), control: formatStylePicker)\n        ]))\n    }\n}\n\nprivate let defaultJsonCode = \"\"\"\n{\n    \"type\" : \"members\",\n    \"members\" : [\n        {\n            \"name\" : \"Alice\",\n            \"age\" : 16\n        },\n        {\n            \"name\" : \"Bob\",\n            \"age\" : 24\n        }\n    ],\n}\n\"\"\"\n\nprivate let defaultYamlCode = \"\"\"\ntype: members\nmembers:\n- age: 16\n  name: Alice\n- age: 24\n  name: Bob\n\"\"\"\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Convert/NumberBaseConverterView+.swift",
    "content": "//\n//  NumberBaseConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class NumberBaseConverterViewController: NSViewController {\n    private let cell = NumberBaseConverterView()\n    \n    @RestorableState(\"numbase.format\") private var formatNumber = true\n    @RestorableState(\"numbase.2\") private var value2 = \"1 0101 1010 0101 0011\"\n    @RestorableState(\"numbase.10\") private var value10 = \"88,659\"\n    @RestorableState(\"numbase.8\") private var value8 = \"255 123\"\n    @RestorableState(\"numbase.16\") private var value16 = \"1 5A53\"\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$value2\n            .sink{[unowned self] in cell.binarySection.string = $0 }.store(in: &objectBag)\n        self.$value8\n            .sink{[unowned self] in cell.octalSection.string = $0 }.store(in: &objectBag)\n        self.$value10\n            .sink{[unowned self] in cell.decimalSection.string = $0 }.store(in: &objectBag)\n        self.$value16\n            .sink{[unowned self] in cell.hexSection.string = $0 }.store(in: &objectBag)\n        self.$formatNumber\n            .sink{[unowned self] in cell.formatSwitch.state = $0 ? .on : .off }.store(in: &objectBag)\n        \n        self.cell.binarySection.stringPublisher\n            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 2) }.store(in: &objectBag)\n        self.cell.octalSection.stringPublisher\n            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 8) }.store(in: &objectBag)\n        self.cell.decimalSection.stringPublisher\n            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 10) }.store(in: &objectBag)\n        self.cell.hexSection.stringPublisher\n            .sink{[unowned self] in self.updateValue(string: $0, inputRadix: 16) }.store(in: &objectBag)\n        self.cell.formatSwitch.actionPublisher.map{[unowned self] in self.cell.formatSwitch.state == .on }\n            .sink{[unowned self] in self.formatNumber = $0; updateFormat() }.store(in: &objectBag)\n    }\n    \n    private func updateFormat() {\n        self.updateValue(string: value10, inputRadix: 10)\n    }\n    private func updateValue(string: String, inputRadix: Int) {\n        let value = Int(string.replacingOccurrences(of: \" \", with: \"\").replacingOccurrences(of: \",\", with: \"\"), radix: inputRadix)\n        self.value2 = self.convertBinary(value, format: self.formatNumber)\n        self.value8 = self.convertOctal(value, format: self.formatNumber)\n        self.value10 = self.convertDecimal(value, format: self.formatNumber)\n        self.value16 = self.convertHex(value, format: self.formatNumber)\n    }\n    \n    private func convertHex(_ value: Int?, format: Bool) -> String {\n        guard let value = value else { return \"0\" }\n        \n        let string = String(value, radix: 16, uppercase: true)\n        if format { return splitString(string, split: 4, separator: \" \") } else {  return string }\n    }\n    private func convertDecimal(_ value: Int?, format: Bool) -> String {\n        guard let value = value else { return \"0\" }\n        \n        let string = String(value, radix: 10, uppercase: true)\n        if format { return splitString(string, split: 3, separator: \",\") } else {  return string }\n    }\n    private func convertOctal(_ value: Int?, format: Bool) -> String {\n        guard let value = value else { return \"0\" }\n        \n        let string = String(value, radix: 8, uppercase: true)\n        if format { return splitString(string, split: 3, separator: \" \") } else {  return string }\n    }\n    private func convertBinary(_ value: Int?, format: Bool) -> String {\n        guard let value = value else { return \"0\" }\n        \n        let string = String(value, radix: 2, uppercase: true)\n        if format { return splitString(string, split: 4, separator: \" \") } else {  return string }\n    }\n    \n    private func splitString(_ string: String, split: Int, separator: String) -> String {\n        var result = \"\"\n        var count = string.count\n        \n        for c in string {\n            count -= 1\n            result.append(c)\n            if count != 0, count % split == 0 { result.append(separator) }\n        }\n        \n        return result\n    }\n    \n    private func convert(_ value: Int?, radix: Int) -> String {\n        guard let value = value else { return \"0\" }\n        return String(value, radix: radix, uppercase: true)\n    }\n}\n\nfinal private class NumberBaseConverterView: Page {\n    let formatSwitch = NSSwitch()\n    \n    let decimalSection = TextFieldSection(title: \"Decimal\".localized())\n    let hexSection = TextFieldSection(title: \"Hexdecimal\".localized())\n    let octalSection = TextFieldSection(title: \"Octal\".localized())\n    let binarySection = TextFieldSection(title: \"Binary\".localized())\n    \n    private lazy var formatNumberArea = Area(icon: R.Image.format, title: \"Format Number\".localized(), control: formatSwitch)\n    \n    private lazy var configurationSection = Section(title: \"Configuration\".localized(), items: [formatNumberArea])\n    \n    override func onAwake() {        \n        self.addSection(configurationSection)\n        \n        self.addSection(decimalSection)\n        self.addSection(hexSection)\n        self.addSection(octalSection)\n        self.addSection(binarySection)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Format/JSONFormatterView+.swift",
    "content": "//\n//  JSONFormatter+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\nimport SwiftJSONFormatter\n\nfinal class JSONFormatterViewController: NSViewController {\n    \n    @RestorableState(\"json.spacingtype\") var spacingType: JSONSpacingType = .spaces4\n    \n    @RestorableState(\"jq.rawCode\") var rawCode: String = #\"{ \"Hello\": \"World\" }\"#\n    @RestorableState(\"jq.formattedCode\") var formattedCode: String = \"{\\n    \\\"Hello\\\": \\\"World\\\"\\n}\"\n    \n    private let cell = JSONFormatterView()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$spacingType\n            .sink{[unowned self] in cell.indentControl.selectedItem = $0 }.store(in: &objectBag)\n        self.$rawCode\n            .sink{[unowned self] in cell.inputSection.string = $0 }.store(in: &objectBag)\n        self.$formattedCode\n            .sink{[unowned self] in cell.outputSection.string = $0 }.store(in: &objectBag)\n        \n        self.cell.inputSection.stringPublisher\n            .sink{[unowned self] in self.rawCode = $0; updateFormattedCode() }.store(in: &objectBag)\n        self.cell.indentControl.itemPublisher\n            .sink{[unowned self] in self.spacingType = $0; updateFormattedCode() }.store(in: &objectBag)\n    }\n    \n    private func updateFormattedCode() {\n        self.formattedCode = processJSON(rawCode, spacingType: spacingType)\n    }\n    \n    private func processJSON(_ code: String, spacingType: JSONSpacingType) -> String {\n        switch spacingType {\n        case .spaces2: return SwiftJSONFormatter.beautify(code, indent: \"  \")\n        case .spaces4: return SwiftJSONFormatter.beautify(code, indent: \"    \")\n        case .tab1: return SwiftJSONFormatter.beautify(code, indent: \"\\t\")\n        case .minified: return SwiftJSONFormatter.minify(code)\n        }\n    }\n}\n\nenum JSONSpacingType: String, TextItem {\n    case spaces2 = \"2 Spaces\"\n    case spaces4 = \"4 Spaces\"\n    case tab1 = \"1 Tab\"\n    case minified = \"Minified\"\n    \n    var title: String { rawValue.localized() }\n}\n\nfinal private class JSONFormatterView: Page {\n    \n    let indentControl = EnumPopupButton<JSONSpacingType>()\n    let inputSection = CodeViewSection(title: \"Input\".localized(), options: .defaultInput, language: .javascript)\n    let outputSection = CodeViewSection(title: \"Output\".localized(), options: .defaultOutput, language: .javascript)\n        \n    private lazy var indentArea = Area(icon: R.Image.spacing, title: \"Indentation\".localized(), control: indentControl)\n    private lazy var configurationSection = Section(title: \"Configuration\".localized(), items: [indentArea])\n    private lazy var ioStack = self.addSection2(inputSection, outputSection)\n    \n    override func layout() {\n        super.layout()\n        \n        self.ioStack.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 180))\n        }\n    }\n    \n    override func onAwake() {\n        self.addSection(configurationSection)\n        self.outputSection.textView.textView.usesFindBar = true\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Format/SQLFormatterView+.swift",
    "content": "//\n//  SQLFormatterView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nfinal class SQLFormatterViewController: NSViewController {\n    private let cell = SQLFormatterView()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        \n    }\n}\n\nfinal private class SQLFormatterView: Page {\n    override func onAwake() {\n        \n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Format/XMLFormatterView+.swift",
    "content": "//\n//  XMLFormatter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class XMLFormatterViewController: NSViewController {\n    @RestorableState(\"xml.rawCode\") private var rawCode: String = \"\"\n    @RestorableState(\"xml.formattedCode\") private var formattedCode: String = \"\"\n    @RestorableState(\"xml.documentType\") private var documentType: DocumentType = .xmlDocument\n    @RestorableState(\"xml.pretty\") private var pretty = true\n    @RestorableState(\"xml.autofix\") private var autofix = true\n    \n    private let cell = XMLFormatterView()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$rawCode\n            .sink{[unowned self] in cell.inputSection.string = $0 }.store(in: &objectBag)\n        self.$formattedCode\n            .sink{[unowned self] in cell.outputSection.string = $0 }.store(in: &objectBag)\n        self.$documentType\n            .sink{[unowned self] in cell.documentTypeControl.selectedItem = $0 }.store(in: &objectBag)\n        self.$pretty\n            .sink{[unowned self] in cell.prettySwitch.isOn = $0 }.store(in: &objectBag)\n        self.$autofix\n            .sink{[unowned self] in cell.autoFixSwitch.isOn = $0 }.store(in: &objectBag)\n        \n        self.cell.prettySwitch.isOnPublisher\n            .sink{[unowned self] in self.pretty = $0; updateFormattedCode() }.store(in: &objectBag)\n        self.cell.autoFixSwitch.isOnPublisher\n            .sink{[unowned self] in self.autofix = $0; updateFormattedCode() }.store(in: &objectBag)\n        self.cell.documentTypeControl.itemPublisher\n            .sink{[unowned self] in self.documentType = $0; updateFormattedCode() }.store(in: &objectBag)\n        self.cell.inputSection.stringPublisher\n            .sink{[unowned self] in self.rawCode = $0; updateFormattedCode() }.store(in: &objectBag)\n        \n        self.updateFormattedCode()\n    }\n    \n    private func updateFormattedCode() {\n        \n        do {\n            var options = XMLNode.Options()\n            \n            if pretty {\n                options.insert(.nodePrettyPrint)\n            }\n            if autofix {\n                switch documentType {\n                case .htmlDocument: options.insert(.documentTidyHTML)\n                case .xmlDocument: options.insert(.documentTidyXML)\n                }\n            }\n            \n            let document = try XMLDocument(xmlString: rawCode, options: options)\n            \n            self.formattedCode = document.xmlString(options: options)\n                .replacingOccurrences(of: #\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\"#, with: \"\")\n                .replacingOccurrences(of: #\"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\"#, with: \"\")\n                .replacingOccurrences(of: #\"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\"#, with: \"\")\n                .replacingOccurrences(of: #\"<html xmlns=\"http://www.w3.org/1999/xhtml\">\"#, with: \"<html>\")\n                .trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)\n            \n        } catch {\n            self.formattedCode = \"[Invalid Document]\"\n        }\n    }\n}\n \nprivate enum DocumentType: String, TextItem {\n    case htmlDocument = \"HTML Document\"\n    case xmlDocument = \"XML Document\"\n    \n    var title: String { rawValue.localized() }\n}\n\nfinal private class XMLFormatterView: Page {\n    let prettySwitch = NSSwitch()\n    let autoFixSwitch = NSSwitch()\n    let documentTypeControl = EnumPopupButton<DocumentType>()\n    let inputSection = CodeViewSection(title: \"Input\".localized(), options: .defaultInput, language: .xml)\n    let outputSection = CodeViewSection(title: \"Output\".localized(), options: .defaultOutput, language: .xml)\n        \n    private lazy var configurationSection = Section(title: \"Configuration\".localized(), items: [\n        Area(icon: R.Image.convert, title: \"Document Type\".localized(), control: documentTypeControl),\n        NSStackView() => {\n            $0.orientation = .horizontal\n            $0.distribution = .fillEqually\n            $0.addArrangedSubview(Area(icon: R.Image.format, title: \"Auto Fix Document\".localized(), control: autoFixSwitch))\n            $0.addArrangedSubview(Area(icon: R.Image.format, title: \"Pretty Document\".localized(), control: prettySwitch))\n        }\n    ])\n    \n    private lazy var ioStack = self.addSection2(inputSection, outputSection)\n    \n    override func layout() {\n        super.layout()\n        \n        self.ioStack.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 230))\n        }\n    }\n    \n    override func onAwake() {\n        self.addSection(configurationSection)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/ChecksumGeneratorView+.swift",
    "content": "//\n//  ChecksumGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class ChecksumGeneratorViewController: NSViewController {\n    \n    @RestorableState(\"checksum.uppercase\") private var isUppercase = false\n    @RestorableState(\"checksum.alg\") private var hashAlgorithm = HashAlgorithm.md5\n    @RestorableState(\"checksum.comparer\") private var comparer = \"\"\n    \n    @Observable private var output = \"\"\n    @Observable var isError = true\n    @Observable var fileURL: URL?\n    \n    private let cell = ChecksumGeneratorView()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$isUppercase\n            .sink{[unowned self] in cell.formatSwitch.isOn = $0 }.store(in: &objectBag)\n        self.$hashAlgorithm\n            .sink{[unowned self] in cell.hashAlgorithmPicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$output\n            .sink{[unowned self] in cell.outputFieldSection.string = $0 }.store(in: &objectBag)\n        self.$comparer\n            .sink{[unowned self] in cell.compareFieldSection.string = $0 }.store(in: &objectBag)\n        self.$isError\n            .sink{[unowned self] in cell.compareFieldSection.textField.isError = $0 }.store(in: &objectBag)\n        \n        self.cell.formatSwitch.isOnPublisher\n            .sink{[unowned self] in self.isUppercase = $0; updateHash() }.store(in: &objectBag)\n        self.cell.hashAlgorithmPicker.itemPublisher\n            .sink{[unowned self] in self.hashAlgorithm = $0; updateHash() }.store(in: &objectBag)\n        self.cell.compareFieldSection.stringPublisher\n            .sink{[unowned self] in self.comparer = $0; updateComparer() }.store(in: &objectBag)\n        self.cell.fileSection.urlsPublisher.compactMap{ $0.first }\n            .sink{[unowned self] in fileURL = $0; self.updateHash() }.store(in: &objectBag)\n    }\n    \n    private func updateHash() {\n        guard let url = self.fileURL, let data = try? Data(contentsOf: url) else { return NSSound.beep() }\n        \n        switch hashAlgorithm {\n        case .md5: self.output = data.md5().hexString(uppercase: isUppercase)\n        case .sha1: self.output = data.sha1().hexString(uppercase: isUppercase)\n        case .sha256: self.output = data.sha256().hexString(uppercase: isUppercase)\n        case .sha384: self.output = data.sha384().hexString(uppercase: isUppercase)\n        case .sha512: self.output = data.sha512().hexString(uppercase: isUppercase)\n        }\n        self.updateComparer()\n    }\n    \n    private func updateComparer() {\n        self.isError = comparer.lowercased() != output.lowercased()\n    }\n}\n\nextension Data {\n    func hexString(uppercase: Bool) -> String {\n        self.map{ String(format: uppercase ? \"%02X\" : \"%02x\", $0) }.joined()\n    }\n}\n\nprivate enum HashAlgorithm: String, TextItem {\n    case md5 = \"MD5\"\n    case sha1 = \"SHA1\"\n    case sha256 = \"SHA256\"\n    case sha384 = \"SHA384\"\n    case sha512 = \"SHA512\"\n    var title: String { rawValue }\n}\n\nfinal private class ChecksumGeneratorView: Page {\n    let formatSwitch = NSSwitch()\n    let hashAlgorithmPicker = EnumPopupButton<HashAlgorithm>()\n    let fileSection = FileDropSection()\n    let outputFieldSection = TextFieldSection(title: \"Output\".localized(), isEditable: false)\n    let compareFieldSection = TextFieldSection(title: \"Output Comparer\".localized(), isEditable: true)\n    \n    override func onAwake() {\n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.format, title: \"Uppercase\".localized(), control: formatSwitch),\n            Area(icon: R.Image.convert, title: \"Hash Algorithm\".localized(), message: \"Select which algorithm you want to use\".localized(), control: hashAlgorithmPicker)\n        ]))\n        \n        self.addSection(fileSection)\n        \n        self.addSection(outputFieldSection)\n        self.addSection(compareFieldSection)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/HashGeneratorView+.swift",
    "content": "//\n//  HashGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\nimport CryptoSwift\n\nfinal class HashGeneratorViewController: NSViewController {\n    private let cell = HashGeneratorView()\n    \n    @RestorableState(\"hash.upper\") var isUppercase = false\n    @RestorableState(\"hash.input\") var input = \"Hello World\"\n    @RestorableState(\"hash.md5\") var md5 = \"\"\n    @RestorableState(\"hash.sha1\") var sha1 = \"\"\n    @RestorableState(\"hash.sha256\") var sha256 = \"\"\n    @RestorableState(\"hash.sha512\") var sha512 = \"\"\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.updateHash()\n        \n        self.$isUppercase.sink{[unowned self] in self.cell.formatSwitch.isOn = $0 }.store(in: &objectBag)\n        self.$input.sink{[unowned self] in self.cell.textInputSection.string = $0 }.store(in: &objectBag)\n        self.$md5.sink{[unowned self] in self.cell.md5Section.string = $0 }.store(in: &objectBag)\n        self.$sha1.sink{[unowned self] in self.cell.sha1Section.string = $0 }.store(in: &objectBag)\n        self.$sha256.sink{[unowned self] in self.cell.sha256Section.string = $0 }.store(in: &objectBag)\n        self.$sha512.sink{[unowned self] in self.cell.sha512Section.string = $0 }.store(in: &objectBag)\n        \n        self.cell.textInputSection.stringPublisher\n            .sink{[unowned self] in self.input = $0; updateHash() }.store(in: &objectBag)\n        self.cell.formatSwitch.isOnPublisher\n            .sink{[unowned self] in self.isUppercase = $0; updateHash() }.store(in: &objectBag)\n    }\n    \n    private func updateHash() {\n        self.md5 = isUppercase ? input.md5().uppercased() : input.md5()\n        self.sha1 = isUppercase ? input.sha1().uppercased() : input.sha1()\n        self.sha256 = isUppercase ? input.sha256().uppercased() : input.sha256()\n        self.sha512 = isUppercase ? input.sha512().uppercased() : input.sha512()\n    }\n}\n\nfinal class HashGeneratorView: Page {\n    let formatSwitch = NSSwitch()\n    \n    let textInputSection = TextViewSection(title: \"Input\".localized(), options: .all)\n    \n    let md5Section = TextFieldSection(title: \"MD5\", isEditable: false)\n    let sha1Section = TextFieldSection(title: \"SHA1\", isEditable: false)\n    let sha256Section = TextFieldSection(title: \"SHA256\", isEditable: false)\n    let sha512Section = TextFieldSection(title: \"SHA512\", isEditable: false)\n    \n    private lazy var formatNumberArea = Area(icon: R.Image.format, title: \"Uppercase\".localized(), control: formatSwitch)\n    private lazy var configurationSection = Section(title: \"Configuration\".localized(), items: [formatNumberArea])\n\n    override func onAwake() {        \n        self.addSection(configurationSection)\n        \n        self.addSection(textInputSection)\n        self.textInputSection.snp.remakeConstraints{ make in\n            make.height.equalTo(180)\n        }\n        \n        self.addSection(md5Section)\n        self.addSection(sha1Section)\n        self.addSection(sha256Section)\n        self.addSection(sha512Section)\n    }\n}\n\nextension NSSwitch {\n    var isOn: Bool {\n        get { self.state == .on } set { self.state = newValue ? .on : .off }\n    }\n    \n    var isOnPublisher: AnyPublisher<Bool, Never> {\n        self.actionPublisher.map{_ in self.state == .on }.eraseToAnyPublisher()\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/LoremIpsumGeneratorView+.swift",
    "content": "//\n//  LoremIpsumGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class LoremIpsumGeneratorViewController: NSViewController {\n    private let cell = LoremIpsumGeneratorView()\n    \n    @RestorableState(\"li.type\") var generateType = LoremIpsumGenerateType.sentences\n    @RestorableState(\"li.length\") var length = 3\n    @RestorableState(\"li.output\") var output = \"hello world\"\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.generate()\n        \n        self.$generateType.sink{[unowned self] in self.cell.typePicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$length.sink{[unowned self] in self.cell.lengthField.value = Double($0) }.store(in: &objectBag)\n        self.$output.sink{[unowned self] in self.cell.outputSection.string = $0 }.store(in: &objectBag)\n        \n        self.cell.typePicker.itemPublisher\n            .sink{[unowned self] in self.generateType = $0; generate() }.store(in: &objectBag)\n        self.cell.lengthField.valuePublisher.map{ $0.map{ Int($0) } }\n            .sink{[unowned self] in\n                let next = $0.reduce(self.length).clamped(1...)\n                if next != self.length { self.length = next; self.generate() }\n            }.store(in: &objectBag)\n    }\n    \n    private func generate() {\n        switch self.generateType {\n        case .words: self.output = generateWords(length)\n        case .sentences: self.output = generateSentences(length)\n        case .paragraphs: self.output = generateParagraphs(length)\n        }\n    }\n    \n    private func generateParagraphs(_ count: Int) -> String {\n        if count < 0 { return \"\" }\n        return (0..<count).map{_ in generateSentences(.random(in: 3...6)) }.joined(separator: \"\\n\\n\")\n    }\n    private func generateSentences(_ count: Int) -> String {\n        if count < 0 { return \"\" }\n        return (0..<count).map{_ in generateWords(.random(in: 10...20)) }.map{ $0 + \".\" }.joined(separator: \" \")\n    }\n    private func generateWords(_ count: Int) -> String {\n        if count < 0 { return \"\" }\n        return (0..<count).map{_ in wordSource.randomElement()! }.joined(separator: \" \").capitalizingFirstLetter()\n    }\n}\n\nenum LoremIpsumGenerateType: String, TextItem {\n    case words = \"Words\"\n    case sentences = \"Sentences\"\n    case paragraphs = \"Paragraphs\"\n    \n    var title: String { rawValue.localized() }\n}\n\nfinal private class LoremIpsumGeneratorView: Page {\n    let typePicker = EnumPopupButton<LoremIpsumGenerateType>()\n    let lengthField = NumberField()\n    \n    let outputSection = TextViewSection(title: \"Output\".localized(), options: [.outputable, .copyable, .inputable])\n    \n    override func layout() {\n        super.layout()\n    \n        self.outputSection.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 230))\n        }\n    }\n    \n    override func onAwake() {        \n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.text, title: \"Type\".localized(), message: \"Type of generating Lorem Ipsum\".localized(), control: typePicker),\n            Area(icon: R.Image.number, title: \"Length\".localized(), message: \"Length of generating Lorem Ipsum\".localized(), control: lengthField),\n        ]))\n        \n        self.addSection(outputSection)\n    }\n}\n\nprivate let wordSource: Set = [\"est\", \"quis\", \"ipsum\", \"labore\", \"cillum\", \"velit\", \"consequat\", \"dolore\", \"proident\", \"non\", \"sint\", \"nisi\", \"in\", \"officia\", \"sed\", \"deserunt\", \"aute\", \"pariatur\", \"aliquip\", \"eiusmod\", \"ex\", \"excepteur\", \"et\", \"esse\", \"sunt\", \"dolor\", \"nulla\", \"lorem\", \"ullamco\", \"amet\", \"culpa\", \"eu\", \"adipiscing\", \"commodo\", \"ea\", \"fugiat\", \"qui\", \"minim\", \"enim\", \"ut\", \"anim\", \"cupidatat\", \"aliqua\", \"laboris\", \"ad\", \"exercitation\", \"id\", \"mollit\", \"tempor\", \"veniam\", \"reprehenderit\", \"occaecat\", \"sit\", \"consectetur\", \"duis\", \"voluptate\", \"nostrud\", \"laborum\", \"magna\", \"incididunt\", \"elit\", \"irure\", \"do\"]\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/QRCodeGeneratorView+.swift",
    "content": "//\n//  QLCodeGeneratorView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/23.\n//\n\nimport CoreUtil\nimport CoreImage\n\nfinal class QRCodeGeneratorViewController: NSViewController {\n    private let cell = URLDecoderView()\n    \n    @RestorableState(\"qrcode.rawString\") var rawString = \"Hello World\"\n    @RestorableState(\"qrcode.correctionLevel\") var correctionLevel: QRInputCorrectionLevel = .default\n    @Observable var qrimage: NSImage? = nil\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$rawString\n            .sink{[unowned self] in self.cell.inputTextSection.string = $0 }.store(in: &objectBag)\n        self.$qrimage\n            .sink{[unowned self] in self.cell.imageView.image = $0 }.store(in: &objectBag)\n        self.$correctionLevel\n            .sink{[unowned self] in self.cell.correctionLevelPicker.selectedItem = $0 }.store(in: &objectBag)\n        \n        self.cell.inputTextSection.stringPublisher\n            .sink{[unowned self] in self.rawString = $0; updateQRCode() }.store(in: &objectBag)\n        self.cell.correctionLevelPicker.itemPublisher\n            .sink{[unowned self] in self.correctionLevel = $0; updateQRCode() }.store(in: &objectBag)\n        self.cell.exportButton.actionPublisher\n            .sink{[unowned self] in self.exportImage() }.store(in: &objectBag)\n        \n        self.updateQRCode()\n    }\n    \n    private func exportImage() {\n        guard let qrimage = qrimage?.png else { return NSSound.beep() }\n        \n        let panel = NSSavePanel()\n        panel.nameFieldStringValue = \"QRCode.png\"\n        guard panel.runModal() == .OK, let url = panel.url else { return }\n        \n        do {\n            try qrimage.write(to: url)\n        } catch {\n            assertionFailure(\"\\(error)\")\n        }\n    }\n    \n    private func updateQRCode() {\n        self.qrimage = generateQRCode(from: rawString)\n    }\n    \n    private func generateQRCode(from string: String) -> NSImage? {\n        if string.isEmpty { return nil }\n        \n        let data = string.data(using: .utf8)\n        \n        guard let qrfilter = CIFilter(name: \"CIQRCodeGenerator\") else { return nil }\n        qrfilter.setValue(data, forKey: \"inputMessage\")\n        switch correctionLevel {\n        case .high: qrfilter.setValue(\"H\", forKey: \"inputCorrectionLevel\")\n        case .default: qrfilter.setValue(\"Q\", forKey: \"inputCorrectionLevel\")\n        case .medium: qrfilter.setValue(\"M\", forKey: \"inputCorrectionLevel\")\n        case .low: qrfilter.setValue(\"L\", forKey: \"inputCorrectionLevel\")\n        }\n        \n        let transform = CGAffineTransform(scaleX: 3, y: 3)\n        \n        guard let output = qrfilter.outputImage?.transformed(by: transform) else { return nil }\n        \n        let rep = NSCIImageRep(ciImage: output)\n        let nsImage = NSImage(size: rep.size)\n        nsImage.addRepresentation(rep)\n        return nsImage\n    }\n}\n\nenum QRInputCorrectionLevel: String, TextItem {\n    case high = \"High\"\n    case `default` = \"Default\"\n    case medium = \"Medium\"\n    case low = \"Low\"\n    \n    var title: String { rawValue.localized() }\n}\n\nfinal private class URLDecoderView: Page {\n    let correctionLevelPicker = EnumPopupButton<QRInputCorrectionLevel>()\n    let inputTextSection = TextViewSection(title: \"Input\".localized(), options: .defaultInput)\n    let imageView = DragImageView()\n    let exportButton = SectionButton(title: \"Export\".localized(), image: R.Image.export)\n    let imageViewDelegate = DragImageViewBlockDelegate{ \"QRCode.png\" }\n    \n    override func onAwake() {\n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.paramators, title: \"Correction Level\".localized(), control: correctionLevelPicker)\n        ]))\n        self.addSection(inputTextSection)\n        self.inputTextSection.snp.makeConstraints{ make in\n            make.height.equalTo(320)\n        }\n        \n        self.imageView.delegate = imageViewDelegate\n        \n        self.addSection(Section(title: \"QR Code\".localized(), items: [\n            NSStackView() => {\n                $0.alignment = .centerX\n                $0.addArrangedSubview(imageView)\n            }\n        ], toolbarItems: [exportButton]))\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Generator/UUIDGeneratorView+.swift",
    "content": "//\n//  UUIDGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class UUIDGeneratorViewController: NSViewController {\n    private let cell = UUIDGeneratorView()\n    \n    @RestorableState(\"uuid.isHyphened\") var isHyphened = true\n    @RestorableState(\"uuid.uppercase\") var isUppercase = true\n    @RestorableState(\"uuid.count\") var count = 3\n    @RestorableState(\"uuid.uuid\") var uuids = \"\\(UUID().uuidString)\\n\"\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$isHyphened\n            .sink{[unowned self] in self.cell.hyphensSwitch.isOn = $0 }.store(in: &objectBag)\n        self.$isUppercase\n            .sink{[unowned self] in self.cell.uppercaseSwitch.isOn = $0 }.store(in: &objectBag)\n        self.$count\n            .sink{[unowned self] in self.cell.generateCount.value = Double($0) }.store(in: &objectBag)\n        self.$uuids\n            .sink{[unowned self] in self.cell.uuidView.string = $0 }.store(in: &objectBag)\n        \n        self.cell.hyphensSwitch.isOnPublisher\n            .sink{[unowned self] in self.isHyphened = $0 }.store(in: &objectBag)\n        self.cell.uppercaseSwitch.isOnPublisher\n            .sink{[unowned self] in self.isUppercase = $0 }.store(in: &objectBag)\n        self.cell.generateCount.valuePublisher\n            .sink{[unowned self] in self.count = $0.map{ Int($0) }.reduce(self.count).clamped(1...) }.store(in: &objectBag)\n        self.cell.generateButton.actionPublisher\n            .sink{[unowned self] in self.generateUUID() }.store(in: &objectBag)\n        self.cell.clearButton.actionPublisher\n            .sink{[unowned self] in self.uuids = \"\" }.store(in: &objectBag)\n    }\n    \n    private func generateUUID() {\n        for _ in 0..<count {\n            var uuidString = UUID().uuidString\n            if !isHyphened {\n                uuidString = uuidString.replacingOccurrences(of: \"-\", with: \"\")\n            }\n            if !isUppercase {\n                uuidString = uuidString.lowercased()\n            }\n            uuids.append(uuidString)\n            uuids.append(\"\\n\")\n        }\n    }\n}\n\nfinal private class UUIDGeneratorView: Page {\n    let hyphensSwitch = NSSwitch()\n    let uppercaseSwitch = NSSwitch()\n    let generateCount = NumberField()\n    let generateButton = Button(title: \"Generate UUIDs\".localized())\n    let uuidView = TextView() => { $0.isEditable = false }\n    let clearButton = SectionButton(image: R.Image.clear)\n    \n    override func layout() {\n        super.layout()\n        \n        self.uuidView.snp.remakeConstraints{ make in\n            make.height.equalTo(max(200, self.frame.height - 300))\n        }\n    }\n    \n    override func onAwake() {        \n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.hyphen, title: \"Hyphens\".localized(), control: hyphensSwitch),\n            Area(icon: R.Image.format, title: \"Uppercase\".localized(), control: uppercaseSwitch),\n        ]))\n        \n        self.addSection(NSStackView() => {\n            $0.addArrangedSubview(generateCount)\n            $0.addArrangedSubview(NSTextField(labelWithString: \"x\") => {\n                $0.font = .monospacedSystemFont(ofSize: 12, weight: .medium)\n            })\n            $0.addArrangedSubview(generateButton)\n        })\n        self.addSection(Section(title: \"UUIDs\".localized(), items: [\n            uuidView\n        ], toolbarItems: [clearButton]))\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/AndroidIconGenerator.swift",
    "content": "//\n//  AndroidIconGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\n\nenum AndroidIconGenerator {\n    static func make(item: ImageItem, templete: IconTemplete, to destinationURL: URL) -> IconGenerateTask {\n        let image = templete.bake(image: item.image, scale: .x512) \n        \n        let complete = Promise<Void, Error>.tryAsync{\n            guard\n                let s48 = image.resizedAspectFit(to: [48, 48], fillColor: .clear).png,\n                let s72 = image.resizedAspectFit(to: [72, 72], fillColor: .clear).png,\n                let s96 = image.resizedAspectFit(to: [96, 96], fillColor: .clear).png,\n                let s144 = image.resizedAspectFit(to: [144, 144], fillColor: .clear).png,\n                let s192 = image.resizedAspectFit(to: [192, 192], fillColor: .clear).png,\n                let s512 = image.resizedAspectFit(to: [512, 512], fillColor: .clear).png\n            else { throw IconGenerateError.convertError }\n            \n            do {\n                try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)\n                \n                try s48.write(to: destinationURL.appendingPathComponent(\"icon_mdpi.png\"))\n                try s72.write(to: destinationURL.appendingPathComponent(\"icon_hdpi.png\"))\n                try s96.write(to: destinationURL.appendingPathComponent(\"icon_xhdpi.png\"))\n                try s144.write(to: destinationURL.appendingPathComponent(\"icon_xxhdpi.png\"))\n                try s192.write(to: destinationURL.appendingPathComponent(\"icon_xxxhdpi.png\"))\n                try s512.write(to: destinationURL.appendingPathComponent(\"play_store.png\"))\n            } catch {\n                throw IconGenerateError.exportError(error)\n            }\n        }\n            \n        return .init(imageItem: item, complete: complete)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IOSIconGenerator.swift",
    "content": "//\n//  IcnsGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IosIconGenerator {\n    struct ExportOptions: OptionSet {\n        let rawValue: UInt64\n        \n        static let iphone = ExportOptions(rawValue: 1 << 0)\n        static let ipad = ExportOptions(rawValue: 1 << 1)\n        static let carplay = ExportOptions(rawValue: 1 << 2)\n        static let mac = ExportOptions(rawValue: 1 << 3)\n        static let applewatch = ExportOptions(rawValue: 1 << 4)\n    }\n    \n    static func make(item: ImageItem, options: ExportOptions, to destinationURL: URL) -> IconGenerateTask {\n        let complete = Promise<Void, Error>.tryAsync{\n            let image = item.image\n            let fillColor = NSColor.black\n            \n            guard\n                let s16 = image.resizedAspectFit(to: [16, 16], fillColor: fillColor).png,\n                let s20 = image.resizedAspectFit(to: [20, 20], fillColor: fillColor).png,\n                let s29 = image.resizedAspectFit(to: [29, 29], fillColor: fillColor).png,\n                let s32 = image.resizedAspectFit(to: [32, 32], fillColor: fillColor).png,\n                let s40 = image.resizedAspectFit(to: [40, 40], fillColor: fillColor).png,\n                let s48 = image.resizedAspectFit(to: [48, 48], fillColor: fillColor).png,\n                let s55 = image.resizedAspectFit(to: [55, 55], fillColor: fillColor).png,\n                let s57 = image.resizedAspectFit(to: [57, 57], fillColor: fillColor).png,\n                let s58 = image.resizedAspectFit(to: [58, 58], fillColor: fillColor).png,\n                let s60 = image.resizedAspectFit(to: [60, 60], fillColor: fillColor).png,\n                let s64 = image.resizedAspectFit(to: [64, 64], fillColor: fillColor).png,\n                let s66 = image.resizedAspectFit(to: [66, 66], fillColor: fillColor).png,\n                let s76 = image.resizedAspectFit(to: [76, 76], fillColor: fillColor).png,\n                let s80 = image.resizedAspectFit(to: [80, 80], fillColor: fillColor).png,\n                let s87 = image.resizedAspectFit(to: [87, 87], fillColor: fillColor).png,\n                let s88 = image.resizedAspectFit(to: [88, 88], fillColor: fillColor).png,\n                let s92 = image.resizedAspectFit(to: [92, 92], fillColor: fillColor).png,\n                let s100 = image.resizedAspectFit(to: [100, 100], fillColor: fillColor).png,\n                let s102 = image.resizedAspectFit(to: [102, 102], fillColor: fillColor).png,\n                let s114 = image.resizedAspectFit(to: [114, 114], fillColor: fillColor).png,\n                let s120 = image.resizedAspectFit(to: [120, 120], fillColor: fillColor).png,\n                let s128 = image.resizedAspectFit(to: [128, 128], fillColor: fillColor).png,\n                let s152 = image.resizedAspectFit(to: [152, 152], fillColor: fillColor).png,\n                let s167 = image.resizedAspectFit(to: [167, 167], fillColor: fillColor).png,\n                let s172 = image.resizedAspectFit(to: [172, 172], fillColor: fillColor).png,\n                let s180 = image.resizedAspectFit(to: [180, 180], fillColor: fillColor).png,\n                let s196 = image.resizedAspectFit(to: [196, 196], fillColor: fillColor).png,\n                let s216 = image.resizedAspectFit(to: [216, 216], fillColor: fillColor).png,\n                let s234 = image.resizedAspectFit(to: [234, 234], fillColor: fillColor).png,\n                let s256 = image.resizedAspectFit(to: [256, 256], fillColor: fillColor).png,\n                let s512 = image.resizedAspectFit(to: [512, 512], fillColor: fillColor).png,\n                let s1024 = image.resizedAspectFit(to: [1024, 1024], fillColor: fillColor).png\n            else { throw IconGenerateError.convertError }\n            \n            do {\n                try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)\n                \n                if options.contains(.iphone) {\n                    try s40.write(to: destinationURL.appendingPathComponent(\"iPhone Notification@2x.png\"))\n                    try s60.write(to: destinationURL.appendingPathComponent(\"iPhone Notification@3x.png\"))\n                    \n                    try s29.write(to: destinationURL.appendingPathComponent(\"iPhone Settings.png\"))\n                    try s58.write(to: destinationURL.appendingPathComponent(\"iPhone Settings@2x.png\"))\n                    try s87.write(to: destinationURL.appendingPathComponent(\"iPhone Settings@3x.png\"))\n                    \n                    try s80.write(to: destinationURL.appendingPathComponent(\"iPhone Spotlight@2x.png\"))\n                    try s120.write(to: destinationURL.appendingPathComponent(\"iPhone Spotlight@3x.png\"))\n                    \n                    try s57.write(to: destinationURL.appendingPathComponent(\"iPhone App iOS 5,6.png\"))\n                    try s114.write(to: destinationURL.appendingPathComponent(\"iPhone App iOS 5,6@2x.png\"))\n                    \n                    try s120.write(to: destinationURL.appendingPathComponent(\"iPhone App@2x.png\"))\n                    try s180.write(to: destinationURL.appendingPathComponent(\"iPhone App@3x.png\"))\n                }\n                \n                if options.contains(.ipad) {\n                    try s20.write(to: destinationURL.appendingPathComponent(\"iPad Notification.png\"))\n                    try s40.write(to: destinationURL.appendingPathComponent(\"iPad Notification@2x.png\"))\n                    \n                    try s29.write(to: destinationURL.appendingPathComponent(\"iPad Settings.png\"))\n                    try s58.write(to: destinationURL.appendingPathComponent(\"iPad Settings@2x.png\"))\n                    \n                    try s40.write(to: destinationURL.appendingPathComponent(\"iPad Spotlight.png\"))\n                    try s80.write(to: destinationURL.appendingPathComponent(\"iPad Spotlight@2x.png\"))\n                    \n                    try s76.write(to: destinationURL.appendingPathComponent(\"iPad App.png\"))\n                    try s152.write(to: destinationURL.appendingPathComponent(\"iPad App@2x.png\"))\n                    \n                    try s167.write(to: destinationURL.appendingPathComponent(\"iPad Pro App@2x.png\"))\n                }\n                \n                if options.contains(.iphone) || options.contains(.ipad) {\n                    try s1024.write(to: destinationURL.appendingPathComponent(\"App Store iOS.png\"))\n                }\n                \n                if options.contains(.carplay) {\n                    try s120.write(to: destinationURL.appendingPathComponent(\"CarPlay@2x.png\"))\n                    try s180.write(to: destinationURL.appendingPathComponent(\"CarPlay@3x.png\"))\n                }\n                \n                if options.contains(.mac) {\n                    try s16.write(to: destinationURL.appendingPathComponent(\"Mac 16x16.png\"))\n                    try s32.write(to: destinationURL.appendingPathComponent(\"Mac 16x16@2x.png\"))\n                    \n                    try s32.write(to: destinationURL.appendingPathComponent(\"Mac 32x32.png\"))\n                    try s64.write(to: destinationURL.appendingPathComponent(\"Mac 32x32@2x.png\"))\n                    \n                    try s128.write(to: destinationURL.appendingPathComponent(\"Mac 128x128.png\"))\n                    try s256.write(to: destinationURL.appendingPathComponent(\"Mac 128x128@2x.png\"))\n                    \n                    try s256.write(to: destinationURL.appendingPathComponent(\"Mac 256x256.png\"))\n                    try s512.write(to: destinationURL.appendingPathComponent(\"Mac 256x256@2x.png\"))\n                    \n                    try s512.write(to: destinationURL.appendingPathComponent(\"Mac 512x512.png\"))\n                    try s1024.write(to: destinationURL.appendingPathComponent(\"Mac 512x512@2x.png\"))\n                }\n                \n                if options.contains(.applewatch) {\n                    try s48.write(to: destinationURL.appendingPathComponent(\"Apple Watch Notification Center 48x28@2x.png\"))\n                    try s55.write(to: destinationURL.appendingPathComponent(\"Apple Watch Notification Center 55x55@2x.png\"))\n                    try s66.write(to: destinationURL.appendingPathComponent(\"Apple Watch Notification Center 66x66@2x.png\"))\n                    \n                    try s58.write(to: destinationURL.appendingPathComponent(\"Apple Watch Companion Settings@2x.png\"))\n                    try s87.write(to: destinationURL.appendingPathComponent(\"Apple Watch Companion Settings@3x.png\"))\n                    \n                    try s80.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 38mm@2x.png\"))\n                    try s88.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 40mm@2x.png\"))\n                    try s92.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 41mm@2x.png\"))\n                    try s100.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 44mm@2x.png\"))\n                    try s102.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 45mm@2x.png\"))\n                    \n                    try s172.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 172x172@2x.png\"))\n                    try s196.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 196x196@2x.png\"))\n                    try s216.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 216x216@2x.png\"))\n                    try s234.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 234x234@2x.png\"))\n                    \n                    try s1024.write(to: destinationURL.appendingPathComponent(\"Apple Watch App Store.png\"))\n                }\n                \n            } catch {\n                throw IconGenerateError.exportError(error)\n            }\n        }\n        \n        return .init(imageItem: item, complete: complete)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IcnsGenerator.swift",
    "content": "//\n//  IcnsGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IcnsGenerator {\n    private static let iconutilURL = URL(fileURLWithPath: \"/usr/bin/iconutil\")\n    private static let temporaryDirectory = FileManager.default.temporaryDirectory.appendingPathComponent(\"IcnsGenerator\") => {\n        try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)\n    }\n    \n    static func make(item: ImageItem, templete: IconTemplete, to destinationURL: URL) -> IconGenerateTask {\n        let complete = Promise<URL, Error>\n            .tryAsync{\n                let iconsetURL = temporaryDirectory.appendingPathComponent(UUID().uuidString).appendingPathExtension(\"iconset\")\n                try IconsetGenerator.generateIconset(image: item.image, templete: templete, to: iconsetURL)\n                return iconsetURL\n            }\n            .flatPeek{ Terminal.run(iconutilURL, arguments: [\"-c\", \"icns\", \"--output\", destinationURL.path, $0.path]) }\n            .tryPeek{ try FileManager.default.removeItem(at: $0) }\n            .eraseToVoid()\n        \n        return IconGenerateTask(imageItem: item, complete: complete)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IcoGenerator.swift",
    "content": "//\n//  IcoGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\n\n\nenum IcoGenerator {\n    static func make(item: ImageItem, templete: IconTemplete, to destinationURL: URL) -> IconGenerateTask {\n        let image = templete.bake(image: item.image, scale: .x256)\n        \n        let complete = Promise<URL, Error>.tryAsync{\n            let tmpURL = FileManager.default.temporaryDirectory.appendingPathComponent(\"\\(UUID().uuidString).png\")\n            try image.png?.write(to: tmpURL)\n            return tmpURL\n        }\n        .flatPeek{ FFExecutor.execute([], inputURL: $0, destinationURL: destinationURL).eraseToError().flatMap{ $0.complete } }\n        .tryPeek{ try FileManager.default.removeItem(at: $0) }\n        .eraseToVoid()\n        \n        return IconGenerateTask(imageItem: item, complete: complete)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IconFolderGenerator.swift",
    "content": "//\n//  IconFolderGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\nimport CoreGraphics\n\nenum IconFolderGenerator {\n    static func make(item: ImageItem, templete: IconTemplete, to destinationURL: URL) -> IconGenerateTask {\n        IconGenerateTask(imageItem: item, complete: .tryAsync{\n            try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)\n            let image = templete.bake(image: item.image, scale: .x512)\n            NSWorkspace.shared.setIcon(image, forFile: destinationURL.path, options: .excludeQuickDrawElementsIconCreationOption)\n        })\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IconGenerator+Model.swift",
    "content": "//\n//  IconGenerator+Model.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nstruct IconGenerateTask {\n    let imageItem: ImageItem\n    let complete: Promise<Void, Error>\n}\n\nenum IconGenerateError: Error {\n    case convertError\n    case exportError(Error)\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IconsetGenerator.swift",
    "content": "//\n//  IconsetGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IconsetGenerator {\n    static func make(item: ImageItem, templete: IconTemplete, to destinationURL: URL) -> IconGenerateTask {\n        IconGenerateTask(imageItem: item, complete: .tryAsync{\n            try self.generateIconset(image: item.image, templete: templete, to: destinationURL)\n        })\n    }\n    \n    static func generateIconset(image: NSImage, templete: IconTemplete, to destinationURL: URL) throws {\n        let iconset = templete.bakeIconSet(image: image)\n        \n        do {\n            try iconset.write(to: destinationURL)\n        } catch {\n            throw IconGenerateError.exportError(error)\n        }\n        \n        return ()\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/IosIconGenerator.swift",
    "content": "//\n//  IcnsGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nenum IosIconGenerator {\n    struct ExportOptions: OptionSet {\n        let rawValue: UInt64\n        \n        static let iphone = ExportOptions(rawValue: 1 << 0)\n        static let ipad = ExportOptions(rawValue: 1 << 1)\n        static let carplay = ExportOptions(rawValue: 1 << 2)\n        static let mac = ExportOptions(rawValue: 1 << 3)\n        static let applewatch = ExportOptions(rawValue: 1 << 4)\n    }\n    \n    static func make(item: ImageItem, options: ExportOptions, to destinationURL: URL) -> IconGenerateTask {\n        let complete = Promise<Void, Error>.tryAsync{\n            let image = item.image\n            let fillColor = NSColor.black\n            \n            guard\n                let s16 = image.resizedAspectFit(to: [16, 16], fillColor: fillColor).png,\n                let s20 = image.resizedAspectFit(to: [20, 20], fillColor: fillColor).png,\n                let s29 = image.resizedAspectFit(to: [29, 29], fillColor: fillColor).png,\n                let s32 = image.resizedAspectFit(to: [32, 32], fillColor: fillColor).png,\n                let s40 = image.resizedAspectFit(to: [40, 40], fillColor: fillColor).png,\n                let s48 = image.resizedAspectFit(to: [48, 48], fillColor: fillColor).png,\n                let s55 = image.resizedAspectFit(to: [55, 55], fillColor: fillColor).png,\n                let s57 = image.resizedAspectFit(to: [57, 57], fillColor: fillColor).png,\n                let s58 = image.resizedAspectFit(to: [58, 58], fillColor: fillColor).png,\n                let s60 = image.resizedAspectFit(to: [60, 60], fillColor: fillColor).png,\n                let s64 = image.resizedAspectFit(to: [64, 64], fillColor: fillColor).png,\n                let s66 = image.resizedAspectFit(to: [66, 66], fillColor: fillColor).png,\n                let s76 = image.resizedAspectFit(to: [76, 76], fillColor: fillColor).png,\n                let s80 = image.resizedAspectFit(to: [80, 80], fillColor: fillColor).png,\n                let s87 = image.resizedAspectFit(to: [87, 87], fillColor: fillColor).png,\n                let s88 = image.resizedAspectFit(to: [88, 88], fillColor: fillColor).png,\n                let s92 = image.resizedAspectFit(to: [92, 92], fillColor: fillColor).png,\n                let s100 = image.resizedAspectFit(to: [100, 100], fillColor: fillColor).png,\n                let s102 = image.resizedAspectFit(to: [102, 102], fillColor: fillColor).png,\n                let s114 = image.resizedAspectFit(to: [114, 114], fillColor: fillColor).png,\n                let s120 = image.resizedAspectFit(to: [120, 120], fillColor: fillColor).png,\n                let s128 = image.resizedAspectFit(to: [128, 128], fillColor: fillColor).png,\n                let s152 = image.resizedAspectFit(to: [152, 152], fillColor: fillColor).png,\n                let s167 = image.resizedAspectFit(to: [167, 167], fillColor: fillColor).png,\n                let s172 = image.resizedAspectFit(to: [172, 172], fillColor: fillColor).png,\n                let s180 = image.resizedAspectFit(to: [180, 180], fillColor: fillColor).png,\n                let s196 = image.resizedAspectFit(to: [196, 196], fillColor: fillColor).png,\n                let s216 = image.resizedAspectFit(to: [216, 216], fillColor: fillColor).png,\n                let s234 = image.resizedAspectFit(to: [234, 234], fillColor: fillColor).png,\n                let s256 = image.resizedAspectFit(to: [256, 256], fillColor: fillColor).png,\n                let s512 = image.resizedAspectFit(to: [512, 512], fillColor: fillColor).png,\n                let s1024 = image.resizedAspectFit(to: [1024, 1024], fillColor: fillColor).png\n            else { throw IconGenerateError.convertError }\n            \n            do {\n                try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)\n                \n                if options.contains(.iphone) {\n                    try s40.write(to: destinationURL.appendingPathComponent(\"iPhone Notification@2x.png\"))\n                    try s60.write(to: destinationURL.appendingPathComponent(\"iPhone Notification@3x.png\"))\n                    \n                    try s29.write(to: destinationURL.appendingPathComponent(\"iPhone Settings.png\"))\n                    try s58.write(to: destinationURL.appendingPathComponent(\"iPhone Settings@2x.png\"))\n                    try s87.write(to: destinationURL.appendingPathComponent(\"iPhone Settings@3x.png\"))\n                    \n                    try s80.write(to: destinationURL.appendingPathComponent(\"iPhone Spotlight@2x.png\"))\n                    try s120.write(to: destinationURL.appendingPathComponent(\"iPhone Spotlight@3x.png\"))\n                    \n                    try s57.write(to: destinationURL.appendingPathComponent(\"iPhone App iOS 5,6.png\"))\n                    try s114.write(to: destinationURL.appendingPathComponent(\"iPhone App iOS 5,6@2x.png\"))\n                    \n                    try s120.write(to: destinationURL.appendingPathComponent(\"iPhone App@2x.png\"))\n                    try s180.write(to: destinationURL.appendingPathComponent(\"iPhone App@3x.png\"))\n                }\n                \n                if options.contains(.ipad) {\n                    try s20.write(to: destinationURL.appendingPathComponent(\"iPad Notification.png\"))\n                    try s40.write(to: destinationURL.appendingPathComponent(\"iPad Notification@2x.png\"))\n                    \n                    try s29.write(to: destinationURL.appendingPathComponent(\"iPad Settings.png\"))\n                    try s58.write(to: destinationURL.appendingPathComponent(\"iPad Settings@2x.png\"))\n                    \n                    try s40.write(to: destinationURL.appendingPathComponent(\"iPad Spotlight.png\"))\n                    try s80.write(to: destinationURL.appendingPathComponent(\"iPad Spotlight@2x.png\"))\n                    \n                    try s76.write(to: destinationURL.appendingPathComponent(\"iPad App.png\"))\n                    try s152.write(to: destinationURL.appendingPathComponent(\"iPad App@2x.png\"))\n                    \n                    try s167.write(to: destinationURL.appendingPathComponent(\"iPad Pro App@2x.png\"))\n                }\n                \n                if options.contains(.iphone) || options.contains(.ipad) {\n                    try s1024.write(to: destinationURL.appendingPathComponent(\"App Store iOS.png\"))\n                }\n                \n                if options.contains(.carplay) {\n                    try s120.write(to: destinationURL.appendingPathComponent(\"CarPlay@2x.png\"))\n                    try s180.write(to: destinationURL.appendingPathComponent(\"CarPlay@3x.png\"))\n                }\n                \n                if options.contains(.mac) {\n                    try s16.write(to: destinationURL.appendingPathComponent(\"Mac 16x16.png\"))\n                    try s32.write(to: destinationURL.appendingPathComponent(\"Mac 16x16@2x.png\"))\n                    \n                    try s32.write(to: destinationURL.appendingPathComponent(\"Mac 32x32.png\"))\n                    try s64.write(to: destinationURL.appendingPathComponent(\"Mac 32x32@2x.png\"))\n                    \n                    try s128.write(to: destinationURL.appendingPathComponent(\"Mac 128x128.png\"))\n                    try s256.write(to: destinationURL.appendingPathComponent(\"Mac 128x128@2x.png\"))\n                    \n                    try s256.write(to: destinationURL.appendingPathComponent(\"Mac 256x256.png\"))\n                    try s512.write(to: destinationURL.appendingPathComponent(\"Mac 256x256@2x.png\"))\n                    \n                    try s512.write(to: destinationURL.appendingPathComponent(\"Mac 512x512.png\"))\n                    try s1024.write(to: destinationURL.appendingPathComponent(\"Mac 512x512@2x.png\"))\n                }\n                \n                if options.contains(.applewatch) {\n                    try s48.write(to: destinationURL.appendingPathComponent(\"Apple Watch Notification Center 48x28@2x.png\"))\n                    try s55.write(to: destinationURL.appendingPathComponent(\"Apple Watch Notification Center 55x55@2x.png\"))\n                    try s66.write(to: destinationURL.appendingPathComponent(\"Apple Watch Notification Center 66x66@2x.png\"))\n                    \n                    try s58.write(to: destinationURL.appendingPathComponent(\"Apple Watch Companion Settings@2x.png\"))\n                    try s87.write(to: destinationURL.appendingPathComponent(\"Apple Watch Companion Settings@3x.png\"))\n                    \n                    try s80.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 38mm@2x.png\"))\n                    try s88.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 40mm@2x.png\"))\n                    try s92.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 41mm@2x.png\"))\n                    try s100.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 44mm@2x.png\"))\n                    try s102.write(to: destinationURL.appendingPathComponent(\"Apple Watch Home Screen 45mm@2x.png\"))\n                    \n                    try s172.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 172x172@2x.png\"))\n                    try s196.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 196x196@2x.png\"))\n                    try s216.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 216x216@2x.png\"))\n                    try s234.write(to: destinationURL.appendingPathComponent(\"Apple Watch Short Look 234x234@2x.png\"))\n                    \n                    try s1024.write(to: destinationURL.appendingPathComponent(\"Apple Watch App Store.png\"))\n                }\n                \n            } catch {\n                throw IconGenerateError.exportError(error)\n            }\n        }\n        \n        return .init(imageItem: item, complete: complete)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Generators/PngIconGenerator.swift",
    "content": "//\n//  PNGGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport Foundation\n\nenum PngIconGenerator {\n    static func make(item: ImageItem, templete: IconTemplete, scale: IconSet.Scale, to destinationURL: URL) -> IconGenerateTask {\n        IconGenerateTask(imageItem: item, complete: .tryAsync{\n            try templete.bake(image: item.image, scale: scale).png?.write(to: destinationURL)\n        })\n    }\n}\n\nenum JpegIconGenerator {\n    static func make(item: ImageItem, templete: IconTemplete, scale: IconSet.Scale, to destinationURL: URL) -> IconGenerateTask {\n        IconGenerateTask(imageItem: item, complete: .tryAsync{\n            try templete.bake(image: item.image, scale: scale).jpeg?.write(to: destinationURL)\n        })\n    }\n}\n\nenum GifIconGenerator {\n    static func make(item: ImageItem, templete: IconTemplete, scale: IconSet.Scale, to destinationURL: URL) -> IconGenerateTask {\n        IconGenerateTask(imageItem: item, complete: .tryAsync{\n            try templete.bake(image: item.image, scale: scale).gif?.write(to: destinationURL)\n        })\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconImageManager.swift",
    "content": "//\n//  IconImageManager.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\n\nfinal class IconImageManager {\n    var templetes = [IconTemplete]()\n    private var templeteMap = [String: IconTemplete]()\n    \n    func templete(for identifier: String) -> IconTemplete? {\n        self.templeteMap[identifier]\n    }\n    func register(_ templete: IconTemplete) {\n        self.templetes.append(templete)\n        self.templeteMap[templete.identifier] = templete\n    }\n}\n\nextension IconImageManager {\n    static let shared = IconImageManager() => {\n        $0.register(OriginalIconTemplete())\n        $0.register(FolderFillIconTemplete())\n        $0.register(FolderCenterIconTemplete())\n        $0.register(FolderCenterEngravedIconTemplete())\n        $0.register(BigSurFillIconTemplete())\n        $0.register(AndroidIconTemplete())\n        $0.register(CircleIconTemplete())\n        $0.register(RoundedRectIconTemplete())\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconSet.swift",
    "content": "//\n//  IconSet.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\n\n\n\nstruct IconSet {\n    enum Scale: Int {\n        case x16, x32, x64, x128, x256, x512, x1024\n        \n        var size: CGFloat {\n            switch self {\n            case .x16: return 16\n            case .x32: return 32\n            case .x64: return 64\n            case .x128: return 128\n            case .x256: return 256\n            case .x512: return 512\n            case .x1024: return 1024\n            }\n        }\n        var point: Int { Int(size) }\n    }\n    \n    let icon16: NSImage\n    let icon32: NSImage\n    let icon64: NSImage\n    let icon128: NSImage\n    let icon256: NSImage\n    let icon512: NSImage\n    let icon1024: NSImage\n    \n    func image(for scale: Scale) -> NSImage {\n        switch scale {\n        case .x16: return icon16\n        case .x32: return icon32\n        case .x64: return icon64\n        case .x128: return icon128\n        case .x256: return icon256\n        case .x512: return icon512\n        case .x1024: return icon1024\n        }\n    }\n    \n    init(icon16: NSImage, icon32: NSImage, icon64: NSImage, icon128: NSImage, icon256: NSImage, icon512: NSImage, icon1024: NSImage) {\n        self.icon16 = icon16\n        self.icon32 = icon32\n        self.icon64 = icon64\n        self.icon128 = icon128\n        self.icon256 = icon256\n        self.icon512 = icon512\n        self.icon1024 = icon1024\n    }\n    \n    init?(make: (Scale) -> NSImage?) {\n        guard let icon16 = make(.x16), let icon32 = make(.x32), let icon64 = make(.x64), let icon128 = make(.x128), let icon256 = make(.x256), let icon512 = make(.x512), let icon1024 = make(.x1024) else { return nil }\n        self.init(icon16: icon16, icon32: icon32, icon64: icon64, icon128: icon128, icon256: icon256, icon512: icon512, icon1024: icon1024)\n    }\n    \n    init?(bundleResouces: (Scale) -> String) {\n        self.init(make: { Bundle.main.image(forResource: bundleResouces($0)) })\n    }\n}\n\nextension IconSet {\n    func write(to url: URL) throws {\n        try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)\n        try self.icon16.png?.write(to: url.appendingPathComponent(\"icon_16x16.png\"))\n        try self.icon32.png?.write(to: url.appendingPathComponent(\"icon_16x16@2x.png\"))\n        try self.icon32.png?.write(to: url.appendingPathComponent(\"icon_32x32.png\"))\n        try self.icon64.png?.write(to: url.appendingPathComponent(\"icon_32x32@2x.png\"))\n        try self.icon64.png?.write(to: url.appendingPathComponent(\"icon_64x64.png\"))\n        try self.icon128.png?.write(to: url.appendingPathComponent(\"icon_64x64@2x.png\"))\n        try self.icon128.png?.write(to: url.appendingPathComponent(\"icon_128x128.png\"))\n        try self.icon256.png?.write(to: url.appendingPathComponent(\"icon_128x128@2x.png\"))\n        try self.icon256.png?.write(to: url.appendingPathComponent(\"icon_256x256.png\"))\n        try self.icon512.png?.write(to: url.appendingPathComponent(\"icon_256x256@2x.png\"))\n        try self.icon512.png?.write(to: url.appendingPathComponent(\"icon_512x512.png\"))\n        try self.icon1024.png?.write(to: url.appendingPathComponent(\"icon_512x512@2x.png\"))\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconTemplete+.swift",
    "content": "//\n//  FolderFillIconImage.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\nimport CoreGraphics\n\nstruct OriginalIconTemplete: IconTemplete {\n    let title: String = \"Original\"\n    let identifier: String = \"original\"\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        return image.resizedAspectFit(to: [scale.size, scale.size], fillColor: .clear)\n    }\n}\n\nstruct RoundedRectIconTemplete: IconTemplete {\n    let title: String = \"Rounded\"\n    let identifier: String = \"rounded\"\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        let size: CGSize = [scale.size, scale.size]\n        \n        let scaleFactor = scale.size / 1024\n        return NSImage(size: size, cgcanvas: { context in\n            let imageRect = CGRect(size: size).slimmed(by: 64 * scaleFactor)\n            let image = IconTempleteHelper.fillToRect(rect: imageRect, image: image, size: size).cgImage!\n            let cornerRadius = 64 * scaleFactor\n            let circlePath = CGPath(roundedRect: imageRect, cornerWidth: cornerRadius, cornerHeight: cornerRadius, transform: nil)\n            context.saveGState()\n            context.setFillColor(.white)\n            context.addPath(circlePath)\n            context.setShadow(offset: [0, -7] * scaleFactor, blur: 20 * scaleFactor, color: NSColor.black.withAlphaComponent(0.5).cgColor)\n            context.fillPath()\n            context.restoreGState()\n            \n            context.addPath(circlePath)\n            context.clip()\n            context.draw(image, in: context.bounds)\n            context.resetClip()\n        })\n    }\n}\n\nstruct CircleIconTemplete: IconTemplete {\n    let title: String = \"Circle\"\n    let identifier: String = \"circle\"\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        let size: CGSize = [scale.size, scale.size]\n        \n        let scaleFactor = scale.size / 1024\n        return NSImage(size: size, cgcanvas: { context in\n            let imageRect = CGRect(size: size).slimmed(by: 64 * scaleFactor)\n            let image = IconTempleteHelper.fillToRect(rect: imageRect, image: image, size: size).cgImage!\n            let circlePath = CGPath(ellipseIn: imageRect, transform: nil)\n            context.saveGState()\n            context.setFillColor(.white)\n            context.addPath(circlePath)\n            context.setShadow(offset: [0, -7] * scaleFactor, blur: 20 * scaleFactor, color: NSColor.black.withAlphaComponent(0.5).cgColor)\n            context.fillPath()\n            context.restoreGState()\n            \n            context.addPath(circlePath)\n            context.clip()\n            context.draw(image, in: context.bounds)\n            context.resetClip()\n        })\n    }\n}\n\nstruct AndroidIconTemplete: IconTemplete {\n    let title: String = \"Android\"\n    let identifier: String = \"android\"\n    \n    private static let mask = IconSet(make: { Bundle.main.image(forResource: \"android_mask.png\")!.resized(to: [$0.size, $0.size]) })!\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        let mask = Self.mask.image(for: scale)\n        let size: CGSize = [scale.size, scale.size]\n        return NSImage(size: size, cgcanvas: { context in\n            let image = IconTempleteHelper.fillToRect(rect: CGRect(size: size), image: image, size: size).cgImage!\n            \n            context.clip(to: context.bounds, mask: mask.cgImage!.convertToGrayscale())\n            context.setFillColor(.white)\n            context.fill(context.bounds)\n            context.draw(image, in: context.bounds)\n        })\n    }\n}\n\nstruct BigSurFillIconTemplete: IconTemplete {\n    let title: String = \"Big Sur Icon\"\n    let identifier: String = \"bigsur_icon\"\n    private static let background = IconSet(bundleResouces: { \"squircle_back_\\($0.point)x\\($0.point).png\" })!\n    private static let mask = IconSet(bundleResouces: { \"squircle_mask_\\($0.point)x\\($0.point).png\" })!\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        let background = Self.background.image(for: scale)\n        let mask = Self.mask.image(for: scale)\n        \n        return NSImage(size: background.size, cgcanvas: { context in\n            let image = IconTempleteHelper.fillToRect(rect: folderRect(scale), image: image, size: background.size).cgImage!\n            \n            context.draw(background.cgImage!, in: context.bounds)\n            context.clip(to: context.bounds, mask: mask.cgImage!.convertToGrayscale())\n            context.draw(image, in: context.bounds)\n        })\n    }\n    \n    private func folderRect(_ scale: IconSet.Scale) -> CGRect {\n        CGRect(origin: [100, 100] * (scale.size / 1024), size: [824, 824] * (scale.size / 1024))\n    }\n}\n\nstruct FolderCenterEngravedIconTemplete: IconTemplete {\n    let title: String = \"Folder (Engraved)\"\n    let identifier: String = \"folder_engraved\"\n    let embossColor = NSColor(patternImage: NSImage(named: \"watermark_mask_bs.png\")!)\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        let background = backgroundIconSet.image(for: scale)\n        \n        return NSImage(size: background.size, cgcanvas: { context in\n            let sizeImage = IconTempleteHelper.fitToRect(rect: imageRect(scale), image: image, size: background.size)\n            context.draw(background.cgImage!, in: context.bounds)\n            let maskImage = maskImage(image: sizeImage, color: embossColor.cgColor, size: background.size).cgImage!\n            context.setShadow(offset: [0, -2] * (scale.size / 512), blur: 2 * (scale.size / 512), color: NSColor.white.withAlphaComponent(0.2).cgColor)\n            context.draw(maskImage, in: context.bounds)\n        })\n    }\n        \n    private func maskImage(image: NSImage, color: CGColor, size: CGSize) -> NSImage {\n        NSImage(size: size, cgcanvas: { context in\n            context.setFillColor(.clear)\n            context.fill(context.bounds)\n            context.clip(to: context.bounds, mask: image.cgImage!)\n            context.setFillColor(color)\n            context.fill(context.bounds)\n        })\n    }\n    \n    private func imageRect(_ scale: IconSet.Scale) -> CGRect {\n        switch scale {\n        case .x1024: return CGRect(origin: [248, 235], size: [530, 530])\n        default: return CGRect(origin: [130, 115] * (scale.size / 512), size: [255, 255] * (scale.size / 512))\n        }\n    }\n}\n\nstruct FolderCenterIconTemplete: IconTemplete {\n    let title: String = \"Folder (Center)\"\n    let identifier: String = \"folder_center\"\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        let background = backgroundIconSet.image(for: scale)\n        \n        return NSImage(size: background.size, cgcanvas: { context in\n            let image = IconTempleteHelper.fitToRect(rect: imageRect(scale), image: image, size: background.size).cgImage!\n            context.draw(background.cgImage!, in: context.bounds)\n            context.draw(image, in: context.bounds)\n        })\n    }\n\n    private func imageRect(_ scale: IconSet.Scale) -> CGRect {\n        switch scale {\n        case .x1024: return CGRect(origin: [248, 235], size: [530, 530])\n        default: return CGRect(origin: [130, 115] * (scale.size / 512), size: [255, 255] * (scale.size / 512))\n        }\n    }\n}\n\nstruct FolderFillIconTemplete: IconTemplete {\n    let title: String = \"Folder (Fill)\"\n    let identifier: String = \"folder_fill\"\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage {\n        let background = backgroundIconSet.image(for: scale)\n        let mask = maskIconSet.image(for: scale)\n        let top = topIconSet.image(for: scale)\n        \n        return NSImage(size: background.size, cgcanvas: { context in\n            let image = IconTempleteHelper.fillToRect(rect: folderRect(scale), image: image, size: background.size).cgImage!\n            \n            context.draw(background.cgImage!, in: context.bounds)\n            context.clip(to: context.bounds, mask: mask.cgImage!.convertToGrayscale())\n            context.draw(image, in: context.bounds)\n            context.resetClip()\n            context.clip(to: context.bounds, mask: image)\n            context.setAlpha(0.75)\n            context.draw(top.cgImage!, in: context.bounds)\n        })\n    }\n    \n    private func folderRect(_ scale: IconSet.Scale) -> CGRect {\n        switch scale {\n        case .x1024: return CGRect(origin: [24, 113], size: [974, 820])\n        default: return CGRect(origin: [20, 55] * (scale.size / 512), size: [471, 397] * (scale.size / 512))\n        }\n    }\n}\n\nenum IconTempleteHelper {\n    static func fillToRect(rect: CGRect, image: NSImage, size: CGSize) -> NSImage {\n        NSImage(size: size, cgcanvas: { context in\n            let imageSize = image.size * image.size.aspectFillRatio(fillInside: rect.size)\n            let imageRect = CGRect(center: rect.center, size: imageSize)\n            image.draw(in: imageRect, from: NSRect(size: image.size), operation: .sourceOver, fraction: 1)\n        })\n    }\n    \n    static func fitToRect(rect: CGRect, image: NSImage, size: CGSize) -> NSImage {\n        NSImage(size: size, cgcanvas: { context in\n            let imageSize = image.size * image.size.aspectFitRatio(fitInside: rect.size)\n            let imageRect = CGRect(center: rect.center, size: imageSize)\n            image.draw(in: imageRect, from: NSRect(size: image.size), operation: .sourceOver, fraction: 1)\n        })\n    }\n}\n\nprivate let backgroundIconSet = IconSet(bundleResouces: { \"folder_back_\\($0.point)_bs.png\" })!\nprivate let maskIconSet = IconSet(bundleResouces: { \"folder_mask2_\\($0.point)_bs.png\" })!\nprivate let topIconSet = IconSet(\n    icon16: Bundle.main.image(forResource: \"folder_top_512.png\")!.resized(to: [16, 16]),\n    icon32: Bundle.main.image(forResource: \"folder_top_512.png\")!.resized(to: [32, 32]),\n    icon64: Bundle.main.image(forResource: \"folder_top_512.png\")!.resized(to: [64, 64]),\n    icon128: Bundle.main.image(forResource: \"folder_top_512.png\")!.resized(to: [128, 128]),\n    icon256: Bundle.main.image(forResource: \"folder_top_512.png\")!.resized(to: [256, 256]),\n    icon512: Bundle.main.image(forResource: \"folder_top_512.png\")!,\n    icon1024: Bundle.main.image(forResource: \"folder_top_1024.png\")!\n)\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/Icon Templete/IconTemplete.swift",
    "content": "//\n//  IconImageManager+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/27.\n//\n\nimport CoreUtil\n\nprotocol IconTemplete {\n    var title: String { get }\n    var identifier: String { get }\n    \n    func bake(image: NSImage, scale: IconSet.Scale) -> NSImage\n}\n\nextension IconTemplete {\n    func bakeIconSet(image: NSImage) -> IconSet {\n        IconSet(make: { bake(image: image, scale: $0) })!\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Icon Generator/IconGeneratorView+.swift",
    "content": "//\n//  IconGeneratorView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport CoreUtil\n\nfinal class IconGeneratorViewController: NSViewController {\n    private let cell = IconGeneratorView()\n    \n    @RestorableState(\"icongen.exporttype\") var exportType: IconExportType = .icns\n    @RestorableState(\"icongen.iosopt\") var iosOptions: IosIconGenerator.ExportOptions = [.iphone, .ipad]\n    @RestorableState(\"icongen.scale\") var scale: IconSet.Scale = .x1024\n    @RestorableData(\"icongen.image\") var imageItem: ImageItem? = nil\n    @RestorableData(\"icongen.templete\") var templeteName = \"original\"\n    @Observable var iconTemplete: IconTemplete? = nil { didSet { templeteName = iconTemplete?.identifier ?? \"original\" } }\n    @Observable var previewImage: NSImage? = nil\n    \n    let iconTempleteManager = IconImageManager.shared\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$previewImage\n            .sink{[unowned self] in self.cell.imageDropView.image = $0 }.store(in: &objectBag)\n        self.$exportType\n            .sink{[unowned self] in self.cell.exportTypePicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$iosOptions\n            .sink{[unowned self] in self.bindiOSOptionsView($0) }.store(in: &objectBag)\n        self.$iconTemplete\n            .sink{[unowned self] in self.cell.iconTempletePicker.selectedMenuTitle = $0?.title }.store(in: &objectBag)\n        self.$scale\n            .sink{[unowned self] in self.cell.scalePicker.selectedItem = $0 }.store(in: &objectBag)\n        \n        self.cell.clearButton.actionPublisher\n            .sink{[unowned self] in self.imageItem = nil; updatePreviewImage() }.store(in: &objectBag)\n        self.cell.scalePicker.itemPublisher\n            .sink{[unowned self] in self.scale = $0 }.store(in: &objectBag)\n        self.cell.imageDropView.imagePublisher\n            .sink{[unowned self] in self.imageItem = $0; updatePreviewImage() }.store(in: &objectBag)\n        self.cell.exportTypePicker.itemPublisher\n            .sink{[unowned self] in self.exportType = $0; updateOptionView() }.store(in: &objectBag)\n        self.cell.exportButton.actionPublisher\n            .sink{[unowned self] in self.exportIcon() }.store(in: &objectBag)\n        self.cell.iosOptionsView.iPhoneSwitch.isOnPublisher\n            .sink{[unowned self] in self.iosOptions = $0 ? iosOptions.union(.iphone) : iosOptions.subtracting(.iphone) }.store(in: &objectBag)\n        self.cell.iosOptionsView.iPadSwitch.isOnPublisher\n            .sink{[unowned self] in self.iosOptions = $0 ? iosOptions.union(.ipad) : iosOptions.subtracting(.ipad) }.store(in: &objectBag)\n        self.cell.iosOptionsView.appleWatchSwitch.isOnPublisher\n            .sink{[unowned self] in self.iosOptions = $0 ? iosOptions.union(.applewatch) : iosOptions.subtracting(.applewatch) }.store(in: &objectBag)\n        self.cell.iosOptionsView.carplaySwitch.isOnPublisher\n            .sink{[unowned self] in self.iosOptions = $0 ? iosOptions.union(.carplay) : iosOptions.subtracting(.carplay) }.store(in: &objectBag)\n        self.cell.iosOptionsView.macSwitch.isOnPublisher\n            .sink{[unowned self] in self.iosOptions = $0 ? iosOptions.union(.mac) : iosOptions.subtracting(.mac) }.store(in: &objectBag)\n        \n        for templete in self.iconTempleteManager.templetes {\n            self.cell.iconTempletePicker.menuItems.append(NSMenuItem(title: templete.title) {\n                self.iconTemplete = templete\n                self.updatePreviewImage()\n            })\n        }\n        \n        self.iconTemplete = self.iconTempleteManager.templete(for: self.templeteName) ?? self.iconTempleteManager.templetes.first\n        self.updatePreviewImage()\n        self.updateOptionView()\n    }\n    \n    private func updatePreviewImage() {\n        guard let imageItem = imageItem else { return previewImage = nil }\n        \n        if let iconTemplete = iconTemplete {\n            self.previewImage = iconTemplete.bake(image: imageItem.image, scale: .x512)\n        } else {\n            self.previewImage = imageItem.image\n        }\n    }\n    \n    private func bindiOSOptionsView(_ options: IosIconGenerator.ExportOptions) {\n        self.cell.iosOptionsView.iPhoneSwitch.isOn = options.contains(.iphone)\n        self.cell.iosOptionsView.iPadSwitch.isOn = options.contains(.ipad)\n        self.cell.iosOptionsView.appleWatchSwitch.isOn = options.contains(.applewatch)\n        self.cell.iosOptionsView.carplaySwitch.isOn = options.contains(.carplay)\n        self.cell.iosOptionsView.macSwitch.isOn = options.contains(.mac)\n    }\n    \n    private func updateOptionView() {\n        self.cell.iosOptionsView.isHidden = true\n        self.cell.scalePickerArea.isHidden = true\n        switch self.exportType {\n        case .iosAssets: self.cell.iosOptionsView.isHidden = false\n        case .png, .jpeg, .gif: self.cell.scalePickerArea.isHidden = false\n        default: break\n        }\n    }\n    \n    private func exportIcon() {\n        guard let item = imageItem, let filename = exportFilename(), let templete = iconTemplete else { return }\n        let panel = NSSavePanel()\n        panel.nameFieldStringValue = filename\n        guard panel.runModal() == .OK, let url = panel.url else { return }\n                \n        switch self.exportType {\n        case .iconFolder: IconFolderGenerator.make(item: item, templete: templete, to: url) => registerTask(_:)\n        case .iosAssets: IosIconGenerator.make(item: item, options: iosOptions, to: url) => registerTask(_:)\n        case .icns: IcnsGenerator.make(item: item, templete: templete, to: url) => registerTask(_:)\n        case .iconset: IconsetGenerator.make(item: item, templete: templete, to: url) => registerTask(_:)\n        case .androidAssets: AndroidIconGenerator.make(item: item, templete: templete, to: url) => registerTask(_:)\n        case .ico: IcoGenerator.make(item: item, templete: templete, to: url) => registerTask(_:)\n        case .png: PngIconGenerator.make(item: item, templete: templete, scale: scale, to: url) => registerTask(_:)\n        case .jpeg: JpegIconGenerator.make(item: item, templete: templete, scale: scale, to: url) => registerTask(_:)\n        case .gif: GifIconGenerator.make(item: item, templete: templete, scale: scale, to: url) => registerTask(_:)\n        }\n    }\n    \n    private func registerTask(_ task: IconGenerateTask) {\n        task.complete\n            .peekProgressIndicator(\"Generating Icon...\")\n            .sinkWithToast({ \"Icon Exported!\" }, {_ in \"Icon Export Failed!\" })\n    }\n    \n    private func exportFilename() -> String? {\n        guard let item = imageItem else { return nil }\n\n        switch self.exportType {\n        case .icns: return \"\\(item.filenameWithoutExtension).icns\"\n        case .iconFolder: return item.filenameWithoutExtension\n        case .iconset: return \"\\(item.filenameWithoutExtension).iconset\"\n        case .iosAssets: return \"\\(item.filenameWithoutExtension) (iOS Icon)\"\n        case .androidAssets: return \"\\(item.filenameWithoutExtension) (Android Icon)\"\n        case .ico: return \"\\(item.filenameWithoutExtension).ico\"\n        case .png: return \"\\(item.filenameWithoutExtension).png\"\n        case .jpeg: return \"\\(item.filenameWithoutExtension).jpg\"\n        case .gif: return \"\\(item.filenameWithoutExtension).gif\"\n        }\n    }\n}\n\nenum IconExportType: String, TextItem {\n    case iconFolder = \"Icon Folder\"\n    case iosAssets = \"iOS\"\n    case androidAssets = \"Android\"\n    case icns = \"ICNS\"\n    case iconset = \"Icon Set\"\n    case ico = \"ICO\"\n    case png = \"PNG\"\n    case jpeg = \"JPEG\"\n    case gif = \"GIF\"\n    \n    var title: String { rawValue }\n}\n\nextension IconSet.Scale: TextItem {\n    static let allCases: [IconSet.Scale] = [.x16, .x32, .x64, .x128, .x256, .x512, .x1024]\n    \n    var title: String {\n        switch self {\n        case .x16: return \"16px\"\n        case .x32: return \"32px\"\n        case .x64: return \"64px\"\n        case .x128: return \"128px\"\n        case .x256: return \"256px\"\n        case .x512: return \"512px\"\n        case .x1024: return \"1024px\"\n        }\n    }\n}\n\nfinal private class IconGeneratorView: Page {\n    let exportTypePicker = EnumPopupButton<IconExportType>()\n    let iconTempletePicker = PopupButton()\n    let imageDropView = ImageDropView()\n    let iosOptionsView = iOSOptionsView()\n    let scalePicker = EnumPopupButton<IconSet.Scale>()\n    lazy var scalePickerArea = Area(icon: R.Image.paramators, title: \"Scale\", control: scalePicker)\n    let clearButton = SectionButton(title: \"Clear\".localized(), image: R.Image.clear)\n    let exportButton = Button(title: \"Export\")\n    \n    override func onAwake() {\n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.export, title: \"Icon Export Type\", control: exportTypePicker),\n            Area(icon: R.Image.paramators, title: \"Templetes\", control: iconTempletePicker)\n        ]))\n        \n        self.addSection2(\n            Section(title: \"Source\".localized(), items: [\n                imageDropView => {\n                    $0.snp.makeConstraints{ make in\n                        make.height.equalTo(320)\n                    }\n                }\n            ], toolbarItems: [clearButton]),\n            \n            Section(title: \"Options\", items: [\n                scalePickerArea,\n                iosOptionsView,\n                exportButton\n            ])\n        )\n    }\n}\n\nfinal private class iOSOptionsView: NSLoadStackView {\n    let iPhoneSwitch = NSSwitch()\n    let iPadSwitch = NSSwitch()\n    let appleWatchSwitch = NSSwitch()\n    let carplaySwitch = NSSwitch()\n    let macSwitch = NSSwitch()\n    \n    override func onAwake() {\n        self.orientation = .vertical\n        self.addArrangedSubview(Area(icon: R.Image.iphone, title: \"iPhone\", control: iPhoneSwitch))\n        self.addArrangedSubview(Area(icon: R.Image.iphone, title: \"iPad\", control: iPadSwitch))\n        self.addArrangedSubview(Area(icon: R.Image.appleWatch, title: \"Apple Watch\", control: appleWatchSwitch))\n        self.addArrangedSubview(Area(icon: R.Image.carplay, title: \"CarPlay\", control: carplaySwitch))\n        self.addArrangedSubview(Area(icon: R.Image.mac, title: \"Mac\", control: macSwitch))\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/Exporters/DefaultImageExporter.swift",
    "content": "//\n//  DefaultImageExporter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/18.\n//\n\nimport CoreUtil\n\nenum ImageExportError: Error {\n    case nonData\n}\n\nenum DefaultImageExporter {\n    static func exportPNG(_ image: NSImage, to url: URL) -> Promise<Void, Error> {\n        .tryAsync {\n            guard let data = image.png else { throw ImageExportError.nonData }\n            try data.write(to: url)\n        }\n    }\n    static func exportGIF(_ image: NSImage, to url: URL) -> Promise<Void, Error> {\n        .tryAsync {\n            guard let data = image.gif else { throw ImageExportError.nonData }\n            try data.write(to: url)\n        }\n    }\n    static func exportJPEG(_ image: NSImage, to url: URL) -> Promise<Void, Error> {\n        .tryAsync {\n            guard let data = image.jpeg else { throw ImageExportError.nonData }\n            try data.write(to: url)\n        }\n    }\n    static func exportTIFF(_ image: NSImage, to url: URL) -> Promise<Void, Error> {\n        .tryAsync {\n            guard let data = image.tiffRepresentation else { throw ImageExportError.nonData }\n            try data.write(to: url)\n        }\n    }\n}\n\n\nextension NSImage {\n    public var png: Data? { self.data(for: .png) }\n    public var jpeg: Data? {  self.data(for: .jpeg) }\n    public var gif: Data? {  self.data(for: .gif)  }\n    \n    public convenience init(cgImage: CGImage) { self.init(cgImage: cgImage, size: cgImage.size) }\n    \n    public func data(for fileType: NSBitmapImageRep.FileType, properties: [NSBitmapImageRep.PropertyKey : Any] = [:]) -> Data? {\n        guard\n            let tiffRepresentation = self.tiffRepresentation,\n            let bitmap = NSBitmapImageRep(data: tiffRepresentation),\n            let rep = bitmap.representation(using: fileType, properties: properties)\n        else { return nil }\n        \n        return rep\n    }\n}\n\nextension CGImage {\n    public var size: CGSize { CGSize(width: self.width, height: self.height) }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/Exporters/HeicImageExporter.swift",
    "content": "//\n//  HeicConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/18.\n//\n\nimport AVFoundation\nimport CoreUtil\n\nenum HeicExportError: Error {\n    case heicNotSupported\n    case cgImageMissing\n    case couldNotFinalize\n}\n\nenum HeicImageExporter {\n    static func export(_ image: NSImage, to url: URL) -> Promise<Void, Error> {\n        Promise.tryAsync{\n            let data = NSMutableData()\n            guard let cgImage = image.cgImage else { throw HeicExportError.cgImageMissing }\n            guard let destination = CGImageDestinationCreateWithData(data, AVFileType.heic as CFString, 1, nil) else { throw HeicExportError.heicNotSupported }\n            CGImageDestinationAddImage(destination, cgImage, [:] as CFDictionary)\n            guard CGImageDestinationFinalize(destination) else { throw HeicExportError.couldNotFinalize }\n            try data.write(to: url)\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/Exporters/WebpImageExporter.swift",
    "content": "//\n//  WebpExporter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/18.\n//\n\nimport CoreUtil\n\nenum WebpExportError: Error {\n    case noImageData\n}\n\nenum WebpImageExporter {\n    private static let cwebpURL = Bundle.current.url(forResource: \"cwebp\", withExtension: nil)!\n    private static let inputDataURL = FileManager.temporaryDirectoryURL.appendingPathComponent(\"WebpInputData\") => {\n        try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)\n    }\n    \n    static func export(_ image: NSImage, to url: URL) -> Promise<Void, Error> {\n        Promise<URL, Error>.tryAsync{\n            let url = inputDataURL.appendingPathComponent(UUID().uuidString)\n            guard let data = image.tiffRepresentation else { throw WebpExportError.noImageData }\n            try data.write(to: url)\n            return url\n        }\n        .flatPeek{ Terminal.run(cwebpURL, arguments: [$0.path, \"-o\", url.path]) }\n        .tryPeek{ try FileManager.default.removeItem(at: $0) }\n        .eraseToVoid()\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/ImageConverter.swift",
    "content": "//\n//  ImageConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nstruct ImageConvertTask {\n    let image: NSImage\n    let title: String\n    let size: CGSize\n    let destinationURL: URL\n    let isDone: Promise<Void, Error>\n}\n\nenum ImageConverter {\n    private static let destinationDirectory = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask)[0].appendingPathComponent(\"DevToys\") => {\n        try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)\n    }\n    \n    static func convert(_ item: ImageItem, format: ImageFormatType, resize: Bool, size: CGSize, scale: ImageScaleMode) -> ImageConvertTask {\n        var image = item.image\n        \n        if resize {\n            switch scale {\n            case .scaleToFill: image = image.resizedAspectFill(to: size)\n            case .scaleToFit: image = image.resizedAspectFit(to: size)\n            }\n        }\n        \n        let filename = \"\\(item.filenameWithoutExtension).\\(format.exp)\"\n        let destinationURL = destinationDirectory.appendingPathComponent(filename)\n        let isDone = exportPromise(image, to: format, destinationURL: destinationURL)\n            .receive(on: .main)\n            .peek{ NSWorkspace.shared.activateFileViewerSelecting([destinationURL]) }\n        \n        return ImageConvertTask(image: item.image, title: item.filename, size: item.image.size, destinationURL: destinationURL, isDone: isDone)\n    }\n    \n    private static func exportPromise(_ image: NSImage, to format: ImageFormatType, destinationURL: URL) -> Promise<Void, Error> {\n        switch format {\n        case .webp: return WebpImageExporter.export(image, to: destinationURL)\n        case .heic: return HeicImageExporter.export(image, to: destinationURL)\n        case .png: return DefaultImageExporter.exportPNG(image, to: destinationURL)\n        case .jpg: return DefaultImageExporter.exportJPEG(image, to: destinationURL)\n        case .gif: return DefaultImageExporter.exportGIF(image, to: destinationURL)\n        case .tiff: return DefaultImageExporter.exportTIFF(image, to: destinationURL)\n        }\n    }    \n}\n\nenum ImageFormatType: String, TextItem {\n    case png = \"PNG Format\"\n    case jpg = \"JPEG Format\"\n    case tiff = \"TIFF Format\"\n    case gif = \"GIF Format\"\n    case webp = \"Webp Format\"\n    case heic = \"Heic Format\"\n    \n    var title: String { rawValue.localized() }\n    \n    var exp: String {\n        switch self {\n        case .png: return \"png\"\n        case .jpg: return \"jpg\"\n        case .gif: return \"gif\"\n        case .tiff: return \"tiff\"\n        case .webp: return \"webp\"\n        case .heic: return \"heic\"\n        }\n    }\n}\n\nenum ImageScaleMode: String, TextItem {\n    case scaleToFill = \"Scale to Fill\"\n    case scaleToFit = \"Scale to Fit\"\n    \n    var title: String { rawValue.localized() }\n}\n\nextension NSImage {\n    func resizedAspectFill(to newSize: CGSize) -> NSImage {\n        let bitmapRep = NSBitmapImageRep(size: newSize)\n        let scale = self.size.aspectFillRatio(fillInside: newSize)\n        \n        NSGraphicsContext(bitmapImageRep: bitmapRep)?.perform {\n            self.draw(in: CGRect(center: newSize.convertToPoint()/2, size: self.size * scale), from: .zero, operation: .copy, fraction: 1.0)\n        }\n        \n        return NSImage(bitmapImageRep: bitmapRep)\n    }\n    \n    func resizedAspectFit(to newSize: CGSize, fillColor: NSColor = .black) -> NSImage {\n        let bitmapRep = NSBitmapImageRep(size: newSize)\n        let scale = self.size.aspectFitRatio(fitInside: newSize)\n        \n        NSGraphicsContext(bitmapImageRep: bitmapRep)?.perform {\n            fillColor.setFill()\n            NSRect(size: newSize).fill()\n            draw(in: CGRect(center: newSize.convertToPoint()/2, size: self.size * scale), from: .zero, operation: .sourceOver, fraction: 1.0)\n        }\n        \n        return NSImage(bitmapImageRep: bitmapRep)\n    }\n    \n    \n    func resized(to newSize: NSSize) -> NSImage {\n        let bitmapRep = NSBitmapImageRep(size: newSize)\n        \n        NSGraphicsContext(bitmapImageRep: bitmapRep)?.perform {\n            draw(in: NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height), from: .zero, operation: .copy, fraction: 1.0)\n        }\n        \n        return NSImage(bitmapImageRep: bitmapRep)\n    }\n}\n\nextension NSGraphicsContext {\n    public func perform(_ block: () -> ()) {\n        NSGraphicsContext.saveGraphicsState()\n        NSGraphicsContext.current = self\n        block()\n        NSGraphicsContext.restoreGraphicsState()\n    }\n}\n\nextension NSImage {\n    public convenience init(bitmapImageRep: NSBitmapImageRep) {\n        self.init(size: bitmapImageRep.size)\n        self.addRepresentation(bitmapImageRep)\n    }\n    public convenience init(size: CGSize, colorSpaceName: NSColorSpaceName = .calibratedRGB, canvas: () -> ()) {\n        let bitmapImageRep = NSBitmapImageRep(size: size, colorSpaceName: colorSpaceName)\n        NSGraphicsContext(bitmapImageRep: bitmapImageRep)?.perform(canvas)\n        self.init(bitmapImageRep: bitmapImageRep)\n    }\n    public convenience init(size: CGSize, colorSpaceName: NSColorSpaceName = .calibratedRGB, cgcanvas: (CGContext) -> ()) {\n        self.init(size: size, colorSpaceName: colorSpaceName, canvas: {\n            if let context = NSGraphicsContext.current?.cgContext { cgcanvas(context) }\n        })\n    }\n}\n\nextension NSBitmapImageRep {\n    public convenience init(size: CGSize, colorSpaceName: NSColorSpaceName = .calibratedRGB) {\n        self.init(\n            bitmapDataPlanes: nil, pixelsWide: Int(size.width), pixelsHigh: Int(size.height),\n            bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false,\n            colorSpaceName: colorSpaceName, bytesPerRow: 0, bitsPerPixel: 0\n        )!\n    }\n}\n\n\nextension CGContext {\n    public var size: CGSize { CGSize(width: width, height: height) }\n    public var bounds: CGRect { CGRect(size: size) }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Converter/ImageConverterView+.swift",
    "content": "//\n//  ImageConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class ImageConverterViewController: NSViewController {\n    private let cell = ImageConverterView()\n    \n    @RestorableState(\"imc.format\") private var format = ImageFormatType.png\n    @RestorableState(\"imc.scaleMode\") private var scaleMode = ImageScaleMode.scaleToFill\n    @RestorableState(\"imc.resize\") private var resize = false\n    @RestorableState(\"imc.width\") private var width = 1280.0\n    @RestorableState(\"imc.height\") private var height = 720.0\n    \n    @Observable var task: [ImageConvertTask] = []\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$format\n            .sink{[unowned self] in cell.formatTypePicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$task\n            .sink{[unowned self] in cell.listView.convertTasks = $0 }.store(in: &objectBag)\n        self.$resize\n            .sink{[unowned self] in cell.resizeSwitch.isOn = $0; cell.resizeOptionStack.isHidden = !$0 }.store(in: &objectBag)\n        self.$scaleMode\n            .sink{[unowned self] in cell.scaleModePicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$width\n            .sink{[unowned self] in self.cell.widthField.value = $0 }.store(in: &objectBag)\n        self.$height\n            .sink{[unowned self] in self.cell.heightField.value = $0 }.store(in: &objectBag)\n        \n        self.cell.resizeSwitch.isOnPublisher\n            .sink{[unowned self] in self.resize = $0 }.store(in: &objectBag)\n        self.cell.widthField.valuePublisher\n            .sink{[unowned self] in self.width = $0.reduce(width).clamped(1...) }.store(in: &objectBag)\n        self.cell.heightField.valuePublisher\n            .sink{[unowned self] in self.height = $0.reduce(height).clamped(1...) }.store(in: &objectBag)\n        self.cell.scaleModePicker.itemPublisher\n            .sink{[unowned self] in self.scaleMode = $0 }.store(in: &objectBag)\n        self.cell.formatTypePicker.itemPublisher\n            .sink{[unowned self] in self.format = $0 }.store(in: &objectBag)\n        self.cell.dragPublisher\n            .sink{[unowned self] in self.readURLs($0) }.store(in: &objectBag)\n    }\n    \n    private func readURLs(_ pasteboard: NSPasteboard) {\n        let newImageItems = ImageDropper.images(fromPasteboard: pasteboard)\n        guard !newImageItems.isEmpty else { return }\n        \n        self.task.append(contentsOf: newImageItems.map{\n            ImageConverter.convert($0, format: format, resize: self.resize, size: [CGFloat(width), CGFloat(height)], scale: scaleMode)\n        })\n        \n        self.cell.listView.scrollView.contentView.scrollToBottom()\n    }\n}\n\nfinal private class ImageConverterView: Page {\n    \n    let formatTypePicker = EnumPopupButton<ImageFormatType>()\n    let resizeSwitch = NSSwitch()\n    let widthField = NumberField()\n    let heightField = NumberField()\n    let scaleModePicker = EnumPopupButton<ImageScaleMode>()\n    let listView = ImageListView()\n    let dragPublisher = PassthroughSubject<NSPasteboard, Never>()\n    \n    lazy var resizeOptionStack = NSStackView() => {\n        let spacer = NSView()\n        $0.distribution = .fillProportionally\n        $0.addArrangedSubview(spacer)\n        $0.setCustomSpacing(0, after: spacer)\n        $0.addArrangedSubview(Area(title: \"Scale\".localized(), control: scaleModePicker))\n        $0.addArrangedSubview(Area(title: \"Size\".localized(), control: NSStackView() => {\n            $0.addArrangedSubview(widthField => {\n                $0.snp.makeConstraints{ make in\n                    make.width.equalTo(80)\n                }\n            })\n            $0.addArrangedSubview(NSTextField(labelWithString: \"x\"))\n            $0.addArrangedSubview(heightField => {\n                $0.snp.makeConstraints{ make in\n                    make.width.equalTo(80)\n                }\n            })\n        }))\n    }\n    \n    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {\n        if sender.draggingPasteboard.canReadTypes([.URL, .fileURL, .fileContents]) { return .copy } else { return .none }\n    }\n    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {\n        guard let urls = sender.draggingPasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL], !urls.isEmpty else { return false }\n        self.dragPublisher.send(sender.draggingPasteboard)\n        return true\n    }\n    \n    override func layout() {\n        listView.snp.remakeConstraints{ make in\n            make.height.equalTo(max(200, self.frame.height - 380))\n        }\n        super.layout()\n    }\n    \n    override func onAwake() {\n        self.registerForDraggedTypes([.URL, .fileURL, .fileContents])\n\n        self.addSection(\n            Section(title: \"Configuration\".localized(), items: [\n                Area(icon: R.Image.format, title: \"Image Format\".localized(), control: formatTypePicker),\n                Area(icon: R.Image.paramators, title: \"Resize\".localized(), control: resizeSwitch),\n                resizeOptionStack\n            ])\n        )\n        \n        self.addSection(Section(title: \"Converted Images\".localized(), items: [listView]))\n    }\n}\n\nfinal private class ImageListView: NSLoadView {\n    let scrollView = NSScrollView()\n    let listView = NSTableView.list()\n    var convertTasks = [ImageConvertTask]() { didSet { listView.reloadData() } }\n    \n    override func updateLayer() {\n        self.layer?.backgroundColor = R.Color.controlBackgroundColor.cgColor\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.cornerRadius = R.Size.corner\n        self.addSubview(scrollView)\n        self.scrollView.drawsBackground = false\n        self.scrollView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.scrollView.documentView = listView\n        self.listView.delegate = self\n        self.listView.dataSource = self\n        \n        let menu = NSMenu()\n        menu.addItem(title: \"Open in Finder\".localized()) { [self] in\n            if let task = convertTasks.at(listView.clickedRow) {\n                NSWorkspace.shared.activateFileViewerSelecting([task.destinationURL])\n            }\n        }\n        self.listView.menu = menu\n    }\n}\n\nextension ImageListView: NSTableViewDataSource, NSTableViewDelegate {\n    func numberOfRows(in tableView: NSTableView) -> Int { convertTasks.count }\n    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { 46 }\n    \n    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        let cell = ImageListCell()\n        let task = convertTasks[row]\n        cell.imageView.image = task.image\n        cell.titleLabel.stringValue = task.title\n        cell.sizeLabel.stringValue = \"\\(task.size.width.formattedString()) x \\(task.size.height.formattedString())\"\n        task.isDone\n            .finally {\n                cell.checkImageView.isHidden = false\n                cell.progressIndicator.isHidden = true\n            }\n            .sink({\n                cell.checkImageView.image = R.Image.check\n                }, {\n                    print($0)\n                    cell.checkImageView.image = R.Image.error\n                }\n            )\n        \n        return cell\n    }\n}\n\nfinal private class ImageListCell: NSLoadStackView {\n    let imageView = NSImageView()\n    let titleLabel = NSTextField(labelWithString: \"Sample.png\") => {\n        $0.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n        $0.lineBreakMode = .byTruncatingTail\n    }\n    let checkImageView = NSImageView()\n    let progressIndicator = NSProgressIndicator()\n    let sizeLabel = NSTextField(labelWithString: \"100 x 100\") => {\n        $0.font = .systemFont(ofSize: R.Size.controlFontSize)\n        $0.textColor = .secondaryLabelColor\n        $0.lineBreakMode = .byTruncatingTail\n    }\n    \n    override func updateLayer() {\n        imageView.layer?.backgroundColor = NSColor.tertiaryLabelColor.withAlphaComponent(0.05).cgColor\n    }\n    \n    override func onAwake() {\n        self.imageView.wantsLayer = true\n        self.imageView.layer?.cornerRadius = R.Size.corner\n        \n        self.addArrangedSubview(checkImageView)\n        self.checkImageView.isHidden = true\n        self.checkImageView.snp.makeConstraints{ make in\n            make.size.equalTo(16)\n        }\n        \n        self.addArrangedSubview(progressIndicator)\n        self.progressIndicator.style = .spinning\n        self.progressIndicator.startAnimation(nil)\n        self.progressIndicator.snp.makeConstraints{ make in\n            make.size.equalTo(16)\n        }\n        \n        self.addArrangedSubview(imageView)\n        self.spacing = 16\n        self.edgeInsets = .init(x: 16, y: 4)\n        self.imageView.snp.makeConstraints{ make in\n            make.width.equalTo(48)\n            make.height.equalTo(28)\n        }\n        \n        let titleStack = NSStackView()\n        self.addArrangedSubview(titleStack)\n        titleStack.orientation = .vertical\n        titleStack.alignment = .left\n        titleStack.spacing = 4\n        titleStack.distribution = .fillProportionally\n        titleStack.addArrangedSubview(titleLabel)\n        titleStack.addArrangedSubview(sizeLabel)\n        titleStack.snp.makeConstraints{ make in\n            make.right.equalToSuperview().inset(16)\n        }\n    }\n}\n\nprivate let formatter = NumberFormatter() => { $0.maximumFractionDigits = 2 }\n\nextension CGFloat {\n    public func formattedString() -> String { formatter.string(from: NSNumber(value: native)) ?? \"0\" }\n}\n\nextension Double {\n    public func formattedString() -> String { formatter.string(from: NSNumber(value: self)) ?? \"0\" }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Optimizer/ImageOptimaizerView.swift",
    "content": "//\n//  Image Optimizer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class ImageOptimizerViewController: NSViewController {\n    private let cell = ImageOptimizerView()\n    \n    @Observable var tasks = [ImageOptimizeTask]()\n    @RestorableState(\"imop.level\") var level = OptimizeLevel.medium\n    @RestorableState(\"imop.override\") var overrideSource = false\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.cell.urlPublisher\n            .sink{[unowned self] in processFiles($0) }.store(in: &objectBag)\n        self.cell.deletePublisher\n            .sink{[unowned self] in deleteResult($0) }.store(in: &objectBag)\n        self.cell.levelPicker.itemPublisher\n            .sink{[unowned self] in self.level = $0 }.store(in: &objectBag)\n        self.cell.overrideSwiftch.isOnPublisher\n            .sink{[unowned self] in self.overrideSource = $0 }.store(in: &objectBag)\n        \n        self.$tasks\n            .sink{[unowned self] in self.cell.tasks = $0 }.store(in: &objectBag)\n        self.$level\n            .sink{[unowned self] in self.cell.levelPicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$overrideSource\n            .sink{[unowned self] in self.cell.overrideSwiftch.isOn = $0 }.store(in: &objectBag)\n        \n        self.cell.listView.menu = NSMenu() => { menu in\n            menu.addItem(title: \"Open in Finder\".localized()) { [self] in\n                if let task = tasks.at(cell.listView.clickedRow) {\n                    NSWorkspace.shared.activateFileViewerSelecting([task.url])\n                }\n            }\n        }\n    }\n    \n    private func deleteResult(_ indexes: [Int]) {\n        indexes.reversed().forEach{\n            if case .pending = self.tasks[$0].result.state {} else {\n                self.tasks.remove(at: $0)\n            }\n        }\n    }\n    private func processFiles(_ urls: [URL]) {\n        do {\n            self.tasks.append(contentsOf: try urls.compactMap{\n                try ImageOptimizer.optimize($0, override: overrideSource, optimizeLevel: level)\n            })\n        } catch ImageOptimizeError.noAccessToDirectory(let url) {\n            Toast(message: \"No access to directory '\\(url.lastPathComponent)'\", color: .systemRed).show()\n        } catch ImageOptimizeError.unkownType(let fileExtension) {\n            Toast(message: \"Unsupported file type '\\(fileExtension)'\", color: .systemRed).show()\n        } catch {\n            print(error)\n            Toast(message: \"Unkown Error\", color: .systemRed).show()\n        }\n    }\n}\n\n\nfinal private class ImageOptimizerView: Page {\n    let overrideSwiftch = NSSwitch()\n    let listView = ImageListView.list()\n    let listScrollView = NSScrollView()\n    \n    let urlPublisher = PassthroughSubject<[URL], Never>()\n    let deletePublisher = PassthroughSubject<[Int], Never>()\n    \n    var tasks: [ImageOptimizeTask] = [] {\n        didSet {\n            listView.reloadData()\n            self.subviews.forEach{ $0.needsLayout = true }\n        }\n    }\n    let levelPicker = EnumPopupButton<OptimizeLevel>()\n    \n    override func keyDown(with event: NSEvent) {\n        switch event.hotKey {\n        case .delete: deletePublisher.send(self.listView.selectedRowIndexes.map{ $0 })\n        default: super.keyDown(with: event)\n        }\n    }\n    \n    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {\n        if sender.draggingPasteboard.canReadTypes([.URL, .fileURL, .fileContents]) { return .copy }\n        return .none\n    }\n    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {\n        guard let urls = sender.draggingPasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL] else {\n            return false\n        }\n        urlPublisher.send(urls)\n        return true\n    }\n    \n    override func layout() {\n        listScrollView.snp.remakeConstraints{ make in\n            make.height.equalTo(max(200, self.frame.height - 260))\n        }\n        super.layout()\n    }\n    \n    override func onAwake() {\n        self.registerForDraggedTypes([.URL, .fileURL, .fileContents])\n        \n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.paramators, title: \"Optimize Level\".localized(), control: levelPicker),\n            Area(icon: R.Image.export, title: \"Override original file\".localized(), control: overrideSwiftch)\n        ]))\n        \n        self.listScrollView.documentView = listView\n        \n        self.addSection(Section(title: \"Images\".localized(), items: [listScrollView]))\n        self.listView.snp.makeConstraints{ make in\n            make.height.greaterThanOrEqualTo(1) // AppKitのバグ対処用\n        }\n        \n        self.listView.allowsMultipleSelection = true\n        self.listView.delegate = self\n        self.listView.dataSource = self\n    }\n}\n\nextension ImageOptimizerView: NSTableViewDataSource, NSTableViewDelegate {\n    func numberOfRows(in tableView: NSTableView) -> Int { tasks.count }\n    \n    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { 32 }\n    \n    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        let cell = ImageOptimizeCell()\n        let task = tasks[row]\n        cell.titleLabel.stringValue = task.title\n        cell.doneCheckView.isHidden = true\n        cell.indicator.isHidden = false\n        \n        task.result\n            .receive(on: .main)\n            .sink({\n                cell.doneCheckView.isHidden = false\n                cell.indicator.isHidden = true\n                cell.resultLabel.stringValue = $0\n            }, {\n                cell.doneCheckView.isHidden = false\n                cell.indicator.isHidden = true\n                cell.resultLabel.stringValue = \"\\($0)\"\n                cell.resultLabel.textColor = .red\n            })\n        \n        return cell\n    }\n}\n\nfinal private class ImageListView: NSLoadTableView {\n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n    }\n}\n\nfinal private class ImageOptimizeCell: NSLoadView {\n    let titleLabel = NSTextField(labelWithString: \"Title.png\")\n    let resultLabel = NSTextField(labelWithString: \"Optimizing...\")\n    let indicator = NSProgressIndicator()\n    let stackView = NSStackView()\n    let doneCheckView = NSImageView()\n    \n    override func onAwake() {\n        self.addSubview(stackView)\n        self.stackView.edgeInsets = .init(x: 8, y: 8)\n        self.stackView.distribution = .fillProportionally\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.stackView.addArrangedSubview(doneCheckView)\n        self.doneCheckView.isHidden = true\n        self.doneCheckView.image = R.Image.check\n        self.doneCheckView.snp.makeConstraints{ make in\n            make.size.equalTo(16)\n        }\n        \n        self.stackView.addArrangedSubview(indicator)\n        self.indicator.style = .spinning\n        self.indicator.startAnimation(nil)\n        self.indicator.snp.makeConstraints{ make in\n            make.size.equalTo(14)\n        }\n        \n        self.stackView.addArrangedSubview(titleLabel)\n        self.titleLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n        \n        self.stackView.addArrangedSubview(resultLabel)\n        self.resultLabel.alignment = .right\n        self.resultLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n    }\n}\n\n\nextension NSPasteboard {\n    func canReadTypes(_ types: [PasteboardType]) -> Bool {\n        self.canReadItem(withDataConformingToTypes: types.map{ $0.rawValue })\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/Image Optimizer/ImageOptimizer.swift",
    "content": "//\n//  ImageOptimizer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/02.\n//\n\nimport CoreUtil\n\nstruct ImageOptimizeTask {\n    let title: String\n    let url: URL\n    let result: Promise<String, Error>\n}\n\nenum ImageOptimizeError: Error {\n    case noAccessToDirectory(URL)\n    case unkownType(fileExtension: String)\n}\n\nenum OptimizeLevel: String, TextItem {\n    case low = \"Low\"\n    case medium = \"Medium\"\n    case high = \"High\"\n    case veryHigh = \"Very High (Slow)\"\n    \n    var title: String { rawValue.localized() }\n}\n\nenum ImageOptimizer {\n    static func optimize(_ url: URL, override: Bool, optimizeLevel: OptimizeLevel) throws -> ImageOptimizeTask {\n        let ext = url.pathExtension.lowercased()\n        if ext == \"png\" { return try PNGOptimizer.optimize(url, override: override, optimizeLevel: optimizeLevel) }\n        if ext == \"jpg\" || ext == \"jpeg\" { return try JPEGOptimizer.optimize(url, override: override, optimizeLevel: optimizeLevel) }\n        \n        throw ImageOptimizeError.unkownType(fileExtension: ext)\n    }\n}\n\n\nenum PNGOptimizer {\n    private static let optpingURL = Bundle.current.url(forResource: \"optipng\", withExtension: nil)!\n    \n    static func optimize(_ url: URL, override: Bool, optimizeLevel: OptimizeLevel) throws -> ImageOptimizeTask {\n        var arguments = [String]()\n        switch optimizeLevel {\n        case .low: arguments.append(\"-o1\")\n        case .medium: arguments.append(\"-o2\")\n        case .high: arguments.append(\"-o3\")\n        case .veryHigh: arguments.append(\"-o7\")\n        }\n        if !override {\n            let destinationURL = FileConflictAvoider.avoidConflict(url)\n            arguments.append(contentsOf: [\"-out\", destinationURL.path])\n        }\n        arguments.append(url.path)\n        \n        let fileCompression = FileCompression(url: url)\n        let promise = Terminal.run(optpingURL, arguments: arguments)\n            .map{ _ in\n                fileCompression.currentCompressionRatioString()\n            }\n        \n        return ImageOptimizeTask(title: url.lastPathComponent, url: url, result: promise)\n    }\n}\n\nenum JPEGOptimizer {\n    private static let jpegoptimURL = Bundle.current.url(forResource: \"jpegoptim\", withExtension: nil)!\n            \n    static func optimize(_ url: URL, override: Bool, optimizeLevel: OptimizeLevel) throws -> ImageOptimizeTask {\n        let directoryURL = url.deletingLastPathComponent()\n        guard FileAccessChecker.becomeAccessable(to: directoryURL) else { throw ImageOptimizeError.noAccessToDirectory(directoryURL) }\n            \n        var arguments = [String]()\n        switch optimizeLevel {\n        case .low: arguments.append(contentsOf: [\"--strip-all\"])\n        case .medium: arguments.append(contentsOf: [\"--strip-all\", \"-m95\"])\n        case .high: arguments.append(contentsOf: [\"--strip-all\", \"-m90\"])\n        case .veryHigh: arguments.append(contentsOf: [\"--strip-all\", \"-m80\"])\n        }\n        if !override {\n            let destinationURL = FileConflictAvoider.avoidConflict(url)\n            arguments.append(contentsOf: [\"--dest\", destinationURL.path])\n        }\n        arguments.append(url.path)\n        \n        \n        let fileCompression = FileCompression(url: url)\n        let promise = Terminal.run(jpegoptimURL, arguments: arguments)\n            .map{ _ in\n                fileCompression.currentCompressionRatioString()\n            }\n        \n        return ImageOptimizeTask(title: url.lastPathComponent, url: url, result: promise)\n    }\n}\n\nextension String: Error {}\n\nfinal class FileCompression {\n    let initialSize: Double?\n    let url: URL\n    \n    init(url: URL) {\n        self.url = url\n        self.initialSize = try? FileManager.default.attributesOfItem(atPath: url.path)[.size] as? Double\n    }\n    \n    private static let numberFormatter = NumberFormatter() => { $0.maximumFractionDigits = 2 }\n    \n    func currentCompressionRatioString() -> String {\n        let currentSize = try? FileManager.default.attributesOfItem(atPath: url.path)[.size] as? Double\n        \n        guard let initialSize = initialSize, let currentSize = currentSize, initialSize != 0 else { return \"-%\" }\n        let percent = currentSize / initialSize * 100\n        guard let formattedString = FileCompression.numberFormatter.string(from: NSNumber(value: percent)) else { return \"-%\" }\n        return formattedString + \"%\"\n    }\n}\n\nenum FileAccessChecker {\n    static func becomeAccessable(to directoryURL: URL) -> Bool {\n        if hasAccess(to: directoryURL) { return true }\n        let panel = NSOpenPanel()\n        panel.message = \"Select Open to allow access to '\\(directoryURL.lastPathComponent)'\"\n        panel.directoryURL = directoryURL\n        panel.canChooseDirectories = true\n        panel.canChooseFiles = false\n        panel.allowsMultipleSelection = false\n        panel.allowsOtherFileTypes = false\n        guard panel.runModal() == .OK else { return false }\n        guard panel.url == directoryURL else { return false }\n        return true\n    }\n    static func hasAccess(to directoryURL: URL) -> Bool {\n        do {\n            let url = directoryURL.deletingLastPathComponent().appendingPathComponent(\".devtoys_mac_write_test\")\n            try Data().write(to: url)\n            try FileManager.default.removeItem(at: url)\n            return true\n        } catch {\n            return false\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/PDFGeneratorView+.swift",
    "content": "//\n//  PDFGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/02.\n//\n\nimport CoreUtil\n\nfinal class PDFGeneratorViewController: NSViewController {\n    private let cell = PDFGeneratorView()\n    \n    @RestorableData(\"pdf.input\") var images = [ImageItem]()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$images\n            .sink{[unowned self] in cell.imageListView.imageItems = $0 }.store(in: &objectBag)\n        \n        self.cell.dragPublisher\n            .sink{[unowned self] in readURLs($0) }.store(in: &objectBag)\n        self.cell.generateButton.actionPublisher\n            .sink{[unowned self] in makePDF(from: self.images.map{ $0.image }) }.store(in: &objectBag)\n        self.cell.imageListView.removePublisher\n            .sink{[unowned self] in $0.reversed().forEach{ self.images.remove(at: $0) } }.store(in: &objectBag)\n        self.cell.imageListView.movePublisher\n            .sink{[unowned self] in self.moveItems($0, to: $1) }.store(in: &objectBag)\n        self.cell.clearButton.actionPublisher\n            .sink{[unowned self] in self.images = [] }.store(in: &objectBag)\n    }\n    \n    private func moveItems(_ fromRows: [Int], to row: Int) {\n        guard !fromRows.isEmpty else { return }\n        \n        let fromMin = fromRows.min()!\n        \n        let fromRows = fromRows.sorted().reversed()\n        var nextImages = self.images\n        var removed = [ImageItem]()\n        \n        for fromRow in fromRows {\n            let item = nextImages.remove(at: fromRow)\n            removed.append(item)\n        }\n        \n        removed.reverse()\n        \n        if row < fromMin {\n            nextImages.insert(contentsOf: removed, at: row)\n        } else {\n            nextImages.insert(contentsOf: removed, at: row - fromRows.count)\n        }\n        self.images = nextImages\n    }\n    \n    private func readURLs(_ pasteboard: NSPasteboard) {\n        let newImageItems = ImageDropper.images(fromPasteboard: pasteboard)\n        guard !newImageItems.isEmpty else { return }\n        images.append(contentsOf: newImageItems)\n        cell.imageListView.contentView.scrollToBottom()\n    }\n    \n    private func makePDF(from images: [NSImage]) {\n        let panel = NSSavePanel()\n        panel.allowedFileTypes = [\"pdf\"]\n        guard panel.runModal() == .OK, let url = panel.url else { return }\n        \n        let promise = Promise<Void, Never>.async { resolve, _ in\n            let pdfData = NSMutableData()\n            \n            var mediaSize = CGRect(x: 0, y: 0, width: 2000, height: 1000)\n            let pdfConsumer = CGDataConsumer(data: pdfData as CFMutableData)!\n            let pdfContext = CGContext(consumer: pdfConsumer, mediaBox: &mediaSize, nil)!\n            \n            for image in images {\n                var rect = CGRect(size: image.size)\n                pdfContext.beginPage(mediaBox: &rect)\n                pdfContext.draw(image.cgImage!, in: rect)\n                pdfContext.endPage()\n            }\n            pdfContext.closePDF()\n            \n            FileManager.default.createFile(atPath: url.path, contents: pdfData as Data, attributes: nil)\n            \n            resolve(())\n        }\n        .receive(on: .main)\n        \n        promise\n            .peekProgressIndicator(\"Generating PDF...\".localized())\n            .sinkWithToast({_ in \"PDF Exported!\".localized() })\n    }\n}\n \nfinal private class PDFGeneratorView: Page {\n    let imageListView = ImageListView()\n    let clearButton = SectionButton(title: \"Clear\".localized(), image: R.Image.clear)\n    let generateButton = Button(title: \"Generate PDF\".localized())\n    let dragPublisher = PassthroughSubject<NSPasteboard, Never>()\n    \n    override func layout() {\n        super.layout()\n        self.imageListView.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 120))\n        }\n    }\n    \n    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {\n        if sender.draggingPasteboard.canReadTypes([.URL, .fileURL, .fileContents]) { return .copy } else { return .none }\n    }\n    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {\n        guard let urls = sender.draggingPasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL], !urls.isEmpty else { return false }\n        self.dragPublisher.send(sender.draggingPasteboard)\n        return true\n    }\n    \n    override func onAwake() {\n        self.registerForDraggedTypes([.URL, .fileURL, .fileContents])\n        \n        self.addSection2(\n            Section(title: \"Images\".localized(), items: [imageListView], toolbarItems: [clearButton]),\n            Section(title: \"Configuration\".localized(), items: [\n                generateButton,\n            ])\n        ) => {\n            $0.alignment = .top\n        }\n    }\n}\n\nstruct ImageItem: Codable {\n    let fileURL: URL\n    var filename: String { fileURL.lastPathComponent }\n    var filenameWithoutExtension: String { fileURL.lastPathComponentWithoutPathExtension }\n    var image: NSImage { imageContainer.image }\n    \n    private let imageContainer: NSImageContainer\n    \n    init(fileURL: URL, image: NSImage) {\n        self.fileURL = fileURL\n        self.imageContainer = .wrap(image)\n    }\n    init?(fileURL: URL) {\n        guard let image = NSImage(contentsOf: fileURL) else { return nil }\n        self.imageContainer = .wrap(image)\n        self.fileURL = fileURL\n    }\n}\n\nextension URL {\n    var lastPathComponentWithoutPathExtension: String {\n        self.deletingPathExtension().lastPathComponent\n    }\n}\n\nfinal private class ImageListView: NSLoadScrollView {\n    let listView = NSTableView.list()\n    var imageItems = [ImageItem]() { didSet { listView.reloadData() } }\n    var removePublisher = PassthroughSubject<[Int], Never>()\n    var movePublisher = PassthroughSubject<(from: [Int], to: Int), Never>()\n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n\n    override func keyDown(with event: NSEvent) {\n        switch event.hotKey {\n        case .delete: self.removePublisher.send(listView.selectedRowIndexes.map{ $0 })\n        default: super.keyDown(with: event)\n        }\n    }\n    \n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func onAwake() {\n        self.drawsBackground = false\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        self.layer?.cornerRadius = R.Size.corner\n        self.documentView = listView\n        self.listView.delegate = self\n        self.listView.allowsMultipleSelection = true\n        self.listView.dataSource = self\n        self.listView.registerForDraggedTypes([.imageItem])\n    }\n}\n\nextension ImageListView: NSTableViewDelegate, NSTableViewDataSource {\n    \n    private class Cell: NSLoadStackView {\n        let imageView = NSImageView()\n        let titleLabel = NSTextField(labelWithString: \"Title\")\n        let pageLabel = NSTextField(labelWithString: \"Page 1\")\n        \n        override func updateLayer() {\n            imageView.layer?.backgroundColor = NSColor.tertiaryLabelColor.withAlphaComponent(0.05).cgColor\n        }\n        \n        override func onAwake() {\n            self.imageView.wantsLayer = true\n            self.imageView.layer?.cornerRadius = R.Size.corner\n            self.spacing = 16\n            self.edgeInsets = .init(x: 16, y: 4)\n            self.addArrangedSubview(imageView)\n            self.imageView.snp.makeConstraints{ make in\n                make.width.equalTo(100)\n                make.height.equalTo(64)\n            }\n            \n            self.addArrangedSubview(NSStackView() => {\n                $0.orientation = .vertical\n                $0.alignment = .left\n                $0.addArrangedSubview(titleLabel)\n                $0.addArrangedSubview(pageLabel)\n            })\n            self.titleLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n            self.titleLabel.lineBreakMode = .byTruncatingTail\n            \n            self.pageLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n            self.pageLabel.textColor = .secondaryLabelColor\n            self.pageLabel.lineBreakMode = .byTruncatingTail\n        }\n    }\n    \n    func numberOfRows(in tableView: NSTableView) -> Int { self.imageItems.count }\n    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { 80 }\n    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        let cell = Cell()\n        let imageItem = imageItems[row]\n        cell.titleLabel.stringValue = imageItem.filename\n        cell.imageView.image = imageItem.image\n        cell.pageLabel.stringValue = \"\\(\"Page\".localized()) \\(row + 1)\"\n        \n        return cell\n    }\n    \n    func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {\n        if edge == .trailing {\n            return [.init(style: .destructive, title: \"Delete\".localized(), handler: { _, row in\n                self.removePublisher.send([row])\n            })]\n        }\n        return []\n    }\n    \n    func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {\n        NSPasteboardItem() => {\n            $0.setPropertyList(row, forType: .imageItem)\n        }\n    }\n    \n    func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {\n        if dropOperation == .above { return .move }\n        return .none\n    }\n    \n    func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {\n        guard dropOperation == .above else { return false }\n        guard let fromRow = info.draggingPasteboard.pasteboardItems?.map({ $0.propertyList(forType: .imageItem) }) as? [Int] else { return false }\n        \n        movePublisher.send((fromRow, row))\n        \n        return true\n    }\n}\n\nextension NSPasteboard.PasteboardType {\n    static let imageItem = NSPasteboard.PasteboardType(\"com.devtoys.imageitem\")\n}\n\nextension NSClipView {\n    func scrollToBottom() {\n        guard let last = self.documentView?.frame.size.height, let scrollView = self.enclosingScrollView else { return }\n        self.scroll(to: [0, last - scrollView.frame.height])\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Graphic/QRCodeReaderView+.swift",
    "content": "//\n//  QRCodeReaderView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\nimport AVFoundation\n\nfinal class QRCodeReaderViewController: NSViewController {\n    private let cell = QRCodeReaderView()\n    \n    @RestorableState(\"qrcoder.inputtype\") var inputType: QRCodeInputType = .photo\n    \n    @Observable var image: CIImage? = nil\n    @Observable var detectedBound: CIQRCodeFeature?\n    @Observable var detectedMessage: String = \"\"\n    \n    private let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: nil)!\n    private let detectionQueue = DispatchQueue(label: \"qr.code.detector\", qos: .userInteractive, attributes: .concurrent)\n    private let cameraManager = CameraManager()\n    private var lastUpdate = Date()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.cell.imageDropView.imagePublisher\n            .sink{[unowned self] in self.image = $0.image.ciImage; updateDetection() }.store(in: &objectBag)\n        self.cell.inputTypePicker.itemPublisher\n            .sink{[unowned self] in self.inputType = $0; updateCameraState() }.store(in: &objectBag)\n        self.cell.inputClearButton.actionPublisher\n            .sink{[unowned self] in self.image = nil; resetDetectionState() }.store(in: &objectBag)\n        \n        self.$image.map{ $0.map{ NSImage(ciImage: $0) } }\n            .sink{[unowned self] in self.cell.imageDropView.image = $0 }.store(in: &objectBag)\n        self.$detectedBound\n            .sink{[unowned self] in self.cell.imageDropView.detectionBounds = $0 }.store(in: &objectBag)\n        self.$detectedMessage\n            .sink{[unowned self] in self.cell.outputTextView.string = $0 }.store(in: &objectBag)\n        self.$inputType\n            .sink{[unowned self] in self.cell.inputTypePicker.selectedItem = $0 }.store(in: &objectBag)\n    }\n    \n    private func updateCameraState() {\n        self.image = nil\n        self.detectedBound = nil\n        self.detectedMessage = \"\"\n        switch self.inputType {\n        case .photo:\n            self.cameraManager.stopSession()\n        case .camera:\n            self.cameraManager.startSession(self)\n        }\n    }\n    \n    override func viewDidAppear() {\n        if self.inputType == .camera { self.cameraManager.startSession(self) }\n    }\n    override func viewDidDisappear() {\n        self.cameraManager.stopSession()\n    }\n    \n    private func resetDetectionState() {\n        self.detectedBound = nil\n        self.detectedMessage = \"\"\n    }\n    \n    private func updateDetection() {\n        guard abs(lastUpdate.timeIntervalSinceNow) > 1 else { return }\n        guard let image = image else { resetDetectionState(); return }\n        \n        self.lastUpdate = Date()\n        self.readQRCode(image)\n            .receive(on: .main)\n            .sink{[self] in\n                guard let feature = $0 else { detectedBound = nil; return }\n                \n                self.detectedBound = feature\n                self.detectedMessage = feature.messageString ?? \"\"\n            }\n    }\n    \n    private func readQRCode(_ ciImage: CIImage) -> Promise<CIQRCodeFeature?, Never> {\n        .async(on: detectionQueue){ self.detector.features(in: ciImage).first as? CIQRCodeFeature }\n    }\n}\n\nextension QRCodeReaderViewController: AVCaptureVideoDataOutputSampleBufferDelegate {\n    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n        connection.videoOrientation = .portrait\n        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }\n        DispatchQueue.main.async {\n            guard self.inputType == .camera else { return }\n            self.image = CIImage(cvPixelBuffer: pixelBuffer).oriented(.upMirrored)\n            self.updateDetection()\n        }\n    }\n}\n\nenum QRCodeInputType: String, TextItem {\n    case photo = \"Photo\"\n    case camera = \"Camera\"\n    \n    var title: String { rawValue }\n}\n\nfinal private class QRCodeReaderView: Page {\n    \n    let inputTypePicker = EnumPopupButton<QRCodeInputType>()\n    let inputClearButton = SectionButton(image: R.Image.clear)\n    let imageDropView = QRImageDropView()\n    let outputTextView = TextViewSection(title: \"Output\".localized(), options: .defaultOutput)\n    \n    override func layout() {\n        super.layout()\n        \n        self.outputTextView.snp.updateConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 200))\n        }\n    }\n    \n    override func onAwake() {\n        self.addSection(Section(\n            title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.paramators, title: \"QR Code Input Type\", control: inputTypePicker)\n        ]))\n        self.addSection2(\n            Section(title: \"Input\".localized(), items: [imageDropView], toolbarItems: [inputClearButton]),\n            outputTextView\n        )\n        \n        self.imageDropView.snp.makeConstraints{ make in\n            make.height.equalTo(320)\n        }\n    }\n}\n\nfinal private class QRImageDropView: ImageDropView {\n    var detectionBounds: CIQRCodeFeature? = nil { didSet { updateDetectionBounds() } }\n    \n    private func updateDetectionBounds() {\n        guard let image = self.image, let detectionBounds = detectionBounds else {\n            return self.detectedBoundLayer.isHidden = true\n        }\n        self.detectedBoundLayer.isHidden = false\n        \n        let scale = image.size.aspectFitRatio(fitInside: imageView.frame.size)\n        let imageRect = CGRect(center: imageView.bounds.center, size: image.size * scale)\n        \n        let path = CGMutablePath()\n        path.move(to: imageRect.origin + detectionBounds.topLeft * scale)\n        path.addLine(to: imageRect.origin + detectionBounds.bottomLeft * scale)\n        path.addLine(to: imageRect.origin + detectionBounds.bottomRight * scale)\n        path.addLine(to: imageRect.origin + detectionBounds.topRight * scale)\n        path.closeSubpath()\n        \n        detectedBoundLayer.path = path\n    }\n    \n    override func layout() {\n        super.layout()\n        updateDetectionBounds()\n    }\n    \n    private let detectedBoundView = NSView()\n    private let detectedBoundLayer = CAShapeLayer.animationDisabled()\n    \n    override func onAwake() {\n        super.onAwake()\n        \n        self.wantsLayer = true\n        self.imageView.addSubview(detectedBoundView)\n        self.imageView.snp.remakeConstraints{ make in\n            make.top.bottom.equalToSuperview().inset(16)\n            make.centerX.equalToSuperview()\n        }\n        self.detectedBoundView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        self.detectedBoundView.wantsLayer = true\n        self.detectedBoundLayer.lineWidth = 5\n        self.detectedBoundLayer.strokeColor = NSColor.yellow.cgColor\n        self.detectedBoundLayer.fillColor = nil\n        self.detectedBoundView.layer?.addSublayer(detectedBoundLayer)\n    }\n}\n\nextension NSImage {\n    var ciImage: CIImage? {\n        self.cgImage.map{ CIImage(cgImage: $0) }\n    }\n    \n    convenience init(ciImage: CIImage) {\n        let rep = NSCIImageRep(ciImage: ciImage)\n        self.init(size: rep.size)\n        self.addRepresentation(rep)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/HomeView+.swift",
    "content": "//\n//  HomeViewController+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nclass SearchViewController: HomeViewController {\n    override func chainObjectDidLoad() {\n        self.appModel.$searchQuery.map{ Query($0) }\n            .sink{[unowned self] query in self.tools = appModel.toolManager.allTools().filter{ query.matches(to: $0.title) } }\n            .store(in: &objectBag)\n    }\n}\n\nclass HomeViewController: NSViewController {\n    private let scrollView = NSScrollView()\n    private let collectionView = NSCollectionView()\n    \n    var tools: [Tool] = [] {\n        didSet { collectionView.reloadData() }\n    }\n    \n    override func loadView() {\n        self.view = scrollView\n        self.scrollView.documentView = collectionView\n        \n        let flowLayout = LeftAlignedCollectionViewFlowLayout()\n        flowLayout.itemSize = [125, 230]\n        flowLayout.sectionInset = NSEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)\n        flowLayout.minimumInteritemSpacing = 8\n        \n        self.collectionView.dataSource = self\n        self.collectionView.collectionViewLayout = flowLayout\n        self.collectionView.register(ToolCollectionItem.self, forItemWithIdentifier: ToolCollectionItem.identifier)\n        self.collectionView.addGestureRecognizer(NSClickGestureRecognizer(target: self, action: #selector(onClick)))\n    }\n    \n    @objc private func onClick(_ recognizer: NSGestureRecognizer) {\n        guard let indexPath = collectionView.indexPathForItem(at: recognizer.location(in: collectionView)),\n              let tool = self.tools.at(indexPath.item)\n        else { return }\n        \n        self.appModel.tool = tool\n    }\n    \n    override func chainObjectDidLoad() {\n        self.tools = appModel.toolManager.allTools().filter{ $0.showOnHome }\n    }\n}\n\nextension HomeViewController: NSCollectionViewDataSource {\n    func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {\n        self.tools.count\n    }\n    \n    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {\n        let item = collectionView.makeItem(withIdentifier: ToolCollectionItem.identifier, for: indexPath) as! ToolCollectionItem\n        let tool = self.tools[indexPath.item]\n        \n        item.cell.icon = tool.icon\n        item.cell.title = tool.title\n        item.cell.toolDescription = tool.toolDescription\n        \n        return item\n    }\n}\n\nfinal private class ToolCollectionItem: NSCollectionViewItem {\n    static let identifier = NSUserInterfaceItemIdentifier(\"ToolCollectionItem\")\n    \n    let cell = AllToolCell()\n    \n    override func loadView() { self.view = cell }\n}\n\nfinal private class AllToolCell: NSLoadView {\n    var icon: NSImage? {\n        get { iconView.iconView.image } set { iconView.iconView.image = newValue }\n    }\n    var title: String {\n        get { titleLabel.stringValue } set { titleLabel.stringValue = newValue }\n    }\n    var toolDescription: String {\n        get { descriptionLabel.stringValue } set { descriptionLabel.stringValue = newValue }\n    }\n    \n    private let iconView = AllToolCellIconView()\n    private let iconContainer = NSView()\n    \n    private let labelStack = NSStackView()\n    private let titleLabel = NSTextField(labelWithString: \"Hello World\")\n    private let descriptionLabel = NSTextField(labelWithString: \"Here you can see the next type of development environment.\")\n    private let backgroundLayer = CALayer.animationDisabled()\n    private var isMouseInside = false { didSet { needsDisplay = true } }\n    \n    override func updateLayer() {\n        self.backgroundLayer.areAnimationsEnabled = true\n        \n        if isMouseInside {\n            self.backgroundLayer.backgroundColor = NSColor.textColor.withAlphaComponent(0.1).cgColor\n        } else {\n            self.backgroundLayer.backgroundColor = NSColor.textColor.withAlphaComponent(0.05).cgColor\n        }\n        \n        self.backgroundLayer.areAnimationsEnabled = false\n    }\n    \n    override func mouseEntered(with event: NSEvent) {\n        self.isMouseInside = true\n    }\n    override func mouseExited(with event: NSEvent) {\n        self.isMouseInside = false\n    }\n    override func viewDidHide() {\n        self.isMouseInside = false\n    }\n    \n    override func updateTrackingAreas() {\n        self.trackingAreas.forEach(removeTrackingArea(_:))\n        self.addTrackingRect(bounds, owner: self, userData: nil, assumeInside: true)\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        self.backgroundLayer.cornerRadius = R.Size.corner\n        self.backgroundLayer.shadowRadius = 2\n        self.backgroundLayer.shadowOpacity = 0.2\n        self.backgroundLayer.shadowOffset = [0, 2]\n        \n        self.addSubview(iconContainer)\n        self.iconContainer.snp.makeConstraints{ make in\n            make.right.left.top.equalToSuperview()\n            make.size.equalTo(125)\n        }\n        \n        self.iconContainer.addSubview(iconView)\n        self.iconView.snp.makeConstraints{ make in\n            make.size.equalTo(74)\n            make.center.equalToSuperview()\n        }\n        \n        self.addSubview(labelStack)\n        self.labelStack.orientation = .vertical\n        self.labelStack.spacing = 4\n        self.labelStack.alignment = .left\n        self.labelStack.snp.makeConstraints{ make in\n            make.right.left.equalToSuperview().inset(10)\n            make.top.equalTo(iconContainer.snp.bottom)\n        }\n        \n        self.labelStack.addArrangedSubview(titleLabel)\n        self.titleLabel.lineBreakMode = .byWordWrapping\n        self.titleLabel.font = .systemFont(ofSize: 10.5, weight: .medium)\n        \n        self.labelStack.addArrangedSubview(descriptionLabel)\n        self.descriptionLabel.lineBreakMode = .byWordWrapping\n        self.descriptionLabel.font = .systemFont(ofSize: 10)\n        self.descriptionLabel.textColor = .secondaryLabelColor\n    }\n}\n\nfinal private class AllToolCellIconView: NSLoadView {\n    let iconView = NSImageView()\n    private let backgroundLayer = CALayer.animationDisabled()\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func updateLayer() {\n        self.backgroundLayer.backgroundColor = NSColor.quaternaryLabelColor.cgColor\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        self.backgroundLayer.cornerRadius = R.Size.corner\n        self.backgroundLayer.shadowRadius = 2\n        self.backgroundLayer.shadowOpacity = 0.2\n        self.backgroundLayer.shadowOffset = [0, 2]\n        \n        self.addSubview(iconView)\n        self.iconView.image = R.Image.Tool.base64Coder\n        self.iconView.contentTintColor = .textColor\n        self.iconView.snp.makeConstraints{ make in\n            make.size.equalTo(40)\n            make.center.equalToSuperview()\n        }\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Audio Converter/AudioConverter.swift",
    "content": "//\n//  AudioConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\n\nstruct AudioConvertOptions {\n    let thumbsize: CGSize\n    let removeSourceFile: Bool\n}\n\nstruct AudioConvertTask {\n    let title: String\n    let sourceURL: URL\n    let destinationURL: URL\n    let fftask: Promise<FFTask, Never>\n    \n    var completePromise: Promise<Void, Never> {\n        fftask.flatMap{ $0.complete.replaceError(with: ()) }\n    }\n}\n\nstruct AudioConvertGroup {\n    var title: String\n    var formats: [AudioConvertFormat]\n}\n\nstruct AudioConvertFormat: Codable {\n    var title: String\n    var ext: String\n    var options: [String]\n}\n\n\nenum AudioConverter {\n    static func convert(from sourceURL: URL, format: AudioConvertFormat, options: AudioConvertOptions, destinationURL: URL) -> AudioConvertTask {\n        let fftask = FFExecutor.execute(format.options, inputURL: sourceURL, destinationURL: destinationURL)\n        \n        fftask.eraseToError().flatMap{ $0.complete }\n            .peek{\n                if options.removeSourceFile {\n                    NSWorkspace.shared.recycle([sourceURL], completionHandler: nil)\n                    NSSound.dragToTrash?.play()\n                }\n            }\n            .catch({_ in })\n        \n        return AudioConvertTask(title: sourceURL.lastPathComponent, sourceURL: sourceURL, destinationURL: destinationURL, fftask: fftask)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Audio Converter/AudioConverterView+.swift",
    "content": "//\n//  AudioConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\nimport Quartz\n\nfinal class AudioConverterViewController: NSViewController {\n    private let cell = AudioConverterView()\n    \n    @Observable var tasks = [AudioConvertTask]()\n    @RestorableData(\"audio.format\") var format: AudioConvertFormat = convertGroups[0].formats[1]\n    @RestorableState(\"audio.removeSource\") var removeSource = false\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$tasks\n            .sink{[unowned self] in cell.listView.convertTasks = $0 }.store(in: &objectBag)\n        self.$format\n            .sink{[unowned self] in cell.formatPicker.selectedMenuTitle = $0.title }.store(in: &objectBag)\n        self.$removeSource\n            .sink{[unowned self] in cell.removeFileSwitch.isOn = $0 }.store(in: &objectBag)\n        \n        self.cell.formatPublisher\n            .sink{[unowned self] in self.format = $0 }.store(in: &objectBag)\n        self.cell.removeFileSwitch.isOnPublisher\n            .sink{[unowned self] in self.removeSource = $0 }.store(in: &objectBag)\n        self.cell.dropPublisher\n            .sink{[unowned self] in handleDrop($0) }.store(in: &objectBag)\n        self.cell.listView.removePublisher\n            .sink{[unowned self] in removeItems($0) }.store(in: &objectBag)\n        self.cell.clearButton.actionPublisher\n            .sink{[unowned self] in clearTasks() }.store(in: &objectBag)\n    }\n    \n    private func clearTasks() {\n        tasks = tasks.filter{ $0.completePromise.state.isSettled }\n    }\n    \n    private func removeItems(_ indexSet: IndexSet) {\n        for index in indexSet.reversed() {\n            if !tasks[index].completePromise.state.isSettled {\n                self.tasks.remove(at: index)\n            } else {\n                NSSound.beep()\n            }\n        }\n    }\n    \n    private func handleDrop(_ urls: [URL]) {\n        let urls = urls.flatMap{ AudioFileScanner.scan($0) }\n        var newTasks = [AudioConvertTask]()\n        \n        for url in urls {\n            let destinationURL = FileConflictAvoider.avoidConflict(url.deletingPathExtension().appendingPathExtension(format.ext))\n            let options = AudioConvertOptions(thumbsize: AudioConvertTaskCell.thumbnailSize, removeSourceFile: removeSource)\n            let task = AudioConverter.convert(from: url, format: format, options: options, destinationURL: destinationURL)\n            newTasks.append(task)\n        }\n        \n        self.tasks.insert(contentsOf: newTasks, at: 0)\n    }\n}\n\nfinal private class AudioConverterView: Page {\n    let formatPicker = PopupButton()\n    let removeFileSwitch = NSSwitch()\n    let listView = AudioConvertListView()\n    let clearButton = SectionButton(title: \"Clear\".localized(), image: R.Image.clear)\n    \n    let formatPublisher = PassthroughSubject<AudioConvertFormat, Never>()\n    let dropPublisher = PassthroughSubject<[URL], Never>()\n    \n    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {\n        if sender.draggingPasteboard.canReadTypes([.fileURL]) { return .copy } else { return .none }\n    }\n    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {\n        guard let urls = sender.draggingPasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL], !urls.isEmpty else { return false }\n        dropPublisher.send(urls)\n        return true\n    }\n    \n    override func layout() {\n        listView.snp.remakeConstraints{ make in\n            make.height.equalTo(max(200, self.frame.height - 270))\n        }\n        super.layout()\n    }\n    \n    override func onAwake() {\n        self.registerForDraggedTypes([.fileURL])\n        \n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.format, title: \"Format\".localized(), control: formatPicker),\n            Area(icon: R.Image.paramators, title: \"Remove source file\".localized(), message: \"Whether to delete the source file after exporting a Audio\".localized(), control: removeFileSwitch)\n        ]))\n        \n        self.addSection(Section(title: \"Files\".localized(), items: [\n            listView\n        ], toolbarItems: [clearButton]))\n        \n        self.registerFormats(convertGroups)\n    }\n    \n    private func registerFormats(_ groups: [AudioConvertGroup]) {\n        for group in groups {\n            let item = NSMenuItem(title: group.title, isSelected: false, isEnabled: true, action: nil)\n            let submenu = NSMenu()\n            for format in group.formats {\n                submenu.addItem(title: format.title, action: {\n                    self.formatPublisher.send(format)\n                })\n            }\n            item.submenu = submenu\n            formatPicker.menuItems.append(item)\n        }\n    }\n}\n\nfinal private class AudioConvertListView: NSLoadView, QLPreviewPanelDataSource, QLPreviewPanelDelegate {\n    let scrollView = NSScrollView()\n    let listView = EmptyImageTableView.list()\n    let removePublisher = PassthroughSubject<IndexSet, Never>()\n    var convertTasks = [AudioConvertTask]() { didSet { listView.reloadData() } }\n    \n    override func updateLayer() {\n        self.layer?.backgroundColor = R.Color.controlBackgroundColor.cgColor\n    }\n    \n    override func keyDown(with event: NSEvent) {\n        switch event.hotKey {\n        case .space: showQuickLook()\n        case .delete: removePublisher.send(listView.selectedRowIndexes)\n        default: super.keyDown(with: event)\n        }\n    }\n    \n    private func showQuickLook() {\n        guard let panel = QLPreviewPanel.shared() else { return }\n        panel.dataSource = self\n        panel.delegate = self\n        panel.makeKeyAndOrderFront(nil)\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.cornerRadius = R.Size.corner\n        self.addSubview(scrollView)\n        self.scrollView.drawsBackground = false\n        self.scrollView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.scrollView.documentView = listView\n        self.listView.setFileDropEmptyView()\n        self.listView.delegate = self\n        self.listView.dataSource = self\n        self.listView.allowsMultipleSelection = true\n        \n        let menu = NSMenu()\n        menu.addItem(title: \"Open in Finder\".localized()) { [self] in\n            guard let task = convertTasks.at(listView.clickedRow) else { return }\n            NSWorkspace.shared.activateFileViewerSelecting([task.destinationURL])\n        }\n        menu.addItem(title: \"Delete\".localized()) { [self] in\n            if listView.clickedRow >= 0 { removePublisher.send(.init(integer: listView.clickedRow)) }\n        }\n        menu.addItem(title: \"Quick Look\".localized()) { [self] in\n            self.showQuickLook()\n        }\n        \n        self.listView.menu = menu\n    }\n    \n    func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {\n        self.listView.selectedRowIndexes.count\n    }\n    func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem {\n        let index = self.listView.selectedRowIndexes.map{ $0 }[index]\n        return convertTasks[index].destinationURL as QLPreviewItem\n    }\n    func previewPanel(_ panel: QLPreviewPanel!, sourceFrameOnScreenFor item: QLPreviewItem!) -> NSRect {\n        guard let index = convertTasks.firstIndex(where: { item.isEqual($0.destinationURL) }) else { return .zero }\n        \n        return listView.convertToScreen(listView.rect(ofRow: index))\n    }\n}\n\nextension AudioConvertListView: NSTableViewDataSource, NSTableViewDelegate {\n    func numberOfRows(in tableView: NSTableView) -> Int { convertTasks.count }\n    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { 64 }\n    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        let cell = AudioConvertTaskCell()\n        let task = convertTasks[row]\n        \n        cell.titleLabel.stringValue = task.title\n        cell.infoLabel.stringValue = \"Starting...\".localized()\n        \n        task.fftask\n            .receive(on: .main)\n            .sink{ task in\n                task.$progress\n                    .receive(on: DispatchQueue.main, options: nil)\n                    .filter{ $0 != 0 }\n                    .sink{[unowned cell] in\n                        cell.progressView.doubleValue = $0\n                        cell.infoLabel.stringValue = \"\\(Int($0 * 100))%\"\n                    }\n                    .store(in: &cell.objectBag)\n                \n                task.complete\n                    .receive(on: .main)\n                    .sink({\n                        cell.infoLabel.stringValue = \"Complete\".localized()\n                    }, { error in\n                        cell.infoLabel.textColor = .systemRed\n                        cell.infoLabel.stringValue = \"Convert Failed\".localized()\n                    })\n            }\n        \n        return cell\n    }\n}\n\nfinal private class AudioConvertTaskCell: NSLoadView {\n    \n    static let thumbnailSize: CGSize = [50, 50]\n    static let thumbnailImageSize: CGSize = thumbnailSize * (NSScreen.main?.backingScaleFactor ?? 1)\n    \n    let thumbnailImageView = NSImageView()\n    let progressView = NSProgressIndicator()\n    let titleLabel = NSTextField(labelWithString: \"Title\")\n    let infoLabel = NSTextField(labelWithString: \"Title\")\n    \n    private let stackView = NSStackView()\n    private let titleStackView = NSStackView()\n    \n    override func onAwake() {\n        self.addSubview(stackView)\n        self.stackView.edgeInsets = .init(x: 16, y: 8)\n        self.stackView.distribution = .fillProportionally\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.stackView.addArrangedSubview(thumbnailImageView)\n        self.thumbnailImageView.isHidden = true\n        self.thumbnailImageView.snp.makeConstraints{ make in\n            make.size.equalTo(AudioConvertTaskCell.thumbnailSize)\n        }\n        self.stackView.addArrangedSubview(titleStackView)\n        \n        self.titleStackView.spacing = 0\n        self.titleStackView.orientation = .vertical\n        self.titleStackView.alignment = .left\n        \n        self.titleStackView.addArrangedSubview(titleLabel)\n        self.titleLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n        \n        self.titleStackView.addArrangedSubview(progressView)\n        self.progressView.isIndeterminate = false\n        self.progressView.minValue = 0\n        self.progressView.maxValue = 1\n        self.progressView.usesThreadedAnimation = false\n        \n        self.titleStackView.addArrangedSubview(infoLabel)\n        self.infoLabel.font = .systemFont(ofSize: R.Size.controlFontSize)\n    }\n}\n\n\nprivate let convertGroups = [\n    AudioConvertGroup(title: \"ACC(M4A)\", formats: [\n        AudioConvertFormat(title: \"ACC 44100Hz 64kbps\", ext: \"m4a\", options: [\"-ar\", \"44100\", \"-b:a\", \"64k\", \"-c:v\", \"copy\"]),\n        AudioConvertFormat(title: \"ACC 44100Hz 128kbps\", ext: \"m4a\", options: [\"-ar\", \"44100\", \"-b:a\", \"128k\", \"-c:v\", \"copy\"]),\n        AudioConvertFormat(title: \"ACC 44100Hz 256bps\", ext: \"m4a\", options: [\"-ar\", \"44100\", \"-b:a\", \"256k\", \"-c:v\", \"copy\"])\n    ]),\n    AudioConvertGroup(title: \"FLAC\", formats: [\n        AudioConvertFormat(title: \"FLAC 32000Hz\", ext: \"flac\", options: [\"-ar\", \"32000\"]),\n        AudioConvertFormat(title: \"FLAC 44100Hz\", ext: \"flac\", options: [\"-ar\", \"44100\"]),\n        AudioConvertFormat(title: \"FLAC 48000Hz\", ext: \"flac\", options: [\"-ar\", \"48000\"]),\n    ]),\n    AudioConvertGroup(title: \"M4R\", formats: [\n        AudioConvertFormat(title: \"M4R 44100Hz 64kbs\", ext: \"m4r\", options: [\"-ar\", \"44100\", \"-b:a\", \"64k\"]),\n        AudioConvertFormat(title: \"M4R 44100Hz 96kbs\", ext: \"m4r\", options: [\"-ar\", \"44100\", \"-b:a\", \"96k\"]),\n        AudioConvertFormat(title: \"M4R 44100Hz 128kbs\", ext: \"m4r\", options: [\"-ar\", \"44100\", \"-b:a\", \"128k\"]),\n        AudioConvertFormat(title: \"M4R 44100Hz 224kbs\", ext: \"m4r\", options: [\"-ar\", \"44100\", \"-b:a\", \"224k\"]),\n        AudioConvertFormat(title: \"M4R 44100Hz 320kbs\", ext: \"m4r\", options: [\"-ar\", \"44100\", \"-b:a\", \"320k\"]),\n    ]),\n    AudioConvertGroup(title: \"MP3\", formats: [\n        AudioConvertFormat(title: \"MP3 44100Hz 64kbs\", ext: \"mp3\", options: [\"-ar\", \"44100\", \"-b:a\", \"64k\"]),\n        AudioConvertFormat(title: \"MP3 44100Hz 96kbs\", ext: \"mp3\", options: [\"-ar\", \"44100\", \"-b:a\", \"96k\"]),\n        AudioConvertFormat(title: \"MP3 44100Hz 128kbs\", ext: \"mp3\", options: [\"-ar\", \"44100\", \"-b:a\", \"128k\"]),\n        AudioConvertFormat(title: \"MP3 44100Hz 224kbs\", ext: \"mp3\", options: [\"-ar\", \"44100\", \"-b:a\", \"224k\"]),\n        AudioConvertFormat(title: \"MP3 44100Hz 256kbs\", ext: \"mp3\", options: [\"-ar\", \"44100\", \"-b:a\", \"256k\"]),\n        AudioConvertFormat(title: \"MP3 44100Hz 320kbs\", ext: \"mp3\", options: [\"-ar\", \"44100\", \"-b:a\", \"320k\"]),\n    ]),\n    AudioConvertGroup(title: \"WAV\", formats: [\n        AudioConvertFormat(title: \"WAV 32000Hz\", ext: \"wav\", options: [\"-ar\", \"32000\"]),\n        AudioConvertFormat(title: \"WAV 44100Hz\", ext: \"wav\", options: [\"-ar\", \"44100\"]),\n        AudioConvertFormat(title: \"WAV 48000Hz\", ext: \"wav\", options: [\"-ar\", \"48000\"])\n    ])\n]\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Audio Converter/AudioFileScanner.swift",
    "content": "//\n//  FileTreeScanner.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/22.\n//\n\nimport CoreUtil\n\nenum AudioFileScanner {\n    \n    private static var supportedExtensions: Set<String> = [\n        \"mp2\", \"mp3\", \"aac\", \"flac\", \"wma\", \"ogg\", \"ac3\", \"m4a\", \"tta\", \"ape\", \"wav\", \"aiff\", \"aifc\", \"gsm\", \"dct\", \"au\",\n        \"mp4\", \"mkv\", \"mov\", \"avi\", \"wmv\"\n    ]\n    \n    static func scan(_ url: URL) -> [URL] {\n        var urls = [URL]()\n        \n        func isAudioFile(_ url: URL) -> Bool {\n            supportedExtensions.contains(url.pathExtension.lowercased())\n        }\n        \n        if isAudioFile(url) { urls.append(url) }\n        \n        guard let enumerator = FileManager.default\n                .enumerator(at: url, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants])\n        else { return urls }\n        \n        for case let fileURL as URL in enumerator {\n            guard let resourceValues = try? fileURL.resourceValues(forKeys: [.isRegularFileKey]) else { continue }\n            guard let isRegularFile = resourceValues.isRegularFile, isRegularFile else { continue }\n        \n            if isAudioFile(fileURL) { urls.append(fileURL) }\n        }\n        \n        return urls\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Color.swift",
    "content": "//\n//  Color.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nstruct Color: Codable {\n    var hue: CGFloat\n    var saturation: CGFloat\n    var brightness: CGFloat\n    var alpha: CGFloat\n    \n    var nsColor: NSColor { NSColor(colorSpace: .current, hue: hue, saturation: saturation, brightness: brightness, alpha: alpha) }\n    var cgColor: CGColor { nsColor.cgColor }\n    \n    var rgb: (CGFloat, CGFloat, CGFloat) {\n        let nsColor = self.nsColor\n        return (nsColor.redComponent, nsColor.greenComponent, nsColor.blueComponent)\n    }\n    \n    var cmyk: (cyan: CGFloat, magenta: CGFloat, yellow: CGFloat, black:CGFloat) {\n        let (r, g, b) = self.rgb\n\n        let k = 1.0 - max(r, g, b)\n        var c = (1.0-r-k) / (1.0-k)\n        var m = (1.0-g-k) / (1.0-k)\n        var y = (1.0-b-k) / (1.0-k)\n\n        if c.isNaN { c = 0.0 }\n        if m.isNaN { m = 0.0 }\n        if y.isNaN { y = 0.0 }\n\n        return (cyan: c, magenta: m, yellow: y, black: k)\n    }\n    \n    var hsl: (hue: CGFloat, saturation: CGFloat, lightness: CGFloat) {\n        var (h, s, b) = (hue, saturation, brightness)\n        \n        let l = ((2.0 - s) * b) / 2.0\n\n        switch l {\n        case 0.0, 1.0: s = 0.0\n        case 0.0..<0.5: s = (s * b) / (l * 2.0)\n        default: s = (s * b) / (2.0 - l * 2.0)\n        }\n        return (hue: h, saturation: s, lightness: l)\n    }\n\n    init(hue: CGFloat, saturation: CGFloat, lightness: CGFloat, alpha: CGFloat = 1.0) {\n        var (h, s, l) = (hue, saturation, lightness)\n\n        let t = s * ((l < 0.5) ? l : (1.0 - l))\n        let b = l + t\n        s = (l > 0.0) ? (2.0 * t / b) : 0.0\n\n        self.init(hue: h, saturation: s, brightness: b, alpha: alpha)\n    }\n    \n    init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) {\n        self.hue = hue\n        self.saturation = saturation\n        self.brightness = brightness\n        self.alpha = alpha\n    }\n    \n    init(nsColor: NSColor) {\n        self.init(hue: nsColor.hueComponent, saturation: nsColor.saturationComponent, brightness: nsColor.brightnessComponent, alpha: nsColor.alphaComponent)\n    }\n    \n    init?(hex3: String, alpha: CGFloat) {\n        if hex3.isEmpty { return nil }\n        guard hex3.count == 3 else { NSSound.beep(); return nil }\n        let scanner = Scanner(string: hex3)\n        var components: UInt64 = 0\n        guard scanner.scanHexInt64(&components) else { NSSound.beep(); return nil }\n        let r = CGFloat((components & 0xF00) >> 8) / 255.0 \n        let g = CGFloat((components & 0x0F0) >> 4) / 255.0\n        let b = CGFloat((components & 0x00F) >> 0) / 255.0\n        \n        self.init(nsColor: NSColor(red: 17 * r, green: 17 * g, blue: 17 * b, alpha: alpha))\n    }\n    \n    \n    init?(hex6: String, alpha: CGFloat) {\n        guard hex6.count == 6 else { NSSound.beep(); return nil }\n        let scanner = Scanner(string: hex6)\n        var components: UInt64 = 0\n        guard scanner.scanHexInt64(&components) else { NSSound.beep(); return nil }\n        let r = CGFloat((components & 0xFF0000) >> 16) / 255.0\n        let g = CGFloat((components & 0x00FF00) >> 8) / 255.0\n        let b = CGFloat((components & 0x0000FF) >> 0) / 255.0\n        \n        self.init(nsColor: NSColor(red: r, green: g, blue: b, alpha: alpha))\n    }\n    \n    init?(hex8: String) {\n        guard hex8.count == 8 else { NSSound.beep(); return nil }\n        let scanner = Scanner(string: hex8)\n        var components: UInt64 = 0\n        guard scanner.scanHexInt64(&components) else { NSSound.beep(); return nil }\n        let r = CGFloat((components & 0xFF000000) >> 24) / 255.0\n        let g = CGFloat((components & 0x00FF0000) >> 16) / 255.0\n        let b = CGFloat((components & 0x0000FF00) >> 8) / 255.0\n        let a = CGFloat((components & 0x000000FF) >> 0) / 255.0\n        \n        self.init(nsColor: NSColor(red: r, green: g, blue: b, alpha: a))\n    }\n    \n    func withAlpha(_ alpha: CGFloat) -> Color {\n        Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha.clamped(0...1))\n    }\n    func withRed(_ value: CGFloat) -> Color {\n        Color(nsColor: NSColor(red: value.clamped(0...1), green: nsColor.greenComponent, blue: nsColor.blueComponent, alpha: alpha))\n    }\n    func withGreen(_ value: CGFloat) -> Color {\n        Color(nsColor: NSColor(red: nsColor.redComponent, green: value.clamped(0...1), blue: nsColor.blueComponent, alpha: alpha))\n    }\n    func withBlue(_ value: CGFloat) -> Color {\n        Color(nsColor: NSColor(red: nsColor.redComponent, green: nsColor.greenComponent, blue: value.clamped(0...1), alpha: alpha))\n    }\n    func withSB(_ saturation: CGFloat, _ brightness: CGFloat) -> Color {\n        Color(hue: hue, saturation: saturation.clamped(0...1), brightness: brightness.clamped(0...1), alpha: alpha)\n    }\n    func withSaturation(_ saturation: CGFloat) -> Color {\n        Color(hue: hue, saturation: saturation.clamped(0...1), brightness: brightness, alpha: alpha)\n    }\n    func withBrightness(_ brightness: CGFloat) -> Color {\n        Color(hue: hue, saturation: saturation, brightness: brightness.clamped(0...1), alpha: alpha)\n    }\n    func withHue(_ hue: CGFloat) -> Color {\n        Color(hue: hue.clamped(0...1), saturation: saturation, brightness: brightness, alpha: alpha)\n    }\n    func withHSLHue(_ hue: CGFloat) -> Color {\n        let (_, s, l) = self.hsl\n        return Color(hue: hue, saturation: s, lightness: l)\n    }\n    func withHSLSaturation(_ saturation: CGFloat) -> Color {\n        let (h, _, l) = self.hsl\n        return Color(hue: h, saturation: saturation, lightness: l)\n    }\n    func withHSLLightness(_ lightness: CGFloat) -> Color {\n        let (h, s, _) = self.hsl\n        return Color(hue: h, saturation: s, lightness: lightness)\n    }\n}\n\nextension Color {\n    static let `default` = Color(hue: 0, saturation: 1, brightness: 1, alpha: 1)\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/ColorPickerView+.swift",
    "content": "//\n//  ColorPickerView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\n\nfinal class ColorPickerViewController: NSViewController {\n    private let cell = ColorPickerView()\n    \n    @RestorableData(\"colorpick.color\") var color: Color = Color(hue: 0.48, saturation: 0.9, brightness: 0.9, alpha: 1)\n    @RestorableState(\"colorpick.pickertype\") var pickerType: ColorPickerType = .hsbBox\n    @RestorableState(\"colorpick.copyType\") var copyType: ColorCopyType = .webRGBA\n    \n    @Observable var hex3: String? = nil\n    @Observable var hex6: String = \"\"\n    @Observable var hex8: String = \"\"\n    \n    @Observable var red: CGFloat = 0\n    @Observable var green: CGFloat = 0\n    @Observable var blue: CGFloat = 0\n    \n    @Observable var cyan: CGFloat = 0\n    @Observable var magenta: CGFloat = 0\n    @Observable var yellow: CGFloat = 0\n    @Observable var key: CGFloat = 0\n    @Observable var copyValue = \"\"\n    \n    override func loadView() { self.view = cell }\n    \n    private func updateComponents() {\n        let (red, green, blue) = color.rgb\n        let (cyan, magenta, yellow, key) = color.cmyk\n        \n        self.hex6 = String(format: \"%02X%02X%02X\", Int(red * 255), Int(green * 255), Int(blue * 255))\n        self.hex3 = self.makeHex3(hex6: hex6)\n        self.hex8 = String(format: \"%02X%02X%02X%02X\", Int(red * 255), Int(green * 255), Int(blue * 255), Int(color.alpha * 255))\n        \n        self.red = round(red * 255)\n        self.green = round(green * 255)\n        self.blue = round(blue * 255)\n        \n        self.cyan = round(cyan * 100)\n        self.magenta = round(magenta * 100)\n        self.yellow = round(yellow * 100)\n        self.key = round(key * 100)\n        \n        switch copyType {\n        case .components: break\n        case .iosUIColor: self.copyValue = \"UIColor(red: \\(red.cf), green: \\(green.cf), blue: \\(blue.cf), alpha: \\(color.alpha.cf))\"\n        case .macNSColor: self.copyValue = \"NSColor(red: \\(red.cf), green: \\(green.cf), blue: \\(blue.cf), alpha: \\(color.alpha.cf))\"\n        case .swiftuiRGBColor: self.copyValue = \"Color(red: \\(red.cf), green: \\(green.cf), blue: \\(blue.cf), opacity: \\(color.alpha.cf))\"\n        case .swiftuiHSBColor: self.copyValue = \"Color(hue: \\(color.hue.cf), saturation: \\(color.saturation.cf), brightness: \\(color.brightness.cf), opacity: \\(color.alpha.cf))\"\n        case .androidARGB:\n            if color.alpha == 1 {\n                self.copyValue = \"Color.rgb(\\(Int(red * 255)), \\(Int(green * 255)), \\(Int(blue * 255)))\"\n            } else {\n                self.copyValue = \"Color.argb(\\(Int(color.alpha * 255)), \\(Int(red * 255)), \\(Int(green * 255)), \\(Int(blue * 255)))\"\n            }\n        case .androidHEX:\n            if color.alpha == 1 {\n                self.copyValue = \"Color.parseColor(\\\"#\\(self.hex6)\\\")\"\n            } else {\n                self.copyValue = \"Color.parseColor(\\\"#\\(self.hex8)\\\")\"\n            }\n        case .androidXML:\n            if color.alpha == 1 {\n                self.copyValue = \"<color name=\\\"color\\\">#\\(self.hex6)</color>\"\n            } else {\n                self.copyValue = \"<color name=\\\"color\\\">#\\(self.hex8)</color>\"\n            }\n        case .webHEX:\n            if color.alpha == 1 {\n                self.copyValue = \"#\\(self.hex6)\"\n            } else {\n                self.copyValue = \"#\\(self.hex8)\"\n            }\n        case .webRGBA:\n            if color.alpha == 1 {\n                self.copyValue = \"rgb(\\(Int(red * 255)), \\(Int(green * 255)), \\(Int(blue * 255)))\"\n            } else {\n                self.copyValue = \"rgba(\\(Int(red * 255)), \\(Int(green * 255)), \\(Int(blue * 255)), \\(color.alpha.formattedString()))\"\n            }\n        case .webHSLA:\n            let (h, s, l) = color.hsl\n            if color.alpha == 1 {\n                self.copyValue = \"hsl(\\(Int(h * 360))deg, \\(Int(s * 100))%, \\(Int(l * 100))%)\"\n            } else {\n                self.copyValue = \"hsla(\\(Int(h * 360))deg, \\(Int(s * 100))%, \\(Int(l * 100))%, \\(color.alpha.formattedString()))\"\n            }\n        }\n    }\n    \n    private func makeHex3(hex6: String) -> String? {\n        guard hex6.count == 6 else { return nil }\n        let charactors = hex6.map{ $0 }\n        guard charactors[0] == charactors[1], charactors[2] == charactors[3], charactors[4] == charactors[5] else { return nil }\n        return \"\\(charactors[0])\\(charactors[2])\\(charactors[4])\"\n    }\n    \n    private func pickColor() {\n        ACPixelPicker().show()\n            .peek{[self] in self.color = $0; updateComponents() }\n            .catchCancel{}\n    }\n    \n    override func viewDidLoad() {\n        self.$hex3.sink{[unowned self] in self.cell.hex3TextField.string = $0 ?? \"\" }.store(in: &objectBag)\n        self.$hex6.sink{[unowned self] in self.cell.hex6TextField.string = $0 }.store(in: &objectBag)\n        self.$hex8.sink{[unowned self] in self.cell.hex8TextField.string = $0 }.store(in: &objectBag)\n        \n        self.$red.sink{[unowned self] in self.cell.redField.value = $0 }.store(in: &objectBag)\n        self.$green.sink{[unowned self] in self.cell.greenField.value = $0 }.store(in: &objectBag)\n        self.$blue.sink{[unowned self] in self.cell.blueField.value = $0 }.store(in: &objectBag)\n        \n        self.$cyan.sink{[unowned self] in self.cell.cyanField.value = $0 }.store(in: &objectBag)\n        self.$magenta.sink{[unowned self] in self.cell.magentaField.value = $0 }.store(in: &objectBag)\n        self.$yellow.sink{[unowned self] in self.cell.yellowField.value = $0 }.store(in: &objectBag)\n        self.$key.sink{[unowned self] in self.cell.keyField.value = $0 }.store(in: &objectBag)\n        self.$pickerType.sink{[unowned self] in self.cell.pickerTypePicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$copyType.sink{[unowned self] in self.cell.colorCopyTypePicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$copyValue.sink{[unowned self] in self.cell.textCopyField.string = $0 }.store(in: &objectBag)\n        \n        self.$pickerType\n            .map{[unowned self] type -> NSView in\n                switch type {\n                case .hsbBox: return self.cell.boxHSBPicker\n                case .hsbCircle: return self.cell.circleBoxHSBPicker\n                case .hsbCircleAndBars: return self.cell.circleBarsHSBPicker\n                }\n            }\n            .sink{[unowned self] in self.cell.pickerPlaceholder.contentView = $0 }\n            .store(in: &objectBag)\n        \n        self.$copyType\n            .map{[unowned self] type -> NSView in\n                switch type {\n                case .components: return cell.paramatorsStack\n                default: return cell.textCopyField\n                }\n            }\n            .sink{[unowned self] in self.cell.colorCopyPlaceholder.contentView = $0 }\n            .store(in: &objectBag)\n        \n        self.$color\n            .sink{[unowned self] in\n                cell.boxHSBPicker.color = $0\n                cell.circleBoxHSBPicker.color = $0\n                cell.circleBarsHSBPicker.color = $0\n                cell.colorSampleView.color = $0.cgColor\n                cell.alphaField.value = round($0.alpha * 100)\n            }\n            .store(in: &objectBag)\n        \n        self.cell.pickerTypePicker.itemPublisher\n            .sink{[unowned self] in self.pickerType = $0 }.store(in: &objectBag)\n        self.cell.colorCopyTypePicker.itemPublisher\n            .sink{[unowned self] in self.copyType = $0; updateComponents() }.store(in: &objectBag)\n        self.cell.hex3TextField.endEditingStringPublisher\n            .sink{[unowned self] in self.color = Color(hex3: $0, alpha: color.alpha) ?? color; updateComponents() }.store(in: &objectBag)\n        self.cell.hex6TextField.endEditingStringPublisher\n            .sink{[unowned self] in self.color = Color(hex6: $0, alpha: color.alpha) ?? color; updateComponents() }.store(in: &objectBag)\n        self.cell.hex8TextField.endEditingStringPublisher\n            .sink{[unowned self] in self.color = Color(hex8: $0) ?? color; updateComponents() }.store(in: &objectBag)\n        \n        self.cell.boxHSBPicker.colorPublisher.merge(with: cell.circleBoxHSBPicker.colorPublisher, cell.circleBarsHSBPicker.colorPublisher)\n            .sink{[unowned self] in self.color = $0; updateComponents() }.store(in: &objectBag)\n        \n        self.cell.alphaField.publisher\n            .sink{[unowned self] in self.color = self.color.withAlpha($0/100); updateComponents() }.store(in: &objectBag)\n        self.cell.redField.publisher\n            .sink{[unowned self] in self.color = self.color.withRed($0/255); updateComponents() }.store(in: &objectBag)\n        self.cell.greenField.publisher\n            .sink{[unowned self] in self.color = self.color.withGreen($0/255); updateComponents() }.store(in: &objectBag)\n        self.cell.blueField.publisher\n            .sink{[unowned self] in self.color = self.color.withBlue($0/255); updateComponents() }.store(in: &objectBag)\n        \n        self.cell.pixelPickerButton.actionPublisher\n            .sink{[unowned self] in self.pickColor() }.store(in: &objectBag)\n        \n        self.updateComponents()\n    }\n}\n\nenum ColorPickerType: String, TextItem {\n    case hsbBox = \"HSB Box\"\n    case hsbCircle = \"HSB Circle\"\n    case hsbCircleAndBars = \"HSB Circle and Bars\"\n    \n    var title: String { rawValue.localized() }\n}\n\nenum ColorCopyType: String, TextItem {\n    case components = \"Components\"\n    case iosUIColor = \"iOS UIColor\"\n    case macNSColor = \"mac NSColor\"\n    case swiftuiHSBColor = \"SwiftUI HSB Color\"\n    case swiftuiRGBColor = \"SwiftUI RGB Color\"\n    case androidARGB = \"Android RGB\"\n    case androidHEX = \"Android HEX\"\n    case androidXML = \"Android XML\"\n    case webHEX = \"Web HEX\"\n    case webRGBA = \"Web RGB\"\n    case webHSLA = \"Web HSL\"\n    \n    var title: String { rawValue }\n}\n\nfinal private class ColorPickerView: Page {\n    let pickerTypePicker = EnumPopupButton<ColorPickerType>()\n    \n    let boxHSBPicker = BoxHSBColorPicker()\n    let circleBoxHSBPicker = CircleBoxHSBColorPicker()\n    let circleBarsHSBPicker = CircleBarsHSBColorPicker()\n    \n    let pickerPlaceholder = NSPlaceholderView()\n    \n    let colorSampleView = ColorSampleView()\n    let pixelPickerButton = SectionButton(title: \"Pick Color\", image: R.Image.spuit)\n    let alphaField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    \n    let colorCopyTypePicker = EnumPopupButton<ColorCopyType>()\n    let colorCopyPlaceholder = NSPlaceholderView()\n    \n    let hex3TextField = TextField() => { $0.placeholder = \"#XXX\" }\n    let hex6TextField = TextField() => { $0.placeholder = \"#XXXXXX\" }\n    let hex8TextField = TextField() => { $0.placeholder = \"#XXXXXXXX\" }\n        \n    let redField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    let greenField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    let blueField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    \n    let cyanField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    let magentaField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    let yellowField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    let keyField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    \n    let hueField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    let saturationField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    let brightnessField = NumberField() => { $0.snp.makeConstraints{ make in make.width.equalTo(100) } }\n    \n    let textCopyField = TextField()\n    \n    lazy var paramatorsStack = NSStackView() => { paramatorsStack in\n        paramatorsStack.alignment = .top\n        paramatorsStack.addArrangedSubview(Section(title: \"RGB\", orientation: .vertical, items: [\n            redField, greenField, blueField\n        ]))\n        paramatorsStack.addArrangedSubview(Section(title: \"HSB\", orientation: .vertical, items: [\n            hueField, saturationField, brightnessField\n        ]))\n        paramatorsStack.addArrangedSubview(Section(title: \"CMYK\", orientation: .vertical, items: [\n            cyanField, magentaField, yellowField, keyField\n        ]))\n    }\n    \n    override func onAwake() {\n        self.addSection(Area(icon: R.Image.settings, title: \"Picker Type\".localized(), control: pickerTypePicker))\n        self.pickerPlaceholder.contentView = circleBarsHSBPicker\n        self.addSection(pickerPlaceholder)\n        \n        let componentsStack = NSStackView()\n        componentsStack.orientation = .horizontal\n        componentsStack.addArrangedSubview(colorSampleView)\n        componentsStack.addArrangedSubview(pixelPickerButton)\n        componentsStack.addArrangedSubview(NSView())\n        componentsStack.addArrangedSubview(alphaField)\n        \n        self.addSection(componentsStack)\n        \n        self.addSection(Section(title: \"Color Hex\".localized(), orientation: .horizontal, fillWidth: false, items: [\n            hex3TextField, hex6TextField, hex8TextField\n        ]))\n                \n        self.addSection(Section(title: \"Color Copy\".localized(), items: [\n            Area(icon: R.Image.copy, title: \"Color Copy Type\".localized(), control: colorCopyTypePicker),\n            self.colorCopyPlaceholder\n        ]))\n\n        self.textCopyField.font = .monospacedSystemFont(ofSize: R.Size.controlTitleFontSize, weight: .regular)\n    }\n}\n\nextension NumberField {\n    var publisher: AnyPublisher<CGFloat, Never> {\n        valuePublisher.map{ CGFloat($0.reduce(self.value.native)) }.eraseToAnyPublisher()\n    }\n}\n\n\nextension CGFloat {\n    private static let numberFormatter = NumberFormatter() => {\n        $0.maximumFractionDigits = 2\n        $0.minimumFractionDigits = 2\n    }\n    fileprivate var cf: String {\n        Self.numberFormatter.string(from: NSNumber(value: native)) ?? \"0\"\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/BoxHSBColorPicker.swift",
    "content": "//\n//  BoxColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class BoxHSBColorPicker: NSLoadStackView {\n    \n    var color = Color.default {\n        didSet {\n            self.colorBox.color = color\n            self.hueBar.color = color\n            self.opacityBar.color = color\n        }\n    }\n    \n    var colorPublisher: AnyPublisher<Color, Never> {\n        let p1 = colorBox.valuePublisher.map{ self.color.withSB($0.saturation, $0.brightness) }\n        let p2 = hueBar.huePublisher.map{ self.color.withHue($0) }\n        let p3 = opacityBar.opacityPublisher.map{ v in self.color <=> { $0.alpha = v } }\n        \n        return p1.merge(with: p2, p3).eraseToAnyPublisher()\n    }\n    \n    let colorBox = ColorBoxView()\n    let hueBar = HueBarView()\n    let opacityBar = OpacityBarView()\n    \n    override func onAwake() {\n        self.orientation = .horizontal\n        self.spacing = 16\n        self.addArrangedSubview(colorBox)\n        self.addArrangedSubview(hueBar)\n        self.addArrangedSubview(opacityBar)\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(200)\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/BrightnessBarView.swift",
    "content": "//\n//  BrightnessBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class BrightnessBarView: NSLoadView {\n    var color: Color = .default { didSet { self.updateHandle(); updateColorLayer() } }\n    let lightnessPublisher = PassthroughSubject<CGFloat, Never>()\n    \n    private let handleLayer = ColorPickerHandleLayer()\n    private let colorLayer = CAGradientLayer.animationDisabled()\n    \n    override func layout() {\n        super.layout()\n        self.colorLayer.frame = bounds\n        self.updateHandle()\n    }\n    \n    override func mouseDown(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    override func mouseDragged(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    \n    private func sendLocation(_ location: CGPoint) {\n        self.lightnessPublisher.send((location.y / bounds.height).clamped(0...1))\n    }\n    \n    private func updateColorLayer() {\n        self.colorLayer.colors = [\n            NSColor(colorSpace: .current, hue: color.hue, saturation: color.saturation, brightness: 0, alpha: 1).cgColor,\n            NSColor(colorSpace: .current, hue: color.hue, saturation: color.saturation, brightness: 1, alpha: 1).cgColor\n        ]\n    }\n    \n    private func updateHandle() {\n        self.handleLayer.color = color.withAlpha(1).cgColor\n        self.handleLayer.frame.center = [bounds.midX, color.brightness * bounds.height]\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.width.equalTo(R.ColorPicker.barWidth)\n        }\n        self.wantsLayer = true\n        self.layer?.addSublayer(colorLayer)\n        self.layer?.addSublayer(handleLayer)\n        self.layer?.cornerRadius = R.Size.corner\n        self.layer?.borderWidth = 1\n        self.layer?.borderColor = CGColor.black.withAlpha(0.2)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/CircleBarsHSBColorPicker.swift",
    "content": "//\n//  CircleBarsHSBColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\n\nfinal class CircleBarsHSBColorPicker: NSLoadStackView {\n    var color = Color.default {\n        didSet {\n            self.circleHueBar.color = color\n            self.opacityBar.color = color\n            self.saturationBar.color = color\n            self.lightnessBar.color = color\n        }\n    }\n    \n    var colorPublisher: AnyPublisher<Color, Never> {\n        let p2 = opacityBar.opacityPublisher.map{ v in self.color <=> { $0.alpha = v } }\n        let p1 = circleHueBar.huePublisher.map{ self.color.withHue($0) }\n        let p3 = saturationBar.saturationPublisher.map{ self.color.withSaturation($0) }\n        let p4 = lightnessBar.lightnessPublisher.map{ self.color.withBrightness($0) }\n        \n        return p1.merge(with: p2, p3, p4).eraseToAnyPublisher()\n    }\n    \n    let circleHueBar = CircleHueBarView()\n    let saturationBar = SaturationBarView()\n    let lightnessBar = BrightnessBarView()\n    let opacityBar = OpacityBarView()\n    \n    override func onAwake() {\n        self.orientation = .horizontal\n        self.spacing = 16\n        self.addArrangedSubview(circleHueBar)\n        self.addArrangedSubview(saturationBar)\n        self.addArrangedSubview(lightnessBar)\n        self.addArrangedSubview(opacityBar)\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(250)\n        }\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/CircleBoxHSBColorPicker.swift",
    "content": "//\n//  CircleColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class CircleBoxHSBColorPicker: NSLoadStackView {\n    var color = Color.default {\n        didSet {\n            self.colorBox.color = color\n            self.circleHueBar.color = color\n            self.opacityBar.color = color\n        }\n    }\n    \n    var colorPublisher: AnyPublisher<Color, Never> {\n        let p1 = colorBox.valuePublisher.map{ self.color.withSB($0.saturation, $0.brightness) }\n        let p2 = circleHueBar.huePublisher.map{ self.color.withHue($0) }\n        let p3 = opacityBar.opacityPublisher.map{ v in self.color <=> { $0.alpha = v } }\n        \n        return p1.merge(with: p2, p3).eraseToAnyPublisher()\n    }\n    \n    let colorBox = ColorBoxView()\n    let circleHueBar = CircleHueBarView()\n    let opacityBar = OpacityBarView()\n    \n    override func onAwake() {\n        self.orientation = .horizontal\n        self.spacing = 16\n        self.addArrangedSubview(circleHueBar)\n        self.circleHueBar.placeholder.contentView = colorBox\n        self.addArrangedSubview(opacityBar)\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(250)\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/CircleHueBarView.swift",
    "content": "//\n//  CircleHueBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\n\nfinal class CircleHueBarView: NSLoadView {\n    var color: Color = .default { didSet { self.updateHandle() } }\n    let huePublisher = PassthroughSubject<CGFloat, Never>()\n    let placeholder = NSPlaceholderView()\n    \n    private let handleLayer = ColorPickerHandleLayer()\n    private let maskLayer = CAShapeLayer.animationDisabled()\n    private let borderLayer = CAShapeLayer.animationDisabled()\n    private let hueLayer = CAGradientLayer.animationDisabled()\n    \n    override func mouseDown(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    override func mouseDragged(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    \n    private func sendLocation(_ location: CGPoint) {\n        let delta = bounds.center - location\n        let radius = atan2(delta.y, delta.x) / (2 * .pi) + 0.5\n        huePublisher.send(radius.clamped(0...1))\n    }\n    \n    private func updateHandle() {\n        self.handleLayer.color = Color(hue: color.hue, saturation: 1, brightness: 1, alpha: 1).cgColor\n        let radius = (color.hue) * 2 * .pi\n        self.handleLayer.frame.center = bounds.center + [cos(radius), sin(radius)] * (self.bounds.size.convertToPoint()/2 - [R.ColorPicker.barWidth, R.ColorPicker.barWidth]/2)\n    }\n    \n    override func layout() {\n        super.layout()\n        self.hueLayer.frame = bounds\n        self.maskLayer.path = CGPath(ellipseIn: bounds.slimmed(by: R.ColorPicker.barWidth/2), transform: nil)\n        self.borderLayer.path = self.maskLayer.path!\n            .copy(strokingWithWidth: R.ColorPicker.barWidth-1, lineCap: CGLineCap.butt, lineJoin: .miter, miterLimit: .infinity)\n        self.updateHandle()\n        \n        let half = (bounds.width)/2\n        let delta = half - half/sqrt(2)\n        self.placeholder.frame = bounds.slimmed(by: delta+R.ColorPicker.barWidth)\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.snp.makeConstraints{ make in\n            make.width.equalTo(self.snp.height)\n        }\n        \n        self.layer?.addSublayer(hueLayer)\n        self.layer?.addSublayer(borderLayer)\n        self.layer?.addSublayer(handleLayer)\n        self.hueLayer.colors = hueColors\n        self.hueLayer.startPoint = [0.5, 0.5]\n        self.hueLayer.endPoint = [1, 0.5]\n        self.hueLayer.type = .conic\n        \n        self.hueLayer.mask = maskLayer\n        self.maskLayer.lineWidth = R.ColorPicker.barWidth\n        self.maskLayer.fillColor = nil\n        self.maskLayer.strokeColor = .black\n        \n        self.borderLayer.lineWidth = 1\n        self.borderLayer.fillColor = nil\n        self.borderLayer.strokeColor = .black.withAlpha(0.2)\n        \n        self.addSubview(placeholder)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/ColorBoxView.swift",
    "content": "//\n//  ColorBoxView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class ColorBoxView: NSLoadView {\n    let valuePublisher = PassthroughSubject<(saturation: CGFloat, brightness: CGFloat), Never>()\n    \n    var color: Color = .default { didSet { self.updateHandle(); self.updateHue() } }\n    \n    private let hueLayer = CAGradientLayer.animationDisabled()\n    private let handleLayer = ColorPickerHandleLayer()\n    private let brightnessLayer = CAGradientLayer.animationDisabled()\n    \n    override func mouseDown(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    override func mouseDragged(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    \n    private func sendLocation(_ location: CGPoint) {\n        let sb = location / bounds.size.convertToPoint()\n        self.valuePublisher.send((saturation: sb.x.clamped(0...1), brightness: sb.y.clamped(0...1)))\n    }\n    \n    private func updateHue() {\n        self.hueLayer.colors = [CGColor.white, NSColor(colorSpace: .current, hue: color.hue, saturation: 1, brightness: 1, alpha: 1).cgColor]\n    }\n    \n    private func updateHandle() {\n        let centerX = color.saturation * bounds.width\n        let centerY = color.brightness * bounds.height\n        \n        self.handleLayer.color = color.cgColor.withAlpha(1)\n        self.handleLayer.frame.center = bounds.origin + [centerX, centerY]\n    }\n    \n    override func layout() {\n        super.layout()\n        self.hueLayer.frame = bounds\n        self.brightnessLayer.frame = bounds\n        self.updateHandle()\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(hueLayer)\n        self.layer?.addSublayer(brightnessLayer)\n        self.layer?.addSublayer(handleLayer)\n        self.layer?.cornerRadius = R.Size.corner\n        self.layer?.borderWidth = 1\n        self.layer?.borderColor = CGColor.black.withAlpha(0.2)\n        \n        self.hueLayer.startPoint = [0, 0.5]\n        self.hueLayer.endPoint = [1, 0.5]\n        \n        self.brightnessLayer.startPoint = [0.5, 1]\n        self.brightnessLayer.endPoint = [0.5, 0]\n        self.brightnessLayer.colors = [CGColor.clear, CGColor.black]\n    }\n}\n\nextension CGColor {\n    func withAlpha(_ alpha: CGFloat) -> CGColor {\n        self.copy(alpha: alpha)!\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/ColorPickerHandleLayer.swift",
    "content": "//\n//  ColorPickerHandleLayer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nprivate let handleSize: CGFloat = 16\n\nfinal class ColorPickerHandleLayer: CALoadLayer {\n    var color: CGColor = .white {\n        didSet { colorLayer.backgroundColor = color }\n    }\n    \n    private let colorLayer = CALayer.animationDisabled()\n    \n    override func onAwake() {\n        self.frame.size = [handleSize, handleSize]\n        self.areAnimationsEnabled = false\n        self.cornerRadius = handleSize/2\n        self.borderWidth = 2\n        self.borderColor = .white\n        self.backgroundColor = R.Color.transparentBackground.cgColor\n        \n        self.shadowOpacity = 0.2\n        self.shadowOffset = .zero\n        self.shadowRadius = 1\n        \n        self.addSublayer(colorLayer)\n        \n        let colorLayerRect = bounds.slimmed(by: 1.5)\n        self.colorLayer.frame = colorLayerRect\n        self.colorLayer.cornerRadius = colorLayerRect.height/2\n        self.colorLayer.backgroundColor = .white\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/ColorSampleView.swift",
    "content": "//\n//  ColorSampleView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class ColorSampleView: NSLoadView {\n    var color: CGColor = .white {\n        didSet { colorLayer.backgroundColor = color }\n    }\n    \n    private let colorLayer = CALayer.animationDisabled()\n    \n    override func layout() {\n        super.layout()\n        self.colorLayer.frame = bounds\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.width.equalTo(64)\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.wantsLayer = true\n        self.layer?.cornerRadius = R.Size.corner\n        self.layer?.borderWidth = 1\n        self.layer?.borderColor = NSColor.black.withAlphaComponent(0.2).cgColor\n        self.layer?.backgroundColor = R.Color.transparentBackground.cgColor\n        self.layer?.addSublayer(colorLayer)\n        self.colorLayer.backgroundColor = .white\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/HueBarView.swift",
    "content": "//\n//  HueBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class HueBarView: NSLoadView {\n    \n    var color: Color = .default { didSet { self.updateHandle() } }\n    let huePublisher = PassthroughSubject<CGFloat, Never>()\n    \n    private let handleLayer = ColorPickerHandleLayer()\n    private let hueLayer = CAGradientLayer.animationDisabled()\n    \n    override func mouseDown(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    override func mouseDragged(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    \n    private func sendLocation(_ location: CGPoint) {\n        huePublisher.send((location.y / bounds.height).clamped(0...1))\n    }\n    \n    private func updateHandle() {\n        self.handleLayer.color = Color(hue: color.hue, saturation: 1, brightness: 1, alpha: 1).cgColor\n        self.handleLayer.frame.center = [bounds.midX, color.hue * bounds.height]\n    }\n    \n    override func layout() {\n        super.layout()\n        self.hueLayer.frame = bounds\n        self.updateHandle()\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.width.equalTo(R.ColorPicker.barWidth)\n        }\n        self.wantsLayer = true\n        self.layer?.addSublayer(hueLayer)\n        self.layer?.addSublayer(handleLayer)\n        self.layer?.cornerRadius = R.Size.corner\n        self.layer?.borderWidth = 1\n        self.layer?.borderColor = CGColor.black.withAlpha(0.2)\n        \n        self.hueLayer.colors = hueColors\n    }\n}\n\nlet hueColors = stride(from: 0, to: 1, by: 0.01).map{ NSColor(colorSpace: .current, hue: CGFloat($0), saturation: 1, brightness: 1, alpha: 1).cgColor }\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/OpacityBarView.swift",
    "content": "//\n//  OpacityBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class OpacityBarView: NSLoadView {\n    var color: Color = .default { didSet { self.updateHandle(); updateColorLayer() } }\n    let opacityPublisher = PassthroughSubject<CGFloat, Never>()\n    \n    private let handleLayer = ColorPickerHandleLayer()\n    private let colorLayer = CAGradientLayer.animationDisabled()\n    \n    override func layout() {\n        super.layout()\n        self.colorLayer.frame = bounds\n        self.updateHandle()\n    }\n    \n    override func mouseDown(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    override func mouseDragged(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    \n    private func sendLocation(_ location: CGPoint) {\n        self.opacityPublisher.send((location.y / bounds.height).clamped(0...1))\n    }\n    \n    private func updateColorLayer() {\n        self.colorLayer.colors = [color.cgColor.withAlpha(0), color.cgColor.withAlpha(1)]\n    }\n    \n    private func updateHandle() {\n        self.handleLayer.color = color.cgColor\n        self.handleLayer.frame.center = [bounds.midX, color.alpha * bounds.height]\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.width.equalTo(R.ColorPicker.barWidth)\n        }\n        self.wantsLayer = true\n        self.layer?.addSublayer(colorLayer)\n        self.layer?.addSublayer(handleLayer)\n        self.layer?.cornerRadius = R.Size.corner\n        self.layer?.borderWidth = 1\n        self.layer?.borderColor = CGColor.black.withAlpha(0.2)\n        self.layer?.backgroundColor = R.Color.transparentBackground.cgColor\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Components/SaturationBarView.swift",
    "content": "//\n//  SaturationBarView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nimport CoreUtil\n\nfinal class SaturationBarView: NSLoadView {\n    var color: Color = .default { didSet { self.updateHandle(); updateColorLayer() } }\n    let saturationPublisher = PassthroughSubject<CGFloat, Never>()\n    \n    private let handleLayer = ColorPickerHandleLayer()\n    private let colorLayer = CAGradientLayer.animationDisabled()\n    \n    override func layout() {\n        super.layout()\n        self.colorLayer.frame = bounds\n        self.updateHandle()\n    }\n    \n    override func mouseDown(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    override func mouseDragged(with event: NSEvent) {\n        self.sendLocation(event.location(in: self))\n    }\n    \n    private func sendLocation(_ location: CGPoint) {\n        self.saturationPublisher.send((location.y / bounds.height).clamped(0...1))\n    }\n    \n    private func updateColorLayer() {\n        self.colorLayer.colors = [\n            NSColor(colorSpace: .current, hue: color.hue, saturation: 0, brightness: color.brightness, alpha: 1).cgColor,\n            NSColor(colorSpace: .current, hue: color.hue, saturation: 1, brightness: color.brightness, alpha: 1).cgColor\n        ]\n    }\n    \n    private func updateHandle() {\n        self.handleLayer.color = color.withAlpha(1).cgColor\n        self.handleLayer.frame.center = [bounds.midX, color.saturation * bounds.height]\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.width.equalTo(R.ColorPicker.barWidth)\n        }\n        self.wantsLayer = true\n        self.layer?.addSublayer(colorLayer)\n        self.layer?.addSublayer(handleLayer)\n        self.layer?.cornerRadius = R.Size.corner\n        self.layer?.borderWidth = 1\n        self.layer?.borderColor = CGColor.black.withAlpha(0.2)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayController.swift",
    "content": "//\n//  PPOverlayController.swift\n//  Pixel Picker\n//\n\nimport Cocoa\nimport Carbon.HIToolbox\n\nprivate let magnification = CGFloat(12)\n\nclass ACOverlayController: NSWindowController {\n\n    // ================================================================================================== //\n    // MARK: - Outlet -\n\n    @IBOutlet weak var overlayPanel: ACOverlayPanel!\n    @IBOutlet weak var wrapper: PPOverlayWrapper!\n    @IBOutlet weak var preview: ACOverlayPreview!\n\n    @IBOutlet weak var infoPanel: ACOverlayPanel!\n    @IBOutlet weak var infoWrapper: NSView!\n    @IBOutlet weak var infoDetailField: NSTextField!\n\n    // ================================================================================================== //\n    // MARK: - Properties -\n\n    private var completion: (NSColor) -> Void = {_ in }\n    private static let panelSizeNormal: CGFloat = 150\n    private static let panelSizeLarge: CGFloat = 300\n    private var panelSize: CGFloat = ACOverlayController.panelSizeNormal\n\n    private var lastActiveApp: NSRunningApplication?\n    private var lastMouseLocation = NSEvent.mouseLocation\n    private var lastHighlightedColor: NSColor = NSColor.black\n    private var eventMonitor: Any?\n\n    private var isEnabled: Bool = false {\n        didSet {\n            if isEnabled {\n                lastMouseLocation = NSEvent.mouseLocation\n                startMonitoringEvents()\n            } else {\n                stopMonitoringEvents()\n            }\n        }\n    }\n\n    // ================================================================================================== //\n    // MARK: - View Cycle -\n    override func awakeFromNib() {\n        infoDetailField.font = .monospacedSystemFont(ofSize: 11, weight: .regular)\n        infoDetailField.textColor = .white\n        infoWrapper.layer?.backgroundColor = #colorLiteral(red: 0.1315930784, green: 0.1315930784, blue: 0.1315930784, alpha: 1)\n        infoWrapper.wantsLayer = true\n        infoWrapper.layer?.cornerRadius = R.Size.corner\n        infoWrapper.layer?.backgroundColor = NSColor.black.cgColor\n\n        eventMonitor = NSEvent.addLocalMonitorForEvents(matching: [.keyDown]) {[weak self] in\n            guard let self = self else { return nil }\n\n            if self.isEnabled { self.keyDown(with: $0) }\n            return nil\n        }\n    }\n\n    private var globalMonitors: [Any] = []\n    private func startMonitoringEvents() {\n        stopMonitoringEvents()\n        globalMonitors.append(NSEvent.addGlobalMonitorForEvents(matching: [.flagsChanged]) { self.flagsChanged(with: $0) }!)\n        globalMonitors.append(NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved]) { self.mouseMoved(with: $0) }!)\n    }\n    private func stopMonitoringEvents() {\n        while globalMonitors.count > 0 { NSEvent.removeMonitor(globalMonitors.popLast()!) }\n    }\n\n    // ================================================================================================== //\n    // MARK: - Control -\n    override func mouseDown(with event: NSEvent) {\n        hidePicker()\n        pickColor()\n    }\n\n    override func keyDown(with event: NSEvent) {\n        switch Int(event.keyCode) {\n        case kVK_Escape:\n            hidePicker()\n        case kVK_Space:\n            hidePicker()\n            pickColor()\n        default: break\n        }\n    }\n    override func mouseMoved(with event: NSEvent) {\n        if isEnabled {\n            let currentMouseLocation = NSEvent.mouseLocation\n            let nextMouseLocation = currentMouseLocation\n            updatePreview(aroundPoint: nextMouseLocation)\n            lastMouseLocation = nextMouseLocation\n        }\n    }\n\n    // ================================================================================================== //\n    // MARK: - Privtaes -\n    private func moveByPixel(dx: CGFloat, dy: CGFloat) {\n        var mouseLoc = lastMouseLocation\n        let currentScreen = getScreenWithMouse()\n        guard let screenFrame = currentScreen?.frame, let screenScale = currentScreen?.backingScaleFactor else {\n            return\n        }\n        mouseLoc.x += dx / screenScale\n        mouseLoc.y += dy / screenScale\n        lastMouseLocation = mouseLoc\n        updatePreview(aroundPoint: mouseLoc)\n        mouseLoc.y = screenFrame.maxY - mouseLoc.y\n        CGDisplayMoveCursorToPoint(0, mouseLoc)\n    }\n\n    func pickColor() {\n        completion(lastHighlightedColor)\n    }\n\n    func showPicker(_ completion: @escaping (NSColor) -> Void) {\n        self.completion = completion\n        if overlayPanel.isVisible || infoPanel.isVisible { return }\n        isEnabled = true\n        overlayPanel.activate(withSize: panelSize, infoPanel: infoPanel)\n\n        if NSWorkspace.shared.frontmostApplication?.bundleIdentifier != Bundle.main.bundleIdentifier {\n            lastActiveApp = NSWorkspace.shared.frontmostApplication\n        }\n\n        wrapper.layer?.cornerRadius = panelSize / 2\n        updatePreview(aroundPoint: NSEvent.mouseLocation)\n        hideCursor()\n    }\n\n    private func hidePicker() {\n        isEnabled = false\n\n        showCursor()\n        self.overlayPanel.orderOut(self)\n        self.infoPanel.orderOut(self)\n\n        if self.lastActiveApp != nil, self.lastActiveApp != NSRunningApplication.current {\n            self.lastActiveApp!.activate(options: .activateAllWindows)\n            self.lastActiveApp = nil\n        }\n\n        self.close()\n        if let eventMonitor = eventMonitor {\n            NSEvent.removeMonitor(eventMonitor)\n        }\n    }\n\n    private func getScreenWithMouse() -> NSScreen? {\n        let mouseLocation = NSEvent.mouseLocation\n        let screens = NSScreen.screens\n        let screenWithMouse = screens.first { NSMouseInRect(mouseLocation, $0.frame, false) }\n\n        return screenWithMouse\n    }\n\n    private func updateInfoPanel(_ color: NSColor) {\n        infoDetailField.stringValue = color.hexColorCode()\n    }\n\n    private func getScreenShot(aroundPoint point: NSPoint) -> CGImage? {\n        let cgPoint = convertToCGCoordinateSystem(point)\n        let rect = CGRect(x: cgPoint.x - panelSize / 2, y: cgPoint.y - panelSize / 2, width: panelSize, height: panelSize)\n        return CGWindowListCreateImage(rect, [.optionOnScreenBelowWindow], CGWindowID(overlayPanel.windowNumber), .bestResolution)\n    }\n\n    private func updatePreview(aroundPoint point: NSPoint) {\n        if !overlayPanel.isKeyWindow {\n            overlayPanel.activate(withSize: panelSize, infoPanel: infoPanel)\n            showCursor()\n            hideCursor()\n        }\n\n        overlayPanel.setFrameOrigin(NSPoint(x: point.x - (panelSize / 2), y: point.y - (panelSize / 2)))\n        let normalisedPoint = NSPoint(x: round(point.x * 2) / 2, y: round(point.y * 2) / 2)\n        guard let screenShot = getScreenShot(aroundPoint: normalisedPoint) else { return }\n\n        let zoomReciprocal: CGFloat = 1.0 / magnification\n        let currentSize = CGFloat(screenShot.width) + 1\n        let origin = floor(currentSize * ((1 - zoomReciprocal) / 2))\n        let x = origin + (isHalf(normalisedPoint.x) ? 1 : 0)\n        let y = origin + (isHalf(normalisedPoint.y) ? 1 : 0)\n\n        let zoomedSize = floor(ensureOdd(currentSize * zoomReciprocal))\n        let croppedRect = CGRect(x: x, y: y, width: zoomedSize, height: zoomedSize)\n        let zoomedImage: CGImage = screenShot.cropping(to: croppedRect)!\n        let pixelSize = panelSize / zoomedSize\n\n        return updatePreview(zoomedImage, pixelSize, zoomedSize)\n    }\n\n    private func updatePreview(_ image: CGImage, _ pixelSize: CGFloat, _ numberOfPixels: CGFloat) {\n        let middlePosition = numberOfPixels / 2\n\n        let colorAtPixel = image.colorAt(x: Int(middlePosition), y: Int(middlePosition))\n        let contrastingColor = colorAtPixel.bestContrastingColor()\n\n        updateInfoPanel(colorAtPixel)\n\n        preview.layer?.contents = image\n        preview.updateCrosshair(pixelSize, middlePosition, contrastingColor.cgColor)\n        preview.updateGrid(cellSize: pixelSize, numberOfCells: Int(numberOfPixels), shouldDisplay: true)\n\n        lastHighlightedColor = colorAtPixel\n    }\n}\n\nextension NSColor {\n    public func hexColorCode() -> String {\n        String(format: \"%02X%02X%02X\", Int(round(self.redComponent * 255)), Int(round(self.greenComponent * 255)), Int(round(self.blueComponent * 255)))\n    }\n    \n    public convenience init?(colorSpace: NSColorSpace, hexColorCode: String) {\n        guard hexColorCode.count == 6 else { return nil }\n        \n        let scanner = Scanner(string: hexColorCode)\n        var value = UInt64.zero\n        scanner.scanHexInt64(&value)\n        \n        let r = CGFloat((value & 0xFF0000) >> 16) / 255\n        let g = CGFloat((value & 0x00FF00) >>  8) / 255\n        let b = CGFloat((value & 0x0000FF) >>  0) / 255\n        \n        self.init(colorSpace: colorSpace, red: r, green: g, blue: b, alpha: 1)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayController.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"19529\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"19529\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\" customClass=\"NSApplication\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customObject id=\"ECQ-9M-Pkg\" customClass=\"ACOverlayController\" customModule=\"DevToys\" customModuleProvider=\"target\">\n            <connections>\n                <outlet property=\"infoDetailField\" destination=\"Re2-GH-fyd\" id=\"K03-75-cf9\"/>\n                <outlet property=\"infoPanel\" destination=\"OMO-LB-w57\" id=\"GGj-Y6-LfU\"/>\n                <outlet property=\"infoWrapper\" destination=\"HED-rR-FDP\" id=\"21H-Tc-c4W\"/>\n                <outlet property=\"overlayPanel\" destination=\"gZA-A3-IZ5\" id=\"DUd-MU-oD4\"/>\n                <outlet property=\"preview\" destination=\"oj3-ml-2qo\" id=\"xLc-pu-U90\"/>\n                <outlet property=\"window\" destination=\"gZA-A3-IZ5\" id=\"GLv-sO-WxM\"/>\n                <outlet property=\"wrapper\" destination=\"acW-WA-gq2\" id=\"Mpu-0H-rtC\"/>\n            </connections>\n        </customObject>\n        <window title=\"Window\" allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" restorable=\"NO\" visibleAtLaunch=\"NO\" frameAutosaveName=\"\" animationBehavior=\"default\" id=\"gZA-A3-IZ5\" customClass=\"ACOverlayPanel\" customModule=\"DevToys\" customModuleProvider=\"target\">\n            <windowStyleMask key=\"styleMask\" utility=\"YES\" nonactivatingPanel=\"YES\"/>\n            <windowPositionMask key=\"initialPositionMask\" leftStrut=\"YES\" rightStrut=\"YES\" topStrut=\"YES\" bottomStrut=\"YES\"/>\n            <rect key=\"contentRect\" x=\"196\" y=\"132\" width=\"101\" height=\"101\"/>\n            <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"2560\" height=\"1415\"/>\n            <view key=\"contentView\" id=\"acW-WA-gq2\" customClass=\"PPOverlayWrapper\" customModule=\"DevToys\" customModuleProvider=\"target\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"101\" height=\"101\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <customView translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"oj3-ml-2qo\" customClass=\"ACOverlayPreview\" customModule=\"DevToys\" customModuleProvider=\"target\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"101\" height=\"101\"/>\n                    </customView>\n                </subviews>\n                <constraints>\n                    <constraint firstItem=\"oj3-ml-2qo\" firstAttribute=\"top\" secondItem=\"acW-WA-gq2\" secondAttribute=\"top\" id=\"HXK-hi-eiB\"/>\n                    <constraint firstAttribute=\"bottom\" secondItem=\"oj3-ml-2qo\" secondAttribute=\"bottom\" id=\"UTp-UT-EH9\"/>\n                    <constraint firstAttribute=\"trailing\" secondItem=\"oj3-ml-2qo\" secondAttribute=\"trailing\" id=\"gd3-Pq-3Cn\"/>\n                    <constraint firstItem=\"oj3-ml-2qo\" firstAttribute=\"leading\" secondItem=\"acW-WA-gq2\" secondAttribute=\"leading\" id=\"jC3-qE-mqJ\"/>\n                </constraints>\n            </view>\n            <point key=\"canvasLocation\" x=\"236\" y=\"82\"/>\n        </window>\n        <window title=\"Window\" allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" restorable=\"NO\" visibleAtLaunch=\"NO\" frameAutosaveName=\"\" animationBehavior=\"default\" id=\"OMO-LB-w57\" customClass=\"ACOverlayPanel\" customModule=\"DevToys\" customModuleProvider=\"target\">\n            <windowStyleMask key=\"styleMask\" utility=\"YES\" nonactivatingPanel=\"YES\"/>\n            <rect key=\"contentRect\" x=\"926\" y=\"538\" width=\"100\" height=\"29\"/>\n            <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"2560\" height=\"1415\"/>\n            <view key=\"contentView\" id=\"HED-rR-FDP\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"100\" height=\"29\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Re2-GH-fyd\">\n                        <rect key=\"frame\" x=\"-2\" y=\"8\" width=\"104\" height=\"14\"/>\n                        <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Label\" id=\"IYd-1Y-7cd\">\n                            <font key=\"font\" metaFont=\"label\" size=\"11\"/>\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                </subviews>\n                <constraints>\n                    <constraint firstItem=\"Re2-GH-fyd\" firstAttribute=\"leading\" secondItem=\"HED-rR-FDP\" secondAttribute=\"leading\" id=\"aZf-QY-Lpd\"/>\n                    <constraint firstAttribute=\"bottom\" secondItem=\"Re2-GH-fyd\" secondAttribute=\"bottom\" constant=\"8\" id=\"amm-jV-oWa\"/>\n                    <constraint firstAttribute=\"trailing\" secondItem=\"Re2-GH-fyd\" secondAttribute=\"trailing\" id=\"jWO-5f-uxW\"/>\n                </constraints>\n            </view>\n            <point key=\"canvasLocation\" x=\"236\" y=\"236.5\"/>\n        </window>\n    </objects>\n</document>\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayPanel.swift",
    "content": "//\n//  ACOverlayPanel.swift\n//  PixelPicker\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nclass ACOverlayPanel: NSPanel {\n    override var canBecomeKey: Bool { true }\n    override var canBecomeMain: Bool { true }\n\n    override func awakeFromNib() {\n        self.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary]\n\n        self.level = .popUpMenu\n        self.styleMask = .nonactivatingPanel\n        self.isOpaque = false\n        self.backgroundColor = NSColor.clear\n        self.acceptsMouseMovedEvents = true\n    }\n\n    func activate(withSize size: CGFloat, infoPanel: ACOverlayPanel) {\n        makeKeyAndOrderFront(self)\n        setFrame(NSRect(x: frame.origin.x, y: frame.origin.y, width: size + 1, height: size + 1), display: false)\n        addChildWindow(infoPanel, ordered: .above)\n        let origin = NSPoint(x: frame.midX - infoPanel.frame.width / 2, y: frame.midY - 40)\n        infoPanel.setFrameOrigin(origin)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayPreview.swift",
    "content": "//\n//  ACOverlayPreview.swift\n//  PixelPicker\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nclass ACOverlayPreview: NSView, CALayerDelegate {\n\n    private var grid: CAShapeLayer = CAShapeLayer()\n    private var lastCellSize: CGFloat?\n    private var lastNumberOfCells: Int?\n\n    var crosshair: CAShapeLayer = CAShapeLayer()\n\n    override var wantsUpdateLayer: Bool {\n        get { return true }\n    }\n\n    override func awakeFromNib() {\n        wantsLayer = true\n        layer?.magnificationFilter = .nearest\n        layer?.contentsGravity = .resizeAspectFill\n        layer?.delegate = self\n\n        // Add the grid shape layers to the view.\n        grid.strokeColor = NSColor.lightGray.cgColor\n        grid.fillColor = nil\n        layer?.addSublayer(grid)\n\n        // Prepare crosshair shape layers.\n        crosshair.strokeColor = NSColor.black.cgColor\n        crosshair.fillColor = nil\n        layer?.addSublayer(crosshair)\n    }\n\n    // Update the crosshair with the correct color, position and size.\n    func updateCrosshair(_ pixelSize: CGFloat, _ middle: CGFloat, _ color: CGColor) {\n        let pos: CGFloat = (pixelSize * middle) - (pixelSize / 2) + 0.5\n        let pixelRect = NSRect(x: pos, y: pos, width: pixelSize, height: pixelSize)\n\n        crosshair.path = CGPath(rect: pixelRect, transform: nil)\n        crosshair.strokeColor = color\n        setNeedsDisplay(pixelRect)\n    }\n\n    // Redraws the grid in the preview.\n    func updateGrid(cellSize size: CGFloat, numberOfCells n: Int, shouldDisplay: Bool) {\n        // Disable implicit animations within this transaction.\n        CATransaction.setDisableActions(true)\n        grid.opacity = 0.25\n\n        // Only redraw the grid if we need to display it and the dimensions have changed since last\n        // the last time we drew it.\n        guard shouldDisplay && (size != lastCellSize || n != lastNumberOfCells) else { return }\n        lastCellSize = size\n        lastNumberOfCells = n\n\n        let path = NSBezierPath()\n        let start = CGFloat(0) + 0.5\n        let end = CGFloat(n) * size + 0.5\n\n        for i in 1..<n {\n            let pos = CGFloat(i) * size + 0.5\n            path.move(to: NSPoint(x: pos, y: start))\n            path.line(to: NSPoint(x: pos, y: end))\n            path.move(to: NSPoint(x: start, y: pos))\n            path.line(to: NSPoint(x: end, y: pos))\n        }\n\n        grid.path = path.cgPath\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACOverlayWrapper.swift",
    "content": "//\n//  ACOverlayWrapper.swift\n//  PixelPicker\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\n\nclass PPOverlayWrapper: NSView {\n\n    override var wantsUpdateLayer: Bool {\n        get { return true }\n    }\n\n    override func awakeFromNib() {\n        wantsLayer = true\n        layer?.backgroundColor = NSColor.white.cgColor\n        layer?.borderColor = NSColor.black.cgColor\n        layer?.borderWidth = 1\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/ACPixelPicker.swift",
    "content": "//\n//  ACPixelPicker.swift\n//  AxComponents\n//\n//  Created by yuki on 2020/06/30.\n//  Copyright © 2020 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport CoreUtil\n\nclass ACPixelPicker {\n\n    private var controller: ACOverlayController!\n\n    init() {\n        let nib = NSNib(nibNamed: \"ACOverlayController\", bundle: .current)!\n        var topLevelObjects: NSArray? = []\n        nib.instantiate(withOwner: self, topLevelObjects: &topLevelObjects)\n\n        guard let controller = topLevelObjects?.compactMap({ $0 as? ACOverlayController }).first else { fatalError() }\n\n        self.controller = controller\n    }\n\n    func show(_ completion: @escaping (Color?) -> Void) {\n        controller.showPicker {\n            completion(Color(nsColor: $0))\n        }\n    }\n}\n\nextension ACPixelPicker {\n    func show() -> Promise<Color, PromiseCancelError> {\n        Promise{ resolve, reject in\n            self.show{ if let color = $0 { resolve(color) } else { reject(.shared) } }\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Ex+CGImage.swift",
    "content": "//\n//  CGImage.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nextension CGImage {\n    func colorAt(x: Int, y: Int) -> NSColor {\n        assert(0 <= x && x < self.width)\n        assert(0 <= y && y < self.height)\n\n        let bitmapBytesPerRow = width * 4\n        let bitmapByteCount = bitmapBytesPerRow * Int(self.height)\n\n        // Allocate memory for image data. This is the destination in memory where any drawing to\n        // the bitmap context will be rendered.\n        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)\n        let bitmapData = malloc(bitmapByteCount)\n\n        // Since we manually allocate memeory for the data, we must ensure that the same memory is\n        // freed after we've used it.\n        defer { free(bitmapData) }\n\n        // Create the bitmap context.\n        let context = CGContext(\n            data: bitmapData,\n            width: self.width,\n            height: self.height,\n            bitsPerComponent: 8,\n            bytesPerRow: bitmapBytesPerRow,\n            space: .current,\n            bitmapInfo: bitmapInfo.rawValue\n        )\n\n        // Extract the pixel data from the right offset.\n        if context != nil {\n            // First, we draw the image data onto the context we created.\n            let rect = CGRect(x: 0, y: 0, width: self.width, height: self.height)\n            context!.draw(self, in: rect)\n\n            // Then we extract the data at the right spot.\n            let data = context!.data!\n            let offset = 4 * (y * width + x)\n\n            let a = CGFloat(data.load(fromByteOffset: offset, as: UInt8.self)) / 255.0\n            let r = CGFloat(data.load(fromByteOffset: offset + 1, as: UInt8.self)) / 255.0\n            let g = CGFloat(data.load(fromByteOffset: offset + 2, as: UInt8.self)) / 255.0\n            let b = CGFloat(data.load(fromByteOffset: offset + 3, as: UInt8.self)) / 255.0\n            \n            return NSColor(red: r, green: g, blue: b, alpha: a)\n        }\n\n        // Creating the context failed, so return a default color instead.\n        // Hopefully, this should never happen.\n\n        return NSColor.black\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Ex+NSBezierPath.swift",
    "content": "//\n//  NSBezierPath.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nextension NSBezierPath {\n    var cgPath: CGPath {\n        let path = CGMutablePath()\n        var points = [CGPoint](repeating: .zero, count: 3)\n        for i in 0 ..< self.elementCount {\n            switch self.element(at: i, associatedPoints: &points) {\n            case .moveTo: path.move(to: points[0])\n            case .lineTo: path.addLine(to: points[0])\n            case .curveTo: path.addCurve(to: points[2], control1: points[0], control2: points[1])\n            case .closePath: path.closeSubpath()\n            @unknown default: fatalError()\n            }\n        }\n        return path\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Ex+NSColor.swift",
    "content": "//\n//  NSColor.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nextension NSColor {\n    func image(withSize size: NSSize) -> NSImage {\n        let image = NSImage(size: size)\n        image.lockFocus()\n        self.set()\n        NSRect(origin: NSPoint.zero, size: size).fill()\n        image.unlockFocus()\n        return image\n    }\n\n    func bestContrastingColor() -> NSColor {\n        let rgb: [CGFloat] = [self.redComponent, self.greenComponent, self.blueComponent].map({\n            if $0 <= 0.03928 {\n                return $0 / 12.92\n            } else {\n                return pow(($0 + 0.055) / 1.055, 2.4)\n            }\n        })\n\n        let L = 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]\n        return L > 0.197 ? NSColor.black : NSColor.white\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/ShowAndHideCursor.h",
    "content": "//\n//  ShowAndHideCursor.h\n//  Pixel Picker\n//\n\n#ifndef ShowAndHideCursor_h\n#define ShowAndHideCursor_h\n\n#import <Foundation/Foundation.h>\n#import <AppKit/AppKit.h>\n\nCGDirectDisplayID kCGDirectMainDisplayGetter(void);\n\n#endif\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/ShowAndHideCursor.m",
    "content": "//\n//  ShowAndHideCursor.m\n//  Pixel Picker\n//\n\n#include \"ShowAndHideCursor.h\"\n\n// Unfortunately `kCGDirectMainDisplay` is unavailable in Swift.\nCGDirectDisplayID kCGDirectMainDisplayGetter() {\n    return kCGDirectMainDisplay;\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/ShowAndHideCursor.swift",
    "content": "//\n//  ShowAndHideCursor.swift\n//  Pixel Picker\n//\n\nimport Foundation\nimport ApplicationServices\n\ntypealias notAPrivateAPI0 = @convention(c) () -> CInt\ntypealias notAPrivateAPI1 = @convention(c) (CInt, CInt, CFString, CFTypeRef) -> CGError\n\nlet unsuspiciousArrayOfIntsThatDoNotObfuscateAnything: [[Int]] = [\n    [1, 3, 3, 7],\n    [\n        84, 123, 118, 120, 106, 115, 54, 84, 114, 108, 125, 109, 127, 135, 62, 86, 131,\n        115, 128, 121, 140, 133, 137, 131, 140, 73, 92, 140, 141, 138, 136, 131, 130, 150,\n        140, 147, 147, 121, 140, 154, 159, 147, 142, 145, 160, 92, 149, 162, 146, 159, 152,\n        171, 164, 168, 162, 103, 122, 170, 171, 168, 166, 161, 160, 180, 170, 177, 177, 151,\n        170, 184, 189, 177, 172, 175, 190\n    ],\n    [97, 70, 75, 88, 74, 108, 110, 106, 127, 119, 128, 80, 125, 125, 126, 118, 117, 135, 125, 132, 132],\n    [70, 75, 88, 89, 108, 124, 76, 121, 121, 122, 114, 113, 131, 121, 128, 128, 99, 134, 132, 134, 124, 138, 141, 147]\n]\n\nfunc aFnThatDoesNotObfuscateAnythingAtAll(_ i: Int, _ ints: [Int]) -> String {\n    return String(ints.enumerated().map({ Character(UnicodeScalar($0.element + i - $0.offset)!) }))\n}\n\nlet anInconspicuousListOfPointersThatDoNotPointToPrivateAPIs: [UnsafeMutableRawPointer] = {\n    var list = [UnsafeMutableRawPointer]()\n    let aTotallyPublicFrameworkPath = aFnThatDoesNotObfuscateAnythingAtAll(-1, unsuspiciousArrayOfIntsThatDoNotObfuscateAnything[1])\n    if let handle = dlopen(aTotallyPublicFrameworkPath, RTLD_LAZY) {\n        for (i, s) in unsuspiciousArrayOfIntsThatDoNotObfuscateAnything.dropFirst(2).enumerated() {\n            if let sym = dlsym(handle, aFnThatDoesNotObfuscateAnythingAtAll(-(i + 2), s)) {\n                list.append(sym)\n            }\n        }\n        dlclose(handle)\n    }\n\n    return list\n}()\n\nlet kCGDirectMainDisplay = kCGDirectMainDisplayGetter()\n\nvar cursorIsHidden = false\n\nfunc showCursor() {\n    CGDisplayShowCursor(kCGDirectMainDisplay)\n}\n\nfunc hideCursor() {\n    let pt0 = anInconspicuousListOfPointersThatDoNotPointToPrivateAPIs[0]\n    let cid = unsafeBitCast(pt0, to: notAPrivateAPI0.self)()\n    let pStr = \"SetsCursorInBackground\" as CFString\n    let pt1 = anInconspicuousListOfPointersThatDoNotPointToPrivateAPIs[1]\n    _ = unsafeBitCast(pt1, to: notAPrivateAPI1.self)(cid, cid, pStr, kCFBooleanTrue)\n\n    CGDisplayHideCursor(kCGDirectMainDisplay)\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/Pixel Picker/Utils/Util+PixelPicker.swift",
    "content": "//\n//  Util.swift\n//  Pixel Picker\n//\n\nimport Cocoa\n\nlet APP_NAME = Bundle.main.infoDictionary![kCFBundleNameKey as String] as! String\nlet APPLE_INTERFACE_STYLE = \"AppleInterfaceStyle\"\n\n// Copies the given string to the clipboard.\nfunc copyToPasteboard(stringValue value: String) {\n    NSPasteboard.general.declareTypes([.string], owner: nil)\n    NSPasteboard.general.setString(value, forType: .string)\n}\n\n// Ensure that the given number is odd.\nfunc ensureOdd(_ x: CGFloat) -> CGFloat {\n    if Int(x) % 2 == 0 { return x + 1 }\n    return x\n}\n\n// Checks whether a float roughly ends in \".5\".\nfunc isHalf(_ x: CGFloat) -> Bool {\n    return Int(x * 2) % 2 != 0\n}\n\n// The Cocoa APIs have a coordinate system (origin is top-left of the screen) but the\n// Carbon/CoreGraphics APIs use an old coordinate system where the origin is the\n// bottom-left corner *of the primary display*.\n// The primary display is always the first item of the NSScreen.screens array.\nfunc convertToCGCoordinateSystem(_ point: NSPoint) -> CGPoint {\n    return CGPoint(x: point.x, y: NSScreen.screens[0].frame.size.height - point.y)\n}\n\n// Returns the screen which contains the mouse cursor.\nfunc getScreenFromPoint(_ point: NSPoint) -> NSScreen? {\n    return NSScreen.screens.first { NSMouseInRect(point, $0.frame, false) }\n}\n\n// Checks if the given point is outside of the given rect.\n// Returns which coordinates are outside, if any.\nenum Coordinate {\n    case x, y, both, none\n    static func isOutsideRect(_ point: NSPoint, _ rect: NSRect) -> Coordinate {\n        let x = point.x < rect.origin.x || point.x > (rect.origin.x + rect.width)\n        let y = point.y < rect.origin.y || point.y > (rect.origin.y + rect.height)\n        if x && y { return .both }\n        if x { return .x }\n        if y { return .y }\n        return .none\n    }\n}\n\n// A simple helper to run animations with the same context configration.\nfunc runAnimation(_ f: (NSAnimationContext) -> Void, done: (() -> Void)?) {\n    NSAnimationContext.runAnimationGroup({ context in\n        context.duration = 0.5\n        context.timingFunction = CAMediaTimingFunction.init(name: .easeInEaseOut)\n        context.allowsImplicitAnimation = true\n        f(context)\n    }, completionHandler: done)\n}\n\n// Make menu bar images templates with 16x16 dimensions.\nfunc setupMenuBarIcon(_ image: NSImage?) -> NSImage? {\n    image?.isTemplate = true\n    image?.size = NSSize(width: 16, height: 16)\n    return image\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Color Picker/R+ColorPicker.swift",
    "content": "//\n//  R+ColorPicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\nextension R {\n    enum ColorPicker {\n//        static let pickerHeight: CGFloat = 200\n        static let barWidth: CGFloat = 20\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Movie to Gif/GifConverter.swift",
    "content": "//\n//  GifConverter.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\nimport CoreGraphics\n\nstruct GifConvertOptions {\n    let thumbsize: CGSize\n    let width: CGFloat\n    let fps: Int\n    let removeSourceFile: Bool\n}\n\nstruct GifConvertTask {\n    let thumbnail: NSImage?\n    let title: String\n    let movieURL: URL\n    let destinationURL: URL\n    let fftask: Promise<FFTask, Never>\n}\n\nenum GifConverter {\n    static func convert(_ movieURL: URL, options: GifConvertOptions, to destinationURL: URL) -> Promise<GifConvertTask, Never> {\n        var arguments = [String]()\n        \n        arguments.append(\"-filter_complex\")\n        arguments.append(\"[0:v] fps=\\(options.fps),scale=\\(options.width):-1,split [a][b];[a] palettegen [p];[b][p] paletteuse\")\n                \n        let fftask = FFExecutor.execute(arguments, inputURL: movieURL, destinationURL: destinationURL)\n        let thumbnail = FFThumnailGenerator.thumbnail(of: movieURL, size: options.thumbsize)\n        \n        fftask.eraseToError().flatMap{ $0.complete }\n            .peek{\n                if options.removeSourceFile {\n                    NSWorkspace.shared.recycle([movieURL], completionHandler: nil)\n                    NSSound.dragToTrash?.play()\n                }\n            }\n            .catch({_ in })\n        \n        return thumbnail.map{\n            GifConvertTask(thumbnail: $0, title: movieURL.lastPathComponent, movieURL: movieURL, destinationURL: destinationURL, fftask: fftask)\n        }\n    }\n}\n\nextension NSSound {\n    static let dragToTrash = NSSound(contentsOfFile: \"/System/Library/Components/CoreAudio.component/Contents/SharedSupport/SystemSounds/dock/drag to trash.aif\", byReference: true)\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Media/Movie to Gif/GifConverterView+.swift",
    "content": "//\n//  MovieToGifView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\nimport CoreGraphics\nimport Quartz\n\nfinal class GifConverterViewController: NSViewController {\n    private let cell = GifConverterView()\n    \n    @Observable var tasks = [GifConvertTask]()\n    @RestorableState(\"gif.width\") var width = 640.0\n    @RestorableState(\"gif.fps\") var fps = 10\n    @RestorableState(\"gif.removeSource\") var removeSource = false\n    \n    override func loadView() { self.view = cell }\n    \n    override func chainObjectDidLoad() {\n        self.$tasks\n            .sink{[unowned self] in cell.listView.convertTasks = $0 }.store(in: &objectBag)\n        self.$width\n            .sink{[unowned self] in cell.widthField.value = $0 }.store(in: &objectBag)\n        self.$fps\n            .sink{[unowned self] in cell.fpsField.value = CGFloat($0) }.store(in: &objectBag)\n        self.$removeSource\n            .sink{[unowned self] in cell.removeFileSwitch.isOn = $0 }.store(in: &objectBag)\n        \n        self.cell.widthField.publisher\n            .sink{[unowned self] in self.width = $0 }.store(in: &objectBag)\n        self.cell.fpsField.publisher\n            .sink{[unowned self] in self.fps = Int($0) }.store(in: &objectBag)\n        self.cell.removeFileSwitch.isOnPublisher\n            .sink{[unowned self] in self.removeSource = $0 }.store(in: &objectBag)\n        \n        self.cell.dropPublisher\n            .sink{[unowned self] in handleDrop($0) }.store(in: &objectBag)\n        self.cell.listView.removePublisher\n            .sink{[unowned self] in removeItems($0) }.store(in: &objectBag)\n    }\n    \n    private func removeItems(_ indexSet: IndexSet) {\n        for index in indexSet.reversed() {\n            self.tasks.remove(at: index)\n        }\n    }\n    \n    private func handleDrop(_ urls: [URL]) {\n        var newTasks = [Promise<GifConvertTask, Never>]()\n        \n        for url in urls {\n            let destinationURL = url.deletingPathExtension().appendingPathExtension(\"gif\")\n            let options = GifConvertOptions(thumbsize: GifConvertTaskCell.thumbnailImageSize, width: width, fps: fps, removeSourceFile: removeSource)\n            let task = GifConverter.convert(url, options: options, to: destinationURL)\n            newTasks.append(task)\n        }\n        \n        Promise.combineAll(newTasks)\n            .receive(on: .main)\n            .sink{ self.tasks.insert(contentsOf: $0, at: 0) }\n    }\n}\n\nfinal private class GifConverterView: Page {\n    let fpsField = NumberField(autoWidth: ())\n    let widthField = NumberField(autoWidth: ())\n    let removeFileSwitch = NSSwitch()\n    \n    let listView = GifConvertListView()\n    let dropPublisher = PassthroughSubject<[URL], Never>()\n    \n    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {\n        if sender.draggingPasteboard.canReadTypes([.fileURL]) { return .copy } else { return .none }\n    }\n    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {\n        guard let urls = sender.draggingPasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL], !urls.isEmpty else { return false }\n        dropPublisher.send(urls)\n        return true\n    }\n    \n    override func layout() {\n        listView.snp.remakeConstraints{ make in\n            make.height.equalTo(max(200, self.frame.height - 330))\n        }\n        super.layout()\n    }\n    \n    override func onAwake() {\n        self.registerForDraggedTypes([.fileURL])\n        \n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.spacing, title: \"Width\".localized(), message: \"The width of the Gif file\".localized(), control: widthField),\n            Area(icon: R.Image.paramators, title: \"FPS\".localized(), message: \"FPS of the Gif file to be exported\".localized(), control: fpsField),\n            Area(icon: R.Image.paramators, title: \"Remove source file\".localized(), message: \"Whether to delete the source file after exporting a Gif\".localized(), control: removeFileSwitch)\n        ]))\n        \n        self.addSection(Section(title: \"Images\".localized(), items: [\n            listView\n        ]))\n    }\n}\n\nfinal private class GifConvertListView: NSLoadView, QLPreviewPanelDataSource, QLPreviewPanelDelegate {\n    let scrollView = NSScrollView()\n    let listView = EmptyImageTableView.list() => { $0.setFileDropEmptyView() }\n    let removePublisher = PassthroughSubject<IndexSet, Never>()\n    var convertTasks = [GifConvertTask]() { didSet { listView.reloadData() } }\n    \n    override func updateLayer() {\n        self.layer?.backgroundColor = R.Color.controlBackgroundColor.cgColor\n    }\n    \n    override func keyDown(with event: NSEvent) {\n        switch event.hotKey {\n        case .space: showQuickLook()\n        case .delete: removePublisher.send(listView.selectedRowIndexes)\n        default: super.keyDown(with: event)\n        }\n    }\n    \n    private func showQuickLook() {\n        guard let panel = QLPreviewPanel.shared() else { return }\n        panel.dataSource = self\n        panel.delegate = self\n        panel.makeKeyAndOrderFront(nil)\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.cornerRadius = R.Size.corner\n        self.addSubview(scrollView)\n        self.scrollView.drawsBackground = false\n        self.scrollView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.scrollView.documentView = listView\n        self.listView.delegate = self\n        self.listView.dataSource = self\n        self.listView.allowsMultipleSelection = true\n        \n        let menu = NSMenu()\n        menu.addItem(title: \"Open in Finder\".localized()) { [self] in\n            guard let task = convertTasks.at(listView.clickedRow) else { return }\n            NSWorkspace.shared.activateFileViewerSelecting([task.destinationURL])\n        }\n        menu.addItem(title: \"Delete\".localized()) { [self] in\n            if listView.clickedRow >= 0 { removePublisher.send(.init(integer: listView.clickedRow)) }\n        }\n        menu.addItem(title: \"Quick Look\".localized()) { [self] in\n            self.showQuickLook()\n        }\n        \n        self.listView.menu = menu\n    }\n    \n    func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {\n        self.listView.selectedRowIndexes.count\n    }\n    func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem {\n        let index = self.listView.selectedRowIndexes.map{ $0 }[index]\n        return convertTasks[index].destinationURL as QLPreviewItem\n    }\n    func previewPanel(_ panel: QLPreviewPanel!, sourceFrameOnScreenFor item: QLPreviewItem!) -> NSRect {\n        guard let index = convertTasks.firstIndex(where: { item.isEqual($0.destinationURL) }) else { return .zero }\n        \n        return listView.convertToScreen(listView.rect(ofRow: index))\n    }\n}\n\nextension GifConvertListView: NSTableViewDataSource, NSTableViewDelegate {\n    func numberOfRows(in tableView: NSTableView) -> Int { convertTasks.count }\n    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { 64 }\n    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        let cell = GifConvertTaskCell()\n        let task = convertTasks[row]\n        \n        cell.titleLabel.stringValue = task.title\n        cell.infoLabel.stringValue = \"Starting...\".localized()\n        cell.thumbnailImageView.image = task.thumbnail\n        \n        task.fftask\n            .receive(on: .main)\n            .sink{ task in\n                task.$progress\n                    .receive(on: DispatchQueue.main, options: nil)\n                    .filter{ $0 != 0 }\n                    .sink{[unowned cell] in\n                        cell.progressView.doubleValue = $0\n                        cell.infoLabel.stringValue = \"\\(Int($0 * 100))%\"\n                    }\n                    .store(in: &cell.objectBag)\n                \n                task.complete\n                    .receive(on: .main)\n                    .sink({\n                        cell.infoLabel.stringValue = \"Complete\".localized()\n                    }, { error in\n                        cell.infoLabel.textColor = .systemRed\n                        cell.infoLabel.stringValue = \"Convert Failed\".localized()\n                    })\n            }\n        \n        return cell\n    }\n}\n\nfinal private class GifConvertTaskCell: NSLoadView {\n    \n    static let thumbnailSize: CGSize = [50, 50]\n    static let thumbnailImageSize: CGSize = thumbnailSize * (NSScreen.main?.backingScaleFactor ?? 1)\n    \n    let thumbnailImageView = NSImageView()\n    let progressView = NSProgressIndicator()\n    let titleLabel = NSTextField(labelWithString: \"Title\")\n    let infoLabel = NSTextField(labelWithString: \"Title\")\n    \n    private let stackView = NSStackView()\n    private let titleStackView = NSStackView()\n    \n    override func onAwake() {\n        self.addSubview(stackView)\n        self.stackView.edgeInsets = .init(x: 16, y: 8)\n        self.stackView.distribution = .fillProportionally\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        \n        self.stackView.addArrangedSubview(thumbnailImageView)\n        self.thumbnailImageView.snp.makeConstraints{ make in\n            make.size.equalTo(GifConvertTaskCell.thumbnailSize)\n        }\n        self.stackView.addArrangedSubview(titleStackView)\n        \n        self.titleStackView.spacing = 0\n        self.titleStackView.orientation = .vertical\n        self.titleStackView.alignment = .left\n        \n        self.titleStackView.addArrangedSubview(titleLabel)\n        self.titleLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n        \n        self.titleStackView.addArrangedSubview(progressView)\n        self.progressView.isIndeterminate = false\n        self.progressView.minValue = 0\n        self.progressView.maxValue = 1\n        self.progressView.usesThreadedAnimation = false\n        \n        self.titleStackView.addArrangedSubview(infoLabel)\n        self.infoLabel.font = .systemFont(ofSize: R.Size.controlFontSize)\n    }\n}\n\nextension NSView {\n    public func convertToScreen(_ rect: CGRect) -> CGRect {\n        let windowRect = self.convert(rect, to: nil)\n        guard let window = self.window else { return windowRect }\n        return window.convertToScreen(windowRect)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/SettingView+.swift",
    "content": "//\n//  SettingView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/16.\n//\n\nimport CoreUtil\n\nfinal class SettingViewController: NSViewController {\n    private let cell = SettingView()\n    \n    override func loadView() { self.view = cell }\n    \n    override func chainObjectDidLoad() {\n        self.appModel.settings.$appearanceType\n            .sink{[unowned self] in self.cell.appearancePicker.selectedItem = $0 }.store(in: &objectBag)\n        \n        self.cell.appearancePicker.itemPublisher\n            .sink{[unowned self] in self.appModel.settings.appearanceType = $0 }.store(in: &objectBag)\n    }\n}\n\nextension Settings.AppearanceType: TextItem {\n    static let allCases: [Self] = [.useSystemSettings, .lightMode, .darkMode]\n    \n    var title: String { rawValue.localized() }\n}\n\nfinal private class SettingView: Page {\n    \n    let appearancePicker = EnumPopupButton<Settings.AppearanceType>()\n    \n    override func onAwake() {\n        self.addSection(\n            Area(icon: R.Image.paramators, title: \"App Theme\".localized(), message: \"Select which app theme to display\".localized(), control: appearancePicker)\n        )\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Text/HyphenationRemoverView+.swift",
    "content": "import CoreUtil\n\nfinal class HyphenationRemoverViewController: NSViewController {\n    @RestorableState(\"hyphenation.rawCode\") private var rawCode: String = \"\"\n    @RestorableState(\"hyphenation.formattedCode\") private var formattedCode: String = \"\"\n\n    private let cell = HyphenationFormatterView()\n\n    override func loadView() { self.view = cell }\n\n    override func viewDidLoad() {\n        self.$rawCode\n            .sink{[unowned self] in cell.inputSection.string = $0 }.store(in: &objectBag)\n        self.$formattedCode\n            .sink{[unowned self] in cell.outputSection.string = $0 }.store(in: &objectBag)\n        self.cell.inputSection.stringPublisher\n            .sink{[unowned self] in self.rawCode = $0; updateFormattedCode() }.store(in: &objectBag)\n\n        self.updateFormattedCode()\n    }\n\n    private func updateFormattedCode() {\n        self.formattedCode = getFormattedText(rawCode)\n    }\n\n    private func getFormattedText(_ input: String) -> String {\n        let lines = input\n            .components(separatedBy: .newlines)\n            .map { $0.replacingOccurrences(of: \"- \", with: \"\") }\n        let output = lines\n            .joined(separator: \" \")\n            .replacingOccurrences(of: \"  \", with: \"\\n\")\n        return output\n    }\n}\n\nfinal private class HyphenationFormatterView: Page {\n    let inputSection = CodeViewSection(title: \"Input\".localized(), options: .defaultInput, language: .plaintext)\n    let outputSection = CodeViewSection(title: \"Output\".localized(), options: .defaultOutput, language: .plaintext)\n\n    private lazy var ioStack = self.addSection2(inputSection, outputSection)\n\n    override func layout() {\n        super.layout()\n        \n        self.ioStack.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 150))\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Text/JSON Search/JSONNormalSearchView.swift",
    "content": "//\n//  JSONNormalSearchView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/25.\n//\n\nimport CoreUtil\n\nfinal class JSONNormalSearchView: NSLoadView {\n    private let textView = CodeTextView(language: .json)\n    \n    override func onAwake() {\n        \n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Text/JSON Search/JSONSearchView+.swift",
    "content": "//\n//  JSONSearchView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/25.\n//\n\nimport CoreUtil\n\nfinal class JSONSearchViewController: NSViewController {\n    private let cell = JSONSearchView()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        \n    }\n}\n\nenum JSONSearchType: String, TextItem {\n    case nomral = \"Normal Search\"\n    case regex = \"Regex Search\"\n    case jsonPath = \"JSONPath Search\"\n    \n    var title: String { rawValue }\n}\n\nfinal private class JSONSearchView: Page {\n    \n    let searchTypePicker = EnumPopupButton<JSONSearchType>()\n    \n    override func onAwake() {\n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.search, title: \"Search Type\", control: searchTypePicker)\n        ]))\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Text/RegexTesterView+.swift",
    "content": "//\n//  RegexTesterView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport CoreUtil\n\nfinal class RegexTesterViewController: NSViewController {\n    private let cell = RegexTesterView()\n    \n    @RestorableState(\"rx.pattern\") var pattern = #\"(macOS|OS X) \\d+\\.\\d+\"#\n    @RestorableState(\"rx.sample\") var text = defaultText\n    \n    @Observable var regex: NSRegularExpression? = nil\n    @Observable var isError = false\n    @Observable var matches = [NSRange]()\n    \n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.cell.regexField.changeStringPublisher\n            .sink{[unowned self] in self.pattern = $0; self.updateRegex() }.store(in: &objectBag)\n        self.cell.textView.stringPublisher\n            .sink{[unowned self] in self.text = $0; self.executeRegex() }.store(in: &objectBag)\n        \n        self.$isError.sink{[unowned self] in self.cell.regexField.isError = $0 }.store(in: &objectBag)\n        self.$pattern.sink{[unowned self] in self.cell.regexField.string = $0 }.store(in: &objectBag)\n        self.$text.sink{[unowned self] in self.cell.textView.string = $0 }.store(in: &objectBag)\n        self.$matches.sink{[unowned self] in self.cell.textView.highlightRanges = $0 }.store(in: &objectBag)\n        \n        self.updateRegex()\n    }\n    \n    private func updateRegex() {\n        do {\n            self.regex = try NSRegularExpression(pattern: pattern, options: .none)\n            self.isError = false\n        } catch {\n            self.isError = true\n            self.matches = []\n            self.regex = nil\n        }\n        self.executeRegex()\n    }\n    \n    private func executeRegex() {\n        guard let regex = self.regex else { return }\n        let nsstring = text as NSString\n        \n        let matches = regex.matches(in: text, options: .none, range: NSRange(location: 0, length: nsstring.length))\n        var ranges = [NSRange]()\n        for matche in matches {\n            ranges.append(matche.range)\n        }\n        \n        self.matches = ranges\n    }\n}\n\nfinal private class RegexTesterView: Page {\n    let regexField = TextField(showCopyButton: false)\n    let textView = RegexTextView()\n    \n    override func layout() {\n        super.layout()\n        self.textView.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 190))\n        }\n    }\n    \n    override func onAwake() {        \n        self.regexField.isError = true\n        self.regexField.font = .monospacedSystemFont(ofSize: R.Size.controlTitleFontSize, weight: .regular)\n        self.addSection(Section(title: \"Reguler expression\".localized(), items: [regexField]))\n        self.addSection(Section(title: \"Text\".localized(), items: [textView]))\n    }\n}\n\nprivate let defaultText = \"\"\"\nOS X 10.9 Mavericks\nOS X 10.10 Yosemite\nOS X 10.11 El Capitan\nmacOS 10.12 Sierra\nmacOS 10.13 High Sierra\nmacOS 10.14 Mojave\nmacOS 10.15 Catalina\nmacOS 11.0 Big Sur\nmacOS 12.0 Monterey\n\"\"\"\n"
  },
  {
    "path": "DevToys/DevToys/Body/Text/TextDiffView+.swift",
    "content": "//\n//  TextDiffView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/23.\n//\n\nimport DiffMatchPatch\nimport CoreUtil\n\nfinal class TextDiffViewController: NSViewController {\n    \n    @RestorableState(\"txtdiff.operation\") var operation: TextCheckOperation = .characters\n    @RestorableState(\"txtdiff.input1\") var input1 = \"Hello World!\"\n    @RestorableState(\"txtdiff.input2\") var input2 = \"Hello DevToys!\"\n    \n    @Observable var diffAttributedString = NSAttributedString()\n    \n    private let cell = TextDiffView()\n\n    override func loadView() { self.view = cell }\n    \n    override func viewDidLoad() {\n        self.$operation\n            .sink{[unowned self] in self.cell.checkOperationPicker.selectedItem = $0 }.store(in: &objectBag)\n        self.$input1\n            .sink{[unowned self] in self.cell.input1Section.string = $0 }.store(in: &objectBag)\n        self.$input2\n            .sink{[unowned self] in self.cell.input2Section.string = $0 }.store(in: &objectBag)\n        self.$diffAttributedString\n            .sink{[unowned self] in self.cell.outputSection.textView.textView.textStorage?.setAttributedString($0) }.store(in: &objectBag)\n        \n        self.cell.input1Section.stringPublisher\n            .sink{[unowned self] in self.input1 = $0; updateDiff() }.store(in: &objectBag)\n        self.cell.input2Section.stringPublisher\n            .sink{[unowned self] in self.input2 = $0; updateDiff() }.store(in: &objectBag)\n        self.cell.checkOperationPicker.itemPublisher\n            .sink{[unowned self] in self.operation = $0; updateDiff() }.store(in: &objectBag)\n        \n        self.updateDiff()\n    }\n    \n    private func updateDiff() {\n        let diffs = TextDifferenceChecker.compare(input1, input2, operation: self.operation)\n        self.diffAttributedString = buildAttributedString(from: diffs)\n    }\n    \n    private func buildAttributedString(from diffs: [Difference]) -> NSAttributedString {\n        let attributedString = NSMutableAttributedString()\n        let defaultAttributes = [\n            NSAttributedString.Key.foregroundColor: NSColor.textColor,\n            NSAttributedString.Key.font : NSFont.monospacedSystemFont(ofSize: 12, weight: .regular)\n        ]\n        \n        for diff in diffs {\n            switch diff.operation {\n            case .equal:\n                attributedString.append(NSAttributedString(string: diff.text, attributes: defaultAttributes))\n            case .insert:\n                attributedString.append(NSAttributedString(string: diff.text, attributes: defaultAttributes.merging([\n                    NSAttributedString.Key.backgroundColor : NSColor.systemGreen.withAlphaComponent(0.7)\n                ], uniquingKeysWith: { a, _ in a }) ))\n            case .delete:\n                attributedString.append(NSAttributedString(string: diff.text, attributes: defaultAttributes.merging([\n                    NSAttributedString.Key.backgroundColor : NSColor.systemRed.withAlphaComponent(0.7)\n                ], uniquingKeysWith: { a, _ in a }) ))\n            }\n        }\n        \n        return attributedString\n    }\n}\n\nextension TextCheckOperation: TextItem {\n    public static let allCases: [TextCheckOperation] = [.characters, .words, .lines]\n    \n    var title: String {\n        switch self {\n        case .characters: return \"By Characters\".localized()\n        case .words: return \"By Words\".localized()\n        case .lines: return \"By Lines\".localized()\n        }\n    }\n}\n\nfinal private class TextDiffView: Page {\n    let checkOperationPicker = EnumPopupButton<TextCheckOperation>()\n    \n    let input1Section = CodeViewSection(title: \"Input 1\".localized(), options: .defaultInput, language: .plaintext)\n    let input2Section = CodeViewSection(title: \"Input 2\".localized(), options: .defaultInput, language: .plaintext)\n    let outputSection = TextViewSection(title: \"Output\".localized(), options: .defaultOutput)\n\n    override func layout() {\n        super.layout()\n        \n    }\n    \n    override func onAwake() {\n        self.addSection(Section(title: \"Configuration\".localized(), items: [\n            Area(icon: R.Image.format, title: \"Diff Style\".localized(), control: checkOperationPicker)\n        ]))\n        \n        self.addSection2(input1Section, input2Section)\n        self.input1Section.snp.makeConstraints{ make in\n            make.height.equalTo(320)\n        }\n        \n        self.addSection(outputSection)\n        self.outputSection.textView.textView.font = .monospacedSystemFont(ofSize: 12, weight: .regular)\n        self.outputSection.snp.makeConstraints{ make in\n            make.height.equalTo(320)\n        }\n        \n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Text/TextInspectorView+.swift",
    "content": "//\n//  TextInspector.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class TextInspectorViewController: NSViewController {\n    private let cell = TextInspectorView()\n    \n    @RestorableState(\"textin.input\") private var input = \"Hello World\"\n    @RestorableState(\"textin.output\") private var output = \"hello_world\"\n    @RestorableState(\"textin.convert\") private var convertType: ConvertType = .camelCase\n    @RestorableState(\"textin.info\") private var information: String = \"\"\n    \n    override func loadView() { self.view = cell }\n    \n    private func updateInfo() {\n        var result = \"\"\n        func append(_ label: String, data: Any) {\n            result += \"\\(label): \".padding(toLength: 24, withPad: \" \", startingAt: 0)\n            result += \"\\(data)\"\n            result += \"\\n\"\n        }\n        \n        append(\"Charactors\".localized(), data: input.count)\n        append(\"Words\".localized(), data: input.split(separator: \" \").count)\n        append(\"Lines\".localized(), data: input.split(separator: \"\\n\").count)\n        append(\"Bytes\".localized(), data: input.data(using: .utf8)!.count)\n        \n        self.information = result\n    }\n    \n    override func viewDidLoad() {\n        self.$input\n            .sink{[unowned self] in cell.inputSection.string = $0 }.store(in: &objectBag)\n        self.$output\n            .sink{[unowned self] in cell.outputSection.string = $0 }.store(in: &objectBag)\n        self.$convertType.map{ ConvertType.allCases.firstIndex(of: $0) }\n            .sink{[unowned self] in cell.tagCloudView.selectedItem = $0 }.store(in: &objectBag)\n        self.$information\n            .sink{[unowned self] in cell.informationView.string = $0 }.store(in: &objectBag)\n        \n        self.cell.inputSection.stringPublisher\n            .sink{[unowned self] in self.input = $0; generate(); updateInfo() }.store(in: &objectBag)\n        self.cell.tagCloudView.selectPublisher.map{ ConvertType.allCases[$0] }\n            .sink{[unowned self] in self.convertType = $0; generate() }.store(in: &objectBag)\n        \n        self.updateInfo()\n    }\n    \n    private func generate() {\n        switch self.convertType {\n        case .originalCase: self.output = input\n        case .sentenceCase: self.output = input.capitalizingFirstLetter()\n        case .lowerCase: self.output = input.lowercased()\n        case .upperCase: self.output = input.uppercased()\n        case .titleCase: self.output = input.capitalized\n        case .camelCase: self.output = input.capitalized.split(separator: \" \").joined().lowercaseFirstLetter()\n        case .pascalCase: self.output = input.capitalized.split(separator: \" \").joined()\n        case .snakeCase: self.output = input.lowercased().split(separator: \" \").joined(separator: \"_\")\n        case .constantCase: self.output = input.uppercased().split(separator: \" \").joined(separator: \"_\")\n        case .kebabCase: self.output = input.lowercased().split(separator: \" \").joined(separator: \"-\")\n        case .cobolCase: self.output = input.uppercased().split(separator: \" \").joined(separator: \"-\")\n        case .trainCase: self.output = input.capitalized.split(separator: \" \").joined(separator: \"-\")\n        case .urlLowerSlugify: self.output = input.slugify(lowercase: true)\n        case .urlPascalSlugify: self.output = input.slugify(lowercase: false)\n        }\n    }\n}\n\nextension String {\n    func capitalizingFirstLetter() -> String { prefix(1).capitalized + dropFirst() }\n    func lowercaseFirstLetter() -> String { prefix(1).lowercased() + dropFirst() }\n}\n\nprivate enum ConvertType: String, CaseIterable {\n    case originalCase = \"OriginalCase\"\n    case sentenceCase = \"Sentence case\"\n    case lowerCase = \"lower case\"\n    case upperCase = \"UPPER CASE\"\n    case titleCase = \"Title Case\"\n    case camelCase = \"camelCase\"\n    case pascalCase = \"PascalCase\"\n    case snakeCase = \"snake_case\"\n    case constantCase = \"CONSTANT_CASE\"\n    case kebabCase = \"kebab-case\"\n    case cobolCase = \"COBOL-CASE\"\n    case trainCase = \"Traint-Case\"\n    case urlPascalSlugify = \"URL-slugify\"\n    case urlLowerSlugify = \"url-lower-slugify\"\n}\n\nfinal class TextInspectorView: Page {\n    let inputSection = TextViewSection(title: \"Input\".localized(), options: .defaultInput)\n    let tagCloudView = TagCloudView()\n    let outputSection = TextViewSection(title: \"Output\".localized(), options: .defaultOutput)\n    let informationView = NSTextView()\n    \n    override func layout() {\n        super.layout()\n    \n        self.outputSection.snp.remakeConstraints{ make in\n            make.height.equalTo(max(240, self.frame.height - 360))\n        }\n    }\n    \n    override func onAwake() {\n        let convertSection = Section(title: \"Convert\".localized(), items: [tagCloudView])\n        self.addSection(convertSection)\n        self.tagCloudView.items = ConvertType.allCases.map{ $0.rawValue }\n        self.tagCloudView.isSelectable = true\n        \n        self.addSection2(inputSection, outputSection)\n\n        self.tagCloudView.snp.remakeConstraints{ make in\n            make.height.equalTo(68)\n            make.width.equalToSuperview()\n        }\n        \n        self.informationView.font = .monospacedSystemFont(ofSize: R.Size.controlTitleFontSize, weight: .regular)\n        \n        self.informationView.snp.makeConstraints{ make in\n            make.height.equalTo(100)\n        }\n        self.informationView.backgroundColor = .clear\n        self.informationView.isEditable = false\n        self.addSection(Section(title: \"Information\".localized(), items: [\n            informationView\n        ]))\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/CameraViewController.swift",
    "content": "//\n//  ViewController.swift\n//  macOS Camera\n//\n//  Created by Mihail Șalari. on 4/24/17.\n//  Copyright © 2017 Mihail Șalari. All rights reserved.\n//\n\nimport CoreUtil\nimport AVFoundation\n\nfinal class CameraManager {\n    \n    let videoSession = AVCaptureSession()\n    \n    private var cameraDevice: AVCaptureDevice!\n    private let sessionQueue = DispatchQueue(label: \"buffer.queue\")\n    private var isPrepared = false\n    \n    func startSession(_ delegate: AVCaptureVideoDataOutputSampleBufferDelegate) {\n        if !isPrepared {\n            self.prepareCamera(delegate)\n            isPrepared = true\n        }\n        if !videoSession.isRunning { videoSession.startRunning() }\n    }\n    \n    func stopSession() {\n        if videoSession.isRunning { videoSession.stopRunning() }\n    }\n    \n    private func findCameraDevice() -> AVCaptureDevice? {\n        let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .unspecified)\n        guard let device = discoverySession.devices.first, device.hasMediaType(AVMediaType.video) else { return nil }\n        return device\n    }\n    \n    private func prepareCamera(_ delegate: AVCaptureVideoDataOutputSampleBufferDelegate) {\n        guard let device = self.findCameraDevice() else { return }\n        self.cameraDevice = device\n        self.videoSession.sessionPreset = .photo\n        \n        do {\n            let input = try AVCaptureDeviceInput(device: device)\n            if videoSession.canAddInput(input) { videoSession.addInput(input) }\n        } catch {\n            print(error.localizedDescription)\n        }\n               \n        let videoOutput = AVCaptureVideoDataOutput()\n        videoOutput.setSampleBufferDelegate(delegate, queue: sessionQueue)\n        if videoSession.canAddOutput(videoOutput) { videoSession.addOutput(videoOutput) }\n    }\n}\n\nextension AVAuthorizationStatus: CustomStringConvertible {\n    public var description: String {\n        switch self {\n        case .notDetermined: return \"notDetermined\"\n        case .restricted: return \"restricted\"\n        case .denied: return \"denied\"\n        case .authorized: return \"authorized\"\n        @unknown default: fatalError()\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/FileConflictAvoider.swift",
    "content": "//\n//  FileConflictAvoider.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/22.\n//\n\nimport CoreUtil\n\nenum FileConflictAvoider {\n    \n    private static let autoFilenameRegex = try! NSRegularExpression(pattern: #\"(.*)\\s\\(\\d+\\)$\"#, options: [])\n    \n    static func avoidConflict(_ url: URL) -> URL {\n        let ext = url.pathExtension\n        let basename = url.deletingLastPathComponent()\n        let filename = filterAutoSuffix(url.deletingPathExtension().lastPathComponent)\n        \n        let rfilename = Identifier.make(with: .brackedNumberPostfix(filename)) {\n            !FileManager.default.fileExists(atPath: basename.appendingPathComponent($0).appendingPathExtension(ext).path)\n        }\n        \n        let result = basename.appendingPathComponent(rfilename).appendingPathExtension(ext)\n        return result\n    }\n    \n    private static func filterAutoSuffix(_ filename: String) -> String {\n        let nsString = filename as NSString\n        guard let match = autoFilenameRegex.matches(in: filename, options: [], range: NSRange(location: 0, length: nsString.length)).first else { return filename }\n        print(match)\n        guard match.numberOfRanges >= 2 else { return filename }\n        let basename = nsString.substring(with: match.range(at: 1))\n        \n        return basename\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/Identifier.swift",
    "content": "//\n//  Identifier.swift\n//  CoreUtil\n//\n//  Created by yuki on 2021/04/29.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\npublic enum Identifier {\n    @inlinable public static func make(with rule: Identifier.Rule, notContainsIn set: Set<String>) -> String {\n        make(with: rule) { !set.contains($0) }\n    }\n    \n    @inlinable public static func make(with rule: Identifier.Rule, _ condition: (String) -> Bool) -> String {\n       var identifier = rule.next()\n       \n       while !condition(identifier) {\n           identifier = rule.next()\n       }\n       \n       return identifier\n    }\n    \n    public struct Rule {\n        @usableFromInline let next: () -> String\n        \n        @inlinable public init(_ next: @escaping ()->String) {\n            self.next = next\n        }\n    }\n}\n\nextension Identifier.Rule {\n    @inlinable public static func uuid() -> Identifier.Rule {\n        Identifier.Rule { UUID().uuidString }\n    }\n    @inlinable public static func brackedNumberPostfix(_ base: String, separtor: String = \" \") -> Identifier.Rule {\n        var counter = 0\n        return Identifier.Rule {\n            defer { counter += 1 }\n            return counter == 0 ? base : base + \"\\(separtor)(\\(counter))\"\n        }\n    }\n    @inlinable public static func numberPostfix(_ base: String, separtor: String = \" \") -> Identifier.Rule {\n       var counter = 0\n       return Identifier.Rule {\n           defer { counter += 1 }\n           return counter == 0 ? base : \"\\(base)\\(separtor)\\(counter)\"\n       }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ImageDropper.swift",
    "content": "//\n//  ImageDropper.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport Cocoa\n\nenum ImageDropper {\n    static func images(fromPasteboard pasteboard: NSPasteboard) -> [ImageItem] {\n        var newImageItems = [ImageItem]()\n        guard let items = pasteboard.pasteboardItems else { return [] }\n        \n        if items.count == 1, let url = (pasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL])?.first {\n            guard let image = NSImage(pasteboard: pasteboard) else { return [] }\n            newImageItems = [ImageItem(fileURL: url, image: image)]\n        } else {\n            guard let urls = pasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL] else { return [] }\n            let images = urls.compactMap{ url in\n                NSImage(contentsOf: url).map{ ImageItem(fileURL: url, image: $0) }\n            }\n            newImageItems = images\n        }\n        \n        return newImageItems\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/Slugify.swift",
    "content": "//\n//  Slugify.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/26.\n//\n\nimport Foundation\n\nextension String {\n    public func slugify(delimiter: String = \"-\", lowercase: Bool) -> String {\n        var slug = self\n        if lowercase { slug = slug.lowercased() }\n        \n        slugifyReplacements.forEach{ slug = slug.replacingOccurrences(of: $0, with: $1) }\n        \n        slug = dupeSpaceRegExp.stringByReplacingMatches(in: slug, options: [], range: NSRange(location: 0, length: (slug as NSString).length), withTemplate: \" \")\n        slug = punctuationRegExp.stringByReplacingMatches(in: slug, options: [], range: NSRange(location: 0, length: (slug as NSString).length), withTemplate: \"\")\n        slug = slug.replacingOccurrences(of: \" \", with: delimiter)\n        \n        return slug\n    }\n}\n\nprivate let dupeSpaceRegExp = try! NSRegularExpression(pattern: #\"\\s{2,}\"#, options: [])\nprivate let punctuationRegExp = try! NSRegularExpression(pattern: #\"[^\\w\\s-]\"#, options: [])\n\n\nprivate let slugifyReplacements = [\n    \"¹\": \"1\",\n      \"²\": \"2\",\n      \"³\": \"3\",\n      \"º\": \"o\",\n      \"°\": \"0\",\n      \"æ\": \"ae\",\n      \"ǽ\": \"ae\",\n      \"À\": \"A\",\n      \"Á\": \"A\",\n      \"Â\": \"A\",\n      \"Ã\": \"A\",\n      \"Å\": \"A\",\n      \"Ǻ\": \"A\",\n      \"Ă\": \"A\",\n      \"Ǎ\": \"A\",\n      \"Ạ\": \"A\",\n      \"Ả\": \"A\",\n      \"ả\": \"a\",\n      \"ạ\": \"a\",\n      \"Ầ\": \"A\",\n      \"ầ\": \"a\",\n      \"Ẩ\": \"A\",\n      \"ẩ\": \"a\",\n      \"Ẫ\": \"A\",\n      \"ẫ\": \"a\",\n      \"Ậ\": \"A\",\n      \"ậ\": \"a\",\n      \"Ắ\": \"A\",\n      \"ắ\": \"a\",\n      \"Ằ\": \"Ằ\",\n      \"ằ\": \"ằ\",\n      \"Ẳ\": \"A\",\n      \"ẳ\": \"a\",\n      \"Ẵ\": \"A\",\n      \"ẵ\": \"a\",\n      \"Ặ\": \"A\",\n      \"ặ\": \"a\",\n      \"Æ\": \"AE\",\n      \"Ǽ\": \"AE\",\n      \"à\": \"a\",\n      \"á\": \"a\",\n      \"â\": \"a\",\n      \"ã\": \"a\",\n      \"å\": \"a\",\n      \"ǻ\": \"a\",\n      \"ă\": \"a\",\n      \"ǎ\": \"a\",\n      \"ª\": \"a\",\n      \"@\": \"at\",\n      \"&\": \"and\",\n      \"Ĉ\": \"CX\",\n      \"Ċ\": \"C\",\n      \"ĉ\": \"cx\",\n      \"ċ\": \"c\",\n      \"©\": \"c\",\n      \"Ð\": \"Dj\",\n      \"Đ\": \"Dj\",\n      \"ð\": \"dj\",\n      \"đ\": \"dj\",\n      \"È\": \"E\",\n      \"É\": \"E\",\n      \"Ê\": \"E\",\n      \"Ë\": \"E\",\n      \"Ĕ\": \"E\",\n      \"Ė\": \"E\",\n      \"è\": \"e\",\n      \"é\": \"e\",\n      \"ê\": \"e\",\n      \"ë\": \"e\",\n      \"ĕ\": \"e\",\n      \"ė\": \"e\",\n      \"Ệ\": \"E\",\n      \"ệ\": \"e\",\n      \"Ể\": \"E\",\n      \"ể\": \"e\",\n      \"Ẹ\": \"E\",\n      \"ẻ\": \"e\",\n      \"Ẻ\": \"E\",\n      \"ẽ\": \"e\",\n      \"Ẽ\": \"E\",\n      \"ễ\": \"e\",\n      \"Ễ\": \"E\",\n      \"ẹ\": \"e\",\n      \"ƒ\": \"f\",\n      \"Ĝ\": \"GX\",\n      \"Ġ\": \"G\",\n      \"ĝ\": \"gx\",\n      \"ġ\": \"g\",\n      \"Ĥ\": \"HX\",\n      \"Ħ\": \"H\",\n      \"ĥ\": \"hx\",\n      \"ħ\": \"h\",\n      \"Ì\": \"I\",\n      \"Í\": \"I\",\n      \"Î\": \"I\",\n      \"Ï\": \"I\",\n      \"Ĩ\": \"I\",\n      \"Ĭ\": \"I\",\n      \"Ǐ\": \"I\",\n      \"Į\": \"I\",\n      \"Ĳ\": \"IJ\",\n      \"ì\": \"i\",\n      \"í\": \"i\",\n      \"î\": \"i\",\n      \"ï\": \"i\",\n      \"ĩ\": \"i\",\n      \"ĭ\": \"i\",\n      \"ǐ\": \"i\",\n      \"į\": \"i\",\n      \"Ỉ\": \"I\",\n      \"ỉ\": \"i\",\n      \"Ị\": \"I\",\n      \"ị\": \"i\",\n      \"ĳ\": \"ij\",\n      \"Ĵ\": \"JX\",\n      \"ĵ\": \"jx\",\n      \"Ĺ\": \"L\",\n      \"Ľ\": \"L\",\n      \"Ŀ\": \"L\",\n      \"ĺ\": \"l\",\n      \"ľ\": \"l\",\n      \"ŀ\": \"l\",\n      \"Ñ\": \"N\",\n      \"ñ\": \"n\",\n      \"ŉ\": \"n\",\n      \"Ò\": \"O\",\n      \"Ô\": \"O\",\n      \"Õ\": \"O\",\n      \"Ō\": \"O\",\n      \"Ŏ\": \"O\",\n      \"Ǒ\": \"O\",\n      \"Ő\": \"O\",\n      \"Ơ\": \"O\",\n      \"Ø\": \"O\",\n      \"Ǿ\": \"O\",\n      \"Œ\": \"OE\",\n      \"ò\": \"o\",\n      \"ô\": \"o\",\n      \"õ\": \"o\",\n      \"ō\": \"o\",\n      \"ŏ\": \"o\",\n      \"ǒ\": \"o\",\n      \"ő\": \"o\",\n      \"ơ\": \"o\",\n      \"ø\": \"o\",\n      \"ǿ\": \"o\",\n      \"Ọ\": \"O\",\n      \"ọ\": \"o\",\n      \"Ổ\": \"O\",\n      \"ỗ\": \"o\",\n      \"Ỗ\": \"o\",\n      \"ổ\": \"o\",\n      \"Ộ\": \"O\",\n      \"ộ\": \"o\",\n      \"ợ\": \"o\",\n      \"Ợ\": \"o\",\n      \"Ở\": \"O\",\n      \"ở\": \"o\",\n      \"Ỡ\": \"O\",\n      \"ỡ\": \"o\",\n      \"œ\": \"oe\",\n      \"Ŕ\": \"R\",\n      \"Ŗ\": \"R\",\n      \"ŕ\": \"r\",\n      \"ŗ\": \"r\",\n      \"Ŝ\": \"SX\",\n      \"Ș\": \"S\",\n      \"ŝ\": \"sx\",\n      \"ș\": \"s\",\n      \"ſ\": \"s\",\n      \"Ţ\": \"T\",\n      \"Ț\": \"T\",\n      \"Ŧ\": \"T\",\n      \"Þ\": \"TH\",\n      \"ţ\": \"t\",\n      \"ț\": \"t\",\n      \"ŧ\": \"t\",\n      \"þ\": \"th\",\n      \"Ù\": \"U\",\n      \"Ú\": \"U\",\n      \"Û\": \"U\",\n      \"Ũ\": \"U\",\n      \"Ŭ\": \"UX\",\n      \"Ű\": \"U\",\n      \"Ų\": \"U\",\n      \"Ư\": \"U\",\n      \"Ǔ\": \"U\",\n      \"Ǖ\": \"U\",\n      \"Ǘ\": \"U\",\n      \"Ǚ\": \"U\",\n      \"Ǜ\": \"U\",\n      \"ù\": \"u\",\n      \"ú\": \"u\",\n      \"û\": \"u\",\n      \"ũ\": \"u\",\n      \"ŭ\": \"ux\",\n      \"ű\": \"u\",\n      \"ų\": \"u\",\n      \"ư\": \"u\",\n      \"ǔ\": \"u\",\n      \"ǖ\": \"u\",\n      \"ǘ\": \"u\",\n      \"ǚ\": \"u\",\n      \"ǜ\": \"u\",\n      \"Ụ\": \"U\",\n      \"Ủ\": \"U\",\n      \"ủ\": \"u\",\n      \"ụ\": \"u\",\n      \"Ŵ\": \"W\",\n      \"ŵ\": \"w\",\n      \"Ý\": \"Y\",\n      \"Ÿ\": \"Y\",\n      \"Ŷ\": \"Y\",\n      \"ý\": \"y\",\n      \"ÿ\": \"y\",\n      \"ŷ\": \"y\",\n      \"Ъ\": \"\",\n      \"Ь\": \"\",\n      \"А\": \"A\",\n      \"Б\": \"B\",\n      \"Ц\": \"C\",\n      \"Ч\": \"Ch\",\n      \"Д\": \"D\",\n      \"Е\": \"E\",\n      \"Ё\": \"E\",\n      \"Э\": \"E\",\n      \"Ф\": \"F\",\n      \"Г\": \"G\",\n      \"Х\": \"H\",\n      \"И\": \"I\",\n      \"Й\": \"J\",\n      \"Я\": \"Ja\",\n      \"Ю\": \"Ju\",\n      \"К\": \"K\",\n      \"Л\": \"L\",\n      \"М\": \"M\",\n      \"Н\": \"N\",\n      \"О\": \"O\",\n      \"П\": \"P\",\n      \"Р\": \"R\",\n      \"С\": \"S\",\n      \"Ш\": \"Sh\",\n      \"Щ\": \"Shch\",\n      \"Т\": \"T\",\n      \"У\": \"U\",\n      \"В\": \"V\",\n      \"Ы\": \"Y\",\n      \"З\": \"Z\",\n      \"Ж\": \"Zh\",\n      \"ъ\": \"\",\n      \"ь\": \"\",\n      \"а\": \"a\",\n      \"б\": \"b\",\n      \"ц\": \"c\",\n      \"ч\": \"ch\",\n      \"д\": \"d\",\n      \"е\": \"e\",\n      \"ё\": \"e\",\n      \"э\": \"e\",\n      \"ф\": \"f\",\n      \"г\": \"g\",\n      \"х\": \"h\",\n      \"и\": \"i\",\n      \"й\": \"j\",\n      \"я\": \"ja\",\n      \"ю\": \"ju\",\n      \"к\": \"k\",\n      \"л\": \"l\",\n      \"м\": \"m\",\n      \"н\": \"n\",\n      \"о\": \"o\",\n      \"п\": \"p\",\n      \"р\": \"r\",\n      \"с\": \"s\",\n      \"ш\": \"sh\",\n      \"щ\": \"shch\",\n      \"т\": \"t\",\n      \"у\": \"u\",\n      \"в\": \"v\",\n      \"ы\": \"y\",\n      \"з\": \"z\",\n      \"ж\": \"zh\",\n      \"Ä\": \"AE\",\n      \"Ö\": \"OE\",\n      \"Ü\": \"UE\",\n      \"ß\": \"ss\",\n      \"ä\": \"ae\",\n      \"ö\": \"oe\",\n      \"ü\": \"ue\",\n      \"Ç\": \"C\",\n      \"Ğ\": \"G\",\n      \"İ\": \"I\",\n      \"Ş\": \"S\",\n      \"ç\": \"c\",\n      \"ğ\": \"g\",\n      \"ı\": \"i\",\n      \"ş\": \"s\",\n      \"Ā\": \"A\",\n      \"Ē\": \"E\",\n      \"Ģ\": \"G\",\n      \"Ī\": \"I\",\n      \"Ķ\": \"K\",\n      \"Ļ\": \"L\",\n      \"Ņ\": \"N\",\n      \"Ū\": \"U\",\n      \"ā\": \"a\",\n      \"ē\": \"e\",\n      \"ģ\": \"g\",\n      \"ī\": \"i\",\n      \"ķ\": \"k\",\n      \"ļ\": \"l\",\n      \"ņ\": \"n\",\n      \"ū\": \"u\",\n      \"Ґ\": \"G\",\n      \"І\": \"I\",\n      \"Ї\": \"Ji\",\n      \"Є\": \"Ye\",\n      \"ґ\": \"g\",\n      \"і\": \"i\",\n      \"ї\": \"ji\",\n      \"є\": \"ye\",\n      \"Č\": \"C\",\n      \"Ď\": \"Dj\",\n      \"Ě\": \"E\",\n      \"Ň\": \"N\",\n      \"Ř\": \"R\",\n      \"Š\": \"S\",\n      \"Ť\": \"T\",\n      \"Ů\": \"U\",\n      \"Ž\": \"Z\",\n      \"č\": \"c\",\n      \"ď\": \"dj\",\n      \"ě\": \"e\",\n      \"ň\": \"n\",\n      \"ř\": \"r\",\n      \"š\": \"s\",\n      \"ť\": \"t\",\n      \"ů\": \"u\",\n      \"ž\": \"z\",\n      \"Ą\": \"A\",\n      \"Ć\": \"C\",\n      \"Ę\": \"E\",\n      \"Ł\": \"L\",\n      \"Ń\": \"N\",\n      \"Ó\": \"O\",\n      \"Ś\": \"S\",\n      \"Ź\": \"Z\",\n      \"Ż\": \"Z\",\n      \"ą\": \"a\",\n      \"ć\": \"c\",\n      \"ę\": \"e\",\n      \"ł\": \"l\",\n      \"ń\": \"n\",\n      \"ó\": \"o\",\n      \"ś\": \"s\",\n      \"ź\": \"z\",\n      \"ż\": \"z\",\n      \"Α\": \"A\",\n      \"Β\": \"B\",\n      \"Γ\": \"G\",\n      \"Δ\": \"D\",\n      \"Ε\": \"E\",\n      \"Ζ\": \"Z\",\n      \"Η\": \"E\",\n      \"Θ\": \"Th\",\n      \"Ι\": \"I\",\n      \"Κ\": \"K\",\n      \"Λ\": \"L\",\n      \"Μ\": \"M\",\n      \"Ν\": \"N\",\n      \"Ξ\": \"X\",\n      \"Ο\": \"O\",\n      \"Π\": \"P\",\n      \"Ρ\": \"R\",\n      \"Σ\": \"S\",\n      \"Τ\": \"T\",\n      \"Υ\": \"Y\",\n      \"Ỷ\": \"Y\",\n      \"ỷ\": \"y\",\n      \"Ỹ\": \"Y\",\n      \"ỹ\": \"y\",\n      \"Ỵ\": \"Y\",\n      \"ỵ\": \"y\",\n      \"Φ\": \"Ph\",\n      \"Χ\": \"Ch\",\n      \"Ψ\": \"Ps\",\n      \"Ω\": \"O\",\n      \"Ϊ\": \"I\",\n      \"Ϋ\": \"Y\",\n      \"ά\": \"a\",\n      \"έ\": \"e\",\n      \"ή\": \"e\",\n      \"ί\": \"i\",\n      \"ΰ\": \"Y\",\n      \"α\": \"a\",\n      \"β\": \"b\",\n      \"γ\": \"g\",\n      \"δ\": \"d\",\n      \"ε\": \"e\",\n      \"ζ\": \"z\",\n      \"η\": \"e\",\n      \"θ\": \"th\",\n      \"ι\": \"i\",\n      \"κ\": \"k\",\n      \"λ\": \"l\",\n      \"μ\": \"m\",\n      \"ν\": \"n\",\n      \"ξ\": \"x\",\n      \"ο\": \"o\",\n      \"π\": \"p\",\n      \"ρ\": \"r\",\n      \"ς\": \"s\",\n      \"σ\": \"s\",\n      \"τ\": \"t\",\n      \"υ\": \"y\",\n      \"φ\": \"ph\",\n      \"χ\": \"ch\",\n      \"ψ\": \"ps\",\n      \"ω\": \"o\",\n      \"ϊ\": \"i\",\n      \"ϋ\": \"y\",\n      \"ό\": \"o\",\n      \"ύ\": \"y\",\n      \"ώ\": \"o\",\n      \"ϐ\": \"b\",\n      \"ϑ\": \"th\",\n      \"ϒ\": \"Y\",\n      \"أ\": \"a\",\n      \"ب\": \"b\",\n      \"ت\": \"t\",\n      \"ث\": \"th\",\n      \"ج\": \"g\",\n      \"ح\": \"h\",\n      \"خ\": \"kh\",\n      \"د\": \"d\",\n      \"ذ\": \"th\",\n      \"ر\": \"r\",\n      \"ز\": \"z\",\n      \"س\": \"s\",\n      \"ش\": \"sh\",\n      \"ص\": \"s\",\n      \"ض\": \"d\",\n      \"ط\": \"t\",\n      \"ظ\": \"th\",\n      \"ع\": \"aa\",\n      \"غ\": \"gh\",\n      \"ف\": \"f\",\n      \"ق\": \"k\",\n      \"ك\": \"k\",\n      \"ل\": \"l\",\n      \"م\": \"m\",\n      \"ن\": \"n\",\n      \"ه\": \"h\",\n      \"و\": \"o\",\n      \"ي\": \"y\"\n]\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFMpegExecutor.swift",
    "content": "//\n//  FFMpegExecutor.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\n\nenum FFExecutor {\n    private static let ffmpegURL = Bundle.current.url(forResource: \"ffmpeg\", withExtension: nil)!\n    \n    static func execute(_ arguments: [String], inputURL: URL, destinationURL: URL) -> Promise<FFTask, Never> {\n        let arguments = [\"-i\", inputURL.path, \"-y\"] + arguments + [destinationURL.path]\n                \n        let task = Process()\n        let outputPipe = Pipe()\n        let errorPipe = Pipe()\n        task.executableURL = ffmpegURL\n        task.arguments = arguments\n        task.standardOutput = outputPipe\n        task.standardError = errorPipe\n                                \n        var duration: FFTime? { didSet { durationPromise.fullfill(duration) } }\n        let durationPromise = Promise<FFTime?, Never>()\n                \n        let completePromise = Promise<Void, Error>.tryAsync{ resolve, reject in\n            try task.run()\n            task.waitUntilExit()\n            \n            if task.terminationStatus != 0 {\n                reject(TerminalError.nonZeroExit(errorPipe.readStringToEndOfFile ?? \"[binary]\"))\n            } else {\n                resolve(())\n            }\n        }\n        \n        let dtask = durationPromise\n            .map{ FFTask(duration: $0, complete: completePromise) }\n        let ctask = completePromise\n            .replaceError(with: ())\n            .map{ FFTask(duration: nil, complete: completePromise) }\n        \n        let taskPromise = Promise.first([dtask, ctask])!\n                \n        DispatchQueue.global().async {\n            while let data = errorPipe.fileHandleForReading.availableData.nonEmptyOrNil() {\n                guard let nsString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { continue }\n                                \n                if duration == nil, let fduration = findDuration(in: nsString) {\n                    duration = fduration\n                } else if case .fulfilled(let task) = taskPromise.state, let report = FFProgressReport(progressString: nsString as String) {\n                    task.sendReport(report)\n                }\n            }\n        }\n        \n        return taskPromise\n    }\n    \n    private static func findDuration(in nsString: NSString) -> FFTime? {\n        enum __ {\n            static let rx = try! NSRegularExpression(pattern: \"Duration: (.*?),\", options: [])\n        }\n        let matches = __.rx.matches(in: nsString as String, options: [], range: NSRange(location: 0, length: nsString.length))\n        guard let match = matches.first, match.numberOfRanges == 2 else { return nil }\n        \n        let timeString = nsString.substring(with: match.range(at: 1))\n        return FFTime(timeString: timeString)\n    }\n}\n\nextension Data {\n    func nonEmptyOrNil() -> Data? {\n        if isEmpty { return nil }\n        return self\n    }\n}\n\nextension Promise {\n    public static func first(_ promises: [Promise<Output, Failure>]) -> Promise<Output, Failure>? {\n        if promises.isEmpty { return nil }\n        \n        return Promise{ resolve, reject in\n            for promise in promises { promise.sink(resolve, reject) }\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFProgressReport.swift",
    "content": "//\n//  FFProgressReport.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport CoreUtil\n\nstruct FFProgressReport {\n    let speed: Double\n    let time: FFTime\n    let progress: Progress\n    \n    enum Progress {\n        case `continue`\n        case end\n    }\n    \n    init?(progressData: Data) {\n        if progressData.isEmpty { return nil }\n        guard let string = String(data: progressData, encoding: .utf8) else { return nil }\n        self.init(progressString: string)\n    }\n    \n    init?(progressString: String) {\n        enum Rx {\n            static let time = try! NSRegularExpression(pattern: \"time=(.*)\", options: [])\n            static let speed = try! NSRegularExpression(pattern: \"speed=(.*)\", options: [])\n        }\n        \n        let nsString = progressString as NSString\n        let range = NSRange(location: 0, length: nsString.length)\n        \n        guard let timeMatch = Rx.time.matches(in: progressString, options: [], range: range).first,\n              let time = FFTime(timeString: nsString.substring(with: timeMatch.range(at: 1)))\n        else { return nil }\n        self.time = time\n  \n        guard let speedMatch = Rx.speed.matches(in: progressString, options: [], range: range).first,\n              let speed = Scanner(string: nsString.substring(with: speedMatch.range(at: 1))).scanDouble()\n        else { return nil }\n        self.speed = speed\n        \n        \n        let isEnd = nsString.contains(\"Lsize\")\n        if isEnd { self.progress = .end } else { self.progress = .continue }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFTask.swift",
    "content": "//\n//  FFTask.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\n\nfinal class FFTask {\n    let duration: FFTime?\n    let complete: Promise<Void, Error>\n    \n    @Observable var progress = 0.0\n\n    func sendReport(_ report: FFProgressReport) {\n        guard let duration = duration else { return }\n        let durationInterval = duration.timeInterval\n        let reportInterval = report.time.timeInterval\n        self.progress = reportInterval / durationInterval\n    }\n    \n    init(duration: FFTime?, complete: Promise<Void, Error>) {\n        self.duration = duration\n        self.complete = complete\n        \n        self.complete.finally { self.progress = 1 }\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFThumnailGenerator.swift",
    "content": "//\n//  FFThumnailGenerator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/21.\n//\n\nimport CoreUtil\n\nenum FFThumnailGenerator {\n    private static let thumbnmailURL = FileManager.temporaryDirectoryURL.appendingPathExtension(\"FFThumbnail\") => {\n        try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)\n    }\n    \n    static func thumbnail(of movieURL: URL, size: CGSize) -> Promise<NSImage?, Never> {\n        let filename = UUID().uuidString + \".jpg\"\n        let thumbURL = self.thumbnmailURL.appendingPathComponent(filename)\n        \n        let task = FFExecutor.execute([\n            \"-vframes\", \"1\",\n            \"-f\", \"image2\",\n            \"-vf\", \"scale=\\(size.width):\\(size.height):force_original_aspect_ratio=decrease\"\n        ], inputURL: movieURL, destinationURL: thumbURL)\n        \n        return task.eraseToError().flatMap{ $0.complete }\n            .map{ NSImage(contentsOf: thumbURL) }\n            .replaceError(with: nil)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Body/Utils/ffmpeg/FFTime.swift",
    "content": "//\n//  FFTime.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/20.\n//\n\nimport Foundation\n\nstruct FFTime: CustomStringConvertible {\n    let hour: Int\n    let minute: Int\n    let second: Int\n    let ds: Int\n    \n    var timeInterval: TimeInterval {\n        Double(hour)*60*60 + Double(minute)*60 + Double(second) + Double(ds)/100\n    }\n    var description: String {\n        \"FFTime(\\(hour):\\(minute):\\(second).\\(ds))\"\n    }\n    \n    init?(timeString: String) {\n        let scanner = Scanner(string: timeString)\n        \n        guard let hour = scanner.scanInt(), let s1 = scanner.scanCharacter(), s1 == \":\",\n              let minute = scanner.scanInt(), let s2 = scanner.scanCharacter(), s2 == \":\",\n              let second = scanner.scanInt(), let s3 = scanner.scanCharacter(), s3 == \".\",\n              let ds = scanner.scanInt()\n        else { return nil }\n        \n        self.hour = hour\n        self.minute = minute\n        self.second = second\n        self.ds = ds\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Bridging-Header.h",
    "content": "//\n//  Bridging-Header.h\n//  DevToys\n//\n//  Created by yuki on 2022/02/19.\n//\n\n#ifndef Bridging_Header_h\n#define Bridging_Header_h\n\n#import \"ShowAndHideCursor.h\"\n\n#endif /* Bridging_Header_h */\n"
  },
  {
    "path": "DevToys/DevToys/Component/Area.swift",
    "content": "//\n//  ComponentBaseView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class Area: NSLoadView {\n    var control: NSView? {\n        didSet {\n            oldValue?.removeFromSuperview()\n            if let control = control { self.stackView.addArrangedSubview(control) }\n        }\n    }\n    \n    var icon: NSImage? {\n        get { iconView.image } set { iconView.image = newValue; iconView.isHidden = icon == nil }\n    }\n    var title: String {\n        get { titleLabel.stringValue } set { titleLabel.stringValue = newValue }\n    }\n    var message: String? = \"Message\" {\n        didSet {\n            messageLabel.isHidden = message == nil\n            messageLabel.stringValue = message ?? \"\"\n        }\n    }\n    var insetLevel = 0 {\n        didSet { self.stackView.edgeInsets.left = CGFloat(insetLevel + 1) * 16 }\n    }\n    \n    convenience init(icon: NSImage? = nil, title: String, message: String? = nil, control: NSView) {\n        self.init()\n        self.setup(icon: icon, title: title, message: message, control: control)\n    }\n    \n    private func setup(icon: NSImage?, title: String, message: String?, control: NSView) {\n        self.icon = icon\n        self.title = title\n        self.message = message\n        self.control = control\n    }\n    \n    private let iconView = NSImageView()\n    private let titleLabel = NSTextField(labelWithString: \"Title\")\n    private let messageLabel = NSTextField(labelWithString: \"Message\")\n    private let titleStack = NSStackView()\n    private let stackView = NSStackView()\n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    \n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    \n    override func layout() {\n        super.layout()\n        var edgeInsets = NSEdgeInsets.zero\n        edgeInsets.left = CGFloat(insetLevel) * 16\n        self.backgroundLayer.frame = bounds.slimmed(by: edgeInsets)\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(42)\n        }\n        \n        self.addSubview(stackView)\n        self.stackView.orientation = .horizontal\n        self.stackView.distribution = .fill\n        self.stackView.alignment = .centerY\n        self.stackView.edgeInsets = .init(x: 16, y: 0)\n        self.stackView.spacing = 16\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.stackView.addArrangedSubview(iconView)\n        self.iconView.image = R.Image.Tool.base64Coder\n        self.iconView.snp.makeConstraints{ make in\n            make.size.equalTo(24)\n        }\n        \n        self.stackView.addArrangedSubview(titleStack)\n        self.titleStack.orientation = .vertical\n        self.titleStack.spacing = 4\n        self.titleStack.distribution = .fillProportionally\n        self.titleStack.alignment = .left\n        \n        self.titleStack.addArrangedSubview(titleLabel)\n        self.titleLabel.font = NSFont.systemFont(ofSize: R.Size.controlTitleFontSize)\n        \n        self.titleStack.addArrangedSubview(messageLabel)\n        self.messageLabel.isHidden = true\n        self.messageLabel.font = NSFont.systemFont(ofSize: R.Size.controlFontSize)\n        self.messageLabel.textColor = .secondaryLabelColor\n        self.messageLabel.lineBreakMode = .byTruncatingTail\n        \n        self.stackView.addArrangedSubview(NSView())\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/Button.swift",
    "content": "//\n//  Button.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nfinal class Button: NSLoadButton {\n    override var intrinsicContentSize: NSSize {\n        super.intrinsicContentSize + [64, 0]\n    }\n    \n    override func draw(_ dirtyRect: NSRect) {\n        if isHighlighted {\n            R.Color.controlAccentColor.shadow(withLevel: 0.1)?.setFill()\n        } else {\n            R.Color.controlAccentColor.setFill()\n        }\n        \n        NSBezierPath(roundedRect: bounds, xRadius: R.Size.corner, yRadius: R.Size.corner).fill()\n        (self.title as NSString).draw(center: bounds, attributes: [NSAttributedString.Key.foregroundColor : NSColor.white])\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.isBordered = false\n        self.bezelStyle = .rounded\n    }\n}\n\nextension R.Color {\n    static var controlAccentColor: NSColor { NSColor.controlAccentColor }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/CodeTextView.swift",
    "content": "//\n//  CodeTextView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\nimport Highlightr\nimport AppKit\n\nfinal class CodeTextView: NSLoadView {\n    \n    var string: String { get { textView.string } set { textView.setString(newValue) } }\n    var isEditable: Bool { get { textView.isEditable } set { textView.isEditable = newValue } }\n    override var isSelectable: Bool { get { textView.isSelectable } set { textView.isSelectable = newValue } }\n    \n    var language: Language = .json { didSet { textStorage.language = language.rawValue } }\n    var contentInsets = NSSize.zero {\n        didSet { textView?.textContainerInset = contentInsets }\n    }\n    var stringPublisher: AnyPublisher<String, Never> {\n        textView.stringSubject.map{ self.textView.string }.eraseToAnyPublisher()\n    }\n    \n    convenience init(language: Language) {\n        self.init()\n        setLanguage(language: language)\n    }\n    private func setLanguage(language: Language) {\n        self.language = language\n    }\n    \n    func becomeFocused() {\n        self.window?.makeFirstResponder(self.textView)\n    }\n    \n    private(set) var scrollView: NSScrollView!\n    private(set) var textView: _CodeTextView!\n    private let highlightr = Highlightr()!\n    private lazy var textStorage = CodeAttributedString(highlightr: highlightr) => {\n        $0.language = \"Json\"\n    }\n    \n    override func viewDidChangeEffectiveAppearance() {\n        if self.effectiveAppearance.name == .darkAqua {\n            highlightr.setTheme(to: \"vs2015\")\n        } else {\n            highlightr.setTheme(to: \"vs\")\n        }\n        highlightr.theme.setCodeFont(.monospacedSystemFont(ofSize: R.Size.codeFontSize, weight: .regular))\n    }\n    \n    override func onAwake() {\n        self.viewDidChangeEffectiveAppearance()\n        self.wantsLayer = true\n        self.layer?.cornerRadius = R.Size.corner\n        \n        let layoutManager = NSLayoutManager()\n        textStorage.addLayoutManager(layoutManager)\n\n        let textContainer = NSTextContainer(size: [0, 10000000])\n        textContainer.widthTracksTextView = true\n        textContainer.heightTracksTextView = false\n        textContainer.lineBreakMode = .byWordWrapping\n        layoutManager.addTextContainer(textContainer)\n\n        _CodeTextView.textContainer = textContainer\n        let scrollView = _CodeTextView.scrollableTextView()\n        self.scrollView = scrollView\n        _CodeTextView.textContainer = nil\n        \n        self.addSubview(scrollView)\n        scrollView.automaticallyAdjustsContentInsets = false\n        scrollView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        let textView = scrollView.documentView as! _CodeTextView\n        \n        self.textView = textView\n        self.textView.allowsUndo = true\n        self.textView.usesFindBar = true\n        self.textView.isAutomaticSpellingCorrectionEnabled = false\n        self.textView.isAutomaticQuoteSubstitutionEnabled = false\n        self.textView.isAutomaticDashSubstitutionEnabled = false\n        self.textView.isAutomaticLinkDetectionEnabled = false\n        \n        self.contentInsets = [0, 4]\n        self.textView?.backgroundColor = .quaternaryLabelColor\n    }\n}\n \nfinal class _CodeTextView: NSTextView {\n    static var textContainer: NSTextContainer?\n    \n    let stringSubject = PassthroughSubject<Void, Never>()\n    \n    var sendingValue = false\n    \n    func setString(_ string: String) {\n        if !sendingValue { self.string = string }\n    }\n    \n    override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        self.commonInit()\n    }\n    override init(frame frameRect: NSRect, textContainer container: NSTextContainer?) {\n        super.init(frame: frameRect, textContainer: _CodeTextView.textContainer)\n        self.commonInit()\n    }\n    \n    private func commonInit() {}\n    \n    override func didChangeText() {\n        sendingValue = true\n        stringSubject.send()\n        sendingValue = false\n    }\n    \n    override func insertText(_ value: Any, replacementRange: NSRange) {\n        guard let string = value as? String, let selectedRange = self.selectedRanges.first?.rangeValue else { return super.insertText(value, replacementRange: replacementRange) }\n        \n        let singlePairs = [\"(\": (start: \"(\", end: \")\"), \"[\": (start: \"[\", end: \"]\"), \"{\": (start: \"{\", end: \"}\")]\n        let doublePaits = [\"\\\"\": (start: \"\\\"\", end: \"\\\"\"), \"'\": (start: \"'\", end: \"'\")]\n        \n        func pairWords(_ pair: (start: String, end: String)) {\n            let nsstring = self.string as NSString\n            var selectedWord: String?\n            objc_try({ selectedWord = nsstring.substring(with: selectedRange) }, catch: {_ in})\n            guard let _selectedWord = selectedWord else {\n                return\n            }\n            let word = pair.start + _selectedWord + pair.end\n            super.insertText(word, replacementRange: replacementRange)\n            super.setSelectedRange(NSRange(location: selectedRange.location + pair.start.count, length: selectedRange.length))\n        }\n        \n        if let pair = singlePairs[string] { return pairWords(pair) }\n        if let pair = doublePaits[string], selectedRange.length > 0 { return pairWords(pair) }\n        \n        if let selectedRange = self.selectedRanges.first?.rangeValue {\n            let nsstring = self.string as NSString\n            var _cursorChar: String?\n            objc_try({ _cursorChar = nsstring.substring(with: NSRange(location: selectedRange.location - 1, length: 1)) }, catch: {_ in})\n            guard let cursorChar = _cursorChar else { return super.insertText(string, replacementRange: replacementRange) }\n            if cursorChar == \"(\", string == \")\" { return moveRight(nil) }\n            if cursorChar == \"{\", string == \"}\" { return moveRight(nil) }\n            if cursorChar == \"[\", string == \"]\" { return moveRight(nil) }\n        }\n        \n        super.insertText(string, replacementRange: replacementRange)\n    }\n    \n    override func insertNewline(_ sender: Any?) {\n        guard let selectedRange = self.selectedRanges.first?.rangeValue else { return super.insertNewline(sender) }\n        \n        let nsstring = self.string as NSString\n        let cursorChar = nsstring.substring(with: NSRange(location: selectedRange.location - 1, length: 1))\n        var cursorNextChar: String?\n        \n        objc_try { cursorNextChar = nsstring.substring(with: NSRange(location: selectedRange.location, length: 1)) } catch: {_ in}\n        \n        let (line, _) = self.getLine(nsstring, in: selectedRange)\n        let indent = self.getIndentOfLine(line, spaceCount: 4)\n                \n        if (cursorChar == \"{\" && cursorNextChar == \"}\") || (cursorChar == \"[\" && cursorNextChar == \"]\") {\n            self.insertText(\"\\n\" + String(repeating: \"    \", count: indent+1) + \"\\n\" + String(repeating: \"    \", count: indent), replacementRange: selectedRange)\n            self.moveUp(nil)\n            self.moveToEndOfLine(nil)\n        } else {\n            self.insertText(\"\\n\" + String(repeating: \"    \", count: indent), replacementRange: selectedRange)\n        }\n    }\n    override func moveToBeginningOfLineAndModifySelection(_ sender: Any?) {\n        guard let selectedRange = self.selectedRanges.first?.rangeValue else { return super.moveToBeginningOfLineAndModifySelection(sender) }\n        \n        let nsstring = self.string as NSString\n        let (line, lineRange) = self.getLine(nsstring, in: selectedRange)\n        let spaceCount = self.beginningLineWhiteSpaceCount(line)\n        let spaceStartLocation = lineRange.location + spaceCount\n        \n        let isSpaces = selectedRange.location <= spaceStartLocation\n        if isSpaces {\n            super.moveToBeginningOfLineAndModifySelection(sender)\n        } else {\n            let lineCount = line.count(where: { $0 != \"\\n\" })\n            let range = NSRange(location: selectedRange.location + spaceCount - lineCount, length: lineCount - spaceCount)\n            self.setSelectedRange(range)\n        }\n    }\n    \n    private func beginningLineWhiteSpaceCount(_ line: String) -> Int {\n        var count = 0\n        for c in line {\n            if c == \"\\t\" || c == \" \" { count += 1 } else { return count }\n        }\n        return count\n    }\n    \n    private func getIndentOfLine(_ line: String, spaceCount: Int) -> Int {\n        var indent = 0\n        var space = 0\n        \n        for c in line {\n            if c == \"\\t\" { indent += 1 } else if c == \" \" { space += 1 } else {\n                return indent\n            }\n            if space == spaceCount {\n                indent += 1\n                space = 0\n            }\n        }\n        return indent\n    }\n    private func getLine(_ nsString: NSString, in range: NSRange) -> (String, NSRange) {\n        var start = -1\n        var end = -1\n        nsString.getLineStart(&start, end: &end, contentsEnd: nil, for: range)\n        let range = NSRange(location: start, length: end - start)\n        var line: String?\n        objc_try({ line = nsString.substring(with: range) }, catch: {_ in })\n        return (line ?? \"\", range)\n    }\n    \n    required init?(coder: NSCoder) { fatalError() }\n}\n\nextension CodeTextView {\n    enum Language: String {\n        case abnf = \"abnf\"\n        case accesslog = \"accesslog\"\n        case actionscript = \"actionscript\"\n        case ada = \"ada\"\n        case angelscript = \"angelscript\"\n        case apache = \"apache\"\n        case applescript = \"applescript\"\n        case arcade = \"arcade\"\n        case cpp = \"cpp\"\n        case arduino = \"arduino\"\n        case armasm = \"armasm\"\n        case xml = \"xml\"\n        case asciidoc = \"asciidoc\"\n        case aspectj = \"aspectj\"\n        case autohotkey = \"autohotkey\"\n        case autoit = \"autoit\"\n        case avrasm = \"avrasm\"\n        case awk = \"awk\"\n        case axapta = \"axapta\"\n        case bash = \"bash\"\n        case basic = \"basic\"\n        case bnf = \"bnf\"\n        case brainfuck = \"brainfuck\"\n        case cal = \"cal\"\n        case capnproto = \"capnproto\"\n        case ceylon = \"ceylon\"\n        case clean = \"clean\"\n        case clojure = \"clojure\"\n        case clojureRepl = \"clojure-repl\"\n        case cmake = \"cmake\"\n        case coffeescript = \"coffeescript\"\n        case coq = \"coq\"\n        case cos = \"cos\"\n        case crmsh = \"crmsh\"\n        case crystal = \"crystal\"\n        case cs = \"cs\"\n        case csp = \"csp\"\n        case css = \"css\"\n        case d = \"d\"\n        case markdown = \"markdown\"\n        case dart = \"dart\"\n        case delphi = \"delphi\"\n        case diff = \"diff\"\n        case django = \"django\"\n        case dns = \"dns\"\n        case dockerfile = \"dockerfile\"\n        case dos = \"dos\"\n        case dsconfig = \"dsconfig\"\n        case dts = \"dts\"\n        case dust = \"dust\"\n        case ebnf = \"ebnf\"\n        case elixir = \"elixir\"\n        case elm = \"elm\"\n        case ruby = \"ruby\"\n        case erb = \"erb\"\n        case erlangRepl = \"erlang-repl\"\n        case erlang = \"erlang\"\n        case excel = \"excel\"\n        case fix = \"fix\"\n        case flix = \"flix\"\n        case fortran = \"fortran\"\n        case fsharp = \"fsharp\"\n        case gams = \"gams\"\n        case gauss = \"gauss\"\n        case gcode = \"gcode\"\n        case gherkin = \"gherkin\"\n        case glsl = \"glsl\"\n        case gml = \"gml\"\n        case go = \"go\"\n        case golo = \"golo\"\n        case gradle = \"gradle\"\n        case groovy = \"groovy\"\n        case haml = \"haml\"\n        case handlebars = \"handlebars\"\n        case haskell = \"haskell\"\n        case haxe = \"haxe\"\n        case hsp = \"hsp\"\n        case htmlbars = \"htmlbars\"\n        case http = \"http\"\n        case hy = \"hy\"\n        case inform7 = \"inform7\"\n        case ini = \"ini\"\n        case irpf90 = \"irpf90\"\n        case isbl = \"isbl\"\n        case java = \"java\"\n        case javascript = \"javascript\"\n        case jbossCli = \"jboss-cli\"\n        case json = \"json\"\n        case julia = \"julia\"\n        case juliaRepl = \"julia-repl\"\n        case kotlin = \"kotlin\"\n        case lasso = \"lasso\"\n        case ldif = \"ldif\"\n        case leaf = \"leaf\"\n        case less = \"less\"\n        case lisp = \"lisp\"\n        case livecodeserver = \"livecodeserver\"\n        case livescript = \"livescript\"\n        case llvm = \"llvm\"\n        case lsl = \"lsl\"\n        case lua = \"lua\"\n        case makefile = \"makefile\"\n        case mathematica = \"mathematica\"\n        case matlab = \"matlab\"\n        case maxima = \"maxima\"\n        case mel = \"mel\"\n        case mercury = \"mercury\"\n        case mipsasm = \"mipsasm\"\n        case mizar = \"mizar\"\n        case perl = \"perl\"\n        case mojolicious = \"mojolicious\"\n        case monkey = \"monkey\"\n        case moonscript = \"moonscript\"\n        case n1ql = \"n1ql\"\n        case nginx = \"nginx\"\n        case nimrod = \"nimrod\"\n        case nix = \"nix\"\n        case nsis = \"nsis\"\n        case objectivec = \"objectivec\"\n        case ocaml = \"ocaml\"\n        case openscad = \"openscad\"\n        case oxygene = \"oxygene\"\n        case parser3 = \"parser3\"\n        case pf = \"pf\"\n        case pgsql = \"pgsql\"\n        case php = \"php\"\n        case plaintext = \"plaintext\"\n        case pony = \"pony\"\n        case powershell = \"powershell\"\n        case processing = \"processing\"\n        case profile = \"profile\"\n        case prolog = \"prolog\"\n        case properties = \"properties\"\n        case protobuf = \"protobuf\"\n        case puppet = \"puppet\"\n        case purebasic = \"purebasic\"\n        case python = \"python\"\n        case q = \"q\"\n        case qml = \"qml\"\n        case r = \"r\"\n        case reasonml = \"reasonml\"\n        case rib = \"rib\"\n        case roboconf = \"roboconf\"\n        case routeros = \"routeros\"\n        case rsl = \"rsl\"\n        case ruleslanguage = \"ruleslanguage\"\n        case rust = \"rust\"\n        case sas = \"sas\"\n        case scala = \"scala\"\n        case scheme = \"scheme\"\n        case scilab = \"scilab\"\n        case scss = \"scss\"\n        case shell = \"shell\"\n        case smali = \"smali\"\n        case smalltalk = \"smalltalk\"\n        case sml = \"sml\"\n        case sqf = \"sqf\"\n        case sql = \"sql\"\n        case stan = \"stan\"\n        case stata = \"stata\"\n        case step21 = \"step21\"\n        case stylus = \"stylus\"\n        case subunit = \"subunit\"\n        case swift = \"swift\"\n        case taggerscript = \"taggerscript\"\n        case yaml = \"yaml\"\n        case tap = \"tap\"\n        case tcl = \"tcl\"\n        case tex = \"tex\"\n        case thrift = \"thrift\"\n        case tp = \"tp\"\n        case twig = \"twig\"\n        case typescript = \"typescript\"\n        case vala = \"vala\"\n        case vbnet = \"vbnet\"\n        case vbscript = \"vbscript\"\n        case vbscriptHtml = \"vbscript-html\"\n        case verilog = \"verilog\"\n        case vhdl = \"vhdl\"\n        case vim = \"vim\"\n        case x86asm = \"x86asm\"\n        case xl = \"xl\"\n        case xquery = \"xquery\"\n        case zephir = \"zephir\"\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/ControlBackgroundLayer.swift",
    "content": "//\n//  ControlBackgroundLayer.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class ControlBackgroundLayer: CALoadLayer {\n    func update() {\n        self.backgroundColor = R.Color.controlBackgroundColor.cgColor\n    }\n    override func onAwake() {\n        self.cornerRadius = R.Size.corner\n        self.areAnimationsEnabled = false\n    }\n}\n\nfinal class ControlErrorBackgroundLayer: CALoadLayer {\n    func update(isError: Bool) {\n        if isError {\n            self.backgroundColor = NSColor.systemRed.withAlphaComponent(0.5).cgColor\n        } else {\n            self.backgroundColor = R.Color.controlBackgroundColor.cgColor\n        }\n    }\n    override func onAwake() {\n        self.cornerRadius = R.Size.corner\n        self.areAnimationsEnabled = false\n    }\n}\n\n\nfinal class ControlButtonBackgroundLayer: CALoadLayer {\n    func update(isHighlighted: Bool) {\n        self.areAnimationsEnabled = true\n        defer { self.areAnimationsEnabled = false }\n        \n        if isHighlighted {\n            self.backgroundColor = R.Color.controlHighlightedBackgroundColor.cgColor\n        } else {\n            self.backgroundColor = R.Color.controlBackgroundColor.cgColor\n        }\n    }\n    override func onAwake() {\n        self.cornerRadius = R.Size.corner\n        self.areAnimationsEnabled = false\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/ControlContainer.swift",
    "content": "//\n//  ComponentBaseView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class ControlArea: NSLoadView {\n    var control: NSView? {\n        didSet {\n            oldValue?.removeFromSuperview()\n            if let control = control { self.stackView.addArrangedSubview(control) }\n        }\n    }\n    \n    var icon: NSImage? {\n        get { iconView.image } set { iconView.image = newValue; iconView.isHidden = icon == nil }\n    }\n    var title: String {\n        get { titleLabel.stringValue } set { titleLabel.stringValue = newValue }\n    }\n    var message: String? = \"Message\" {\n        didSet { messageLabel.isHidden = message == nil; messageLabel.stringValue = message ?? \"\" }\n    }\n    \n    convenience init(icon: NSImage? = nil, title: String, message: String? = nil, control: NSView) {\n        self.init()\n        self.setup(icon: icon, title: title, message: message, control: control)\n    }\n    \n    private func setup(icon: NSImage?, title: String, message: String?, control: NSView) {\n        self.icon = icon\n        self.title = title\n        self.message = message\n        self.control = control\n    }\n    \n    private let iconView = NSImageView()\n    private let titleLabel = NSTextField(labelWithString: \"Title\")\n    private let messageLabel = NSTextField(labelWithString: \"Message\")\n    private let titleStack = NSStackView()\n    private let stackView = NSStackView()\n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    \n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(64)\n        }\n        \n        self.addSubview(stackView)\n        self.stackView.orientation = .horizontal\n        self.stackView.edgeInsets = .init(x: 16, y: 0)\n        self.stackView.spacing = 16\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.stackView.addArrangedSubview(iconView)\n        self.iconView.image = R.Image.ToolList.base64Coder\n        self.iconView.snp.makeConstraints{ make in\n            make.size.equalTo(24)\n        }\n        \n        self.stackView.addArrangedSubview(titleStack)\n        self.titleStack.orientation = .vertical\n        self.titleStack.spacing = 4\n        self.titleStack.alignment = .left\n        \n        self.titleStack.addArrangedSubview(titleLabel)\n        self.titleLabel.font = NSFont.systemFont(ofSize: R.Size.controlTitleFontSize)\n        \n        self.titleStack.addArrangedSubview(messageLabel)\n        self.messageLabel.font = NSFont.systemFont(ofSize: R.Size.controlFontSize)\n        self.messageLabel.textColor = .secondaryLabelColor\n        \n        self.stackView.addArrangedSubview(NSView())\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/DatePicker.swift",
    "content": "//\n//  DatePicker.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/04.\n//\n\nimport CoreUtil\n\nfinal class DatePicker: NSLoadView {\n    \n    var date: Date {\n        get { datePicker.dateValue } set { datePicker.dateValue = newValue }\n    }\n    var datePublisher: AnyPublisher<Date, Never> {\n        datePicker.actionPublisher.map{ self.datePicker.dateValue }.eraseToAnyPublisher()\n    }\n\n    private let datePicker = NSDatePicker()\n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    \n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func onAwake() {\n        \n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        \n        self.snp.makeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n    \n        self.addSubview(datePicker)\n        self.datePicker.isBezeled = false\n        self.datePicker.font = .systemFont(ofSize: 14)\n        self.datePicker.snp.makeConstraints{ make in\n            make.centerY.equalToSuperview()\n            make.left.right.equalToSuperview().inset(4)\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/DragImageView.swift",
    "content": "//\n//  ImageBoxView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/25.\n//\n\nimport CoreUtil\nimport AppKit\n\nprotocol DragImageViewDelegate: NSObjectProtocol {\n    func dragImageView(_ dragImageView: DragImageView, draggingFilenameFor image: NSImage) -> String\n}\n\nfinal class DragImageViewBlockDelegate: NSObject, DragImageViewDelegate {\n    private let filename: () -> String\n    \n    init(_ filename: @escaping () -> String) { self.filename = filename }\n    \n    func dragImageView(_ dragImageView: DragImageView, draggingFilenameFor image: NSImage) -> String { filename() }\n}\n\nfinal class DragImageView: NSLoadImageView, NSDraggingSource {\n\n    weak var delegate: DragImageViewDelegate?\n    \n    private var mouseDownLocation: CGPoint?\n    private static let temporaryDirectory = FileManager.default.temporaryDirectory.appendingPathComponent(\"DragDropImageView\") => {\n        try? FileManager.default.createDirectory(at: $0, withIntermediateDirectories: true, attributes: nil)\n    }\n    \n    override func onAwake() {\n        self.isEnabled = true\n    }\n\n    func draggingSession(_: NSDraggingSession, sourceOperationMaskFor _: NSDraggingContext) -> NSDragOperation {\n        return NSDragOperation.copy\n    }\n\n    func draggingSession(_: NSDraggingSession, endedAt _: NSPoint, operation: NSDragOperation) {}\n\n    override func mouseDown(with event: NSEvent) {\n        self.mouseDownLocation = event.location(in: self)\n    }\n    \n    override func mouseDragged(with event: NSEvent) {\n        guard let delegate = self.delegate else { return }\n        guard let mouseDownLocation = mouseDownLocation else { return }\n        \n        let dragPoint = event.locationInWindow\n        let dragDistance = hypot(mouseDownLocation.x - dragPoint.x, mouseDownLocation.y - dragPoint.y)\n        \n        if dragDistance < 3 { return }\n\n        guard let image = self.image else { return }\n        \n        let filename = delegate.dragImageView(self, draggingFilenameFor: image)\n        let imageURL = Self.temporaryDirectory.appendingPathComponent(filename)\n        \n        try! image.tiffRepresentation?.write(to: imageURL)\n\n        let draggingItem = NSDraggingItem(pasteboardWriter: imageURL as NSURL)\n\n        let draggingFrame = bounds\n        draggingItem.draggingFrame = draggingFrame\n        draggingItem.imageComponentsProvider = {\n            let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon)\n            component.contents = image\n            component.frame = draggingFrame\n            return [component]\n        }\n        beginDraggingSession(with: [draggingItem], event: event, source: self)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/EmptyImageTableView.swift",
    "content": "//\n//  EmptyImageTableView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/22.\n//\n\nimport CoreUtil\n\nopen class EmptyImageTableView: NSLoadTableView {\n    \n    open var emptyView: NSView? {\n        get { emptyViewPlaceholder.contentView } set { emptyViewPlaceholder.contentView = newValue }\n    }\n    \n    private let emptyViewPlaceholder = NSPlaceholderView()\n        \n    open override func didRemove(_ rowView: NSTableRowView, forRow row: Int) {\n        super.didRemove(rowView, forRow: row)\n        self.updateRowCount()\n    }\n    open override func didAdd(_ rowView: NSTableRowView, forRow row: Int) {\n        super.didAdd(rowView, forRow: row)\n        self.updateRowCount()\n    }\n    \n    private func updateRowCount() {\n        if numberOfRows == 0 {\n            self.emptyViewPlaceholder.isHidden = false\n        } else {\n            self.emptyViewPlaceholder.isHidden = true\n        }\n    }\n    private func commonInit() {\n        self.addSubview(emptyViewPlaceholder)\n        self.emptyViewPlaceholder.snp.makeConstraints{ make in\n            make.center.equalToSuperview()\n        }\n        self.updateRowCount()\n    }\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        self.commonInit()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        self.commonInit()\n    }\n}\n\nextension EmptyImageTableView {\n    public func setFileDropEmptyView(_ title: String = \"Drop Files Here\".localized()) {\n        self.emptyView = DropIndicatorView(title: title)\n    }\n}\n\nfinal class DropIndicatorView: NSLoadStackView {\n    private let imageView = NSImageView(image: R.Image.drop)\n    private let titleLabel = NSTextField(labelWithString: \"Title\")\n    \n    convenience init(title: String) {\n        self.init()\n        self.titleLabel.stringValue = title\n    }\n    \n    override func onAwake() {\n        self.unregisterDraggedTypes()\n        self.alignment = .centerX\n        self.orientation = .vertical\n        self.addArrangedSubview(imageView)\n        self.addArrangedSubview(titleLabel)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/FileDrop.swift",
    "content": "//\n//  FileDrop.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/02.\n//\n\nimport CoreUtil\n\nfinal class FileDropSection: Section {\n    \n    var urlsPublisher: AnyPublisher<[URL], Never> {\n        fileDrop.urlsPublisher.merge(with: openButton.urlPublisher.map{ [$0] }).eraseToAnyPublisher()\n    }\n    \n    private let fileDrop = FileDrop()\n    private let openButton = OpenSectionButton(title: \"Open\".localized(), image: R.Image.open)\n    \n    override func onAwake() {\n        super.onAwake()\n        self.title = \"File\".localized()\n        self.addToolbarItem(openButton)\n        self.addStackItem(fileDrop)\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(160)\n        }\n    }\n}\n\nfinal class FileDrop: NSLoadView {\n    \n    let urlsPublisher = PassthroughSubject<[URL], Never>()\n    \n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    private let imageView = NSImageView(image: R.Image.drop)\n    private let titleLabel = NSTextField(labelWithString: \"Drop Files Here\".localized())\n    private let stackView = NSStackView()\n    \n    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {\n        sender.draggingPasteboard.canReadTypes([.fileURL]) ? .copy : .none\n    }\n    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {\n        guard let urls = sender.draggingPasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL] else { return false }\n        urlsPublisher.send(urls)\n        return true\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func updateLayer() {\n        backgroundLayer.update()\n    }\n\n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        \n        self.addSubview(stackView)\n        self.stackView.orientation = .vertical\n        self.stackView.snp.makeConstraints{ make in\n            make.center.equalToSuperview()\n        }\n        \n        self.stackView.addArrangedSubview(imageView)\n        self.stackView.addArrangedSubview(titleLabel)\n        self.registerForDraggedTypes([.fileURL])\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/ImageDropView.swift",
    "content": "//\n//  ImageDropView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/28.\n//\n\nimport CoreUtil\n\nclass ImageDropView: NSLoadView {\n    \n    var image: NSImage? {\n        get { imageView.image }\n        set {\n            self.imageView.image = newValue\n            self.dropIndicator.isHidden = newValue != nil\n        }\n    }\n    \n    let imagePublisher = PassthroughSubject<ImageItem, Never>()\n    let imageView = NSImageView()\n    \n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    private let dropIndicator = DropIndicatorView(title: \"Drop Image Here\")\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    \n    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { return .copy }\n    \n    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {\n        let images = ImageDropper.images(fromPasteboard: sender.draggingPasteboard)\n        guard let image = images.first else { return false }\n        \n        imagePublisher.send(image)\n        \n        return true\n    }\n    \n    override func onAwake() {\n        self.imageView.unregisterDraggedTypes()\n        self.registerForDraggedTypes([.fileURL, .URL, .fileContents])\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        \n        self.addSubview(imageView)\n        self.imageView.snp.makeConstraints{ make in\n            make.width.equalTo(180)\n            make.top.bottom.equalToSuperview().inset(16)\n            make.centerX.equalToSuperview()\n        }\n        \n        self.addSubview(dropIndicator)\n        self.dropIndicator.snp.makeConstraints{ make in\n            make.center.equalToSuperview()\n        }\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Component/NumberField.swift",
    "content": "//\n//  NumberField.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\nimport CoreGraphics\n\nfinal class NumberField: NSLoadView {\n    \n    var value: CGFloat = 0 {\n        didSet { textField.stringValue = value.formattedString() }\n    }\n    var valuePublisher: AnyPublisher<Delta<Double>, Never> {\n        self.valueSubject.eraseToAnyPublisher()\n    }\n    var isEnabled: Bool {\n        get { textField.isEnabled } set { textField.isEnabled = newValue }\n    }\n    var showStepper = true {\n        didSet {\n            self.stepper.isHidden = !showStepper\n        }\n    }\n        \n    private let stepper = NumberFieldStepper()\n    private let textField = CustomFocusRingTextField()\n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    private let valueSubject = PassthroughSubject<Delta<Double>, Never>()\n    \n    convenience init(autoWidth: Void) {\n        self.init(width: 100)\n    }\n    \n    convenience init(width: CGFloat) {\n        self.init()\n        self.snp.makeConstraints{ make in\n            make.width.equalTo(width)\n        }\n    }\n    \n    override func layout() {\n        self.backgroundLayer.frame = bounds\n        let textFieldFrame = CGRect(originX: 8, centerY: bounds.midY, size: [bounds.width - 28, textField.intrinsicContentSize.height])\n        \n        let focusRingBounds = CGRect(origin: bounds.origin - textFieldFrame.origin, size: bounds.size)\n        self.textField.focusRingBounds = focusRingBounds\n        self.textField.frame = textFieldFrame\n        super.layout()\n    }\n    \n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    \n    private func receiveString(_ string: String) {\n        guard let value = Double(string) else {\n            self.textField.stringValue = \"0\"\n            return NSSound.beep()\n        }\n        self.valueSubject.send(.to(value))\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.wantsLayer = true\n        self.layer?.cornerRadius = R.Size.corner\n        self.layer?.addSublayer(backgroundLayer)\n        \n        self.addSubview(stepper)\n        self.stepper.snp.makeConstraints{ make in\n            make.right.top.bottom.equalToSuperview()\n        }\n        \n        self.addSubview(textField)\n        self.textField.font = .systemFont(ofSize: 12)\n        self.textField.stringValue = \"0\"\n        \n        self.textField.changeStringPublisher\n            .sink{[unowned self] in self.receiveString($0) }.store(in: &objectBag)\n        self.stepper.upPublisher\n            .sink{[unowned self] in self.valueSubject.send(.by(1)) }.store(in: &objectBag)\n        self.stepper.downPublisher\n            .sink{[unowned self] in self.valueSubject.send(.by(-1)) }.store(in: &objectBag)\n    }\n}\n\nfinal private class NumberFieldStepper: NSLoadControl {\n    \n    let upPublisher = PassthroughSubject<Void, Never>()\n    let downPublisher = PassthroughSubject<Void, Never>()\n    \n    override var isFlipped: Bool { true }\n    \n    private let backgroundLayer = CALayer.animationDisabled()\n    private let upBackgroundLayer = CALayer.animationDisabled()\n    private let downBackgroundLayer = CALayer.animationDisabled()\n    \n    private let upImageView = NSImageView(image: R.Image.stepperUp)\n    private let downImageView = NSImageView(image: R.Image.stepperDown)\n    \n    private var mouseDownPosition: Position? { didSet { needsDisplay = true } }\n    private var highlightPosition: Position? { didSet { needsDisplay = true } }\n    \n    private enum Position { case up, down }\n    \n    private func position(of location: CGPoint) -> Position {\n        if location.y > bounds.height/2 { return .down } else { return .up }\n    }\n    \n    override func mouseDown(with event: NSEvent) {\n        self.mouseDownPosition = position(of: event.location(in: self))\n        self.highlightPosition = position(of: event.location(in: self))\n        \n        Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { timer in\n            timer.invalidate()\n            Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in\n                guard let mouseDownPosition = self.mouseDownPosition else { return timer.invalidate() }\n                self.sendPosition(mouseDownPosition)\n                NSHapticFeedbackManager.defaultPerformer.perform(.levelChange, performanceTime: .now)\n                \n            }\n        }\n    }\n    \n    override func mouseDragged(with event: NSEvent) {\n        if position(of: event.location(in: self)) == mouseDownPosition {\n            self.highlightPosition = mouseDownPosition\n        } else {\n            self.highlightPosition = nil\n        }\n    }\n    override func mouseUp(with event: NSEvent) {\n        defer {\n            self.highlightPosition = nil\n            self.mouseDownPosition = nil\n        }\n        \n        if let position = mouseDownPosition, self.position(of: event.location(in: self)) == position {\n            sendPosition(position)\n        }\n    }\n    \n    private func sendPosition(_ position: Position) {\n        switch position {\n        case .up: upPublisher.send()\n        case .down: downPublisher.send()\n        }\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n        self.upBackgroundLayer.frame = CGRect(origin: [0, 0], size: [bounds.width, bounds.height/2])\n        self.downBackgroundLayer.frame = CGRect(origin: [0, bounds.height/2], size: [bounds.width, bounds.height/2])\n        \n        self.upImageView.frame.center = upBackgroundLayer.frame.center\n        self.downImageView.frame.center = downBackgroundLayer.frame.center\n    }\n    \n    override func updateLayer() {\n        self.backgroundLayer.backgroundColor = R.Color.controlHighlightedBackgroundColor.cgColor\n        \n        if highlightPosition == .up {\n            self.upBackgroundLayer.backgroundColor = R.Color.controlBackgroundColor.cgColor\n        } else {\n            self.upBackgroundLayer.backgroundColor = nil\n        }\n        \n        if highlightPosition == .down {\n            self.downBackgroundLayer.backgroundColor = R.Color.controlBackgroundColor.cgColor\n        } else {\n            self.downBackgroundLayer.backgroundColor = nil\n        }\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        self.addSubview(upImageView)\n        self.upImageView.frame.size = [10, 10]\n        self.addSubview(downImageView)\n        self.downImageView.frame.size = [10, 10]\n        \n        self.backgroundLayer.addSublayer(upBackgroundLayer)\n        self.backgroundLayer.addSublayer(downBackgroundLayer)\n        \n        self.snp.makeConstraints{ make in\n            make.width.equalTo(20)\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/Page.swift",
    "content": "//\n//  ToolPage.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n \nclass Page: NSLoadView { \n    \n    let stackView = NSStackView()\n    let scrollView = NSScrollView()\n    \n    func addSection(_ section: NSView, fillWidth: Bool = true) {\n        self.stackView.addArrangedSubview(section)\n        if fillWidth {\n            section.snp.makeConstraints{ make in\n                make.right.left.equalToSuperview().inset(16)\n            }\n        }\n    }\n    \n    @discardableResult\n    func addSection2(_ stack1: NSView, _ stack2: NSView) -> NSStackView {\n        let stackView = NSStackView()\n        stackView.distribution = .fillEqually\n        stackView.orientation = .horizontal\n        stackView.alignment = .top\n        stackView.addArrangedSubview(stack1)\n        stackView.addArrangedSubview(stack2)\n        self.addSection(stackView)\n        return stackView\n    }\n    \n    private func commonInit() {\n        self.addSubview(scrollView)\n        self.scrollView.contentView = FlipClipView()\n        self.scrollView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.stackView.edgeInsets = NSEdgeInsets(x: 16, y: 16)\n        self.stackView.orientation = .vertical\n        self.stackView.alignment = .left\n        self.scrollView.documentView = stackView\n        \n        self.stackView.snp.makeConstraints{ make in\n            make.top.equalToSuperview()\n            make.right.left.equalToSuperview()\n        }\n    }\n\n    public override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        commonInit()\n    }\n    public required init?(coder: NSCoder) {\n        super.init(coder: coder)\n        commonInit()\n    }\n}\n\nprivate class FlipClipView: NSClipView {\n    override var isFlipped: Bool { true }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/PopupButton.swift",
    "content": "//\n//  PopupButton.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nprotocol TextItem: CaseIterable, Equatable {\n    var title: String { get }\n}\n\nextension RawRepresentable where RawValue == String {\n    var title: String { rawValue }\n}\n\nfinal class EnumPopupButton<Item: TextItem>: PopupButton {\n    \n    var selectedItem: Item? {\n        didSet { selectedMenuTitle = selectedItem?.title }\n    }\n    let itemPublisher = PassthroughSubject<Item, Never>()\n    \n    override func makeMenuItems() -> [NSMenuItem] {\n        Item.allCases.map{ item in\n            NSMenuItem(title: item.title, isSelected: selectedItem == item, action: {\n                self.itemPublisher.send(item)\n            })\n        }\n    }\n}\n\nclass PopupButton: NSLoadButton {\n\n    var menuItems = [NSMenuItem]()\n    var selectedMenuTitle: String? { didSet { self.titleLabel.stringValue = selectedMenuTitle ?? \"No selection\".localized() } }\n    \n    func makeMenuItems() -> [NSMenuItem] { menuItems }\n    \n    private let titleLabel = NSTextField(labelWithString: \"No selection\".localized())\n    private let pulldownIndicator = NSImageView(image: R.Image.pulldownIndicator)\n    private let stackView = NSStackView()\n    private let backgroundLayer = ControlBackgroundLayer.animationDisabled()\n    \n    override var isHighlighted: Bool { didSet { needsDisplay = true } }\n    \n    override func updateLayer() {\n        self.backgroundLayer.update()\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func mouseDown(with event: NSEvent) {\n        let menu = NSMenu()\n        \n        for item in makeMenuItems() { menu.addItem(item) }\n        \n        menu.minimumWidth = self.bounds.width\n        menu.popUp(positioning: menu.items.first(where: { $0.isSelected }), at: .zero, in: self)\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.isBordered = false\n        self.title = \"\"\n        self.layer?.addSublayer(backgroundLayer)\n        \n        self.snp.makeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.addSubview(stackView)\n        self.stackView.spacing = 4\n        self.stackView.edgeInsets = .init(x: 8, y: 0)\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.titleLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n        self.stackView.addArrangedSubview(titleLabel)\n        \n        self.stackView.addArrangedSubview(pulldownIndicator)\n        self.pulldownIndicator.snp.makeConstraints{ make in\n            make.size.equalTo(18)\n        }\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/RegexTextView.swift",
    "content": "//\n//  RegexTextView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport CoreUtil\n\nfinal class RegexTextView: NSLoadView {\n    var string: String { get { textView.string } set { textView.string = newValue } }\n    var highlightRanges = [NSRange]() { didSet { updateHighlights() } }\n    var stringPublisher: AnyPublisher<String, Never> { textView.stringPublisher.eraseToAnyPublisher() }\n    \n    var isEditable: Bool { get { textView.isEditable } set { textView.isEditable = newValue } }\n    override var isSelectable: Bool { get { textView.isSelectable } set { textView.isSelectable = newValue } }\n    \n    private let scrollView = _TextView.scrollableTextView()\n    private lazy var textView = scrollView.documentView as! _TextView\n    \n    private func updateHighlights() {\n        guard let textStorage = textView.textStorage else { return }\n        \n        objc_try {\n            textStorage.removeAttribute(NSAttributedString.Key.backgroundColor, range: NSRange(location: 0, length: textStorage.length))\n            \n            for range in highlightRanges {\n                textStorage.addAttribute(NSAttributedString.Key.backgroundColor, value: NSColor.systemBlue.withAlphaComponent(0.5), range: range)\n            }\n        } catch: { error in\n            print(error)\n        }\n    }\n\n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.cornerRadius = R.Size.corner\n        \n        self.addSubview(scrollView)\n        self.textView.allowsUndo = true\n        self.textView.font = .monospacedSystemFont(ofSize: R.Size.codeFontSize, weight: .regular)\n        self.textView.backgroundColor = .quaternaryLabelColor\n        self.textView.textContainerInset = [0, 4]\n        self.scrollView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n    }\n}\n\nfinal private class _TextView: NSTextView {\n    let stringPublisher = PassthroughSubject<String, Never>()\n    override func didChangeText() { self.stringPublisher.send(string) }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/Section.swift",
    "content": "//\n//  ControlStack.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nclass Section: NSLoadView {\n    var title: String {\n        get { titleLabel.stringValue } set { titleLabel.stringValue = newValue }\n    }\n    var minTitle: Bool = false {\n        didSet {\n            self.titleStackView.snp.updateConstraints{ make in\n                make.height.equalTo(minTitle ? 16 : R.Size.controlHeight)\n            }\n        }\n    }\n    var orientation: NSUserInterfaceLayoutOrientation {\n        get { contentStackView.orientation } set { contentStackView.orientation = newValue }\n    }\n    \n    func addStackItem(_ item: NSView, fillWidth: Bool = true) {\n        self.contentStackView.addArrangedSubview(item)\n        if fillWidth {\n            item.snp.makeConstraints{ make in\n                make.right.left.equalToSuperview()\n            }\n        }\n    }\n    func addToolbarItem(_ item: NSView) {\n        self.titleStackView.addArrangedSubview(item)\n    }\n    func removeToolbarItem(_ item: NSView) {\n        self.titleStackView.removeArrangedSubview(item)\n    }\n    func removeAllToolbarItem() {\n        self.titleStackView.subviews.removeAll(where: { $0 !== titleLabel && $0 !== spacer })\n    }\n    \n    convenience init(title: String, orientation: NSUserInterfaceLayoutOrientation = .vertical, fillWidth: Bool = true, items: [NSView] = [], toolbarItems: [NSView] = []) {\n        self.init()\n        self.title = title\n        self.orientation = orientation\n        for item in items { self.addStackItem(item, fillWidth: fillWidth) }\n        for toolbarItem in toolbarItems { self.addToolbarItem(toolbarItem) }\n    }\n    \n    private let titleLabel = NSTextField(labelWithString: \"Title\")\n    private let spacer = NSView()\n    private let titleStackView = NSStackView()\n    private let contentStackView = NSStackView()\n    \n    override func onAwake() {\n        self.addSubview(titleStackView)\n        self.titleStackView.orientation = .horizontal\n        self.titleStackView.distribution = .fillProportionally\n        self.titleStackView.snp.makeConstraints{ make in\n            make.left.right.top.equalToSuperview()\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.addSubview(contentStackView)\n        self.contentStackView.distribution = .fillEqually\n        self.contentStackView.orientation = .vertical\n        self.contentStackView.snp.makeConstraints{ make in\n            make.bottom.right.left.equalToSuperview()\n            make.top.equalTo(titleStackView.snp.bottom).offset(8)\n        }\n        \n        self.titleStackView.addArrangedSubview(titleLabel)\n        self.titleStackView.addArrangedSubview(spacer)\n        self.titleLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/SectionButton+.swift",
    "content": "//\n//  SectionButton+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class SearchSectionButton: SectionButton {\n    \n    private let selector = NSSelectorFromString(\"performFindPanelAction\")\n    weak var textView: TextViewType?\n    \n    override func onAwake() {\n        super.onAwake()\n        \n        self.image = R.Image.search\n        self.actionPublisher\n            .sink{[unowned self] in\n                guard let textView = textView else { return assertionFailure() }\n                textView.becomeFocused()\n                \n                guard let findMenu = NSApp.mainMenu?.item(withTag: 1001)?.submenu?.item(withTag: 1002)?.submenu else { return }\n                let index = findMenu.indexOfItem(withTag: 1)\n                \n                findMenu.performActionForItem(at: index)\n            }\n            .store(in: &objectBag)\n    }\n}\n\nfinal class OpenSectionButton: SectionButton {\n    \n    let urlPublisher = PassthroughSubject<URL, Never>()\n    \n    var fileStringPublisher: AnyPublisher<String, Never> {\n        urlPublisher.compactMap{ try? String(contentsOf: $0) }.eraseToAnyPublisher()\n    }\n    var fileDataPublisher: AnyPublisher<Data, Never> {\n        urlPublisher.compactMap{ try? Data(contentsOf: $0) }.eraseToAnyPublisher()\n    }\n    \n    @objc private func buttonAction(_: Any) {\n        let panel = NSOpenPanel()\n        guard panel.runModal() == .OK, let url = panel.url else { return }\n        self.urlPublisher.send(url)\n    }\n    \n    override func onAwake() {\n        super.onAwake()\n        self.toolTip = \"Open\".localized()\n        self.title = \"\"\n        self.image = R.Image.open\n        self.setTarget(self, action: #selector(buttonAction))\n    }\n}\n\nfinal class CopySectionButton: SectionButton {\n    \n    var stringContent: String?\n    \n    convenience init(hasTitle: Bool) {\n        self.init()\n        if hasTitle {\n            self.title = \"Copy\".localized()\n        } else {\n            self.title = \"\"\n        }\n    }\n    \n    override func onAwake() {\n        super.onAwake()\n        self.image = R.Image.copy\n        self.toolTip = \"Copy\".localized()\n        \n        self.actionPublisher\n            .sink{[unowned self] in\n                guard let stringContent = self.stringContent else { return NSSound.beep() }\n                NSPasteboard.general.prepareForNewContents(with: .none)\n                NSPasteboard.general.setString(stringContent, forType: .string)\n                Toast.show(message: \"Copied!\".localized())\n            }\n            .store(in: &objectBag)\n    }\n}\n\nfinal class PasteSectionButton: SectionButton {\n    var stringPublisher: AnyPublisher<String?, Never> {\n        self.actionPublisher\n            .peek{ Toast.show(message: \"Pasted!\".localized()) }\n            .map{ return NSPasteboard.general.string(forType: .string) }\n            .eraseToAnyPublisher()\n    }\n    \n    override func onAwake() {\n        super.onAwake()\n        self.toolTip = \"Paste\".localized()\n        self.title = \"Paste\".localized()\n        self.image = R.Image.paste\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/SectionButton.swift",
    "content": "//\n//  ControlStackButton.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nclass SectionButton: NSLoadButton {\n    override var title: String { didSet { updateTitle()  } }\n    override var image: NSImage? { didSet { iconView.image = image } }\n    \n    private let titleLabel = NSTextField(labelWithString: \"Paste\".localized())\n    private let iconView = NSImageView(image: R.Image.Tool.convert)\n    \n    private let stackView = NSStackView()\n    private let backgroundLayer = ControlButtonBackgroundLayer.animationDisabled()\n    \n    override var isHighlighted: Bool { didSet { needsDisplay = true } }\n    \n    private func updateTitle() {\n        titleLabel.stringValue = title\n        if title.isEmpty {\n            titleLabel.isHidden = true\n            self.stackView.distribution = .fillEqually\n        } else {\n            titleLabel.isHidden = false\n        }\n    }\n    \n    override func updateLayer() {\n        self.backgroundLayer.update(isHighlighted: isHighlighted)\n    }\n    \n    override func draw(_ dirtyRect: NSRect) {\n        updateLayer()\n    }\n    \n    override func layout() {\n        super.layout()\n        self.backgroundLayer.frame = bounds\n    }\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.wantsLayer = true\n        self.isBordered = false\n        self.title = \"\"\n        self.layer?.addSublayer(backgroundLayer)\n        \n        self.snp.makeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.addSubview(stackView)\n        self.stackView.spacing = 4\n        self.stackView.distribution = .equalCentering\n        self.stackView.edgeInsets = .init(x: 8, y: 0)\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.stackView.addArrangedSubview(iconView)\n        self.iconView.snp.makeConstraints{ make in\n            make.size.equalTo(20)\n        }\n        \n        self.titleLabel.font = .systemFont(ofSize: R.Size.controlTitleFontSize)\n        self.stackView.addArrangedSubview(titleLabel)\n        \n        self.updateTitle()\n    }\n}\n\nextension NSButton {\n    convenience init(title: String? = nil, image: NSImage? = nil) {\n        self.init()\n        self.setup(title: title, image: image)\n    }\n    \n    private func setup(title: String?, image: NSImage?) {\n        self.title = title ?? \"\"\n        self.image = image\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/TagCloudView.swift",
    "content": "//\n//  TagCloudView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\n\nfinal class TagCloudView: NSLoadView {\n    let collectionView = NSCollectionView()\n    let flowLayout = LeftAlignedCollectionViewFlowLayout()\n    let buttonPublisher = PassthroughSubject<Int, Never>()\n    let selectPublisher = PassthroughSubject<Int, Never>()\n    \n    var selectedItem: Int? {\n        didSet {\n            if let selectedItem = selectedItem {\n                collectionView.selectItems(at: [IndexPath(item: selectedItem, section: 0)], scrollPosition: .bottom)\n            } else {\n                collectionView.deselectAll(nil)\n            }\n        }\n    }\n    override var isSelectable: Bool {\n        get { collectionView.isSelectable } set { collectionView.isSelectable = newValue; collectionView.reloadData() }\n    }\n    var items: [String] = [\"Hello\", \"World\"] {\n        didSet {\n            collectionView.reloadData()\n            DispatchQueue.main.async {[self] in self.reloadHeight() }\n        }\n    }\n    \n    override func layout() {\n        self.reloadHeight()\n        super.layout()\n    }\n    \n    private func reloadHeight() {\n        let collectionViewContentSize = flowLayout.collectionViewContentSize\n        self.snp.remakeConstraints{ make in\n            make.height.equalTo(collectionViewContentSize.height)\n        }\n    }\n    \n    override func onAwake() {\n        self.frame.size = [1, 1]\n        flowLayout.scrollDirection = .vertical\n        flowLayout.estimatedItemSize = .zero\n        flowLayout.minimumInteritemSpacing = 10\n        flowLayout.minimumLineSpacing = 10\n        flowLayout.invalidateLayout()\n        collectionView.collectionViewLayout = flowLayout\n        \n        self.addSubview(collectionView)\n        self.collectionView.dataSource = self\n        self.collectionView.delegate = self\n        self.collectionView.register(TagCloudItem.self, forItemWithIdentifier: TagCloudItem.identifier)\n        self.collectionView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n    }\n}\n\nextension TagCloudView: NSCollectionViewDelegateFlowLayout, NSCollectionViewDataSource {\n    func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {\n        items.count\n    }\n    \n    func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {\n        guard let indexPath = indexPaths.first else { return }\n        selectPublisher.send(indexPath.item)\n    }\n    \n    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {\n        let item = collectionView.makeItem(withIdentifier: TagCloudItem.identifier, for: indexPath) as! TagCloudItem\n        \n        item.cell.isEnabled = !isSelectable\n        item.cell.actionPublisher\n            .sink{ self.buttonPublisher.send(indexPath.item) }.store(in: &item.objectBag)\n        \n        item.cell.label.stringValue = items[indexPath.item]\n        return item\n    }\n    \n    func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {\n        let label = NSTextField(labelWithString: items[indexPath.item])\n        label.font = .systemFont(ofSize: 14)\n        label.sizeToFit()\n        return label.frame.size + [16, 12]\n    }\n}\n\nfinal private class TagCloudItem: NSCollectionViewItem {\n    static let identifier = NSUserInterfaceItemIdentifier(rawValue: \"TagCloudItem\")\n    override var isSelected: Bool { didSet { cell.isSelected = isSelected } }\n    \n    class Cell: NSLoadButton {\n        let label = NSTextField(labelWithString: \"\")\n        let backgroundLayer = ControlButtonBackgroundLayer.animationDisabled()\n        var isSelected: Bool = false { didSet { needsDisplay = true } }\n        \n        override func layout() {\n            super.layout()\n            self.backgroundLayer.frame = bounds\n        }\n        override func updateLayer() {\n            backgroundLayer.update(isHighlighted: isHighlighted)\n            \n            backgroundLayer.areAnimationsEnabled = true\n            if isSelected {\n                backgroundLayer.backgroundColor = NSColor.controlAccentColor.withAlphaComponent(0.5).cgColor\n                backgroundLayer.borderColor = NSColor.controlAccentColor.cgColor\n                backgroundLayer.borderWidth = 1\n            } else {\n                backgroundLayer.borderWidth = 0\n            }\n            backgroundLayer.areAnimationsEnabled = false\n        }\n        \n        override func onAwake() {\n            self.wantsLayer = true\n            self.title = \"\"\n            self.isBordered = false\n            self.layer?.addSublayer(backgroundLayer)\n            \n            self.addSubview(label)\n            self.label.alignment = .center\n            self.label.snp.makeConstraints{ make in\n                make.left.right.equalToSuperview().inset(8)\n                make.centerY.equalToSuperview()\n            }\n        }\n    }\n    \n    let cell = Cell()\n    \n    override func loadView() { self.view = cell }\n}\n\n\nfinal class LeftAlignedCollectionViewFlowLayout: NSCollectionViewFlowLayout {\n    override func layoutAttributesForElements(in rect: NSRect) -> [NSCollectionViewLayoutAttributes] {\n        let attributes = super.layoutAttributesForElements(in: rect)\n\n        var leftMargin = sectionInset.left\n        var maxY: CGFloat = -1.0\n        attributes.forEach { layoutAttribute in\n            if layoutAttribute.representedElementCategory == .item {\n                if layoutAttribute.frame.origin.y >= maxY {\n                    leftMargin = sectionInset.left\n                }\n                layoutAttribute.frame.origin.x = leftMargin\n                leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing\n                maxY = max(layoutAttribute.frame.maxY, maxY)\n            }\n        }\n        return attributes\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Component/TextField.swift",
    "content": "//\n//  TextField.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/30.\n//\n\nimport CoreUtil\n\nfinal class TextField: NSLoadView {\n    var string: String {\n        get { textField.textField.stringValue } set { textField.textField.stringValue = newValue; copyButton.stringContent = newValue }\n    }\n    var placeholder: String? {\n        get { textField.textField.placeholderString } set { textField.textField.placeholderString = newValue }\n    }\n    \n    var changeStringPublisher: AnyPublisher<String, Never> {\n        textField.textField.changeStringPublisher\n    }\n    var endEditingStringPublisher: AnyPublisher<String, Never> {\n        textField.textField.endEditingStringPublisher\n    }\n    var isError: Bool { get { textField.isError } set { textField.isError = newValue } }\n    var font: NSFont? { get { textField.textField.font } set { textField.textField.font = newValue } }\n    var showCopyButton = false { didSet { copyButton.isHidden = !showCopyButton } }\n    var isEditable: Bool = true { didSet { textField.textField.isEditable = isEditable } }\n    \n    convenience init(showCopyButton: Bool) {\n        self.init()\n        self.setup(showCopyButton: showCopyButton)\n    }\n    \n    private func setup(showCopyButton: Bool) {\n        self.showCopyButton = showCopyButton\n    }\n        \n    private let textField = DotNetTextField()\n    private let stackView = NSStackView()\n    private let copyButton = CopySectionButton(hasTitle: false)\n    \n    override func onAwake() {\n        self.snp.makeConstraints{ make in\n            make.height.equalTo(R.Size.controlHeight)\n        }\n        self.addSubview(stackView)\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.stackView.addArrangedSubview(textField)\n        self.textField.textField.lineBreakMode = .byTruncatingTail\n        self.stackView.addArrangedSubview(copyButton)\n        \n        self.textField.snp.makeConstraints{ make in\n            make.height.equalToSuperview()\n        }\n    }\n}\n\nfinal private class DotNetTextField: NSLoadView {\n    let textField = CustomFocusRingTextField()\n    let backgroundLayer = ControlErrorBackgroundLayer.animationDisabled()\n    var isError = false { didSet { needsDisplay = true } }\n    \n    override func layout() {\n        self.backgroundLayer.frame = bounds\n        let textFieldFrame = CGRect(originX: 8, centerY: bounds.midY, size: [bounds.width - 16, textField.intrinsicContentSize.height])\n        \n        let focusRingBounds = CGRect(origin: bounds.origin - textFieldFrame.origin, size: bounds.size)\n        self.textField.focusRingBounds = focusRingBounds\n        self.textField.frame = textFieldFrame\n        super.layout()\n    }\n    \n    \n    override func updateLayer() {\n        self.backgroundLayer.update(isError: isError)\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroundLayer)\n        \n        self.addSubview(textField)\n        self.textField.font = .systemFont(ofSize: 12)\n    }\n}\n\nfinal class CustomFocusRingTextField: NSLoadTextField {\n    var focusRingBounds: CGRect = .zero {\n        didSet { self.noteFocusRingMaskChanged() }\n    }\n    \n    override func drawFocusRingMask() { focusRingPath().fill() }\n    override var focusRingMaskBounds: NSRect { focusRingBounds }\n    \n    public override func mouseDown(with event: NSEvent) {\n        self.selectText(nil)\n    }\n    \n    private func focusRingPath() -> NSBezierPath {\n        NSBezierPath(roundedRect: focusRingBounds, xRadius: R.Size.corner, yRadius: R.Size.corner)\n    }\n    \n    override func onAwake() {\n        self.isBezeled = false\n        self.isBordered = false\n        self.bezelStyle = .roundedBezel\n        self.drawsBackground = false\n        self.backgroundColor = nil\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Component/TextFieldSection.swift",
    "content": "//\n//  TextFieldSection.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nstruct TextFieldSectionOptions: OptionSet {\n    let rawValue: UInt64\n}\n\nfinal class TextFieldSection: Section {\n    var string: String {\n        get { textField.string } set { textField.string = newValue; copyButton.stringContent = newValue }\n    }\n    var stringPublisher: AnyPublisher<String, Never> {\n        textField.changeStringPublisher.merge(with: self.pasteButton.stringPublisher.map{ $0 ?? \"\" }).eraseToAnyPublisher()\n    }\n    \n    convenience init(title: String, isEditable: Bool) {\n        self.init(title: title)\n        self.textField.isEditable = isEditable\n        if !isEditable {\n            self.textField.showCopyButton = true\n            self.minTitle = true\n            self.removeAllToolbarItem()\n        }\n    }\n    \n    let textField = TextField(showCopyButton: false)\n    private let pasteButton = PasteSectionButton()\n    private let copyButton = CopySectionButton(hasTitle: false)\n    \n    override func onAwake() {\n        super.onAwake()\n        self.addStackItem(textField)\n        self.addToolbarItem(pasteButton)\n        self.addToolbarItem(copyButton)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/TextView.swift",
    "content": "//\n//  TextView.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/03.\n//\n\nimport CoreUtil\n\nfinal class TextView: NSLoadView {\n    class _TextView: NSTextView {\n        let stringPublisher = PassthroughSubject<String, Never>()\n        var sendingValue = false\n        override var string: String {\n            get { super.string } set { if !sendingValue { super.string = newValue } }\n        }\n        override func didChangeText() {\n            self.sendingValue = true\n            stringPublisher.send(string)\n            self.sendingValue = false\n        }\n    }\n    \n    var string: String { get { textView.string } set { textView.string = newValue } }\n    var stringPublisher: AnyPublisher<String, Never> { textView.stringPublisher.eraseToAnyPublisher() }\n    \n    var isEditable: Bool { get { textView.isEditable } set { textView.isEditable = newValue } }\n    override var isSelectable: Bool { get { textView.isSelectable } set { textView.isSelectable = newValue } }\n    \n    override func layout() {\n        super.layout()\n        self.backgroudLayer.frame = bounds\n    }\n    \n    override func updateLayer() {\n        self.backgroudLayer.update()\n    }\n    \n    func becomeFocused() {\n        self.window?.makeFirstResponder(self.textView)\n    }\n    \n    private let scrollView = _TextView.scrollableTextView()\n    private let backgroudLayer = ControlBackgroundLayer.animationDisabled()\n    lazy var textView = scrollView.documentView as! _TextView\n\n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(backgroudLayer)\n        \n        self.addSubview(scrollView)\n        self.textView.usesFindBar = true\n        self.textView.allowsUndo = true\n        self.textView.isAutomaticSpellingCorrectionEnabled = false\n        self.textView.isAutomaticQuoteSubstitutionEnabled = false\n        self.textView.isAutomaticDashSubstitutionEnabled = false\n        self.textView.isAutomaticLinkDetectionEnabled = false\n        self.textView.font = .monospacedSystemFont(ofSize: R.Size.codeFontSize, weight: .regular)\n        self.textView.drawsBackground = false\n        self.textView.textContainerInset = [0, 4]\n        self.scrollView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Component/TextViewSection.swift",
    "content": "//\n//  TextViewSection.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/01.\n//\n\nimport CoreUtil\n\nstruct TextSectionOptions: OptionSet {\n    let rawValue: UInt64\n    \n    static let inputable = TextSectionOptions(rawValue: 1 << 0)\n    static let clearable = TextSectionOptions(rawValue: 1 << 1)\n    static let pastable = TextSectionOptions(rawValue: 1 << 2)\n    static let fileImportable = TextSectionOptions(rawValue: 1 << 3)\n    static let outputable = TextSectionOptions(rawValue: 1 << 4)\n    static let copyable = TextSectionOptions(rawValue: 1 << 5)\n    static let searchable = TextSectionOptions(rawValue: 1 << 6)\n    \n    static let defaultInput = TextSectionOptions([.inputable, .clearable, .pastable, .fileImportable, .outputable, .searchable])\n    static let defaultOutput = TextSectionOptions([.outputable, .copyable, .searchable])\n}\n\nprotocol TextViewType: NSView {\n    var string: String { get set }\n    var stringPublisher: AnyPublisher<String, Never> { get }\n    \n    var isEditable: Bool { get set }\n    var isSelectable: Bool { get set }\n    \n    func becomeFocused() \n}\n\nextension TextView: TextViewType {}\nextension CodeTextView: TextViewType {}\n\nfinal class TextViewSection: TextViewSectionBase<TextView> {}\nfinal class CodeViewSection: TextViewSectionBase<CodeTextView> {\n    var language: CodeTextView.Language = .json { didSet { textView.language = language } }\n    \n    convenience init(title: String, options: TextSectionOptions, language: CodeTextView.Language) {\n        self.init(title: title, options: options)\n        self.setup(language: language)\n    }\n    private func setup(language: CodeTextView.Language) {\n        self.language = language\n    }\n}\n\nclass TextViewSectionBase<TextView: TextViewType>: Section {\n    \n    var string = \"\" {\n        didSet {\n            self.textView.string = string\n            self.copyButton.stringContent = string\n        }\n    }\n    var stringPublisher: AnyPublisher<String, Never> {\n        textView.stringPublisher.merge(with: pasteButton.stringPublisher.map{ $0 ?? \"\" }.merge(with: clearButton.actionPublisher.map{ \"\" }, openButton.fileStringPublisher))\n            .eraseToAnyPublisher()\n    }\n    \n    var textSectionOptions = TextSectionOptions.defaultInput { didSet { updateToolbar() } }\n    \n    let textView = TextView()\n    \n    convenience init(title: String, options: TextSectionOptions) {\n        self.init()\n        self.title = title\n        self.setup(options: options)\n    }\n    \n    private func setup(options: TextSectionOptions) {\n        self.textSectionOptions = options\n    }\n    \n    private lazy var pasteButton = PasteSectionButton()\n    private lazy var openButton = OpenSectionButton()\n    private lazy var clearButton = SectionButton(image: R.Image.clear)\n    private lazy var copyButton = CopySectionButton()\n    private lazy var searchButton = SearchSectionButton() => {\n        $0.textView = textView\n    }\n    \n    private func updateToolbar() {\n        self.textView.isEditable = textSectionOptions.contains(.inputable)\n        self.textView.isSelectable = textSectionOptions.contains(.outputable)\n        \n        self.removeAllToolbarItem()\n        \n        if self.textSectionOptions.contains(.pastable) {\n            self.addToolbarItem(pasteButton)\n        }\n        if self.textSectionOptions.contains(.copyable) {\n            self.addToolbarItem(copyButton)\n        }\n        if self.textSectionOptions.contains(.fileImportable) {\n            self.addToolbarItem(openButton)\n        }\n        if self.textSectionOptions.contains(.searchable) {\n            self.addToolbarItem(searchButton)\n        }\n    }\n    \n    override func onAwake() {\n        super.onAwake()\n        self.updateToolbar()\n        \n        self.addStackItem(textView)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Component/Toast.swift",
    "content": "//\n//  ACToast.swift\n//  AxComponents\n//\n//  Created by yuki on 2021/09/13.\n//  Copyright © 2021 yuki. All rights reserved.\n//\n\nimport Cocoa\nimport CoreUtil\nimport DequeModule\nimport UserNotifications\n\nfinal public class Toast {\n    public var message: String {\n        get { toastWindow.toastView.message } set { toastWindow.toastView.message = newValue }\n    }\n    public var action: Action? {\n        get { toastWindow.toastView.action } set { toastWindow.toastView.action = newValue }\n    }\n    public var color: NSColor? {\n        get { toastWindow.toastView.color } set { toastWindow.toastView.color = newValue }\n    }\n    public var closeHandler: () -> () = {}\n    \n    public func addAttributeView(_ view: NSView, position: AttributeViewPosition) {\n        toastWindow.toastView.addAttributeView(view, position: position)\n    }\n    \n    public enum AttributeViewPosition {\n        case left\n        case right\n    }\n    \n    private let toastWindow = ToastWindow()\n    \n    static var showingToast: Toast?\n    static var pendingToasts = Deque<Toast>()\n    \n    public convenience init(message: String, action: Action? = nil, color: NSColor? = nil) {\n        self.init()\n        self.message = message\n        self.action = action\n        self.color = color\n    }\n    \n    public func show(with duration: TimeInterval = 2) {\n        self.show{ handler in\n            DispatchQueue.main.asyncAfter(deadline: .now()+duration) {\n                handler()\n            }\n        }\n    }\n    public func show(with closeHandler: (@escaping () -> ()) -> ()) {\n        if Toast.showingToast != nil {\n            Toast.pendingToasts.append(self)\n            return\n        }\n        \n        Toast.showingToast = self\n        self.toastWindow.show(with: closeHandler) {\n            self.closeHandler()\n            Toast.showingToast = nil\n            guard let nextToast = Toast.pendingToasts.popFirst() else { return }\n            nextToast.show()\n        }\n    }\n}\n\nextension Toast {\n    public static func show(message: String, action: Action? = nil, with duration: TimeInterval = 2) {\n        Toast(message: message, action: action).show(with: duration)\n    }\n    public static func debugLog(message: Any, action: Action? = nil, with duration: TimeInterval = 10) {\n        #if DEBUG\n        Toast(message: \"\\(message)\", action: action).show(with: duration)\n        #endif\n    }\n    public static func showError(message: String, error: Any) {\n        #if DEBUG\n        Toast(message: \"\\(error)\", action: nil, color: .systemRed).show(with: 20)\n        #else\n        Toast(message: message, action: nil, color: .systemRed).show(with: 2)\n        #endif\n    }\n}\n\nfinal private class ToastWindow: NSPanel {\n    let toastView = ToastView()\n    \n    func show(with closeHandler: (@escaping () -> ()) -> (), completion: @escaping () -> ()) {\n        guard let screen = NSScreen.main else { return NSSound.beep() }\n        \n        self.layoutIfNeeded()\n        let frame = CGRect(centerX: screen.frame.size.width / 2, originY: 120, size: self.frame.size)\n        self.setFrame(frame, display: true)\n        \n        self.level = .floating\n        self.appearance = NSAppearance(named: .darkAqua)\n        self.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary]\n        self.orderFrontRegardless()\n        \n        self.alphaValue = 0\n        self.animator().alphaValue = 1\n        \n        closeHandler {\n            self.animator().alphaValue = 0\n            \n            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {\n                self.close()\n                completion()\n            }\n        }\n    }\n    \n    init() {\n        super.init(contentRect: .zero, styleMask: [.nonactivatingPanel, .fullSizeContentView], backing: .buffered, defer: true)\n        self.contentView = toastView\n        self.hasShadow = false\n        self.backgroundColor = .clear\n    }\n}\n\nfinal private class ToastView: NSLoadView {\n    \n    var message: String {\n        get { textField.stringValue } set { textField.stringValue = newValue }\n    }\n    var action: Action? {\n        didSet { reloadAction() }\n    }\n    var color: NSColor? {\n        didSet { reloadColor() }\n    }\n    \n    func addAttributeView(_ view: NSView, position: Toast.AttributeViewPosition) {\n        switch position {\n        case .right: stackView.addArrangedSubview(view)\n        case .left: stackView.insertArrangedSubview(view, at: 0)\n        }\n    }\n    \n    private func reloadAction() {\n        actionButton.isHidden = action == nil\n        actionButton.title = action?.title ?? \"\"\n    }\n    \n    private func reloadColor() {\n        colorView.backgroundColor = color ?? .clear\n    }\n    \n    private let stackView = NSStackView()\n    private let textField = NSTextField(labelWithString: \"\")\n    private let backgroundView = NSVisualEffectView()\n    private let colorView = NSColorView()\n    private let actionButton = ToastButton(title: \"Search Google\")\n        \n    convenience init(message: String) {\n        self.init()\n        self.textField.stringValue = message\n    }\n    \n    @objc private func executeAction(_: Any) {\n        action?.action()\n    }\n    \n    override func onAwake() {\n        self.wantsLayer = true\n        self.layer?.cornerRadius = 10\n\n        self.snp.makeConstraints{ make in\n            make.width.lessThanOrEqualTo(420)\n        }\n        \n        self.addSubview(backgroundView)\n        self.backgroundView.state = .active\n        self.backgroundView.material = .sidebar\n        self.backgroundView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.addSubview(colorView)\n        self.colorView.alphaValue = 0.85\n        self.colorView.backgroundColor = .systemYellow\n        self.colorView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview()\n        }\n        \n        self.addSubview(stackView)\n        self.stackView.snp.makeConstraints{ make in\n            make.edges.equalToSuperview().inset(16)\n        }\n        \n        self.stackView.addArrangedSubview(textField)\n        self.textField.alignment = .center\n        self.textField.lineBreakMode = .byWordWrapping\n        self.textField.textColor = .white\n        \n        self.stackView.addArrangedSubview(actionButton)\n        self.actionButton.bezelStyle = .inline\n        self.actionButton.setTarget(self, action: #selector(executeAction))\n        \n        self.reloadAction()\n    }\n}\n\nfinal private class ToastButton: NSLoadButton {\n    override var intrinsicContentSize: NSSize {\n        super.intrinsicContentSize + [4, 4]\n    }\n    \n    override func draw(_ dirtyRect: NSRect) {\n        \n        if isHighlighted {\n            NSColor.black.withAlphaComponent(0.3).setFill()\n        } else {\n            NSColor.black.withAlphaComponent(0.2).setFill()\n        }\n        NSBezierPath(roundedRect: bounds, xRadius: bounds.height/2, yRadius: bounds.height/2).fill()\n        \n        let nsString = title as NSString\n        nsString.draw(center: bounds, attributes: [\n            NSAttributedString.Key.foregroundColor : NSColor.secondaryLabelColor,\n            NSAttributedString.Key.font : NSFont.systemFont(ofSize: NSFont.smallSystemFontSize, weight: .medium)\n        ])\n    }\n    \n    override func onAwake() {\n        self.bezelStyle = .inline\n    }\n}\n\nextension NSString {\n    public func draw(centerY rect: CGRect, attributes: [NSAttributedString.Key : Any]? = nil) {\n        let actualRect = self.boundingRect(with: rect.size, options: [.usesLineFragmentOrigin], attributes: attributes)\n        let originY = rect.minY + (rect.height - actualRect.height) / 2\n        let drawRect = CGRect(origin: [rect.minX, originY], size: actualRect.size)\n        \n        self.draw(with: drawRect, options: .usesLineFragmentOrigin, attributes: attributes)\n    }\n    public func drawRight(centerY rect: CGRect, attributes: [NSAttributedString.Key : Any]? = nil) {\n        let actualRect = self.boundingRect(with: rect.size, options: [.usesLineFragmentOrigin], attributes: attributes)\n        let originY = rect.minY + (rect.height - actualRect.height) / 2\n        var drawRect = CGRect(origin: [0, originY], size: actualRect.size)\n        drawRect.end.x = rect.end.x\n        \n        self.draw(with: drawRect, options: .usesLineFragmentOrigin, attributes: attributes)\n    }\n    \n    public func draw(center rect: CGRect, attributes: [NSAttributedString.Key : Any]? = nil) {\n        let actualRect = self.boundingRect(with: rect.size, options: [.usesLineFragmentOrigin], attributes: attributes)\n        let origin = (rect.size - actualRect.size).convertToPoint() / 2\n        let drawRect = CGRect(origin: origin, size: actualRect.size)\n        \n        self.draw(with: drawRect, options: .usesLineFragmentOrigin, attributes: attributes)\n    }\n}\n\nextension Promise {\n    public func peekProgressIndicator(_ message: String) -> Promise<Output, Failure> {\n        Toast.showProgressIndicator(message: message, self)\n        return self\n    }\n        \n    public func sinkWithToast(_ successMessage: @escaping (Output) -> String) where Failure == Never {\n        func neverhandler<T>(_ output: T) -> String { \"Never\" }\n        self.sinkWithToast(successMessage, neverhandler)\n    }\n    \n    public func sinkWithToast(_ successMessage: @escaping (Output) -> String, _ failureMessage: @escaping (Failure) -> String) {\n        let toast = Toast()\n        self\n            .receive(on: .main)\n            .sink({ output in\n                toast.color = nil\n                toast.message = successMessage(output)\n                toast.show()\n            }, { error in\n                toast.color = .systemRed\n                toast.message = failureMessage(error)\n                toast.show()\n            })\n    }\n}\n\nextension Toast {\n    fileprivate static func showProgressIndicator<T, F>(message: String, _ promise: Promise<T, F>) {\n        let toast = Toast(message: message)\n        let indicator = NSProgressIndicator()\n        indicator.style = .spinning\n        indicator.startAnimation(nil)\n        indicator.snp.makeConstraints{ make in\n            make.size.equalTo(16)\n        }\n        toast.addAttributeView(indicator, position: .right)\n        toast.show(with: { close in promise.receive(on: .main).finally { close() } })\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/DevToys.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.security.device.audio-input</key>\n\t<true/>\n\t<key>com.apple.security.device.camera</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "DevToys/DevToys/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>NSCameraUsageDescription</key>\n\t<string>Use camera</string>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>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>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>LSApplicationCategoryType</key>\n\t<string>public.app-category.developer-tools</string>\n\t<key>LSMinimumSystemVersion</key>\n\t<string>$(MACOSX_DEPLOYMENT_TARGET)</string>\n\t<key>NSMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>NSPrincipalClass</key>\n\t<string>NSApplication</string>\n\t<key>SUFeedURL</key>\n\t<string>https://obuchiyuki.github.io/DevToysMac/sparkle/appcast.xml</string>\n\t<key>SUPublicEDKey</key>\n\t<string>DOsNciodUTmm6TgsE6uTJtoYBAZqvCjSzztuz+7I+4w=</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "DevToys/DevToys/Model/AppModel.swift",
    "content": "//\n//  AppModel.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nextension NSViewController {\n    var appModel: AppModel! { chainObject as? AppModel }\n}\n\nfinal class AppModel {\n    @Observable var tool: Tool = .home { didSet { toolIdentifier = tool.identifier } }\n    @RestorableState(\"app.toolIdentifier\") var toolIdentifier = \"\"\n    @Observable var searchQuery = \"\"\n    \n    let toolManager = ToolManager.shared\n    let settings = Settings()\n    \n    init() {\n        self.tool = toolManager.toolForIdentifier(toolIdentifier) ?? .home\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Model/Settings.swift",
    "content": "//\n//  Settings.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/16.\n//\n\nimport CoreUtil\n\nfinal class Settings {\n    enum AppearanceType: String {\n        case useSystemSettings = \"Use system setting\"\n        case lightMode = \"Light mode\"\n        case darkMode = \"Dark mode\"\n    }\n     \n    @RestorableState(\"appearance\") var appearanceType: AppearanceType = .useSystemSettings\n}\n"
  },
  {
    "path": "DevToys/DevToys/Model/Tool+Default.swift",
    "content": "//\n//  Tool+Default.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/13.\n//\n\nimport CoreUtil\n\nextension Tool {\n    static let home = Tool(\n        title: \"tool.home.title\".localized(), identifier: \"home\", category: .home, icon: R.Image.Tool.home,\n        toolDescription: \"tool.home.description\".localized(), showAlways: true, showOnHome: false,\n        viewController: HomeViewController()\n    )\n    static let search = Tool(\n        title: \"Search\".localized(), identifier: \"search\", category: .home, icon: R.Image.Tool.home,\n        toolDescription: \"Search tools\".localized(), showAlways: false, showOnHome: false,\n        viewController: SearchViewController()\n    )\n    static let settings = Tool(\n        title: \"Settings\".localized(), identifier: \"settings\", category: .settings, icon: R.Image.Tool.settings,\n        toolDescription: \"Setting of application\".localized(), showAlways: true, showOnHome: true, showOnSidebar: false,\n        viewController: SettingViewController()\n    )\n    \n    // MARK: - Converters -\n    static let jsonYamlConverter = Tool(\n        title: \"tool.jsonyaml.title\".localized(), identifier: \"jsonyaml\", category: .converter, icon: R.Image.Tool.jsonConvert,\n        sidebarTitle: \"tool.jsonyaml.mintitle\".localized(), toolDescription: \"tool.jsonyaml.description\".localized(),\n        viewController: JSONYamlConverterViewController()\n    )\n    static let numberBaseConverter = Tool(\n        title: \"tool.numbase.title\".localized(), identifier: \"numbase\", category: .converter, icon: R.Image.Tool.numberBaseConvert,\n        sidebarTitle: \"tool.numbase.mintitle\".localized(), toolDescription: \"tool.numbase.description\".localized(),\n        viewController: NumberBaseConverterViewController()\n    )\n    static let dateConverter = Tool(\n        title: \"tool.date.title\".localized(), identifier: \"date.converter\", category: .converter, icon: R.Image.Tool.dateConvert,\n        sidebarTitle: \"tool.date.mintitle\".localized(), toolDescription: \"tool.date.description\".localized(),\n        viewController: DateConverterViewController()\n    )\n    \n    // MARK: - Encoder / Decoder -\n    static let htmlCoder = Tool(\n        title: \"tool.html.title\".localized(), identifier: \"html.converter\", category: .encoderDecoder, icon: R.Image.Tool.htmlCoder,\n        sidebarTitle: \"tool.html.mintitle\".localized(), toolDescription: \"tool.html.description\".localized(),\n        viewController: HTMLDecoderViewController()\n    )\n    static let urlCoder = Tool(\n        title: \"tool.url.title\".localized(), identifier: \"url.converter\", category: .encoderDecoder, icon: R.Image.Tool.urlCoder,\n        sidebarTitle: \"tool.url.mintitle\".localized(), toolDescription: \"tool.url.description\".localized(),\n        viewController: URLDecoderViewController()\n    )\n    static let base64Coder = Tool(\n        title: \"tool.base64.title\".localized(), identifier: \"base64.converter\", category: .encoderDecoder, icon: R.Image.Tool.base64Coder,\n        sidebarTitle: \"tool.base64.mintitle\".localized(), toolDescription: \"tool.base64.description\".localized(),\n        viewController: Base64DecoderViewController()\n    )\n    static let jwtCoder = Tool(\n        title: \"tool.jwt.title\".localized(), identifier: \"jwt.converter\", category: .encoderDecoder, icon: R.Image.Tool.jwtCoder,\n        sidebarTitle: \"tool.jwt.mintitle\".localized(), toolDescription: \"tool.jwt.description\".localized(),\n        viewController: JWTDecoderViewController()\n    )\n    \n    // MARK: - Formatter -\n    static let jsonFormatter = Tool(\n        title: \"tool.jsonformat.title\".localized(), identifier: \"json.formatter\", category: .formatter, icon: R.Image.Tool.jsonFormatter,\n        sidebarTitle: \"tool.jsonformat.mintitle\".localized(), toolDescription: \"tool.jsonformat.description\".localized(),\n        viewController: JSONFormatterViewController()\n    )\n    static let xmlFormatter = Tool(\n        title: \"tool.xmlformat.title\".localized(), identifier: \"xml.formatter\", category: .formatter, icon: R.Image.Tool.xmlFormatter,\n        sidebarTitle: \"tool.xmlformat.mintitle\".localized(), toolDescription: \"tool.xmlformat.description\".localized(),\n        viewController: XMLFormatterViewController()\n    )\n    static let sqlFormatter = Tool(\n        title: \"SQL Formatter\".localized(), identifier: \"sql.formatter\", category: .formatter, icon: R.Image.Tool.sqlFormatter,\n        sidebarTitle: \"SQL Formatter\".localized(), toolDescription: \"\".localized(),\n        viewController: SQLFormatterViewController()\n    )\n    \n    // MARK: - Generators -\n    static let hashGenerator = Tool(\n        title: \"tool.hashgen.title\".localized(), identifier: \"hash.generator\", category: .generator, icon: R.Image.Tool.hashGenerator,\n        sidebarTitle: \"tool.hashgen.mintitle\".localized(), toolDescription: \"tool.hashgen.description\".localized(),\n        viewController: HashGeneratorViewController()\n    )\n    static let uuidGenerator = Tool(\n        title: \"tool.uuidgen.title\".localized(), identifier: \"uuid.generator\", category: .generator, icon: R.Image.Tool.uuidGenerator,\n        sidebarTitle: \"tool.uuidgen.mintitle\".localized(), toolDescription: \"tool.uuidgen.description\".localized(),\n        viewController: UUIDGeneratorViewController()\n    )\n    static let loremIpsumGenerator = Tool(\n        title: \"tool.ligen.title\".localized(), identifier: \"loremIpsum.generator\", category: .generator, icon: R.Image.Tool.loremIpsumGenerator,\n        sidebarTitle: \"tool.ligen.mintitle\".localized(), toolDescription: \"tool.ligen.description\".localized(),\n        viewController: LoremIpsumGeneratorViewController()\n    )\n    static let checksumGenerator = Tool(\n        title: \"tool.checksum.title\".localized(), identifier: \"checksum.generator\", category: .generator, icon: R.Image.Tool.hashGenerator,\n        sidebarTitle: \"tool.checksum.mintitle\".localized(), toolDescription: \"tool.checksum.description\".localized(),\n        viewController: ChecksumGeneratorViewController()\n    )\n    static let qrGenerator = Tool(\n        title: \"QR Code Generator\".localized(), identifier: \"qrgenerator\", category: .generator, icon: R.Image.Tool.qrgenerator,\n        sidebarTitle: \"QR Code Generator\".localized(), toolDescription: \"Create a QR code from text\".localized(),\n        viewController: QRCodeGeneratorViewController()\n    )\n    \n    // MARK: - Text -\n    static let textInspector = Tool(\n        title: \"tool.textinspect.title\".localized(), identifier: \"textinspect\", category: .text, icon: R.Image.Tool.textInspector,\n        sidebarTitle: \"tool.textinspect.mintitle\".localized(), toolDescription: \"tool.textinspect.description\".localized(),\n        viewController: TextInspectorViewController()\n    )\n    static let regexTester = Tool(\n        title: \"tool.regex.title\".localized(), identifier: \"regex\", category: .text, icon: R.Image.Tool.regexTester,\n        sidebarTitle: \"tool.regex.mintitle\".localized(), toolDescription: \"tool.regex.description\".localized(),\n        viewController: RegexTesterViewController()\n    )\n    static let textDiff = Tool(\n        title: \"Text Diff\".localized(), identifier: \"textdiff\", category: .text, icon: R.Image.Tool.textInspector,\n        sidebarTitle: \"Text Diff\".localized(), toolDescription: \"Compare two Text and display Diff\".localized(),\n        viewController: TextDiffViewController()\n    )\n    static let hyphenationRemover = Tool(\n        title: \"tool.hyphenremove.title\".localized(), identifier: \"hyphenremove\", category: .text, icon: R.Image.Tool.textInspector,\n        sidebarTitle: \"tool.hyphenremove.mintitle\".localized(), toolDescription: \"tool.hyphenremove.description\".localized(),\n        viewController: HyphenationRemoverViewController()\n    )\n    static let jsonSearch = Tool(\n        title: \"JSON Search\".localized(), identifier: \"jsonsearch\", category: .text, icon: R.Image.Tool.jsonSearch,\n        sidebarTitle: \"JSON Search\".localized(), toolDescription: \"Extract data from JSON in several ways\".localized(),\n        viewController: JSONSearchViewController()\n    )\n    \n    \n    // MARK: - Graphic -\n    static let imageOptimizer = Tool(\n        title: \"tool.imageoptim.title\".localized(), identifier: \"imageoptim\", category: .graphic, icon: R.Image.Tool.imageCompressor,\n        sidebarTitle: \"tool.imageoptim.mintitle\".localized(), toolDescription: \"tool.imageoptim.description\".localized(),\n        viewController: ImageOptimizerViewController()\n    )\n    static let pdfGenerator = Tool(\n        title: \"tool.pdfgen.title\".localized(), identifier: \"pdfgen\", category: .graphic, icon: R.Image.Tool.pdfGenerator,\n        sidebarTitle: \"tool.pdfgen.mintitle\".localized(), toolDescription: \"tool.pdfgen.description\".localized(),\n        viewController: PDFGeneratorViewController()\n    )\n    static let imageConverter = Tool(\n        title: \"tool.imageconvert.title\".localized(), identifier: \"imageconvert\", category: .graphic, icon: R.Image.Tool.imageConverter,\n        sidebarTitle: \"tool.imageconvert.mintitle\".localized(), toolDescription: \"tool.imageconvert.description\".localized(),\n        viewController: ImageConverterViewController()\n    )\n    static let iconGenerator = Tool(\n        title: \"Icon Generator\".localized(), identifier: \"icongenerator\", category: .graphic, icon: R.Image.Tool.iconGenerator,\n        sidebarTitle: \"Icon Generator\".localized(), toolDescription: \"Create a Icon from image\".localized(),\n        viewController: IconGeneratorViewController()\n    )\n    static let qrReader = Tool(\n        title: \"QR Code Reader\".localized(), identifier: \"qrreader\", category: .graphic, icon: R.Image.Tool.iconGenerator,\n        sidebarTitle: \"QR Code Reader\".localized(), toolDescription: \"Read QR Code from image or device camera\".localized(),\n        viewController: QRCodeReaderViewController()\n    )\n    \n    \n    // MARK: - Media -\n    static let colorPicker = Tool(\n        title: \"Color Picker\".localized(), identifier: \"colorpicker\", category: .media, icon: R.Image.Tool.colorPicker,\n        sidebarTitle: \"Color Picker\".localized(), toolDescription: \"Picker the color and copy components\".localized(),\n        viewController: ColorPickerViewController()\n    )\n    static let audioConverter = Tool(\n        title: \"Audio Converter\".localized(), identifier: \"audioconverter\", category: .media, icon: R.Image.Tool.audioConverter,\n        sidebarTitle: \"Audio Converter\".localized(), toolDescription: \"Convert audio from one format to another\".localized(),\n        viewController: AudioConverterViewController()\n    )\n    static let gifConverter = Tool(\n        title: \"Gif Converter\".localized(), identifier: \"gifconverter\", category: .media, icon: R.Image.Tool.gif,\n        sidebarTitle: \"Gif Converter\".localized(), toolDescription: \"Convert a movie to an animated GIF file\".localized(),\n        viewController: GifConverterViewController()\n    )\n    \n}\n\nextension ToolManager {\n    static let shared = ToolManager() => { toolManager in\n        toolManager.registerTool(.home)\n\n        toolManager.registerTool(.jsonYamlConverter)\n        toolManager.registerTool(.numberBaseConverter)\n        toolManager.registerTool(.dateConverter)\n\n        toolManager.registerTool(.htmlCoder)\n        toolManager.registerTool(.urlCoder)\n        toolManager.registerTool(.base64Coder)\n        toolManager.registerTool(.jwtCoder)\n\n        toolManager.registerTool(.jsonFormatter)\n        toolManager.registerTool(.xmlFormatter)\n        toolManager.registerTool(.sqlFormatter)\n\n        toolManager.registerTool(.hashGenerator)\n        toolManager.registerTool(.uuidGenerator)\n        toolManager.registerTool(.loremIpsumGenerator)\n        toolManager.registerTool(.checksumGenerator)\n        toolManager.registerTool(.qrGenerator)\n\n        toolManager.registerTool(.textInspector)\n        toolManager.registerTool(.regexTester)\n        toolManager.registerTool(.textDiff)\n        toolManager.registerTool(.hyphenationRemover)\n\n        toolManager.registerTool(.imageOptimizer)\n        toolManager.registerTool(.pdfGenerator)\n        toolManager.registerTool(.imageConverter)\n        toolManager.registerTool(.iconGenerator)\n        toolManager.registerTool(.qrReader)\n        \n        toolManager.registerTool(.colorPicker)\n        toolManager.registerTool(.audioConverter)\n        toolManager.registerTool(.gifConverter)\n        \n        toolManager.registerTool(.settings)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Model/ToolCategory+Default.swift",
    "content": "//\n//  ToolCategory+Default.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/13.\n//\n\nextension ToolCategory {\n    static let home = ToolCategory(name: \"category.home\".localized(), icon: nil, identifier: \"home\", shouldHideCategory: true)\n    static let converter = ToolCategory(name: \"category.converters\".localized(), icon: R.Image.Tool.convert, identifier: \"converters\")\n    static let encoderDecoder = ToolCategory(name: \"category.encoders_decoders\".localized(), icon: R.Image.Tool.encoderDecoder, identifier: \"encoderDecoder\")\n    static let formatter = ToolCategory(name: \"category.formatters\".localized(), icon: R.Image.Tool.formatter, identifier: \"formatter\")\n    static let generator = ToolCategory(name: \"category.generators\".localized(), icon: R.Image.Tool.generator, identifier: \"generator\")\n    static let text = ToolCategory(name: \"category.text\".localized(), icon: R.Image.Tool.text, identifier: \"text\")\n    static let graphic = ToolCategory(name: \"category.graphic\".localized(), icon: R.Image.Tool.graphic, identifier: \"graphic\")\n    static let media = ToolCategory(name: \"Media\".localized(), icon: R.Image.Tool.media, identifier: \"media\")\n    static let settings = ToolCategory(name: \"Settings\".localized(), icon: nil, identifier: \"settings\", shouldHideCategory: true)\n}\n"
  },
  {
    "path": "DevToys/DevToys/Model/ToolManager+.swift",
    "content": "//\n//  ToolManager.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/12.\n//\n\nimport CoreUtil\nimport OrderedCollections\n\nfinal class ToolManager {\n    private var toolCategoryMap = [ToolCategory: [Tool]]()\n    private var toolIdentifierMap = [String: Tool]()\n    private var categoryIdentifierMap = [String: ToolCategory]()\n    private var categories = OrderedSet<ToolCategory>()\n    \n    func registerTool(_ tool: Tool) {\n        self.toolCategoryMap.arrayAppend(tool, forKey: tool.category)\n        if !categories.contains(tool.category) {\n            self.categories.append(tool.category)\n            self.categoryIdentifierMap[tool.category.identifier] = tool.category\n        }\n        \n        assert(toolIdentifierMap[tool.identifier] == nil, \"Tool with identifier '\\(tool.identifier)' has already been registered.\")\n        self.toolIdentifierMap[tool.identifier] = tool\n    }\n    \n    func allTools() -> [Tool] {\n        self.categories.compactMap{ toolCategoryMap[$0] }.reduce(into: [], +=)\n    }\n    func toolForIdentifier(_ identifier: String) -> Tool? {\n        self.toolIdentifierMap[identifier]\n    }\n    func categoryForIdentifier(_ identifier: String) -> ToolCategory? {\n        self.categoryIdentifierMap[identifier]\n    }\n    func toolsForCategory(_ category: ToolCategory) -> [Tool] {\n        self.toolCategoryMap[category] ?? []\n    }\n    func flattenRootItems() -> [Any] {\n        var items = [Any]()\n        for category in categories {\n            if category.shouldHideCategory {\n                items.append(contentsOf: toolsForCategory(category))\n            } else if !toolsForCategory(category).isEmpty {\n                items.append(category)\n            }\n        }\n        return items\n    }\n}\n\nfinal class ToolCategory: Hashable {\n    let name: String\n    let icon: NSImage?\n    let identifier: String\n    let shouldHideCategory: Bool\n    \n    static func == (lhs: ToolCategory, rhs: ToolCategory) -> Bool {\n        lhs.identifier == rhs.identifier\n    }\n    func hash(into hasher: inout Hasher) {\n        hasher.combine(identifier)\n    }\n    \n    init(name: String, icon: NSImage?, identifier: String, shouldHideCategory: Bool = false) {\n        self.name = name\n        self.icon = icon\n        self.identifier = identifier\n        self.shouldHideCategory = shouldHideCategory\n    }\n}\n\nfinal class Tool {\n    let title: String\n    let identifier: String\n    let category: ToolCategory\n    let icon: NSImage\n    let sidebarTitle: String\n    let toolDescription: String\n    let showAlways: Bool\n    let showOnHome: Bool\n    let showOnSidebar: Bool\n    private(set) lazy var viewController = makeViewController()\n    \n    private let makeViewController: () -> NSViewController\n    \n    init(title: String, identifier: String, category: ToolCategory, icon: NSImage, sidebarTitle: String? = nil, toolDescription: String, showAlways: Bool = false, showOnHome: Bool = true, showOnSidebar: Bool = true, viewController: @autoclosure @escaping () -> NSViewController) {\n        self.title = title\n        self.identifier = identifier\n        self.category = category\n        self.icon = icon\n        self.sidebarTitle = sidebarTitle ?? title\n        self.toolDescription = toolDescription\n        self.showAlways = showAlways\n        self.showOnHome = showOnHome\n        self.showOnSidebar = showOnSidebar\n        self.makeViewController = viewController\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"icon_16x16.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"16x16\"\n    },\n    {\n      \"filename\" : \"icon_16x16@2x.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"16x16\"\n    },\n    {\n      \"filename\" : \"icon_32x32.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"filename\" : \"icon_32x32@2x.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"filename\" : \"icon_128x128.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"icon_128x128@2x.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"icon_256x256.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"icon_256x256@2x.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"icon_512x512.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"512x512\"\n    },\n    {\n      \"filename\" : \"icon_512x512@2x.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"2x\",\n      \"size\" : \"512x512\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/applewatch.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"applewatch.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/carplay.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"carplay.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/check.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Artboard Copy 22.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/clear.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"clear.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/convert.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"convert.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/copy.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/drop.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"drop.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/error.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Artboard Copy 23.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/export.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"export.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/format.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"format.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/hyphen.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"hyphen.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/ipad.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"ipad.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/ipaddress.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"ipaddress.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/iphone.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"iphone.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/mac.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"mac.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/network.status.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"network.status.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/number.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 5.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/open.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"open.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/paramators.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"paramators.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/paste.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"paste.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/pulldown.indicator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 26.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/search.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 25.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/settings.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"settings.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/sidebar.disclosure.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 23.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/spacing.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"number.base.convert copy 2.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/speed.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"speed.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/spuit.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"spuit.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/stepper.down.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Artboard Copy 2.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/stepper.up.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Artboard.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/text.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"provides-namespace\" : true\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/api.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 11.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/audio.convert.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"audio.convert.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/base64.coder.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"base64.coder copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/color.blindness.simulator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"color.blindness.simulator copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/color.picker.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"color.picker.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/convert.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"convert copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/date.convert.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 13.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/encoder.decoder.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"encoder.decoder copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/formatter.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"formatter copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/generator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"generator copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/gif.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"gif.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/graphic.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"graphic copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/hash.generator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"hash.generator copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/home.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"home copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/html.coder.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"html.coder copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/icon.generator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"icon.generator.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/image.compressor.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"image.compressor copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/image.converter.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"image.converter.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/json.convert.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"json.convert copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/json.formatter.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"json.formatter copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/json.search.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"json.search.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/jwt.coder.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"jwt copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/lorem.ipsum.generator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"lorem.ipsum.generator copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/markdown.preview.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Artboard Copy 21.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/media.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"media.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/network.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"network.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/number.base.convert.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"number.base.convert copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/pdf.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy 15.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/qr.generator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"qr.generator.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/regex.tester.imageset/Contents.json",
    "content": "{\n  \"images\": [\n    {\n      \"filename\": \"regex.tester copy.pdf\",\n      \"idiom\": \"universal\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"idiom\": \"universal\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"idiom\": \"universal\",\n      \"scale\": \"3x\"\n    }\n  ],\n  \"info\": {\n    \"author\": \"xcode\",\n    \"version\": 1\n  },\n  \"properties\": {\n    \"template-rendering-intent\": \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/settings.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"settings.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/sql.formatter.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"sql.formatter.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/text.diff.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text.diff copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/text.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"text copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/text.inspector.imageset/Contents.json",
    "content": "{\n  \"images\": [\n    {\n      \"filename\": \"text.inspector copy.pdf\",\n      \"idiom\": \"universal\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"idiom\": \"universal\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"idiom\": \"universal\",\n      \"scale\": \"3x\"\n    }\n  ],\n  \"info\": {\n    \"author\": \"xcode\",\n    \"version\": 1\n  },\n  \"properties\": {\n    \"template-rendering-intent\": \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/url.coder.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"url.coder copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/uuid.generator.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"uuid.generator copy.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/tool/xml.formatter.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"xml.format.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Assets.xcassets/transparent_background.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Group.pdf\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"19529\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" initialViewController=\"B8D-0N-5wS\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"19529\"/>\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=\"DevToys\" id=\"1Xt-HY-uBw\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"DevToys\" systemMenu=\"apple\" id=\"uQy-DD-JDr\">\n                                    <items>\n                                        <menuItem title=\"About DevToys\" id=\"5kV-Vb-QxS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"orderFrontStandardAboutPanel:\" target=\"Ady-hI-5gd\" id=\"Exp-CZ-Vem\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"VOq-y0-SEH\"/>\n                                        <menuItem title=\"Preferences…\" keyEquivalent=\",\" id=\"BOF-NM-1cW\"/>\n                                        <menuItem title=\"Check for Updates...\" id=\"jEz-vy-qLV\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"checkForUpdates:\" target=\"l6n-Pd-XZ6\" id=\"c9W-68-oCg\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"wFC-TO-SCJ\"/>\n                                        <menuItem title=\"Services\" id=\"NMo-om-nkz\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Services\" systemMenu=\"services\" id=\"hz9-B4-Xy5\"/>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"4je-JR-u6R\"/>\n                                        <menuItem title=\"Hide DevToys\" 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 DevToys\" keyEquivalent=\"q\" id=\"4sb-4s-VLi\">\n                                            <connections>\n                                                <action selector=\"terminate:\" target=\"Ady-hI-5gd\" id=\"Te7-pn-YzF\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"File\" id=\"dMs-cI-mzQ\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"File\" id=\"bib-Uj-vzu\">\n                                    <items>\n                                        <menuItem title=\"New\" keyEquivalent=\"n\" id=\"Was-JA-tGl\">\n                                            <connections>\n                                                <action selector=\"newDocument:\" target=\"Ady-hI-5gd\" id=\"4Si-XN-c54\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Open…\" keyEquivalent=\"o\" id=\"IAo-SY-fd9\">\n                                            <connections>\n                                                <action selector=\"openDocument:\" target=\"Ady-hI-5gd\" id=\"bVn-NM-KNZ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Open Recent\" id=\"tXI-mr-wws\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Open Recent\" systemMenu=\"recentDocuments\" id=\"oas-Oc-fiZ\">\n                                                <items>\n                                                    <menuItem title=\"Clear Menu\" id=\"vNY-rz-j42\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"clearRecentDocuments:\" target=\"Ady-hI-5gd\" id=\"Daa-9d-B3U\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"m54-Is-iLE\"/>\n                                        <menuItem title=\"Close\" keyEquivalent=\"w\" id=\"DVo-aG-piG\">\n                                            <connections>\n                                                <action selector=\"performClose:\" target=\"Ady-hI-5gd\" id=\"HmO-Ls-i7Q\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Save…\" keyEquivalent=\"s\" id=\"pxx-59-PXV\">\n                                            <connections>\n                                                <action selector=\"saveDocument:\" target=\"Ady-hI-5gd\" id=\"teZ-XB-qJY\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Save As…\" keyEquivalent=\"S\" id=\"Bw7-FT-i3A\">\n                                            <connections>\n                                                <action selector=\"saveDocumentAs:\" target=\"Ady-hI-5gd\" id=\"mDf-zr-I0C\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Revert to Saved\" keyEquivalent=\"r\" id=\"KaW-ft-85H\">\n                                            <connections>\n                                                <action selector=\"revertDocumentToSaved:\" target=\"Ady-hI-5gd\" id=\"iJ3-Pv-kwq\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"aJh-i4-bef\"/>\n                                        <menuItem title=\"Page Setup…\" keyEquivalent=\"P\" id=\"qIS-W8-SiK\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" shift=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"runPageLayout:\" target=\"Ady-hI-5gd\" id=\"Din-rz-gC5\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Print…\" keyEquivalent=\"p\" id=\"aTl-1u-JFS\">\n                                            <connections>\n                                                <action selector=\"print:\" target=\"Ady-hI-5gd\" id=\"qaZ-4w-aoO\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Edit\" tag=\"1001\" id=\"5QF-Oa-p0T\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Edit\" id=\"W48-6f-4Dl\">\n                                    <items>\n                                        <menuItem title=\"Undo\" keyEquivalent=\"z\" id=\"dRJ-4n-Yzg\">\n                                            <connections>\n                                                <action selector=\"undo:\" target=\"Ady-hI-5gd\" id=\"M6e-cu-g7V\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Redo\" keyEquivalent=\"Z\" id=\"6dh-zS-Vam\">\n                                            <connections>\n                                                <action selector=\"redo:\" target=\"Ady-hI-5gd\" id=\"oIA-Rs-6OD\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"WRV-NI-Exz\"/>\n                                        <menuItem title=\"Cut\" keyEquivalent=\"x\" id=\"uRl-iY-unG\">\n                                            <connections>\n                                                <action selector=\"cut:\" target=\"Ady-hI-5gd\" id=\"YJe-68-I9s\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Copy\" keyEquivalent=\"c\" id=\"x3v-GG-iWU\">\n                                            <connections>\n                                                <action selector=\"copy:\" target=\"Ady-hI-5gd\" id=\"G1f-GL-Joy\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste\" keyEquivalent=\"v\" id=\"gVA-U4-sdL\">\n                                            <connections>\n                                                <action selector=\"paste:\" target=\"Ady-hI-5gd\" id=\"UvS-8e-Qdg\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste and Match Style\" keyEquivalent=\"V\" id=\"WeT-3V-zwk\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"pasteAsPlainText:\" target=\"Ady-hI-5gd\" id=\"cEh-KX-wJQ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Delete\" id=\"pa3-QI-u2k\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"delete:\" target=\"Ady-hI-5gd\" id=\"0Mk-Ml-PaM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Select All\" keyEquivalent=\"a\" id=\"Ruw-6m-B2m\">\n                                            <connections>\n                                                <action selector=\"selectAll:\" target=\"Ady-hI-5gd\" id=\"VNm-Mi-diN\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"uyl-h8-XO2\"/>\n                                        <menuItem title=\"Find\" tag=\"1002\" id=\"4EN-yA-p0u\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Find\" id=\"1b7-l0-nxx\">\n                                                <items>\n                                                    <menuItem title=\"Find…\" tag=\"1\" keyEquivalent=\"f\" id=\"Xz5-n4-O0W\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"cD7-Qs-BN4\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find and Replace…\" tag=\"12\" keyEquivalent=\"f\" id=\"YEy-JH-Tfz\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"WD3-Gg-5AJ\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find Next\" tag=\"2\" keyEquivalent=\"g\" id=\"q09-fT-Sye\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"NDo-RZ-v9R\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find Previous\" tag=\"3\" keyEquivalent=\"G\" id=\"OwM-mh-QMV\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"HOh-sY-3ay\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Use Selection for Find\" tag=\"7\" keyEquivalent=\"e\" id=\"buJ-ug-pKt\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"U76-nv-p5D\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Jump to Selection\" keyEquivalent=\"j\" id=\"S0p-oC-mLd\">\n                                                        <connections>\n                                                            <action selector=\"centerSelectionInVisibleArea:\" target=\"Ady-hI-5gd\" id=\"IOG-6D-g5B\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Spelling and Grammar\" id=\"Dv1-io-Yv7\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Spelling\" id=\"3IN-sU-3Bg\">\n                                                <items>\n                                                    <menuItem title=\"Show Spelling and Grammar\" keyEquivalent=\":\" id=\"HFo-cy-zxI\">\n                                                        <connections>\n                                                            <action selector=\"showGuessPanel:\" target=\"Ady-hI-5gd\" id=\"vFj-Ks-hy3\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Check Document Now\" keyEquivalent=\";\" id=\"hz2-CU-CR7\">\n                                                        <connections>\n                                                            <action selector=\"checkSpelling:\" target=\"Ady-hI-5gd\" id=\"fz7-VC-reM\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"bNw-od-mp5\"/>\n                                                    <menuItem title=\"Check Spelling While Typing\" id=\"rbD-Rh-wIN\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleContinuousSpellChecking:\" target=\"Ady-hI-5gd\" id=\"7w6-Qz-0kB\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Check Grammar With Spelling\" id=\"mK6-2p-4JG\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleGrammarChecking:\" target=\"Ady-hI-5gd\" id=\"muD-Qn-j4w\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Correct Spelling Automatically\" id=\"78Y-hA-62v\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticSpellingCorrection:\" target=\"Ady-hI-5gd\" id=\"2lM-Qi-WAP\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Substitutions\" id=\"9ic-FL-obx\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Substitutions\" id=\"FeM-D8-WVr\">\n                                                <items>\n                                                    <menuItem title=\"Show Substitutions\" id=\"z6F-FW-3nz\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"orderFrontSubstitutionsPanel:\" target=\"Ady-hI-5gd\" id=\"oku-mr-iSq\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"gPx-C9-uUO\"/>\n                                                    <menuItem title=\"Smart Copy/Paste\" id=\"9yt-4B-nSM\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleSmartInsertDelete:\" target=\"Ady-hI-5gd\" id=\"3IJ-Se-DZD\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Quotes\" id=\"hQb-2v-fYv\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticQuoteSubstitution:\" target=\"Ady-hI-5gd\" id=\"ptq-xd-QOA\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Dashes\" id=\"rgM-f4-ycn\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticDashSubstitution:\" target=\"Ady-hI-5gd\" id=\"oCt-pO-9gS\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Links\" id=\"cwL-P1-jid\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticLinkDetection:\" target=\"Ady-hI-5gd\" id=\"Gip-E3-Fov\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Data Detectors\" id=\"tRr-pd-1PS\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticDataDetection:\" target=\"Ady-hI-5gd\" id=\"R1I-Nq-Kbl\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Text Replacement\" id=\"HFQ-gK-NFA\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticTextReplacement:\" target=\"Ady-hI-5gd\" id=\"DvP-Fe-Py6\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Transformations\" id=\"2oI-Rn-ZJC\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Transformations\" id=\"c8a-y6-VQd\">\n                                                <items>\n                                                    <menuItem title=\"Make Upper Case\" id=\"vmV-6d-7jI\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"uppercaseWord:\" target=\"Ady-hI-5gd\" id=\"sPh-Tk-edu\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Make Lower Case\" id=\"d9M-CD-aMd\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"lowercaseWord:\" target=\"Ady-hI-5gd\" id=\"iUZ-b5-hil\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Capitalize\" id=\"UEZ-Bs-lqG\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"capitalizeWord:\" target=\"Ady-hI-5gd\" id=\"26H-TL-nsh\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Speech\" id=\"xrE-MZ-jX0\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Speech\" id=\"3rS-ZA-NoH\">\n                                                <items>\n                                                    <menuItem title=\"Start Speaking\" id=\"Ynk-f8-cLZ\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"startSpeaking:\" target=\"Ady-hI-5gd\" id=\"654-Ng-kyl\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Stop Speaking\" id=\"Oyz-dy-DGm\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"stopSpeaking:\" target=\"Ady-hI-5gd\" id=\"dX8-6p-jy9\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Format\" id=\"jxT-CU-nIS\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Format\" id=\"GEO-Iw-cKr\">\n                                    <items>\n                                        <menuItem title=\"Font\" id=\"Gi5-1S-RQB\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Font\" systemMenu=\"font\" id=\"aXa-aM-Jaq\">\n                                                <items>\n                                                    <menuItem title=\"Show Fonts\" keyEquivalent=\"t\" id=\"Q5e-8K-NDq\">\n                                                        <connections>\n                                                            <action selector=\"orderFrontFontPanel:\" target=\"YLy-65-1bz\" id=\"WHr-nq-2xA\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Bold\" tag=\"2\" keyEquivalent=\"b\" id=\"GB9-OM-e27\">\n                                                        <connections>\n                                                            <action selector=\"addFontTrait:\" target=\"YLy-65-1bz\" id=\"hqk-hr-sYV\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Italic\" tag=\"1\" keyEquivalent=\"i\" id=\"Vjx-xi-njq\">\n                                                        <connections>\n                                                            <action selector=\"addFontTrait:\" target=\"YLy-65-1bz\" id=\"IHV-OB-c03\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Underline\" keyEquivalent=\"u\" id=\"WRG-CD-K1S\">\n                                                        <connections>\n                                                            <action selector=\"underline:\" target=\"Ady-hI-5gd\" id=\"FYS-2b-JAY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"5gT-KC-WSO\"/>\n                                                    <menuItem title=\"Bigger\" tag=\"3\" keyEquivalent=\"+\" id=\"Ptp-SP-VEL\">\n                                                        <connections>\n                                                            <action selector=\"modifyFont:\" target=\"YLy-65-1bz\" id=\"Uc7-di-UnL\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smaller\" tag=\"4\" keyEquivalent=\"-\" id=\"i1d-Er-qST\">\n                                                        <connections>\n                                                            <action selector=\"modifyFont:\" target=\"YLy-65-1bz\" id=\"HcX-Lf-eNd\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"kx3-Dk-x3B\"/>\n                                                    <menuItem title=\"Kern\" id=\"jBQ-r6-VK2\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Kern\" id=\"tlD-Oa-oAM\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"GUa-eO-cwY\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useStandardKerning:\" target=\"Ady-hI-5gd\" id=\"6dk-9l-Ckg\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use None\" id=\"cDB-IK-hbR\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"turnOffKerning:\" target=\"Ady-hI-5gd\" id=\"U8a-gz-Maa\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Tighten\" id=\"46P-cB-AYj\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"tightenKerning:\" target=\"Ady-hI-5gd\" id=\"hr7-Nz-8ro\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Loosen\" id=\"ogc-rX-tC1\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"loosenKerning:\" target=\"Ady-hI-5gd\" id=\"8i4-f9-FKE\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem title=\"Ligatures\" id=\"o6e-r0-MWq\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Ligatures\" id=\"w0m-vy-SC9\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"agt-UL-0e3\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useStandardLigatures:\" target=\"Ady-hI-5gd\" id=\"7uR-wd-Dx6\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use None\" id=\"J7y-lM-qPV\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"turnOffLigatures:\" target=\"Ady-hI-5gd\" id=\"iX2-gA-Ilz\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use All\" id=\"xQD-1f-W4t\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useAllLigatures:\" target=\"Ady-hI-5gd\" id=\"KcB-kA-TuK\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem title=\"Baseline\" id=\"OaQ-X3-Vso\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Baseline\" id=\"ijk-EB-dga\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"3Om-Ey-2VK\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"unscript:\" target=\"Ady-hI-5gd\" id=\"0vZ-95-Ywn\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Superscript\" id=\"Rqc-34-cIF\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"superscript:\" target=\"Ady-hI-5gd\" id=\"3qV-fo-wpU\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Subscript\" id=\"I0S-gh-46l\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"subscript:\" target=\"Ady-hI-5gd\" id=\"Q6W-4W-IGz\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Raise\" id=\"2h7-ER-AoG\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"raiseBaseline:\" target=\"Ady-hI-5gd\" id=\"4sk-31-7Q9\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Lower\" id=\"1tx-W0-xDw\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"lowerBaseline:\" target=\"Ady-hI-5gd\" id=\"OF1-bc-KW4\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"Ndw-q3-faq\"/>\n                                                    <menuItem title=\"Show Colors\" keyEquivalent=\"C\" id=\"bgn-CT-cEk\">\n                                                        <connections>\n                                                            <action selector=\"orderFrontColorPanel:\" target=\"Ady-hI-5gd\" id=\"mSX-Xz-DV3\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"iMs-zA-UFJ\"/>\n                                                    <menuItem title=\"Copy Style\" keyEquivalent=\"c\" id=\"5Vv-lz-BsD\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"copyFont:\" target=\"Ady-hI-5gd\" id=\"GJO-xA-L4q\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Paste Style\" keyEquivalent=\"v\" id=\"vKC-jM-MkH\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"pasteFont:\" target=\"Ady-hI-5gd\" id=\"JfD-CL-leO\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Text\" id=\"Fal-I4-PZk\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Text\" id=\"d9c-me-L2H\">\n                                                <items>\n                                                    <menuItem title=\"Align Left\" keyEquivalent=\"{\" id=\"ZM1-6Q-yy1\">\n                                                        <connections>\n                                                            <action selector=\"alignLeft:\" target=\"Ady-hI-5gd\" id=\"zUv-R1-uAa\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Center\" keyEquivalent=\"|\" id=\"VIY-Ag-zcb\">\n                                                        <connections>\n                                                            <action selector=\"alignCenter:\" target=\"Ady-hI-5gd\" id=\"spX-mk-kcS\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Justify\" id=\"J5U-5w-g23\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"alignJustified:\" target=\"Ady-hI-5gd\" id=\"ljL-7U-jND\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Align Right\" keyEquivalent=\"}\" id=\"wb2-vD-lq4\">\n                                                        <connections>\n                                                            <action selector=\"alignRight:\" target=\"Ady-hI-5gd\" id=\"r48-bG-YeY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"4s2-GY-VfK\"/>\n                                                    <menuItem title=\"Writing Direction\" id=\"H1b-Si-o9J\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Writing Direction\" id=\"8mr-sm-Yjd\">\n                                                            <items>\n                                                                <menuItem title=\"Paragraph\" enabled=\"NO\" id=\"ZvO-Gk-QUH\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                </menuItem>\n                                                                <menuItem id=\"YGs-j5-SAR\">\n                                                                    <string key=\"title\">\tDefault</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionNatural:\" target=\"Ady-hI-5gd\" id=\"qtV-5e-UBP\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"Lbh-J2-qVU\">\n                                                                    <string key=\"title\">\tLeft to Right</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionLeftToRight:\" target=\"Ady-hI-5gd\" id=\"S0X-9S-QSf\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"jFq-tB-4Kx\">\n                                                                    <string key=\"title\">\tRight to Left</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionRightToLeft:\" target=\"Ady-hI-5gd\" id=\"5fk-qB-AqJ\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem isSeparatorItem=\"YES\" id=\"swp-gr-a21\"/>\n                                                                <menuItem title=\"Selection\" enabled=\"NO\" id=\"cqv-fj-IhA\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                </menuItem>\n                                                                <menuItem id=\"Nop-cj-93Q\">\n                                                                    <string key=\"title\">\tDefault</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionNatural:\" target=\"Ady-hI-5gd\" id=\"lPI-Se-ZHp\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"BgM-ve-c93\">\n                                                                    <string key=\"title\">\tLeft to Right</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionLeftToRight:\" target=\"Ady-hI-5gd\" id=\"caW-Bv-w94\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"RB4-Sm-HuC\">\n                                                                    <string key=\"title\">\tRight to Left</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionRightToLeft:\" target=\"Ady-hI-5gd\" id=\"EXD-6r-ZUu\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"fKy-g9-1gm\"/>\n                                                    <menuItem title=\"Show Ruler\" id=\"vLm-3I-IUL\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleRuler:\" target=\"Ady-hI-5gd\" id=\"FOx-HJ-KwY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Copy Ruler\" keyEquivalent=\"c\" id=\"MkV-Pr-PK5\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"copyRuler:\" target=\"Ady-hI-5gd\" id=\"71i-fW-3W2\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Paste Ruler\" keyEquivalent=\"v\" id=\"LVM-kO-fVI\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"pasteRuler:\" target=\"Ady-hI-5gd\" id=\"cSh-wd-qM2\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"View\" id=\"H8h-7b-M4v\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"View\" id=\"HyV-fh-RgO\">\n                                    <items>\n                                        <menuItem title=\"Show Sidebar\" keyEquivalent=\"s\" id=\"kIP-vf-haE\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"toggleSidebar:\" target=\"Ady-hI-5gd\" id=\"iwa-gc-5KM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Enter Full Screen\" keyEquivalent=\"f\" id=\"4J7-dP-txa\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"toggleFullScreen:\" target=\"Ady-hI-5gd\" id=\"dU3-MA-1Rq\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Window\" id=\"aUF-d1-5bR\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Window\" systemMenu=\"window\" id=\"Td7-aD-5lo\">\n                                    <items>\n                                        <menuItem title=\"Minimize\" keyEquivalent=\"m\" id=\"OY7-WF-poV\">\n                                            <connections>\n                                                <action selector=\"performMiniaturize:\" target=\"Ady-hI-5gd\" id=\"VwT-WD-YPe\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Zoom\" id=\"R4o-n2-Eq4\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"performZoom:\" target=\"Ady-hI-5gd\" id=\"DIl-cC-cCs\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"eu3-7i-yIM\"/>\n                                        <menuItem title=\"Bring All to Front\" id=\"LE2-aR-0XJ\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"arrangeInFront:\" target=\"Ady-hI-5gd\" id=\"DRN-fu-gQh\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Help\" id=\"wpr-3q-Mcd\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Help\" systemMenu=\"help\" id=\"F2S-fz-NVQ\">\n                                    <items>\n                                        <menuItem title=\"DevToys Help\" keyEquivalent=\"?\" id=\"FKE-Sm-Kum\">\n                                            <connections>\n                                                <action selector=\"showHelp:\" target=\"Ady-hI-5gd\" id=\"y7X-2Q-9no\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                        </items>\n                    </menu>\n                    <connections>\n                        <outlet property=\"delegate\" destination=\"Voe-Tx-rLC\" id=\"PrD-fu-P6m\"/>\n                    </connections>\n                </application>\n                <customObject id=\"Voe-Tx-rLC\" customClass=\"AppDelegate\" customModule=\"DevToys\" customModuleProvider=\"target\"/>\n                <customObject id=\"YLy-65-1bz\" customClass=\"NSFontManager\"/>\n                <customObject id=\"l6n-Pd-XZ6\" customClass=\"SPUStandardUpdaterController\"/>\n                <customObject id=\"Ady-hI-5gd\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"118\" y=\"-218\"/>\n        </scene>\n        <!--Window Controller-->\n        <scene sceneID=\"R2V-B0-nI4\">\n            <objects>\n                <windowController id=\"B8D-0N-5wS\" customClass=\"AppWindowController\" customModule=\"DevToys\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <window key=\"window\" identifier=\"app\" title=\"DevToys\" allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" releasedWhenClosed=\"NO\" visibleAtLaunch=\"NO\" frameAutosaveName=\"devtoys.frame\" animationBehavior=\"default\" toolbarStyle=\"unified\" id=\"IQv-IB-iLA\">\n                        <windowStyleMask key=\"styleMask\" titled=\"YES\" closable=\"YES\" miniaturizable=\"YES\" resizable=\"YES\" fullSizeContentView=\"YES\"/>\n                        <windowPositionMask key=\"initialPositionMask\" leftStrut=\"YES\" rightStrut=\"YES\" topStrut=\"YES\" bottomStrut=\"YES\"/>\n                        <rect key=\"contentRect\" x=\"196\" y=\"240\" width=\"620\" height=\"540\"/>\n                        <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"1680\" height=\"1027\"/>\n                        <toolbar key=\"toolbar\" implicitIdentifier=\"713C7DDB-DDC8-443B-A41D-721120BB189C\" allowsUserCustomization=\"NO\" displayMode=\"iconOnly\" sizeMode=\"regular\" id=\"OVR-JY-Bvo\">\n                            <allowedToolbarItems>\n                                <toolbarItem implicitItemIdentifier=\"NSToolbarSpaceItem\" id=\"KFp-lV-ESO\"/>\n                                <toolbarItem implicitItemIdentifier=\"NSToolbarFlexibleSpaceItem\" id=\"ORy-LD-yBt\"/>\n                            </allowedToolbarItems>\n                            <defaultToolbarItems>\n                                <toolbarItem reference=\"ORy-LD-yBt\"/>\n                            </defaultToolbarItems>\n                        </toolbar>\n                        <connections>\n                            <outlet property=\"delegate\" destination=\"B8D-0N-5wS\" id=\"98r-iN-zZc\"/>\n                        </connections>\n                    </window>\n                    <connections>\n                        <segue destination=\"XfG-lQ-9wD\" kind=\"relationship\" relationship=\"window.shadowedContentViewController\" id=\"cq2-FE-JQM\"/>\n                    </connections>\n                </windowController>\n                <customObject id=\"Oky-zY-oP4\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"93\" y=\"185\"/>\n        </scene>\n        <!--App 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=\"AppViewController\" customModule=\"DevToys\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"m2S-Jp-Qdl\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"270\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </view>\n                </viewController>\n            </objects>\n            <point key=\"canvasLocation\" x=\"75\" y=\"727\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "DevToys/DevToys/Resource/R.swift",
    "content": "//\n//  R.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport Cocoa\n\nenum R {\n    enum Size {\n        static let corner: CGFloat = 5\n        \n        static let controlTitleFontSize: CGFloat = 12\n        static let controlFontSize: CGFloat = 10.5\n        static let codeFontSize: CGFloat = 12\n        \n        static let controlHeight: CGFloat = 26\n    }\n    enum Color {\n        static var controlBackgroundColor: NSColor { NSColor.textColor.withAlphaComponent(0.08) }\n        static var controlHighlightedBackgroundColor: NSColor { NSColor.textColor.withAlphaComponent(0.15) }\n        static let transparentBackground = NSColor(patternImage: NSImage(named: \"transparent_background\")!)\n    }\n    enum Image {\n        static let sidebarDisclosure = NSImage(named: \"sidebar.disclosure\")!\n        static let pulldownIndicator = NSImage(named: \"pulldown.indicator\")!\n        \n        static let iphone = NSImage(named: \"iphone\")!\n        static let ipad = NSImage(named: \"ipad\")!\n        static let mac = NSImage(named: \"mac\")!\n        static let carplay = NSImage(named: \"carplay\")!\n        static let appleWatch = NSImage(named: \"applewatch\")!\n        \n        static let spuit = NSImage(named: \"spuit\")!\n        static let search = NSImage(named: \"search\")!\n        static let check = NSImage(named: \"check\")!\n        static let error = NSImage(named: \"error\")!\n        \n        static let spacing = NSImage(named: \"spacing\")!\n        static let clear = NSImage(named: \"clear\")!\n        static let open = NSImage(named: \"open\")!\n        static let paste = NSImage(named: \"paste\")!\n        static let copy = NSImage(named: \"copy\")!\n        \n        static let convert = NSImage(named: \"convert\")!\n        static let format = NSImage(named: \"format\")!\n        static let hyphen = NSImage(named: \"hyphen\")!\n        static let paramators = NSImage(named: \"paramators\")!\n        static let settings = NSImage(named: \"settings\")!\n        static let number = NSImage(named: \"number\")!\n        static let text = NSImage(named: \"text\")!\n        \n        static let stepperUp = NSImage(named: \"stepper.up\")!\n        static let stepperDown = NSImage(named: \"stepper.down\")!\n        \n        static let ipaddress = NSImage(named: \"ipaddress\")!\n        static let networkStatus = NSImage(named: \"network.status\")!\n        static let speed = NSImage(named: \"speed\")!\n        static let drop = NSImage(named: \"drop\")!\n        static let export = NSImage(named: \"export\")!\n        \n        enum Tool {\n            static let home = NSImage(named: \"tool/home\")!\n            static let settings = NSImage(named: \"tool/settings\")!\n            \n            static let convert = NSImage(named: \"tool/convert\")!\n            static let jsonConvert = NSImage(named: \"tool/json.convert\")!\n            static let numberBaseConvert = NSImage(named: \"tool/number.base.convert\")!\n            static let dateConvert = NSImage(named: \"tool/date.convert\")!\n            \n            static let encoderDecoder = NSImage(named: \"tool/encoder.decoder\")!\n            static let htmlCoder = NSImage(named: \"tool/html.coder\")!\n            static let urlCoder = NSImage(named: \"tool/url.coder\")!\n            static let base64Coder = NSImage(named: \"tool/base64.coder\")!\n            static let jwtCoder = NSImage(named: \"tool/jwt.coder\")!\n            \n            static let formatter = NSImage(named: \"tool/formatter\")!\n            static let jsonFormatter = NSImage(named: \"tool/json.formatter\")!\n            static let xmlFormatter = NSImage(named: \"tool/xml.formatter\")!\n            static let sqlFormatter = NSImage(named: \"tool/sql.formatter\")!\n            \n            static let generator = NSImage(named: \"tool/generator\")!\n            static let uuidGenerator = NSImage(named: \"tool/uuid.generator\")!\n            static let hashGenerator = NSImage(named: \"tool/hash.generator\")!\n            static let loremIpsumGenerator = NSImage(named: \"tool/lorem.ipsum.generator\")!\n            \n            static let text = NSImage(named: \"tool/text\")!\n            static let textInspector = NSImage(named: \"tool/text.inspector\")!\n            static let regexTester = NSImage(named: \"tool/regex.tester\")!\n            static let textDiff = NSImage(named: \"tool/text.diff\")!\n            static let markdownPreview = NSImage(named: \"tool/markdown.preview\")!\n            static let jsonSearch = NSImage(named: \"tool/json.search\")!\n            \n            static let graphic = NSImage(named: \"tool/graphic\")!\n            static let pdfGenerator = NSImage(named: \"tool/pdf\")!\n            static let colorBlindnessSimulator = NSImage(named: \"tool/color.blindness.simulator\")!\n            static let imageCompressor = NSImage(named: \"tool/image.compressor\")!\n            static let imageConverter = NSImage(named: \"tool/image.converter\")!\n            static let colorPicker = NSImage(named: \"tool/color.picker\")!\n            static let gif = NSImage(named: \"tool/gif\")!\n            static let qrgenerator = NSImage(named: \"tool/qr.generator\")!\n            static let iconGenerator = NSImage(named: \"tool/icon.generator\")!\n            \n            static let media = NSImage(named: \"tool/media\")!\n            static let audioConverter = NSImage(named: \"tool/audio.convert\")!\n            \n            static let network = NSImage(named: \"tool/network\")!\n            static let api = NSImage(named: \"tool/api\")!\n        }\n    }\n}\n\nextension Bundle {\n    static let current = Bundle(for: { class __ {}; return  __.self }())\n}\n"
  },
  {
    "path": "DevToys/DevToys/Resource/de.lproj/Localizable.strings",
    "content": "/*\n  Localizable.strings\n  DevToys\n\n  Created by mheob on 2022/02/14.\n\n*/\n\n// - General -\n\"Configuration\" = \"Konfiguration\";\n\"Format\" = \"Format\";\n\"Pretty\" = \"Pretty\";\n\"Minified\" = \"Minified\";\n\"Encoded\" = \"Encoded\";\n\"Decoded\" = \"Decoded\";\n\"File\" = \"Datei\";\n\"Text\" = \"Text\";\n\"Copy\" = \"Kopieren\";\n\"Paste\" = \"Einfügen\";\n\"Copied!\" = \"Kopiert!\";\n\"Pasted!\" = \"Eingefügt\";\n\"Open\" = \"Open\";\n\"Export\" = \"Exportieren\";\n\"Import\" = \"Importieren\";\n\"Input\" = \"Eingabe\";\n\"Output\" = \"Ausgabe\";\n\"No selection\" = \"Keine Auswahl\";\n\"Drop Files Here\" = \"Dateien hier ablegen\";\n\"Untitled Tool\" = \"Unbenanntes Werkzeug\";\n\"Uppercase\" = \"Großbuchstaben\";\n\"Hyphens\" = \"Silbentrennungen\";\n\"Type\" = \"Typ\";\n\"Length\" = \"Länge\";\n\"Convert\" = \"Konvertieren\";\n\"Information\" = \"Information\";\n\"Clear\" = \"Leeren\";\n\"Delete\" = \"Löschen\";\n\n// - Category -\n\"category.home\" = \"Home\";\n\"category.converters\" = \"Konverter\";\n\"category.encoders_decoders\" = \"Encoders / Decoders\";\n\"category.formatters\" = \"Formatierer\";\n\"category.generators\" = \"Generatoren\";\n\"category.text\" = \"Text\";\n\"category.graphic\" = \"Grafik\";\n\n// - Tool -\n\"tool.home.title\" = \"Home\";\n\"tool.home.mintitle\" = \"Home\";\n\"tool.home.description\" = \"Suche alle Tools.\";\n\n\"tool.jsonyaml.title\" = \"JSON <> Yaml Konverter\";\n\"tool.jsonyaml.mintitle\" = \"JSON <> Yaml\";\n\"tool.jsonyaml.description\" = \"Json-Daten in Yaml konvertieren und umgekehrt\";\n\n\"tool.numbase.title\" = \"Zahlenbasis-Konverter\";\n\"tool.numbase.mintitle\" = \"Zahlenbasis\";\n\"tool.numbase.description\" = \"Zahlen von einer Basis in eine andere umrechnen\";\n\"Format Number\" = \"Zahlenformat\";\n\"Decimal\" = \"Dezimal\";\n\"Hexdecimal\" = \"Hexadezimal\";\n\"Octal\" = \"Oktal\";\n\"Binary\" = \"Binär\";\n\n\"tool.date.title\" = \"Datumskonverter\";\n\"tool.date.mintitle\" = \"Datum\";\n\"tool.date.description\" = \"Konvertiert das Datum von einem Format in ein anderes\";\n\"Now\" = \"Jetzt\";\n\"Date\" = \"Datum\";\n\"Unix Time\" = \"Unix Time\";\n\"ISO 8601\" = \"ISO 8601\";\n\"Calender\" = \"Kalender\";\n\n\"tool.html.title\" = \"HTML Encoder / Decoder\";\n\"tool.html.mintitle\" = \"HTML\";\n\"tool.html.description\" = \"Kodiert oder dekodiert alle zutreffenden Zeichen in ihr entsprechendes HTML\";\n\n\"tool.url.title\" = \"URL Encoder / Decoder\";\n\"tool.url.mintitle\" = \"URL\";\n\"tool.url.description\" = \"Kodiert oder dekodiert alle zutreffenden Zeichen zu ihrer entsprechenden URL\";\n\n\"tool.base64.title\" = \"Base64 Encoder / Decoder\";\n\"tool.base64.mintitle\" = \"Base64\";\n\"tool.base64.description\" = \"Base64-Daten kodieren und dekodieren\";\n\"Source Type\" = \"Quellenart\";\n\"Text Source\" = \"Textquelle\";\n\"File Source\" = \"Dateiquelle\";\n\n\"tool.jwt.title\" = \"JWT Encoder / Decoder\";\n\"tool.jwt.mintitle\" = \"JWT\";\n\"tool.jwt.description\" = \"Dekodiere einen JWT-Header-Payload und eine Signatur\";\n\"JWT Token\" = \"JWT Token\";\n\"Header\" = \"Header\";\n\"Payload\" = \"Payload\";\n\n\"tool.jsonformat.title\" = \"JSON Formatter\";\n\"tool.jsonformat.mintitle\" = \"JSON\";\n\"tool.jsonformat.description\" = \"Json-Daten einrücken oder verkleinern\";\n\"Indentation\" = \"Einrückung\";\n\"2 Spaces\" = \"2 Leerzeichen\";\n\"4 Spaces\" = \"4 Leerzeichen\";\n\"1 Tab\" = \"1 Tab\";\n\n\"tool.xmlformat.title\" = \"XML Formatter\";\n\"tool.xmlformat.mintitle\" = \"XML\";\n\"tool.xmlformat.description\" = \"XML-Daten einrücken oder verkleinern\";\n\"HTML Document\" = \"HTML Dokument\";\n\"XML Document\" = \"XML Dokument\";\n\"Document Type\" = \"Dokumentenart\";\n\"Auto Fix Document\" = \"Auto Fix Dokument\";\n\"Pretty Document\" = \"Pretty Dokument\";\n\n\"tool.hashgen.title\" = \"Hash Generator\";\n\"tool.hashgen.mintitle\" = \"Hash\";\n\"tool.hashgen.description\" = \"Berechne MD5, SHA1, SHA256 und SHA512 Hashes aus Textdaten\";\n\n\"tool.uuidgen.title\" = \"UUID Generator\";\n\"tool.uuidgen.mintitle\" = \"UUID\";\n\"tool.uuidgen.description\" = \"UUIDs generieren\";\n\"Generate UUIDs\" = \"UUIDs generieren\";\n\n\"tool.ligen.title\" = \"Lorem Ipsum Generator\";\n\"tool.ligen.mintitle\" = \"Lorem Ipsum\";\n\"tool.ligen.description\" = \"Lorem Ipsum Platzhaltertext generieren\";\n\"Type of generating Lorem Ipsum\" = \"Art der Lorem Ipsum Erzeugung\";\n\"Length of generating Lorem Ipsum\" = \"Länge der Lorem Ipsum Erzeugung\";\n\"Words\" = \"Wörter\";\n\"Sentences\" = \"Sätze\";\n\"Paragraphs\" = \"Paragraphen\";\n\n\"tool.checksum.title\" = \"Prüfsummen Generator\";\n\"tool.checksum.mintitle\" = \"Prüfsumme\";\n\"tool.checksum.description\" = \"Prüfsumme einer Datei generieren oder testen\";\n\"Output Comparer\" = \"Ausgangsvergleicher\";\n\"Hash Algorithm\" = \"Hash-Algorithmus\";\n\"Select which algorithm you want to use\" = \"Wähle aus, welchen Algorithmus du verwenden möchtest\";\n\n\"tool.checksum.title\" = \"Prüfsummen Generator\";\n\"tool.checksum.mintitle\" = \"Prüfsumme\";\n\"tool.checksum.description\" = \"Prüfsumme einer Datei generieren oder testen\";\n\n\"tool.textinspect.title\" = \"Text Inspektor & Groß-/Kleinschreibung Konverter\";\n\"tool.textinspect.mintitle\" = \"Inspektor & Fallumwandler\";\n\"tool.textinspect.description\" = \"Text analysieren und in verschiedene Groß- und Kleinschreibung umwandeln\";\n\"Charactors\" = \"Schriftzeichen\";\n\"Words\" = \"Wörter\";\n\"Lines\" = \"Lines\";\n\"Bytes\" = \"Bytes\";\n\n\"tool.regex.title\" = \"Regex Tester\";\n\"tool.regex.mintitle\" = \"Regex\";\n\"tool.regex.description\" = \"Regex testen\";\n\"Reguler expression\" = \"Regex Ausdruck\";\n\n\"tool.hyphenremove.title\" = \"Silbentrennung-Entferner\";\n\"tool.hyphenremove.mintitle\" = \"Silbentrennung\";\n\"tool.hyphenremove.description\" = \"Aus PDF-Text kopierte Silbentrennungen entfernen\";\n\n\"tool.imageoptim.title\" = \"PNG / JPEG Kompressor\";\n\"tool.imageoptim.mintitle\" = \"PNG / JPEG Kompressor\";\n\"tool.imageoptim.description\" = \"Verlustfreier PNG- und JPEG-Optimierer\";\n\"Optimize Level\" = \"Optimierungslevel\";\n\"Low\" = \"Niedrig\";\n\"Medium\" = \"Mittel\";\n\"High\" = \"Hoch\";\n\"Very High (Slow)\" = \"Sehr hoch (langsam)\";\n\n\"tool.pdfgen.title\" = \"PDF Generator\";\n\"tool.pdfgen.mintitle\" = \"PDF Generator\";\n\"tool.pdfgen.description\" = \"PDF aus mehreren Bildern generieren\";\n\"Images\" = \"Bilder\";\n\"Size\" = \"Größe\";\n\"Generate PDF\" = \"PDF generieren\";\n\"Page\" = \"Seite\";\n\n\"tool.imageconvert.title\" = \"Bildkonverter\";\n\"tool.imageconvert.mintitle\" = \"Bildkonverter\";\n\"tool.imageconvert.description\" = \"Bilder konvertieren oder Größe ändern\";\n\"PNG Format\" = \"PNG Format\";\n\"JPEG Format\" = \"JPEG Format\";\n\"TIFF Format\" = \"TIFF Format\";\n\"GIF Format\" = \"GIF Format\";\n\"Scale to Fill\" = \"Skalieren zum Füllen\";\n\"Scale to Fit\" = \"Skalieren und einpassen\";\n\"Image Format\" = \"Bildformat\";\n\"Resize\" = \"Größe ändern\";\n\"Converted Images\" = \"Umgewandelte Bilder\";\n\"Scale\" = \"Skalierung\";\n\"Size\" = \"Größe\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/de.lproj/Main.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Customize Toolbar…\"; ObjectID = \"1UK-8n-QPP\"; */\n\"1UK-8n-QPP.title\" = \"Customize Toolbar…\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys\"; ObjectID = \"1Xt-HY-uBw\"; */\n\"1Xt-HY-uBw.title\" = \"DevToys\";\n\n/* Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"1b7-l0-nxx\"; */\n\"1b7-l0-nxx.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower\"; ObjectID = \"1tx-W0-xDw\"; */\n\"1tx-W0-xDw.title\" = \"Lower\";\n\n/* Class = \"NSMenuItem\"; title = \"Raise\"; ObjectID = \"2h7-ER-AoG\"; */\n\"2h7-ER-AoG.title\" = \"Raise\";\n\n/* Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"2oI-Rn-ZJC\"; */\n\"2oI-Rn-ZJC.title\" = \"Transformations\";\n\n/* Class = \"NSMenu\"; title = \"Spelling\"; ObjectID = \"3IN-sU-3Bg\"; */\n\"3IN-sU-3Bg.title\" = \"Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"3Om-Ey-2VK\"; */\n\"3Om-Ey-2VK.title\" = \"Use Default\";\n\n/* Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"3rS-ZA-NoH\"; */\n\"3rS-ZA-NoH.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Tighten\"; ObjectID = \"46P-cB-AYj\"; */\n\"46P-cB-AYj.title\" = \"Tighten\";\n\n/* Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"4EN-yA-p0u\"; */\n\"4EN-yA-p0u.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"4J7-dP-txa\"; */\n\"4J7-dP-txa.title\" = \"Enter Full Screen\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit DevToys\"; ObjectID = \"4sb-4s-VLi\"; */\n\"4sb-4s-VLi.title\" = \"Quit DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"5QF-Oa-p0T\"; */\n\"5QF-Oa-p0T.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Style\"; ObjectID = \"5Vv-lz-BsD\"; */\n\"5Vv-lz-BsD.title\" = \"Copy Style\";\n\n/* Class = \"NSMenuItem\"; title = \"About DevToys\"; ObjectID = \"5kV-Vb-QxS\"; */\n\"5kV-Vb-QxS.title\" = \"About DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"6dh-zS-Vam\"; */\n\"6dh-zS-Vam.title\" = \"Redo\";\n\n/* Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"78Y-hA-62v\"; */\n\"78Y-hA-62v.title\" = \"Correct Spelling Automatically\";\n\n/* Class = \"NSMenu\"; title = \"Writing Direction\"; ObjectID = \"8mr-sm-Yjd\"; */\n\"8mr-sm-Yjd.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"9ic-FL-obx\"; */\n\"9ic-FL-obx.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"9yt-4B-nSM\"; */\n\"9yt-4B-nSM.title\" = \"Smart Copy/Paste\";\n\n/* Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\"; */\n\"AYu-sK-qS6.title\" = \"Main Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\"; */\n\"BOF-NM-1cW.title\" = \"Preferences…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"BgM-ve-c93\"; */\n\"BgM-ve-c93.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Save As…\"; ObjectID = \"Bw7-FT-i3A\"; */\n\"Bw7-FT-i3A.title\" = \"Save As…\";\n\n/* Class = \"NSMenuItem\"; title = \"Close\"; ObjectID = \"DVo-aG-piG\"; */\n\"DVo-aG-piG.title\" = \"Close\";\n\n/* Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"Dv1-io-Yv7\"; */\n\"Dv1-io-Yv7.title\" = \"Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"F2S-fz-NVQ\"; */\n\"F2S-fz-NVQ.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys Help\"; ObjectID = \"FKE-Sm-Kum\"; */\n\"FKE-Sm-Kum.title\" = \"DevToys Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Text\"; ObjectID = \"Fal-I4-PZk\"; */\n\"Fal-I4-PZk.title\" = \"Text\";\n\n/* Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"FeM-D8-WVr\"; */\n\"FeM-D8-WVr.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"GB9-OM-e27\"; */\n\"GB9-OM-e27.title\" = \"Bold\";\n\n/* Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"GEO-Iw-cKr\"; */\n\"GEO-Iw-cKr.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"GUa-eO-cwY\"; */\n\"GUa-eO-cwY.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Font\"; ObjectID = \"Gi5-1S-RQB\"; */\n\"Gi5-1S-RQB.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Writing Direction\"; ObjectID = \"H1b-Si-o9J\"; */\n\"H1b-Si-o9J.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"H8h-7b-M4v\"; */\n\"H8h-7b-M4v.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"HFQ-gK-NFA\"; */\n\"HFQ-gK-NFA.title\" = \"Text Replacement\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"HFo-cy-zxI\"; */\n\"HFo-cy-zxI.title\" = \"Show Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"View\"; ObjectID = \"HyV-fh-RgO\"; */\n\"HyV-fh-RgO.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Subscript\"; ObjectID = \"I0S-gh-46l\"; */\n\"I0S-gh-46l.title\" = \"Subscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Open…\"; ObjectID = \"IAo-SY-fd9\"; */\n\"IAo-SY-fd9.title\" = \"Open…\";\n\n/* Class = \"NSWindow\"; title = \"DevToys\"; ObjectID = \"IQv-IB-iLA\"; */\n\"IQv-IB-iLA.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Justify\"; ObjectID = \"J5U-5w-g23\"; */\n\"J5U-5w-g23.title\" = \"Justify\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"J7y-lM-qPV\"; */\n\"J7y-lM-qPV.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Revert to Saved\"; ObjectID = \"KaW-ft-85H\"; */\n\"KaW-ft-85H.title\" = \"Revert to Saved\";\n\n/* Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\"; */\n\"Kd2-mp-pUS.title\" = \"Show All\";\n\n/* Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"LE2-aR-0XJ\"; */\n\"LE2-aR-0XJ.title\" = \"Bring All to Front\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Ruler\"; ObjectID = \"LVM-kO-fVI\"; */\n\"LVM-kO-fVI.title\" = \"Paste Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"Lbh-J2-qVU\"; */\n\"Lbh-J2-qVU.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Ruler\"; ObjectID = \"MkV-Pr-PK5\"; */\n\"MkV-Pr-PK5.title\" = \"Copy Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\"; */\n\"NMo-om-nkz.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"Nop-cj-93Q\"; */\n\"Nop-cj-93Q.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"OY7-WF-poV\"; */\n\"OY7-WF-poV.title\" = \"Minimize\";\n\n/* Class = \"NSMenuItem\"; title = \"Baseline\"; ObjectID = \"OaQ-X3-Vso\"; */\n\"OaQ-X3-Vso.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide DevToys\"; ObjectID = \"Olw-nP-bQN\"; */\n\"Olw-nP-bQN.title\" = \"Hide DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"OwM-mh-QMV\"; */\n\"OwM-mh-QMV.title\" = \"Find Previous\";\n\n/* Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"Oyz-dy-DGm\"; */\n\"Oyz-dy-DGm.title\" = \"Stop Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Bigger\"; ObjectID = \"Ptp-SP-VEL\"; */\n\"Ptp-SP-VEL.title\" = \"Bigger\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Fonts\"; ObjectID = \"Q5e-8K-NDq\"; */\n\"Q5e-8K-NDq.title\" = \"Show Fonts\";\n\n/* Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"R4o-n2-Eq4\"; */\n\"R4o-n2-Eq4.title\" = \"Zoom\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"RB4-Sm-HuC\"; */\n\"RB4-Sm-HuC.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Superscript\"; ObjectID = \"Rqc-34-cIF\"; */\n\"Rqc-34-cIF.title\" = \"Superscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Ruw-6m-B2m\"; */\n\"Ruw-6m-B2m.title\" = \"Select All\";\n\n/* Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"S0p-oC-mLd\"; */\n\"S0p-oC-mLd.title\" = \"Jump to Selection\";\n\n/* Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"Td7-aD-5lo\"; */\n\"Td7-aD-5lo.title\" = \"Window\";\n\n/* Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"UEZ-Bs-lqG\"; */\n\"UEZ-Bs-lqG.title\" = \"Capitalize\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"VIY-Ag-zcb\"; */\n\"VIY-Ag-zcb.title\" = \"Center\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\"; */\n\"Vdr-fp-XzO.title\" = \"Hide Others\";\n\n/* Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"Vjx-xi-njq\"; */\n\"Vjx-xi-njq.title\" = \"Italic\";\n\n/* Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"W48-6f-4Dl\"; */\n\"W48-6f-4Dl.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Underline\"; ObjectID = \"WRG-CD-K1S\"; */\n\"WRG-CD-K1S.title\" = \"Underline\";\n\n/* Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"Was-JA-tGl\"; */\n\"Was-JA-tGl.title\" = \"New\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"WeT-3V-zwk\"; */\n\"WeT-3V-zwk.title\" = \"Paste and Match Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"Xz5-n4-O0W\"; */\n\"Xz5-n4-O0W.title\" = \"Find…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"YEy-JH-Tfz\"; */\n\"YEy-JH-Tfz.title\" = \"Find and Replace…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"YGs-j5-SAR\"; */\n\"YGs-j5-SAR.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"Ynk-f8-cLZ\"; */\n\"Ynk-f8-cLZ.title\" = \"Start Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Left\"; ObjectID = \"ZM1-6Q-yy1\"; */\n\"ZM1-6Q-yy1.title\" = \"Align Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Paragraph\"; ObjectID = \"ZvO-Gk-QUH\"; */\n\"ZvO-Gk-QUH.title\" = \"Paragraph\";\n\n/* Class = \"NSMenuItem\"; title = \"Print…\"; ObjectID = \"aTl-1u-JFS\"; */\n\"aTl-1u-JFS.title\" = \"Print…\";\n\n/* Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"aUF-d1-5bR\"; */\n\"aUF-d1-5bR.title\" = \"Window\";\n\n/* Class = \"NSMenu\"; title = \"Font\"; ObjectID = \"aXa-aM-Jaq\"; */\n\"aXa-aM-Jaq.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"agt-UL-0e3\"; */\n\"agt-UL-0e3.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Colors\"; ObjectID = \"bgn-CT-cEk\"; */\n\"bgn-CT-cEk.title\" = \"Show Colors\";\n\n/* Class = \"NSMenu\"; title = \"File\"; ObjectID = \"bib-Uj-vzu\"; */\n\"bib-Uj-vzu.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"buJ-ug-pKt\"; */\n\"buJ-ug-pKt.title\" = \"Use Selection for Find\";\n\n/* Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"c8a-y6-VQd\"; */\n\"c8a-y6-VQd.title\" = \"Transformations\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"cDB-IK-hbR\"; */\n\"cDB-IK-hbR.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Selection\"; ObjectID = \"cqv-fj-IhA\"; */\n\"cqv-fj-IhA.title\" = \"Selection\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"cwL-P1-jid\"; */\n\"cwL-P1-jid.title\" = \"Smart Links\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"d9M-CD-aMd\"; */\n\"d9M-CD-aMd.title\" = \"Make Lower Case\";\n\n/* Class = \"NSMenu\"; title = \"Text\"; ObjectID = \"d9c-me-L2H\"; */\n\"d9c-me-L2H.title\" = \"Text\";\n\n/* Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"dMs-cI-mzQ\"; */\n\"dMs-cI-mzQ.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"dRJ-4n-Yzg\"; */\n\"dRJ-4n-Yzg.title\" = \"Undo\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"gVA-U4-sdL\"; */\n\"gVA-U4-sdL.title\" = \"Paste\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"hQb-2v-fYv\"; */\n\"hQb-2v-fYv.title\" = \"Smart Quotes\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"hz2-CU-CR7\"; */\n\"hz2-CU-CR7.title\" = \"Check Document Now\";\n\n/* Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\"; */\n\"hz9-B4-Xy5.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"Smaller\"; ObjectID = \"i1d-Er-qST\"; */\n\"i1d-Er-qST.title\" = \"Smaller\";\n\n/* Class = \"NSMenu\"; title = \"Baseline\"; ObjectID = \"ijk-EB-dga\"; */\n\"ijk-EB-dga.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Kern\"; ObjectID = \"jBQ-r6-VK2\"; */\n\"jBQ-r6-VK2.title\" = \"Kern\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"jFq-tB-4Kx\"; */\n\"jFq-tB-4Kx.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"jxT-CU-nIS\"; */\n\"jxT-CU-nIS.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Sidebar\"; ObjectID = \"kIP-vf-haE\"; */\n\"kIP-vf-haE.title\" = \"Show Sidebar\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"mK6-2p-4JG\"; */\n\"mK6-2p-4JG.title\" = \"Check Grammar With Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Ligatures\"; ObjectID = \"o6e-r0-MWq\"; */\n\"o6e-r0-MWq.title\" = \"Ligatures\";\n\n/* Class = \"NSMenu\"; title = \"Open Recent\"; ObjectID = \"oas-Oc-fiZ\"; */\n\"oas-Oc-fiZ.title\" = \"Open Recent\";\n\n/* Class = \"NSMenuItem\"; title = \"Loosen\"; ObjectID = \"ogc-rX-tC1\"; */\n\"ogc-rX-tC1.title\" = \"Loosen\";\n\n/* Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"pa3-QI-u2k\"; */\n\"pa3-QI-u2k.title\" = \"Delete\";\n\n/* Class = \"NSMenuItem\"; title = \"Save…\"; ObjectID = \"pxx-59-PXV\"; */\n\"pxx-59-PXV.title\" = \"Save…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"q09-fT-Sye\"; */\n\"q09-fT-Sye.title\" = \"Find Next\";\n\n/* Class = \"NSMenuItem\"; title = \"Page Setup…\"; ObjectID = \"qIS-W8-SiK\"; */\n\"qIS-W8-SiK.title\" = \"Page Setup…\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"rbD-Rh-wIN\"; */\n\"rbD-Rh-wIN.title\" = \"Check Spelling While Typing\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"rgM-f4-ycn\"; */\n\"rgM-f4-ycn.title\" = \"Smart Dashes\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Toolbar\"; ObjectID = \"snW-S8-Cw5\"; */\n\"snW-S8-Cw5.title\" = \"Show Toolbar\";\n\n/* Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\"; */\n\"tRr-pd-1PS.title\" = \"Data Detectors\";\n\n/* Class = \"NSMenuItem\"; title = \"Open Recent\"; ObjectID = \"tXI-mr-wws\"; */\n\"tXI-mr-wws.title\" = \"Open Recent\";\n\n/* Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"tlD-Oa-oAM\"; */\n\"tlD-Oa-oAM.title\" = \"Kern\";\n\n/* Class = \"NSMenu\"; title = \"DevToys\"; ObjectID = \"uQy-DD-JDr\"; */\n\"uQy-DD-JDr.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"uRl-iY-unG\"; */\n\"uRl-iY-unG.title\" = \"Cut\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Style\"; ObjectID = \"vKC-jM-MkH\"; */\n\"vKC-jM-MkH.title\" = \"Paste Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Ruler\"; ObjectID = \"vLm-3I-IUL\"; */\n\"vLm-3I-IUL.title\" = \"Show Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Clear Menu\"; ObjectID = \"vNY-rz-j42\"; */\n\"vNY-rz-j42.title\" = \"Clear Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\"; */\n\"vmV-6d-7jI.title\" = \"Make Upper Case\";\n\n/* Class = \"NSMenu\"; title = \"Ligatures\"; ObjectID = \"w0m-vy-SC9\"; */\n\"w0m-vy-SC9.title\" = \"Ligatures\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Right\"; ObjectID = \"wb2-vD-lq4\"; */\n\"wb2-vD-lq4.title\" = \"Align Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"wpr-3q-Mcd\"; */\n\"wpr-3q-Mcd.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"x3v-GG-iWU\"; */\n\"x3v-GG-iWU.title\" = \"Copy\";\n\n/* Class = \"NSMenuItem\"; title = \"Use All\"; ObjectID = \"xQD-1f-W4t\"; */\n\"xQD-1f-W4t.title\" = \"Use All\";\n\n/* Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"xrE-MZ-jX0\"; */\n\"xrE-MZ-jX0.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"z6F-FW-3nz\"; */\n\"z6F-FW-3nz.title\" = \"Show Substitutions\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/en.lproj/Localizable.strings",
    "content": "/*\n  Localizable.strings\n  DevToys\n\n  Created by yuki on 2022/02/13.\n  \n*/\n\n// - General -\n\"Configuration\" = \"Configuration\";\n\"Format\" = \"Format\";\n\"Pretty\" = \"Pretty\";\n\"Minified\" = \"Minified\";\n\"Encoded\" = \"Encoded\";\n\"Decoded\" = \"Decoded\";\n\"File\" = \"File\";\n\"Text\" = \"Text\";\n\"Copy\" = \"Copy\";\n\"Paste\" = \"Paste\";\n\"Copied!\" = \"Copied!\";\n\"Pasted!\" = \"Pasted\";\n\"Open\" = \"Open\";\n\"Export\" = \"Export\";\n\"Import\" = \"Import\";\n\"Input\" = \"Input\";\n\"Output\" = \"Output\";\n\"No selection\" = \"No selection\";\n\"Drop Files Here\" = \"Drop Files Here\";\n\"Untitled Tool\" = \"Untitled Tool\";\n\"Uppercase\" = \"Uppercase\";\n\"Hyphens\" = \"Hyphens\";\n\"Type\" = \"Type\";\n\"Length\" = \"Length\";\n\"Convert\" = \"Convert\";\n\"Information\" = \"Information\";\n\"Clear\" = \"Clear\";\n\"Delete\" = \"Delete\";\n\"Open in Finder\" = \"Open in Finder\";\n\"Quick Look\" = \"Quick Look\";\n\"Default\" = \"Default\";\n\n// - Category -\n\"category.home\" = \"Home\";\n\"category.converters\" = \"Converters\";\n\"category.encoders_decoders\" = \"Encoders / Decoders\";\n\"category.formatters\" = \"Formatters\";\n\"category.generators\" = \"Generators\";\n\"category.text\" = \"Text\";\n\"category.graphic\" = \"Graphic\";\n\"Media\" = \"Media\";\n\n// - Tool -\n\"tool.home.title\" = \"Home\";\n\"tool.home.mintitle\" = \"Home\";\n\"tool.home.description\" = \"Search all tools here.\";\n\n\"tool.jsonyaml.title\" = \"JSON <> Yaml Converter\";\n\"tool.jsonyaml.mintitle\" = \"JSON <> Yaml\";\n\"tool.jsonyaml.description\" = \"Convert Json data to Yaml and vice versa\";\n\n\"tool.numbase.title\" = \"Number Base Converter\";\n\"tool.numbase.mintitle\" = \"Number Base\";\n\"tool.numbase.description\" = \"Convert numbers from one base to another\";\n\"Format Number\" = \"Format Number\";\n\"Decimal\" = \"Decimal\";\n\"Hexdecimal\" = \"Hexadecimal\";\n\"Octal\" = \"Octal\";\n\"Binary\" = \"Binary\";\n\n\"tool.date.title\" = \"Date Converter\";\n\"tool.date.mintitle\" = \"Date\";\n\"tool.date.description\" = \"Converts date from one format to another\";\n\"Now\" = \"Now\";\n\"Date\" = \"Date\";\n\"Unix Time\" = \"Unix Time\";\n\"ISO 8601\" = \"ISO 8601\";\n\"Calender\" = \"Calender\";\n\n\"tool.html.title\" = \"HTML Encoder / Decoder\";\n\"tool.html.mintitle\" = \"HTML\";\n\"tool.html.description\" = \"Encoder or decoder all the applicable characters to their corresponding HTML\";\n\n\"tool.url.title\" = \"URL Encoder / Decoder\";\n\"tool.url.mintitle\" = \"URL\";\n\"tool.url.description\" = \"Encoder or decode all the applicable characters to their corresponding URL\";\n\n\"tool.base64.title\" = \"Base64 Encoder / Decoder\";\n\"tool.base64.mintitle\" = \"Base64\";\n\"tool.base64.description\" = \"Encode and decode Base64 data\";\n\"Source Type\" = \"Source Type\";\n\"Text Source\" = \"Text Source\";\n\"File Source\" = \"File Source\";\n\n\"tool.jwt.title\" = \"JWT Encoder / Decoder\";\n\"tool.jwt.mintitle\" = \"JWT\";\n\"tool.jwt.description\" = \"Decode a JWT header playload and signature\";\n\"JWT Token\" = \"JWT Token\";\n\"Header\" = \"Header\";\n\"Payload\" = \"Payload\";\n\n\"tool.jsonformat.title\" = \"JSON Formatter\";\n\"tool.jsonformat.mintitle\" = \"JSON\";\n\"tool.jsonformat.description\" = \"Indent or minify Json data\";\n\"Indentation\" = \"Indentation\";\n\"2 Spaces\" = \"2 Spaces\";\n\"4 Spaces\" = \"4 Spaces\";\n\"1 Tab\" = \"1 Tab\";\n\n\"tool.xmlformat.title\" = \"XML Formatter\";\n\"tool.xmlformat.mintitle\" = \"XML\";\n\"tool.xmlformat.description\" = \"Indent or minify XML data\";\n\"HTML Document\" = \"HTML Document\";\n\"XML Document\" = \"XML Document\";\n\"Document Type\" = \"Document Type\";\n\"Auto Fix Document\" = \"Auto Fix Document\";\n\"Pretty Document\" = \"Pretty Document\";\n\n\"tool.hashgen.title\" = \"Hash Generator\";\n\"tool.hashgen.mintitle\" = \"Hash\";\n\"tool.hashgen.description\" = \"Calculate MD5, SHA1, SHA256 and SHA 512 hash from text data\";\n\n\"tool.uuidgen.title\" = \"UUID Generator\";\n\"tool.uuidgen.mintitle\" = \"UUID\";\n\"tool.uuidgen.description\" = \"Generate UUIDs\";\n\"Generate UUIDs\" = \"Generate UUIDs\";\n\n\"tool.ligen.title\" = \"Lorem Ipsum Generator\";\n\"tool.ligen.mintitle\" = \"Lorem Ipsum\";\n\"tool.ligen.description\" = \"Generate Lorem Ipsum placeholder text\";\n\"Type of generating Lorem Ipsum\" = \"Type of generating Lorem Ipsum\";\n\"Length of generating Lorem Ipsum\" = \"Length of generating Lorem Ipsum\";\n\"Words\" = \"Words\";\n\"Sentences\" = \"Sentences\";\n\"Paragraphs\" = \"Paragraphs\";\n\n\"tool.checksum.title\" = \"Checksum Generator\";\n\"tool.checksum.mintitle\" = \"Checksum\";\n\"tool.checksum.description\" = \"Generate or Test checksum of a file\";\n\"Output Comparer\" = \"Output Comparer\";\n\"Hash Algorithm\" = \"Hash Algorithm\";\n\"Select which algorithm you want to use\" = \"Select which algorithm you want to use\";\n\n\"tool.checksum.title\" = \"Checksum Generator\";\n\"tool.checksum.mintitle\" = \"Checksum\";\n\"tool.checksum.description\" = \"Generate or Test checksum of a file\";\n\n\"tool.textinspect.title\" = \"Text Inspector & Case Converter\";\n\"tool.textinspect.mintitle\" = \"Inspector & Case Converter\";\n\"tool.textinspect.description\" = \"Analyze text and convert it to different case\";\n\"Charactors\" = \"Characters\";\n\"Words\" = \"Words\";\n\"Lines\" = \"Lines\";\n\"Bytes\" = \"Bytes\";\n\n\"tool.regex.title\" = \"Regex Tester\";\n\"tool.regex.mintitle\" = \"Regex\";\n\"tool.regex.description\" = \"Test regular expression\";\n\"Reguler expression\" = \"Regular expression\";\n\n\"tool.hyphenremove.title\" = \"Hyphenation Remover\";\n\"tool.hyphenremove.mintitle\" = \"Hyphenation\";\n\"tool.hyphenremove.description\" = \"Remove hyphenations copied from PDF text\";\n\n\"tool.imageoptim.title\" = \"PNG / JPEG Compressor\";\n\"tool.imageoptim.mintitle\" = \"PNG / JPEG Compressor\";\n\"tool.imageoptim.description\" = \"Lossless PNG and JPEG optimizer\";\n\"Optimize Level\" = \"Optimize Level\";\n\"Low\" = \"Low\";\n\"Medium\" = \"Medium\";\n\"High\" = \"High\";\n\"Very High (Slow)\" = \"Very High (Slow)\";\n\"Override original file\" = \"Override original file\";\n\n\"tool.pdfgen.title\" = \"PDF Generator\";\n\"tool.pdfgen.mintitle\" = \"PDF Generator\";\n\"tool.pdfgen.description\" = \"Generate PDF from multiple images\";\n\"Images\" = \"Images\";\n\"Size\" = \"Size\";\n\"Generate PDF\" = \"Generate PDF\";\n\"Page\" = \"Page\";\n\n\"tool.imageconvert.title\" = \"Image Converter\";\n\"tool.imageconvert.mintitle\" = \"Image Converter\";\n\"tool.imageconvert.description\" = \"Convert or Resize images\";\n\"PNG Format\" = \"PNG Format\";\n\"JPEG Format\" = \"JPEG Format\";\n\"TIFF Format\" = \"TIFF Format\";\n\"GIF Format\" = \"GIF Format\";\n\"Scale to Fill\" = \"Scale to Fill\";\n\"Scale to Fit\" = \"Scale to Fit\";\n\"Image Format\" = \"Image Format\";\n\"Resize\" = \"Resize\";\n\"Converted Images\" = \"Converted Images\";\n\"Scale\" = \"Scale\";\n\"Size\" = \"Size\";\n\n\"QR Code Generator\" = \"QR Code Generator\";\n\"Create a QR code from text\" = \"Create a QR code from text\";\n\"Correction Level\" = \"Correction Level\";\n\"QR Code\" = \"QR Code\";\n\n\"Settings\" = \"Settings\";\n\"Setting of application\" = \"Setting of application\";\n\"App Theme\" = \"App Theme\";\n\"Select which app theme to display\" = \"Select which app theme to display\";\n\"Use system setting\" = \"Use system setting\";\n\"Light mode\" = \"Light mode\";\n\"Dark mode\" = \"Dark mode\";\n\n\"Color Picker\" = \"Color Picker\";\n\"Picker the color and copy components\" = \"Pick a color and copy the formatted color\";\n\"HSB Box\" = \"HSB Box\";\n\"HSB Circle\" = \"HSB Circle\";\n\"HSB Circle and Bars\" = \"HSB Circle and Bars\";\n\"Pick Color\" = \"Pick Color\";\n\"Picker Type\" = \"Picker Type\";\n\"Color Hex\" = \"Color Hex\";\n\"Color Copy\" = \"Color Copy\";\n\"Color Copy Type\" = \"Type\";\n\n\"Gif Converter\" = \"Gif Converter\";\n\"Convert a movie to an animated GIF file\" = \"Convert a movie to an animated GIF file\";\n\"Width\" = \"Width\";\n\"The width of the Gif file\" = \"The width of the Gif file (height will be determined)\";\n\"FPS\" = \"FPS\";\n\"FPS of the Gif file to be exported\" = \"FPS of the Gif file to be exported\";\n\"Remove source file\" = \"Remove source file\";\n\"Whether to delete the source file after exporting a Gif\" = \"Whether to delete the source file after exporting a Gif\";\n\n\"Audio Converter\" = \"Audio Converter\";\n\"Convert audio from one format to another\" = \"Convert audio from one format to another\";\n\"Whether to delete the source file after exporting a Audio\" = \"Whether to delete the source file after exporting a Audio\";\n\"Starting...\" = \"Starting...\";\n\"Complete\" = \"Complete\";\n\"Convert Failed\" = \"Convert Failed\";\n\n\"Text Diff\" = \"Text Diff\";\n\"Compare two Text and display Diff\" = \"Compare two Text and display Diff\";\n\"By Characters\" = \"Characters\";\n\"By Words\" = \"Words\";\n\"By Lines\" = \"Lines\";\n\"Input 1\" = \"Input 1\";\n\"Input 2\" = \"Input 2\";\n\"Diff Style\" = \"Diff Style\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/en.lproj/Main.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Customize Toolbar…\"; ObjectID = \"1UK-8n-QPP\"; */\n\"1UK-8n-QPP.title\" = \"Customize Toolbar…\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys\"; ObjectID = \"1Xt-HY-uBw\"; */\n\"1Xt-HY-uBw.title\" = \"DevToys\";\n\n/* Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"1b7-l0-nxx\"; */\n\"1b7-l0-nxx.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower\"; ObjectID = \"1tx-W0-xDw\"; */\n\"1tx-W0-xDw.title\" = \"Lower\";\n\n/* Class = \"NSMenuItem\"; title = \"Raise\"; ObjectID = \"2h7-ER-AoG\"; */\n\"2h7-ER-AoG.title\" = \"Raise\";\n\n/* Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"2oI-Rn-ZJC\"; */\n\"2oI-Rn-ZJC.title\" = \"Transformations\";\n\n/* Class = \"NSMenu\"; title = \"Spelling\"; ObjectID = \"3IN-sU-3Bg\"; */\n\"3IN-sU-3Bg.title\" = \"Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"3Om-Ey-2VK\"; */\n\"3Om-Ey-2VK.title\" = \"Use Default\";\n\n/* Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"3rS-ZA-NoH\"; */\n\"3rS-ZA-NoH.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Tighten\"; ObjectID = \"46P-cB-AYj\"; */\n\"46P-cB-AYj.title\" = \"Tighten\";\n\n/* Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"4EN-yA-p0u\"; */\n\"4EN-yA-p0u.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"4J7-dP-txa\"; */\n\"4J7-dP-txa.title\" = \"Enter Full Screen\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit DevToys\"; ObjectID = \"4sb-4s-VLi\"; */\n\"4sb-4s-VLi.title\" = \"Quit DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"5QF-Oa-p0T\"; */\n\"5QF-Oa-p0T.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Style\"; ObjectID = \"5Vv-lz-BsD\"; */\n\"5Vv-lz-BsD.title\" = \"Copy Style\";\n\n/* Class = \"NSMenuItem\"; title = \"About DevToys\"; ObjectID = \"5kV-Vb-QxS\"; */\n\"5kV-Vb-QxS.title\" = \"About DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"6dh-zS-Vam\"; */\n\"6dh-zS-Vam.title\" = \"Redo\";\n\n/* Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"78Y-hA-62v\"; */\n\"78Y-hA-62v.title\" = \"Correct Spelling Automatically\";\n\n/* Class = \"NSMenu\"; title = \"Writing Direction\"; ObjectID = \"8mr-sm-Yjd\"; */\n\"8mr-sm-Yjd.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"9ic-FL-obx\"; */\n\"9ic-FL-obx.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"9yt-4B-nSM\"; */\n\"9yt-4B-nSM.title\" = \"Smart Copy/Paste\";\n\n/* Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\"; */\n\"AYu-sK-qS6.title\" = \"Main Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\"; */\n\"BOF-NM-1cW.title\" = \"Preferences…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"BgM-ve-c93\"; */\n\"BgM-ve-c93.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Save As…\"; ObjectID = \"Bw7-FT-i3A\"; */\n\"Bw7-FT-i3A.title\" = \"Save As…\";\n\n/* Class = \"NSMenuItem\"; title = \"Close\"; ObjectID = \"DVo-aG-piG\"; */\n\"DVo-aG-piG.title\" = \"Close\";\n\n/* Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"Dv1-io-Yv7\"; */\n\"Dv1-io-Yv7.title\" = \"Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"F2S-fz-NVQ\"; */\n\"F2S-fz-NVQ.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys Help\"; ObjectID = \"FKE-Sm-Kum\"; */\n\"FKE-Sm-Kum.title\" = \"DevToys Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Text\"; ObjectID = \"Fal-I4-PZk\"; */\n\"Fal-I4-PZk.title\" = \"Text\";\n\n/* Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"FeM-D8-WVr\"; */\n\"FeM-D8-WVr.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"GB9-OM-e27\"; */\n\"GB9-OM-e27.title\" = \"Bold\";\n\n/* Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"GEO-Iw-cKr\"; */\n\"GEO-Iw-cKr.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"GUa-eO-cwY\"; */\n\"GUa-eO-cwY.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Font\"; ObjectID = \"Gi5-1S-RQB\"; */\n\"Gi5-1S-RQB.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Writing Direction\"; ObjectID = \"H1b-Si-o9J\"; */\n\"H1b-Si-o9J.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"H8h-7b-M4v\"; */\n\"H8h-7b-M4v.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"HFQ-gK-NFA\"; */\n\"HFQ-gK-NFA.title\" = \"Text Replacement\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"HFo-cy-zxI\"; */\n\"HFo-cy-zxI.title\" = \"Show Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"View\"; ObjectID = \"HyV-fh-RgO\"; */\n\"HyV-fh-RgO.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Subscript\"; ObjectID = \"I0S-gh-46l\"; */\n\"I0S-gh-46l.title\" = \"Subscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Open…\"; ObjectID = \"IAo-SY-fd9\"; */\n\"IAo-SY-fd9.title\" = \"Open…\";\n\n/* Class = \"NSWindow\"; title = \"DevToys\"; ObjectID = \"IQv-IB-iLA\"; */\n\"IQv-IB-iLA.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Justify\"; ObjectID = \"J5U-5w-g23\"; */\n\"J5U-5w-g23.title\" = \"Justify\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"J7y-lM-qPV\"; */\n\"J7y-lM-qPV.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Revert to Saved\"; ObjectID = \"KaW-ft-85H\"; */\n\"KaW-ft-85H.title\" = \"Revert to Saved\";\n\n/* Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\"; */\n\"Kd2-mp-pUS.title\" = \"Show All\";\n\n/* Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"LE2-aR-0XJ\"; */\n\"LE2-aR-0XJ.title\" = \"Bring All to Front\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Ruler\"; ObjectID = \"LVM-kO-fVI\"; */\n\"LVM-kO-fVI.title\" = \"Paste Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"Lbh-J2-qVU\"; */\n\"Lbh-J2-qVU.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Ruler\"; ObjectID = \"MkV-Pr-PK5\"; */\n\"MkV-Pr-PK5.title\" = \"Copy Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\"; */\n\"NMo-om-nkz.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"Nop-cj-93Q\"; */\n\"Nop-cj-93Q.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"OY7-WF-poV\"; */\n\"OY7-WF-poV.title\" = \"Minimize\";\n\n/* Class = \"NSMenuItem\"; title = \"Baseline\"; ObjectID = \"OaQ-X3-Vso\"; */\n\"OaQ-X3-Vso.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide DevToys\"; ObjectID = \"Olw-nP-bQN\"; */\n\"Olw-nP-bQN.title\" = \"Hide DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"OwM-mh-QMV\"; */\n\"OwM-mh-QMV.title\" = \"Find Previous\";\n\n/* Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"Oyz-dy-DGm\"; */\n\"Oyz-dy-DGm.title\" = \"Stop Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Bigger\"; ObjectID = \"Ptp-SP-VEL\"; */\n\"Ptp-SP-VEL.title\" = \"Bigger\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Fonts\"; ObjectID = \"Q5e-8K-NDq\"; */\n\"Q5e-8K-NDq.title\" = \"Show Fonts\";\n\n/* Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"R4o-n2-Eq4\"; */\n\"R4o-n2-Eq4.title\" = \"Zoom\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"RB4-Sm-HuC\"; */\n\"RB4-Sm-HuC.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Superscript\"; ObjectID = \"Rqc-34-cIF\"; */\n\"Rqc-34-cIF.title\" = \"Superscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Ruw-6m-B2m\"; */\n\"Ruw-6m-B2m.title\" = \"Select All\";\n\n/* Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"S0p-oC-mLd\"; */\n\"S0p-oC-mLd.title\" = \"Jump to Selection\";\n\n/* Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"Td7-aD-5lo\"; */\n\"Td7-aD-5lo.title\" = \"Window\";\n\n/* Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"UEZ-Bs-lqG\"; */\n\"UEZ-Bs-lqG.title\" = \"Capitalize\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"VIY-Ag-zcb\"; */\n\"VIY-Ag-zcb.title\" = \"Center\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\"; */\n\"Vdr-fp-XzO.title\" = \"Hide Others\";\n\n/* Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"Vjx-xi-njq\"; */\n\"Vjx-xi-njq.title\" = \"Italic\";\n\n/* Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"W48-6f-4Dl\"; */\n\"W48-6f-4Dl.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Underline\"; ObjectID = \"WRG-CD-K1S\"; */\n\"WRG-CD-K1S.title\" = \"Underline\";\n\n/* Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"Was-JA-tGl\"; */\n\"Was-JA-tGl.title\" = \"New\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"WeT-3V-zwk\"; */\n\"WeT-3V-zwk.title\" = \"Paste and Match Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"Xz5-n4-O0W\"; */\n\"Xz5-n4-O0W.title\" = \"Find…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"YEy-JH-Tfz\"; */\n\"YEy-JH-Tfz.title\" = \"Find and Replace…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"YGs-j5-SAR\"; */\n\"YGs-j5-SAR.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"Ynk-f8-cLZ\"; */\n\"Ynk-f8-cLZ.title\" = \"Start Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Left\"; ObjectID = \"ZM1-6Q-yy1\"; */\n\"ZM1-6Q-yy1.title\" = \"Align Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Paragraph\"; ObjectID = \"ZvO-Gk-QUH\"; */\n\"ZvO-Gk-QUH.title\" = \"Paragraph\";\n\n/* Class = \"NSMenuItem\"; title = \"Print…\"; ObjectID = \"aTl-1u-JFS\"; */\n\"aTl-1u-JFS.title\" = \"Print…\";\n\n/* Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"aUF-d1-5bR\"; */\n\"aUF-d1-5bR.title\" = \"Window\";\n\n/* Class = \"NSMenu\"; title = \"Font\"; ObjectID = \"aXa-aM-Jaq\"; */\n\"aXa-aM-Jaq.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"agt-UL-0e3\"; */\n\"agt-UL-0e3.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Colors\"; ObjectID = \"bgn-CT-cEk\"; */\n\"bgn-CT-cEk.title\" = \"Show Colors\";\n\n/* Class = \"NSMenu\"; title = \"File\"; ObjectID = \"bib-Uj-vzu\"; */\n\"bib-Uj-vzu.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"buJ-ug-pKt\"; */\n\"buJ-ug-pKt.title\" = \"Use Selection for Find\";\n\n/* Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"c8a-y6-VQd\"; */\n\"c8a-y6-VQd.title\" = \"Transformations\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"cDB-IK-hbR\"; */\n\"cDB-IK-hbR.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Selection\"; ObjectID = \"cqv-fj-IhA\"; */\n\"cqv-fj-IhA.title\" = \"Selection\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"cwL-P1-jid\"; */\n\"cwL-P1-jid.title\" = \"Smart Links\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"d9M-CD-aMd\"; */\n\"d9M-CD-aMd.title\" = \"Make Lower Case\";\n\n/* Class = \"NSMenu\"; title = \"Text\"; ObjectID = \"d9c-me-L2H\"; */\n\"d9c-me-L2H.title\" = \"Text\";\n\n/* Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"dMs-cI-mzQ\"; */\n\"dMs-cI-mzQ.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"dRJ-4n-Yzg\"; */\n\"dRJ-4n-Yzg.title\" = \"Undo\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"gVA-U4-sdL\"; */\n\"gVA-U4-sdL.title\" = \"Paste\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"hQb-2v-fYv\"; */\n\"hQb-2v-fYv.title\" = \"Smart Quotes\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"hz2-CU-CR7\"; */\n\"hz2-CU-CR7.title\" = \"Check Document Now\";\n\n/* Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\"; */\n\"hz9-B4-Xy5.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"Smaller\"; ObjectID = \"i1d-Er-qST\"; */\n\"i1d-Er-qST.title\" = \"Smaller\";\n\n/* Class = \"NSMenu\"; title = \"Baseline\"; ObjectID = \"ijk-EB-dga\"; */\n\"ijk-EB-dga.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Kern\"; ObjectID = \"jBQ-r6-VK2\"; */\n\"jBQ-r6-VK2.title\" = \"Kern\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"jFq-tB-4Kx\"; */\n\"jFq-tB-4Kx.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"jxT-CU-nIS\"; */\n\"jxT-CU-nIS.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Sidebar\"; ObjectID = \"kIP-vf-haE\"; */\n\"kIP-vf-haE.title\" = \"Show Sidebar\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"mK6-2p-4JG\"; */\n\"mK6-2p-4JG.title\" = \"Check Grammar With Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Ligatures\"; ObjectID = \"o6e-r0-MWq\"; */\n\"o6e-r0-MWq.title\" = \"Ligatures\";\n\n/* Class = \"NSMenu\"; title = \"Open Recent\"; ObjectID = \"oas-Oc-fiZ\"; */\n\"oas-Oc-fiZ.title\" = \"Open Recent\";\n\n/* Class = \"NSMenuItem\"; title = \"Loosen\"; ObjectID = \"ogc-rX-tC1\"; */\n\"ogc-rX-tC1.title\" = \"Loosen\";\n\n/* Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"pa3-QI-u2k\"; */\n\"pa3-QI-u2k.title\" = \"Delete\";\n\n/* Class = \"NSMenuItem\"; title = \"Save…\"; ObjectID = \"pxx-59-PXV\"; */\n\"pxx-59-PXV.title\" = \"Save…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"q09-fT-Sye\"; */\n\"q09-fT-Sye.title\" = \"Find Next\";\n\n/* Class = \"NSMenuItem\"; title = \"Page Setup…\"; ObjectID = \"qIS-W8-SiK\"; */\n\"qIS-W8-SiK.title\" = \"Page Setup…\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"rbD-Rh-wIN\"; */\n\"rbD-Rh-wIN.title\" = \"Check Spelling While Typing\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"rgM-f4-ycn\"; */\n\"rgM-f4-ycn.title\" = \"Smart Dashes\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Toolbar\"; ObjectID = \"snW-S8-Cw5\"; */\n\"snW-S8-Cw5.title\" = \"Show Toolbar\";\n\n/* Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\"; */\n\"tRr-pd-1PS.title\" = \"Data Detectors\";\n\n/* Class = \"NSMenuItem\"; title = \"Open Recent\"; ObjectID = \"tXI-mr-wws\"; */\n\"tXI-mr-wws.title\" = \"Open Recent\";\n\n/* Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"tlD-Oa-oAM\"; */\n\"tlD-Oa-oAM.title\" = \"Kern\";\n\n/* Class = \"NSMenu\"; title = \"DevToys\"; ObjectID = \"uQy-DD-JDr\"; */\n\"uQy-DD-JDr.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"uRl-iY-unG\"; */\n\"uRl-iY-unG.title\" = \"Cut\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Style\"; ObjectID = \"vKC-jM-MkH\"; */\n\"vKC-jM-MkH.title\" = \"Paste Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Ruler\"; ObjectID = \"vLm-3I-IUL\"; */\n\"vLm-3I-IUL.title\" = \"Show Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Clear Menu\"; ObjectID = \"vNY-rz-j42\"; */\n\"vNY-rz-j42.title\" = \"Clear Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\"; */\n\"vmV-6d-7jI.title\" = \"Make Upper Case\";\n\n/* Class = \"NSMenu\"; title = \"Ligatures\"; ObjectID = \"w0m-vy-SC9\"; */\n\"w0m-vy-SC9.title\" = \"Ligatures\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Right\"; ObjectID = \"wb2-vD-lq4\"; */\n\"wb2-vD-lq4.title\" = \"Align Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"wpr-3q-Mcd\"; */\n\"wpr-3q-Mcd.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"x3v-GG-iWU\"; */\n\"x3v-GG-iWU.title\" = \"Copy\";\n\n/* Class = \"NSMenuItem\"; title = \"Use All\"; ObjectID = \"xQD-1f-W4t\"; */\n\"xQD-1f-W4t.title\" = \"Use All\";\n\n/* Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"xrE-MZ-jX0\"; */\n\"xrE-MZ-jX0.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"z6F-FW-3nz\"; */\n\"z6F-FW-3nz.title\" = \"Show Substitutions\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/es.lproj/Localizable.strings",
    "content": "/*\n  Localizable.strings\n  DevToys\n\n  Created by RodrigoTomeES on 2022/02/13.\n  \n*/\n\n// - General -\n\"Configuration\" = \"Configuración\";\n\"Format\" = \"Formatear\";\n\"Pretty\" = \"Pretty\";\n\"Minified\" = \"Minificado\";\n\"Encoded\" = \"Codificado\";\n\"Decoded\" = \"Decodificado\";\n\"File\" = \"Archivo\";\n\"Text\" = \"Texto\";\n\"Copy\" = \"Copiar\";\n\"Paste\" = \"Pegar\";\n\"Copied!\" = \"Copiado!\";\n\"Pasted!\" = \"Pegado\";\n\"Open\" = \"Abrir\";\n\"Export\" = \"Exportar\";\n\"Import\" = \"Importar\";\n\"Input\" = \"Entrada\";\n\"Output\" = \"Salida\";\n\"No selection\" = \"Sin selección\";\n\"Drop Files Here\" = \"Suelte los archivos aquí\";\n\"Untitled Tool\" = \"Herramienta sin título\";\n\"Uppercase\" = \"Mayúscula\";\n\"Hyphens\" = \"Guiones\";\n\"Type\" = \"Tipo\";\n\"Length\" = \"Longitud\";\n\"Convert\" = \"Convertir\";\n\"Information\" = \"Información\";\n\"Clear\" = \"Limpiar\";\n\"Delete\" = \"Eliminar\";\n\n// - Category -\n\"category.home\" = \"Todas las herramientas\";\n\"category.converters\" = \"Conversores\";\n\"category.encoders_decoders\" = \"Codificadores / Decodificadores\";\n\"category.formatters\" = \"Formateadores\";\n\"category.generators\" = \"Generadores\";\n\"category.text\" = \"Texto\";\n\"category.graphic\" = \"Gráficos\";\n\n// - Tool -\n\"tool.home.title\" = \"Todas las herramientas\";\n\"tool.home.mintitle\" = \"Todas las herramientas\";\n\"tool.home.description\" = \"Busca todas las herramientas aquí.\";\n\n\"tool.jsonyaml.title\" = \"Conversor JSON <> Yaml\";\n\"tool.jsonyaml.mintitle\" = \"JSON <> Yaml\";\n\"tool.jsonyaml.description\" = \"Convertir datos Json a Yaml y viceversa\";\n\n\"tool.numbase.title\" = \"Conversor de bases numéricas\";\n\"tool.numbase.mintitle\" = \"Base numérica\";\n\"tool.numbase.description\" = \"Convertir números desde una base a otra\";\n\"Format Number\" = \"Formato del número\";\n\"Decimal\" = \"Decimal\";\n\"Hexdecimal\" = \"Hexadecimal\";\n\"Octal\" = \"Octal\";\n\"Binary\" = \"Binario\";\n\n\"tool.date.title\" = \"Conversor de fechas\";\n\"tool.date.mintitle\" = \"Fecha\";\n\"tool.date.description\" = \"Convierte fechas de un formato a otro\";\n\"Now\" = \"Ahora\";\n\"Date\" = \"Fecha\";\n\"Unix Time\" = \"Formato Unix\";\n\"ISO 8601\" = \"ISO 8601\";\n\"Calender\" = \"Calendario\";\n\n\"tool.html.title\" = \"Codificador / Decodificador de HTML\";\n\"tool.html.mintitle\" = \"HTML\";\n\"tool.html.description\" = \"Codifica o decodifica todos los caracteres aplicables a HTML\";\n\n\"tool.url.title\" = \"Codificador / Decodificador de URLs\";\n\"tool.url.mintitle\" = \"URL\";\n\"tool.url.description\" = \"Codifica o decodifica todos los caracteres aplicables a URLs\";\n\n\"tool.base64.title\" = \"Codificador / Decodificador de Base64\";\n\"tool.base64.mintitle\" = \"Base64\";\n\"tool.base64.description\" = \"Codifica o decodifica datos en Base64\";\n\"Source Type\" = \"Tipo de fuente\";\n\"Text Source\" = \"Tipo texto\";\n\"File Source\" = \"Tipo fichero\";\n\n\"tool.jwt.title\" = \"Codificador / Decodificador de JWT\";\n\"tool.jwt.mintitle\" = \"JWT\";\n\"tool.jwt.description\" = \"Decodifica la carga útil y firma de encabezado de JWT\";\n\"JWT Token\" = \"JWT Token\";\n\"Header\" = \"Header\";\n\"Payload\" = \"Payload\";\n\n\"tool.jsonformat.title\" = \"Formateador de JSON\";\n\"tool.jsonformat.mintitle\" = \"JSON\";\n\"tool.jsonformat.description\" = \"Indenta o minifica JSON\";\n\"Indentation\" = \"Indentación\";\n\"2 Spaces\" = \"2 espacios\";\n\"4 Spaces\" = \"4 espacios\";\n\"1 Tab\" = \"1 tab\";\n\n\"tool.xmlformat.title\" = \"Formateador de XML\";\n\"tool.xmlformat.mintitle\" = \"XML\";\n\"tool.xmlformat.description\" = \"Indenta o minifica XML\";\n\"HTML Document\" = \"Documento HTML\";\n\"XML Document\" = \"Documento XML\";\n\"Document Type\" = \"Tipo de documento\";\n\"Auto Fix Document\" = \"Corrección automática del documento\";\n\"Pretty Document\" = \"Embellecer documento\";\n\n\"tool.hashgen.title\" = \"Generador de Hash\";\n\"tool.hashgen.mintitle\" = \"Hash\";\n\"tool.hashgen.description\" = \"Calcular el hash en MD5, SHA1, SHA256 y SHA 512 de datos de texto\";\n\n\"tool.uuidgen.title\" = \"Generador de UUID\";\n\"tool.uuidgen.mintitle\" = \"UUID\";\n\"tool.uuidgen.description\" = \"Generar UUIDs\";\n\"Generate UUIDs\" = \"Generar UUIDs\";\n\n\"tool.ligen.title\" = \"Generador de Lorem Ipsum\";\n\"tool.ligen.mintitle\" = \"Lorem Ipsum\";\n\"tool.ligen.description\" = \"Generar Lorem Ipsum\";\n\"Type of generating Lorem Ipsum\" = \"Tipo de generación de Lorem Ipsum\";\n\"Length of generating Lorem Ipsum\" = \"Longitud de la generación de Lorem Ipsum\";\n\"Words\" = \"Palabras\";\n\"Sentences\" = \"Frases\";\n\"Paragraphs\" = \"Párrafos\";\n\n\"tool.checksum.title\" = \"Generador de Checksum\";\n\"tool.checksum.mintitle\" = \"Checksum\";\n\"tool.checksum.description\" = \"Genera o comprueba el checksum de un fichero\";\n\"Output Comparer\" = \"Comparar resultado\";\n\"Hash Algorithm\" = \"Algoritmo de hash\";\n\"Select which algorithm you want to use\" = \"Selecciona el algoritmo que quieres usar\";\n\n\"tool.checksum.title\" = \"Generador de Checksum\";\n\"tool.checksum.mintitle\" = \"Checksum\";\n\"tool.checksum.description\" = \"Genera o comprueba el checksum de un fichero\";\n\n\"tool.textinspect.title\" = \"Inspector y conversor de texto\";\n\"tool.textinspect.mintitle\" = \"Inspector y conversor de mayúsculas\";\n\"tool.textinspect.description\" = \"Analiza el texto y convierto a distintos formatos de texto\";\n\"Charactors\" = \"Caracteres\";\n\"Words\" = \"Palabras\";\n\"Lines\" = \"Líneas\";\n\"Bytes\" = \"Bytes\";\n\n\"tool.regex.title\" = \"Evaluador de expresiones regulares\";\n\"tool.regex.mintitle\" = \"Evaluador de Regex\";\n\"tool.regex.description\" = \"Comprueba expresiones regulares\";\n\"Reguler expression\" = \"Expresión regular\";\n\n\"tool.hyphenremove.title\" = \"Eliminador de guiones\";\n\"tool.hyphenremove.mintitle\" = \"Eliminador de guiones\";\n\"tool.hyphenremove.description\" = \"Elimina guiones de textos copiados de un PDF\";\n\n\"tool.imageoptim.title\" = \"Compresor de PNG / JPEG\";\n\"tool.imageoptim.mintitle\" = \"Compresor de PNG / JPEG\";\n\"tool.imageoptim.description\" = \"Optimizador de JPEG y PNG sin perdida\";\n\"Optimize Level\" = \"Nivel de la optimización\";\n\"Low\" = \"Bajo\";\n\"Medium\" = \"Medio\";\n\"High\" = \"Alto\";\n\"Very High (Slow)\" = \"Muy alto (lento)\";\n\n\"tool.pdfgen.title\" = \"Generador de PDFs\";\n\"tool.pdfgen.mintitle\" = \"Generador de PDFs\";\n\"tool.pdfgen.description\" = \"Genera un PDF de multiples imágenes\";\n\"Images\" = \"Imágenes\";\n\"Size\" = \"Tamaño\";\n\"Generate PDF\" = \"Generar PDF\";\n\"Page\" = \"Página\";\n\n\"tool.imageconvert.title\" = \"Conversor de imágenes\";\n\"tool.imageconvert.mintitle\" = \"Conversor de imágenes\";\n\"tool.imageconvert.description\" = \"Convierte o redimensiona imágenes\";\n\"PNG Format\" = \"Formato PNG\";\n\"JPEG Format\" = \"Formato JPEG\";\n\"TIFF Format\" = \"Formato TIFF\";\n\"GIF Format\" = \"Formato GIF\";\n\"Scale to Fill\" = \"Scale to Fill\";\n\"Scale to Fit\" = \"Scale to Fit\";\n\"Image Format\" = \"Formato de imágen\";\n\"Resize\" = \"Redimensionar\";\n\"Converted Images\" = \"Imágenes convertidas\";\n\"Scale\" = \"Escala\";\n\"Size\" = \"Tamaño\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/es.lproj/Main.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Customize Toolbar…\"; ObjectID = \"1UK-8n-QPP\"; */\n\"1UK-8n-QPP.title\" = \"Personalizar barra de herramientas…\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys\"; ObjectID = \"1Xt-HY-uBw\"; */\n\"1Xt-HY-uBw.title\" = \"DevToys\";\n\n/* Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"1b7-l0-nxx\"; */\n\"1b7-l0-nxx.title\" = \"Buscar\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower\"; ObjectID = \"1tx-W0-xDw\"; */\n\"1tx-W0-xDw.title\" = \"Disminuir\";\n\n/* Class = \"NSMenuItem\"; title = \"Raise\"; ObjectID = \"2h7-ER-AoG\"; */\n\"2h7-ER-AoG.title\" = \"Aumentar\";\n\n/* Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"2oI-Rn-ZJC\"; */\n\"2oI-Rn-ZJC.title\" = \"Transformaciones\";\n\n/* Class = \"NSMenu\"; title = \"Spelling\"; ObjectID = \"3IN-sU-3Bg\"; */\n\"3IN-sU-3Bg.title\" = \"Ortografía\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"3Om-Ey-2VK\"; */\n\"3Om-Ey-2VK.title\" = \"Usar valor por defecto\";\n\n/* Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"3rS-ZA-NoH\"; */\n\"3rS-ZA-NoH.title\" = \"Iniciar dictado...\";\n\n/* Class = \"NSMenuItem\"; title = \"Tighten\"; ObjectID = \"46P-cB-AYj\"; */\n\"46P-cB-AYj.title\" = \"Apertar\";\n\n/* Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"4EN-yA-p0u\"; */\n\"4EN-yA-p0u.title\" = \"Buscar\";\n\n/* Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"4J7-dP-txa\"; */\n\"4J7-dP-txa.title\" = \"Usar pantalla completa\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit DevToys\"; ObjectID = \"4sb-4s-VLi\"; */\n\"4sb-4s-VLi.title\" = \"Salir de DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"5QF-Oa-p0T\"; */\n\"5QF-Oa-p0T.title\" = \"Editar\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Style\"; ObjectID = \"5Vv-lz-BsD\"; */\n\"5Vv-lz-BsD.title\" = \"Copiar estilo\";\n\n/* Class = \"NSMenuItem\"; title = \"About DevToys\"; ObjectID = \"5kV-Vb-QxS\"; */\n\"5kV-Vb-QxS.title\" = \"Acerca de DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"6dh-zS-Vam\"; */\n\"6dh-zS-Vam.title\" = \"Rehacer\";\n\n/* Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"78Y-hA-62v\"; */\n\"78Y-hA-62v.title\" = \"Corregir ortografía automáticamente\";\n\n/* Class = \"NSMenu\"; title = \"Writing Direction\"; ObjectID = \"8mr-sm-Yjd\"; */\n\"8mr-sm-Yjd.title\" = \"Dirección de escritura\";\n\n/* Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"9ic-FL-obx\"; */\n\"9ic-FL-obx.title\" = \"Sustituciones\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"9yt-4B-nSM\"; */\n\"9yt-4B-nSM.title\" = \"Copiar/Pegar inteligente\";\n\n/* Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\"; */\n\"AYu-sK-qS6.title\" = \"Menú Principal\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\"; */\n\"BOF-NM-1cW.title\" = \"Preferencias...\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"BgM-ve-c93\"; */\n\"BgM-ve-c93.title\" = \"\\tIzquierda a derecha\";\n\n/* Class = \"NSMenuItem\"; title = \"Save As…\"; ObjectID = \"Bw7-FT-i3A\"; */\n\"Bw7-FT-i3A.title\" = \"Guardar como...\";\n\n/* Class = \"NSMenuItem\"; title = \"Close\"; ObjectID = \"DVo-aG-piG\"; */\n\"DVo-aG-piG.title\" = \"Cerrar\";\n\n/* Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"Dv1-io-Yv7\"; */\n\"Dv1-io-Yv7.title\" = \"Ortografía y gramática\";\n\n/* Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"F2S-fz-NVQ\"; */\n\"F2S-fz-NVQ.title\" = \"Ayuda\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys Help\"; ObjectID = \"FKE-Sm-Kum\"; */\n\"FKE-Sm-Kum.title\" = \"Ayuda de DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Text\"; ObjectID = \"Fal-I4-PZk\"; */\n\"Fal-I4-PZk.title\" = \"Texto\";\n\n/* Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"FeM-D8-WVr\"; */\n\"FeM-D8-WVr.title\" = \"Sustituciones\";\n\n/* Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"GB9-OM-e27\"; */\n\"GB9-OM-e27.title\" = \"Negrita\";\n\n/* Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"GEO-Iw-cKr\"; */\n\"GEO-Iw-cKr.title\" = \"Formato\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"GUa-eO-cwY\"; */\n\"GUa-eO-cwY.title\" = \"Usar valor por defecto\";\n\n/* Class = \"NSMenuItem\"; title = \"Font\"; ObjectID = \"Gi5-1S-RQB\"; */\n\"Gi5-1S-RQB.title\" = \"Fuente\";\n\n/* Class = \"NSMenuItem\"; title = \"Writing Direction\"; ObjectID = \"H1b-Si-o9J\"; */\n\"H1b-Si-o9J.title\" = \"Dirección de escritura\";\n\n/* Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"H8h-7b-M4v\"; */\n\"H8h-7b-M4v.title\" = \"Ver\";\n\n/* Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"HFQ-gK-NFA\"; */\n\"HFQ-gK-NFA.title\" = \"Reemplazar texto\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"HFo-cy-zxI\"; */\n\"HFo-cy-zxI.title\" = \"Mostrar ortografía y gramática\";\n\n/* Class = \"NSMenu\"; title = \"View\"; ObjectID = \"HyV-fh-RgO\"; */\n\"HyV-fh-RgO.title\" = \"Ver\";\n\n/* Class = \"NSMenuItem\"; title = \"Subscript\"; ObjectID = \"I0S-gh-46l\"; */\n\"I0S-gh-46l.title\" = \"Subíndice\";\n\n/* Class = \"NSMenuItem\"; title = \"Open…\"; ObjectID = \"IAo-SY-fd9\"; */\n\"IAo-SY-fd9.title\" = \"Abrir...\";\n\n/* Class = \"NSWindow\"; title = \"DevToys\"; ObjectID = \"IQv-IB-iLA\"; */\n\"IQv-IB-iLA.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Justify\"; ObjectID = \"J5U-5w-g23\"; */\n\"J5U-5w-g23.title\" = \"Justificar\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"J7y-lM-qPV\"; */\n\"J7y-lM-qPV.title\" = \"Sin estilos\";\n\n/* Class = \"NSMenuItem\"; title = \"Revert to Saved\"; ObjectID = \"KaW-ft-85H\"; */\n\"KaW-ft-85H.title\" = \"Volver al guardado anterior\";\n\n/* Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\"; */\n\"Kd2-mp-pUS.title\" = \"Mostrar todo\";\n\n/* Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"LE2-aR-0XJ\"; */\n\"LE2-aR-0XJ.title\" = \"Traer todo al frente\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Ruler\"; ObjectID = \"LVM-kO-fVI\"; */\n\"LVM-kO-fVI.title\" = \"Pegar regla\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"Lbh-J2-qVU\"; */\n\"Lbh-J2-qVU.title\" = \"\\tIzquierda a derecha\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Ruler\"; ObjectID = \"MkV-Pr-PK5\"; */\n\"MkV-Pr-PK5.title\" = \"Copiar regla\";\n\n/* Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\"; */\n\"NMo-om-nkz.title\" = \"Servicios\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"Nop-cj-93Q\"; */\n\"Nop-cj-93Q.title\" = \"\\tValor por defecto\";\n\n/* Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"OY7-WF-poV\"; */\n\"OY7-WF-poV.title\" = \"Minimizar\";\n\n/* Class = \"NSMenuItem\"; title = \"Baseline\"; ObjectID = \"OaQ-X3-Vso\"; */\n\"OaQ-X3-Vso.title\" = \"Línea base\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide DevToys\"; ObjectID = \"Olw-nP-bQN\"; */\n\"Olw-nP-bQN.title\" = \"Ocultar DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"OwM-mh-QMV\"; */\n\"OwM-mh-QMV.title\" = \"Encontrar anterior\";\n\n/* Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"Oyz-dy-DGm\"; */\n\"Oyz-dy-DGm.title\" = \"Parar dictado\";\n\n/* Class = \"NSMenuItem\"; title = \"Bigger\"; ObjectID = \"Ptp-SP-VEL\"; */\n\"Ptp-SP-VEL.title\" = \"Aumentar\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Fonts\"; ObjectID = \"Q5e-8K-NDq\"; */\n\"Q5e-8K-NDq.title\" = \"Mostrar fuentes\";\n\n/* Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"R4o-n2-Eq4\"; */\n\"R4o-n2-Eq4.title\" = \"Zoom\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"RB4-Sm-HuC\"; */\n\"RB4-Sm-HuC.title\" = \"\\tDerecha a izquierda\";\n\n/* Class = \"NSMenuItem\"; title = \"Superscript\"; ObjectID = \"Rqc-34-cIF\"; */\n\"Rqc-34-cIF.title\" = \"Superíndice\";\n\n/* Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Ruw-6m-B2m\"; */\n\"Ruw-6m-B2m.title\" = \"Seleccionar todo\";\n\n/* Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"S0p-oC-mLd\"; */\n\"S0p-oC-mLd.title\" = \"Saltar a la selección\";\n\n/* Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"Td7-aD-5lo\"; */\n\"Td7-aD-5lo.title\" = \"Ventana\";\n\n/* Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"UEZ-Bs-lqG\"; */\n\"UEZ-Bs-lqG.title\" = \"Capitalizar\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"VIY-Ag-zcb\"; */\n\"VIY-Ag-zcb.title\" = \"Centrar\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\"; */\n\"Vdr-fp-XzO.title\" = \"Ocultar otros\";\n\n/* Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"Vjx-xi-njq\"; */\n\"Vjx-xi-njq.title\" = \"Itálica\";\n\n/* Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"W48-6f-4Dl\"; */\n\"W48-6f-4Dl.title\" = \"Editar\";\n\n/* Class = \"NSMenuItem\"; title = \"Underline\"; ObjectID = \"WRG-CD-K1S\"; */\n\"WRG-CD-K1S.title\" = \"Subrayar\";\n\n/* Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"Was-JA-tGl\"; */\n\"Was-JA-tGl.title\" = \"Nueva ventana\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"WeT-3V-zwk\"; */\n\"WeT-3V-zwk.title\" = \"Pegar y combinar estilo\";\n\n/* Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"Xz5-n4-O0W\"; */\n\"Xz5-n4-O0W.title\" = \"Buscar...\";\n\n/* Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"YEy-JH-Tfz\"; */\n\"YEy-JH-Tfz.title\" = \"Buscar y reemplazar...\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"YGs-j5-SAR\"; */\n\"YGs-j5-SAR.title\" = \"\\tValor por defecto\";\n\n/* Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"Ynk-f8-cLZ\"; */\n\"Ynk-f8-cLZ.title\" = \"Comenzar dictado\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Left\"; ObjectID = \"ZM1-6Q-yy1\"; */\n\"ZM1-6Q-yy1.title\" = \"Alinear a la izquierda\";\n\n/* Class = \"NSMenuItem\"; title = \"Paragraph\"; ObjectID = \"ZvO-Gk-QUH\"; */\n\"ZvO-Gk-QUH.title\" = \"Parrafo\";\n\n/* Class = \"NSMenuItem\"; title = \"Print…\"; ObjectID = \"aTl-1u-JFS\"; */\n\"aTl-1u-JFS.title\" = \"Imprimir...\";\n\n/* Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"aUF-d1-5bR\"; */\n\"aUF-d1-5bR.title\" = \"Ventana\";\n\n/* Class = \"NSMenu\"; title = \"Font\"; ObjectID = \"aXa-aM-Jaq\"; */\n\"aXa-aM-Jaq.title\" = \"Fuente\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"agt-UL-0e3\"; */\n\"agt-UL-0e3.title\" = \"Usar valor por defecto\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Colors\"; ObjectID = \"bgn-CT-cEk\"; */\n\"bgn-CT-cEk.title\" = \"Mostrar colores\";\n\n/* Class = \"NSMenu\"; title = \"File\"; ObjectID = \"bib-Uj-vzu\"; */\n\"bib-Uj-vzu.title\" = \"Archivo\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"buJ-ug-pKt\"; */\n\"buJ-ug-pKt.title\" = \"Usar selección para buscar\";\n\n/* Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"c8a-y6-VQd\"; */\n\"c8a-y6-VQd.title\" = \"Transformaciones\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"cDB-IK-hbR\"; */\n\"cDB-IK-hbR.title\" = \"Sin estilos\";\n\n/* Class = \"NSMenuItem\"; title = \"Selection\"; ObjectID = \"cqv-fj-IhA\"; */\n\"cqv-fj-IhA.title\" = \"Selección\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"cwL-P1-jid\"; */\n\"cwL-P1-jid.title\" = \"Enlaces inteligentes\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"d9M-CD-aMd\"; */\n\"d9M-CD-aMd.title\" = \"Convertir a minúsculas\";\n\n/* Class = \"NSMenu\"; title = \"Text\"; ObjectID = \"d9c-me-L2H\"; */\n\"d9c-me-L2H.title\" = \"Texto\";\n\n/* Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"dMs-cI-mzQ\"; */\n\"dMs-cI-mzQ.title\" = \"Archivo\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"dRJ-4n-Yzg\"; */\n\"dRJ-4n-Yzg.title\" = \"Deshacer\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"gVA-U4-sdL\"; */\n\"gVA-U4-sdL.title\" = \"Pegar\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"hQb-2v-fYv\"; */\n\"hQb-2v-fYv.title\" = \"Citas inteligentes\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"hz2-CU-CR7\"; */\n\"hz2-CU-CR7.title\" = \"Comprobar el documento ahora\";\n\n/* Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\"; */\n\"hz9-B4-Xy5.title\" = \"Servicios\";\n\n/* Class = \"NSMenuItem\"; title = \"Smaller\"; ObjectID = \"i1d-Er-qST\"; */\n\"i1d-Er-qST.title\" = \"Disminuir\";\n\n/* Class = \"NSMenu\"; title = \"Baseline\"; ObjectID = \"ijk-EB-dga\"; */\n\"ijk-EB-dga.title\" = \"Línea base\";\n\n/* Class = \"NSMenuItem\"; title = \"Kern\"; ObjectID = \"jBQ-r6-VK2\"; */\n\"jBQ-r6-VK2.title\" = \"Interletraje\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"jFq-tB-4Kx\"; */\n\"jFq-tB-4Kx.title\" = \"\\tDerecha a izquierda\";\n\n/* Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"jxT-CU-nIS\"; */\n\"jxT-CU-nIS.title\" = \"Formato\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Sidebar\"; ObjectID = \"kIP-vf-haE\"; */\n\"kIP-vf-haE.title\" = \"Mostrar barra lateral\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"mK6-2p-4JG\"; */\n\"mK6-2p-4JG.title\" = \"Comprobar la gramática con la ortografía\";\n\n/* Class = \"NSMenuItem\"; title = \"Ligatures\"; ObjectID = \"o6e-r0-MWq\"; */\n\"o6e-r0-MWq.title\" = \"Ligaduras\";\n\n/* Class = \"NSMenu\"; title = \"Open Recent\"; ObjectID = \"oas-Oc-fiZ\"; */\n\"oas-Oc-fiZ.title\" = \"Abrir reciente\";\n\n/* Class = \"NSMenuItem\"; title = \"Loosen\"; ObjectID = \"ogc-rX-tC1\"; */\n\"ogc-rX-tC1.title\" = \"Soltar\";\n\n/* Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"pa3-QI-u2k\"; */\n\"pa3-QI-u2k.title\" = \"Eliminar\";\n\n/* Class = \"NSMenuItem\"; title = \"Save…\"; ObjectID = \"pxx-59-PXV\"; */\n\"pxx-59-PXV.title\" = \"Guardar...\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"q09-fT-Sye\"; */\n\"q09-fT-Sye.title\" = \"Encontrar próximo\";\n\n/* Class = \"NSMenuItem\"; title = \"Page Setup…\"; ObjectID = \"qIS-W8-SiK\"; */\n\"qIS-W8-SiK.title\" = \"Configuración de página...\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"rbD-Rh-wIN\"; */\n\"rbD-Rh-wIN.title\" = \"Revisar la ortografía mientras se escribe\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"rgM-f4-ycn\"; */\n\"rgM-f4-ycn.title\" = \"Guiones inteligentes\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Toolbar\"; ObjectID = \"snW-S8-Cw5\"; */\n\"snW-S8-Cw5.title\" = \"Mostrar barra de herramientas\";\n\n/* Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\"; */\n\"tRr-pd-1PS.title\" = \"Detectores de datos\";\n\n/* Class = \"NSMenuItem\"; title = \"Open Recent\"; ObjectID = \"tXI-mr-wws\"; */\n\"tXI-mr-wws.title\" = \"Abrir reciente\";\n\n/* Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"tlD-Oa-oAM\"; */\n\"tlD-Oa-oAM.title\" = \"Interletraje\";\n\n/* Class = \"NSMenu\"; title = \"DevToys\"; ObjectID = \"uQy-DD-JDr\"; */\n\"uQy-DD-JDr.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"uRl-iY-unG\"; */\n\"uRl-iY-unG.title\" = \"Cortar\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Style\"; ObjectID = \"vKC-jM-MkH\"; */\n\"vKC-jM-MkH.title\" = \"Pegar estilo\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Ruler\"; ObjectID = \"vLm-3I-IUL\"; */\n\"vLm-3I-IUL.title\" = \"Mostrar regla\";\n\n/* Class = \"NSMenuItem\"; title = \"Clear Menu\"; ObjectID = \"vNY-rz-j42\"; */\n\"vNY-rz-j42.title\" = \"Limpiar menú\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\"; */\n\"vmV-6d-7jI.title\" = \"Convertir a mayúsculas\";\n\n/* Class = \"NSMenu\"; title = \"Ligatures\"; ObjectID = \"w0m-vy-SC9\"; */\n\"w0m-vy-SC9.title\" = \"Ligaduras\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Right\"; ObjectID = \"wb2-vD-lq4\"; */\n\"wb2-vD-lq4.title\" = \"Alinear a la derecha\";\n\n/* Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"wpr-3q-Mcd\"; */\n\"wpr-3q-Mcd.title\" = \"Ayuda\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"x3v-GG-iWU\"; */\n\"x3v-GG-iWU.title\" = \"Copiar\";\n\n/* Class = \"NSMenuItem\"; title = \"Use All\"; ObjectID = \"xQD-1f-W4t\"; */\n\"xQD-1f-W4t.title\" = \"Usar todos\";\n\n/* Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"xrE-MZ-jX0\"; */\n\"xrE-MZ-jX0.title\" = \"Iniciar dictado...\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"z6F-FW-3nz\"; */\n\"z6F-FW-3nz.title\" = \"Mostrar substituciones\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/ja.lproj/Localizable.strings",
    "content": "/* \n  Localizable.strings\n  DevToys\n\n  Created by yuki on 2022/02/13.\n  \n*/\n\n// - General -\n\"Configuration\" = \"設定\";\n\"Format\" = \"フォーマット\";\n\"Pretty\" = \"美しく\";\n\"Minified\" = \"小さく\";\n\"Encoded\" = \"エンコード\";\n\"Decoded\" = \"デコード\";\n\"File\" = \"ファイル\";\n\"Text\" = \"テキスト\";\n\"Copy\" = \"コピー\";\n\"Paste\" = \"ペースト\";\n\"Copied!\" = \"コピーされました\";\n\"Pasted!\" = \"ペーストされました\";\n\"Open\" = \"開く\";\n\"Export\" = \"書き出し\";\n\"Import\" = \"開く...\";\n\"Input\" = \"入力\";\n\"Output\" = \"出力\";\n\"No selection\" = \"選択なし\";\n\"Drop Files Here\" = \"ここにファイルをドロップ\";\n\"Untitled Tool\" = \"無名のツール\";\n\"Uppercase\" = \"大文字\";\n\"Hyphens\" = \"ハイフン\";\n\"Type\" = \"種類\";\n\"Length\" = \"長さ\";\n\"Convert\" = \"変換\";\n\"Information\" = \"情報\";\n\"Charactors\" = \"文字数\";\n\"Words\" = \"単語数\";\n\"Lines\" = \"行数\";\n\"Bytes\" = \"バイト数\";\n\"Clear\" = \"クリア\";\n\"Delete\" = \"削除\";\n\"Open in Finder\" = \"Finderで開く\";\n\"Quick Look\" = \"クイックルック\";\n\"Default\" = \"デフォルト\";\n\n// - Category -\n\"category.home\" = \"ホーム\";\n\"category.converters\" = \"変換\";\n\"category.encoders_decoders\" = \"エンコード / デコード\";\n\"category.formatters\" = \"フォーマット\";\n\"category.generators\" = \"生成\";\n\"category.text\" = \"テキスト\";\n\"category.graphic\" = \"画像\";\n\"Media\" = \"メディア\";\n\n// - Tool -\n\"tool.home.title\" = \"ホーム\";\n\"tool.home.mintitle\" = \"ホーム\";\n\"tool.home.description\" = \"全てのツールをここで探せます\";\n\n\"tool.jsonyaml.title\" = \"JSONとYamlの変換\";\n\"tool.jsonyaml.mintitle\" = \"JSON/Yaml\";\n\"tool.jsonyaml.description\" = \"JSONとYamlを相互に変換します\";\n\n\"tool.numbase.title\" = \"基数の変換\";\n\"tool.numbase.mintitle\" = \"基数の変換\";\n\"tool.numbase.description\" = \"数値の進法を変換します\";\n\"Format Number\" = \"数値をフォーマット\";\n\"Decimal\" = \"10進数\";\n\"Hexdecimal\" = \"16進数\";\n\"Octal\" = \"8進数\";\n\"Binary\" = \"2進数\";\n\n\"tool.date.title\" = \"日付の変換\";\n\"tool.date.mintitle\" = \"日付の変換\";\n\"tool.date.description\" = \"日付の表現を変換します\";\n\"Now\" = \"現在\";\n\"Date\" = \"日付\";\n\"Unix Time\" = \"Unix時\";\n\"ISO 8601\" = \"ISO 8601\";\n\"Calender\" = \"カレンダー\";\n\n\"tool.html.title\" = \"HTMLのエンコード・デコード\";\n\"tool.html.mintitle\" = \"HTML\";\n\"tool.html.description\" = \"文字をHTMLエスケープ・アンエスケープします\";\n\n\"tool.url.title\" = \"URLのエンコード・デコード\";\n\"tool.url.mintitle\" = \"URL\";\n\"tool.url.description\" = \"文字をURLパーセントエンコード・逆パーセントエンコードします\";\n\n\"tool.base64.title\" = \"Base64エンコード・デコード\";\n\"tool.base64.mintitle\" = \"Base64\";\n\"tool.base64.description\" = \"文字・ファイルをBase64にエンコード・デコードします\";\n\"Source Type\" = \"入力\";\n\"Text Source\" = \"テキストを入力\";\n\"File Source\" = \"ファイルを入力\";\n\n\"tool.jwt.title\" = \"JWTのデコード\";\n\"tool.jwt.mintitle\" = \"JWT\";\n\"tool.jwt.description\" = \"JWTのヘッダ・ペイロードをデコードします\";\n\"JWT Token\" = \"JWTトークン\";\n\"Header\" = \"ヘッダ\";\n\"Payload\" = \"ペイロード\";\n\n\"tool.jsonformat.title\" = \"JSONのフォーマット\";\n\"tool.jsonformat.mintitle\" = \"JSON\";\n\"tool.jsonformat.description\" = \"JSONデータを美しく表示したり、最小化します\";\n\"Indentation\" = \"インデント\";\n\"2 Spaces\" = \"2スペース\";\n\"4 Spaces\" = \"4スペース\";\n\"1 Tab\" = \"1タブ\";\n\n\"tool.xmlformat.title\" = \"XMLのフォーマット\";\n\"tool.xmlformat.mintitle\" = \"XML\";\n\"tool.xmlformat.description\" = \"XMLデータを美しく表示したり、最小化します\";\n\"HTML Document\" = \"HTMLドキュメント\";\n\"XML Document\" = \"XMLドキュメント\";\n\"Document Type\" = \"ドキュメントの種類\";\n\"Auto Fix Document\" = \"自動修正\";\n\"Pretty Document\" = \"読みやすい表示\";\n\n\"tool.hashgen.title\" = \"Hashを生成\";\n\"tool.hashgen.mintitle\" = \"Hash\";\n\"tool.hashgen.description\" = \"テキストのMD5・SHA1・SHA256・SHA512を計算します\";\n\n\"tool.uuidgen.title\" = \"UUIDを生成\";\n\"tool.uuidgen.mintitle\" = \"UUID\";\n\"tool.uuidgen.description\" = \"UUIDsを生成します\";\n\"Generate UUIDs\" = \"UUIDを生成\";\n\n\"tool.ligen.title\" = \"Lorem Ipsumを生成\";\n\"tool.ligen.mintitle\" = \"Lorem Ipsum\";\n\"tool.ligen.description\" = \"Lorem Ipsumの単語・文・段落を生成します\";\n\"Type of generating Lorem Ipsum\" = \"生成するLorem Ipsumの種類\";\n\"Length of generating Lorem Ipsum\" = \"生成するLorem Ipsumの長さ\";\n\"Words\" = \"文字\";\n\"Sentences\" = \"文章\";\n\"Paragraphs\" = \"段落\";\n\n\"tool.checksum.title\" = \"Checksumを生成\";\n\"tool.checksum.mintitle\" = \"Checksum\";\n\"tool.checksum.description\" = \"ファイルのChecksumを生成・検証します\";\n\"Output Comparer\" = \"出力との比較\";\n\"Hash Algorithm\" = \"ハッシュのアルゴリズム\";\n\"Select which algorithm you want to use\" = \"使いたいアルゴリズムを選んでください\";\n\n\"tool.textinspect.title\" = \"テキストデータと文字変換\";\n\"tool.textinspect.mintitle\" = \"データと文字変換\";\n\"tool.textinspect.description\" = \"テキストのデータの解析・文字変換を行います\";\n\n\"tool.regex.title\" = \"正規表現のテスト\";\n\"tool.regex.mintitle\" = \"正規表現\";\n\"tool.regex.description\" = \"正規表現をテストします\";\n\"Reguler expression\" = \"正規表現\";\n\n\"tool.hyphenremove.title\" = \"ハイフン削除\";\n\"tool.hyphenremove.mintitle\" = \"ハイフン削除\";\n\"tool.hyphenremove.description\" = \"PDFテキストからコピーされたハイフンを削除します\";\n\n\"tool.imageoptim.title\" = \"PNG・JPEG最適化\";\n\"tool.imageoptim.mintitle\" = \"PNG・JPEG最適化\";\n\"tool.imageoptim.description\" = \"PNG・JPEG形式の画像を最適化してファイルサイズを小さくします\";\n\"Optimize Level\" = \"最適化レベル\";\n\"Low\" = \"低レベル\";\n\"Medium\" = \"中レベル\";\n\"High\" = \"高レベル\";\n\"Very High (Slow)\" = \"非常に高レベル (時間がかかります)\";\n\n\"tool.pdfgen.title\" = \"画像をPDF化\";\n\"tool.pdfgen.mintitle\" = \"画像をPDF化\";\n\"tool.pdfgen.description\" = \"複数枚の画像を1つのPDFファイルにまとめます\";\n\"Images\" = \"画像\";\n\"Size\" = \"サイズ\";\n\"Generate PDF\" = \"PDFを作成\";\n\"Page\" = \"ページ\";\n\n\"tool.imageconvert.title\" = \"画像の変換\";\n\"tool.imageconvert.mintitle\" = \"画像の変換\";\n\"tool.imageconvert.description\" = \"画像のフォーマットの変換やリサイズを行います\";\n\"PNG Format\" = \"PNG形式\";\n\"JPEG Format\" = \"JPEG形式\";\n\"TIFF Format\" = \"TIFF形式\";\n\"GIF Format\" = \"GIF形式\";\n\"Scale to Fill\" = \"サイズを埋める\";\n\"Scale to Fit\" = \"サイズ内に収める\";\n\"Image Format\" = \"フォーマット\";\n\"Resize\" = \"リサイズ\";\n\"Converted Images\" = \"変換した画像\";\n\"Scale\" = \"大きさの変換\";\n\"Size\" = \"サイズ\";\n\"Override original file\" = \"元のファイルを上書き\";\n\n\"QR Code Generator\" = \"QRコード作成\";\n\"Create a QR code from text\" = \"テキストからQRコードを作成します\";\n\"Correction Level\" = \"誤り復元\";\n\"QR Code\" = \"QRコード\";\n\n\"Settings\" = \"設定\";\n\"Setting of application\" = \"アプリの設定を行います\";\n\"App Theme\" = \"アプリのテーマ\";\n\"Select which app theme to display\" = \"表示に用いるテーマの選択\";\n\"Use system setting\" = \"自動\";\n\"Light mode\" = \"ライト\";\n\"Dark mode\" = \"ダーク\";\n\n\"Color Picker\" = \"カラーピッカー\";\n\"Picker the color and copy components\" = \"色を選択してフォーマットした文字列をコピーします\";\n\"HSB Box\" = \"HSBボックス\";\n\"HSB Circle\" = \"HSBサークル\";\n\"HSB Circle and Bars\" = \"HSB バー&サークル\";\n\"Pick Color\" = \"色を選択\";\n\"Picker Type\" = \"選択のタイプ\";\n\"Color Hex\" = \"Hex値\";\n\"Color Copy\" = \"色をコピー\";\n\"Color Copy Type\" = \"型\";\n\n\"Gif Converter\" = \"Gifへの変換\";\n\"Convert a movie to an animated GIF file\" = \"動画をアニメーションGifに変換します\";\n\"Width\" = \"幅\";\n\"The width of the Gif file\" = \"Gifファイルの横幅 (高さは自動決定されます)\";\n\"FPS\" = \"FPS\";\n\"FPS of the Gif file to be exported\" = \"書き出すGifファイルのFPS\";\n\"Remove source file\" = \"元ファイルを削除\";\n\"Whether to delete the source file after exporting a Gif\" = \"Gifファイル書き出し後に元ファイルを削除するか\";\n\n\"Audio Converter\" = \"音声フォーマット変換\";\n\"Convert audio from one format to another\" = \"音声ファイルのフォーマット・音質の変更を行います\";\n\"Whether to delete the source file after exporting a Audio\" = \"ファイル書き出し後に元ファイルを削除するか\";\n\"Starting...\" = \"初期化中...\";\n\"Complete\" = \"完了\";\n\"Convert Failed\" = \"変換失敗\";\n\n\"Text Diff\" = \"テキストの比較\";\n\"Compare two Text and display Diff\" = \"2つのテキストを比べて差分を表示します\";\n\"By Characters\" = \"文字\";\n\"By Words\" = \"単語\";\n\"By Lines\" = \"行\";\n\"Input 1\" = \"元のテキスト\";\n\"Input 2\" = \"変更後のテキスト\";\n\"Diff Style\" = \"差分の取り方\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/ja.lproj/Main.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Customize Toolbar…\"; ObjectID = \"1UK-8n-QPP\"; */\n\"1UK-8n-QPP.title\" = \"Customize Toolbar…\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys\"; ObjectID = \"1Xt-HY-uBw\"; */\n\"1Xt-HY-uBw.title\" = \"DevToys\";\n\n/* Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"1b7-l0-nxx\"; */\n\"1b7-l0-nxx.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower\"; ObjectID = \"1tx-W0-xDw\"; */\n\"1tx-W0-xDw.title\" = \"Lower\";\n\n/* Class = \"NSMenuItem\"; title = \"Raise\"; ObjectID = \"2h7-ER-AoG\"; */\n\"2h7-ER-AoG.title\" = \"Raise\";\n\n/* Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"2oI-Rn-ZJC\"; */\n\"2oI-Rn-ZJC.title\" = \"Transformations\";\n\n/* Class = \"NSMenu\"; title = \"Spelling\"; ObjectID = \"3IN-sU-3Bg\"; */\n\"3IN-sU-3Bg.title\" = \"Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"3Om-Ey-2VK\"; */\n\"3Om-Ey-2VK.title\" = \"Use Default\";\n\n/* Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"3rS-ZA-NoH\"; */\n\"3rS-ZA-NoH.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Tighten\"; ObjectID = \"46P-cB-AYj\"; */\n\"46P-cB-AYj.title\" = \"Tighten\";\n\n/* Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"4EN-yA-p0u\"; */\n\"4EN-yA-p0u.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"4J7-dP-txa\"; */\n\"4J7-dP-txa.title\" = \"Enter Full Screen\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit DevToys\"; ObjectID = \"4sb-4s-VLi\"; */\n\"4sb-4s-VLi.title\" = \"Quit DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"5QF-Oa-p0T\"; */\n\"5QF-Oa-p0T.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Style\"; ObjectID = \"5Vv-lz-BsD\"; */\n\"5Vv-lz-BsD.title\" = \"Copy Style\";\n\n/* Class = \"NSMenuItem\"; title = \"About DevToys\"; ObjectID = \"5kV-Vb-QxS\"; */\n\"5kV-Vb-QxS.title\" = \"About DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"6dh-zS-Vam\"; */\n\"6dh-zS-Vam.title\" = \"Redo\";\n\n/* Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"78Y-hA-62v\"; */\n\"78Y-hA-62v.title\" = \"Correct Spelling Automatically\";\n\n/* Class = \"NSMenu\"; title = \"Writing Direction\"; ObjectID = \"8mr-sm-Yjd\"; */\n\"8mr-sm-Yjd.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"9ic-FL-obx\"; */\n\"9ic-FL-obx.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"9yt-4B-nSM\"; */\n\"9yt-4B-nSM.title\" = \"Smart Copy/Paste\";\n\n/* Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\"; */\n\"AYu-sK-qS6.title\" = \"Main Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\"; */\n\"BOF-NM-1cW.title\" = \"Preferences…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"BgM-ve-c93\"; */\n\"BgM-ve-c93.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Save As…\"; ObjectID = \"Bw7-FT-i3A\"; */\n\"Bw7-FT-i3A.title\" = \"Save As…\";\n\n/* Class = \"NSMenuItem\"; title = \"Close\"; ObjectID = \"DVo-aG-piG\"; */\n\"DVo-aG-piG.title\" = \"Close\";\n\n/* Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"Dv1-io-Yv7\"; */\n\"Dv1-io-Yv7.title\" = \"Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"F2S-fz-NVQ\"; */\n\"F2S-fz-NVQ.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys Help\"; ObjectID = \"FKE-Sm-Kum\"; */\n\"FKE-Sm-Kum.title\" = \"DevToys Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Text\"; ObjectID = \"Fal-I4-PZk\"; */\n\"Fal-I4-PZk.title\" = \"Text\";\n\n/* Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"FeM-D8-WVr\"; */\n\"FeM-D8-WVr.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"GB9-OM-e27\"; */\n\"GB9-OM-e27.title\" = \"Bold\";\n\n/* Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"GEO-Iw-cKr\"; */\n\"GEO-Iw-cKr.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"GUa-eO-cwY\"; */\n\"GUa-eO-cwY.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Font\"; ObjectID = \"Gi5-1S-RQB\"; */\n\"Gi5-1S-RQB.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Writing Direction\"; ObjectID = \"H1b-Si-o9J\"; */\n\"H1b-Si-o9J.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"H8h-7b-M4v\"; */\n\"H8h-7b-M4v.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"HFQ-gK-NFA\"; */\n\"HFQ-gK-NFA.title\" = \"Text Replacement\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"HFo-cy-zxI\"; */\n\"HFo-cy-zxI.title\" = \"Show Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"View\"; ObjectID = \"HyV-fh-RgO\"; */\n\"HyV-fh-RgO.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Subscript\"; ObjectID = \"I0S-gh-46l\"; */\n\"I0S-gh-46l.title\" = \"Subscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Open…\"; ObjectID = \"IAo-SY-fd9\"; */\n\"IAo-SY-fd9.title\" = \"Open…\";\n\n/* Class = \"NSWindow\"; title = \"DevToys\"; ObjectID = \"IQv-IB-iLA\"; */\n\"IQv-IB-iLA.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Justify\"; ObjectID = \"J5U-5w-g23\"; */\n\"J5U-5w-g23.title\" = \"Justify\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"J7y-lM-qPV\"; */\n\"J7y-lM-qPV.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Revert to Saved\"; ObjectID = \"KaW-ft-85H\"; */\n\"KaW-ft-85H.title\" = \"Revert to Saved\";\n\n/* Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\"; */\n\"Kd2-mp-pUS.title\" = \"Show All\";\n\n/* Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"LE2-aR-0XJ\"; */\n\"LE2-aR-0XJ.title\" = \"Bring All to Front\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Ruler\"; ObjectID = \"LVM-kO-fVI\"; */\n\"LVM-kO-fVI.title\" = \"Paste Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"Lbh-J2-qVU\"; */\n\"Lbh-J2-qVU.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Ruler\"; ObjectID = \"MkV-Pr-PK5\"; */\n\"MkV-Pr-PK5.title\" = \"Copy Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\"; */\n\"NMo-om-nkz.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"Nop-cj-93Q\"; */\n\"Nop-cj-93Q.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"OY7-WF-poV\"; */\n\"OY7-WF-poV.title\" = \"Minimize\";\n\n/* Class = \"NSMenuItem\"; title = \"Baseline\"; ObjectID = \"OaQ-X3-Vso\"; */\n\"OaQ-X3-Vso.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide DevToys\"; ObjectID = \"Olw-nP-bQN\"; */\n\"Olw-nP-bQN.title\" = \"Hide DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"OwM-mh-QMV\"; */\n\"OwM-mh-QMV.title\" = \"Find Previous\";\n\n/* Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"Oyz-dy-DGm\"; */\n\"Oyz-dy-DGm.title\" = \"Stop Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Bigger\"; ObjectID = \"Ptp-SP-VEL\"; */\n\"Ptp-SP-VEL.title\" = \"Bigger\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Fonts\"; ObjectID = \"Q5e-8K-NDq\"; */\n\"Q5e-8K-NDq.title\" = \"Show Fonts\";\n\n/* Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"R4o-n2-Eq4\"; */\n\"R4o-n2-Eq4.title\" = \"Zoom\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"RB4-Sm-HuC\"; */\n\"RB4-Sm-HuC.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Superscript\"; ObjectID = \"Rqc-34-cIF\"; */\n\"Rqc-34-cIF.title\" = \"Superscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Ruw-6m-B2m\"; */\n\"Ruw-6m-B2m.title\" = \"Select All\";\n\n/* Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"S0p-oC-mLd\"; */\n\"S0p-oC-mLd.title\" = \"Jump to Selection\";\n\n/* Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"Td7-aD-5lo\"; */\n\"Td7-aD-5lo.title\" = \"Window\";\n\n/* Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"UEZ-Bs-lqG\"; */\n\"UEZ-Bs-lqG.title\" = \"Capitalize\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"VIY-Ag-zcb\"; */\n\"VIY-Ag-zcb.title\" = \"Center\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\"; */\n\"Vdr-fp-XzO.title\" = \"Hide Others\";\n\n/* Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"Vjx-xi-njq\"; */\n\"Vjx-xi-njq.title\" = \"Italic\";\n\n/* Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"W48-6f-4Dl\"; */\n\"W48-6f-4Dl.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Underline\"; ObjectID = \"WRG-CD-K1S\"; */\n\"WRG-CD-K1S.title\" = \"Underline\";\n\n/* Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"Was-JA-tGl\"; */\n\"Was-JA-tGl.title\" = \"New\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"WeT-3V-zwk\"; */\n\"WeT-3V-zwk.title\" = \"Paste and Match Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"Xz5-n4-O0W\"; */\n\"Xz5-n4-O0W.title\" = \"Find…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"YEy-JH-Tfz\"; */\n\"YEy-JH-Tfz.title\" = \"Find and Replace…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"YGs-j5-SAR\"; */\n\"YGs-j5-SAR.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"Ynk-f8-cLZ\"; */\n\"Ynk-f8-cLZ.title\" = \"Start Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Left\"; ObjectID = \"ZM1-6Q-yy1\"; */\n\"ZM1-6Q-yy1.title\" = \"Align Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Paragraph\"; ObjectID = \"ZvO-Gk-QUH\"; */\n\"ZvO-Gk-QUH.title\" = \"Paragraph\";\n\n/* Class = \"NSMenuItem\"; title = \"Print…\"; ObjectID = \"aTl-1u-JFS\"; */\n\"aTl-1u-JFS.title\" = \"Print…\";\n\n/* Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"aUF-d1-5bR\"; */\n\"aUF-d1-5bR.title\" = \"Window\";\n\n/* Class = \"NSMenu\"; title = \"Font\"; ObjectID = \"aXa-aM-Jaq\"; */\n\"aXa-aM-Jaq.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"agt-UL-0e3\"; */\n\"agt-UL-0e3.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Colors\"; ObjectID = \"bgn-CT-cEk\"; */\n\"bgn-CT-cEk.title\" = \"Show Colors\";\n\n/* Class = \"NSMenu\"; title = \"File\"; ObjectID = \"bib-Uj-vzu\"; */\n\"bib-Uj-vzu.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"buJ-ug-pKt\"; */\n\"buJ-ug-pKt.title\" = \"Use Selection for Find\";\n\n/* Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"c8a-y6-VQd\"; */\n\"c8a-y6-VQd.title\" = \"Transformations\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"cDB-IK-hbR\"; */\n\"cDB-IK-hbR.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Selection\"; ObjectID = \"cqv-fj-IhA\"; */\n\"cqv-fj-IhA.title\" = \"Selection\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"cwL-P1-jid\"; */\n\"cwL-P1-jid.title\" = \"Smart Links\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"d9M-CD-aMd\"; */\n\"d9M-CD-aMd.title\" = \"Make Lower Case\";\n\n/* Class = \"NSMenu\"; title = \"Text\"; ObjectID = \"d9c-me-L2H\"; */\n\"d9c-me-L2H.title\" = \"Text\";\n\n/* Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"dMs-cI-mzQ\"; */\n\"dMs-cI-mzQ.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"dRJ-4n-Yzg\"; */\n\"dRJ-4n-Yzg.title\" = \"Undo\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"gVA-U4-sdL\"; */\n\"gVA-U4-sdL.title\" = \"Paste\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"hQb-2v-fYv\"; */\n\"hQb-2v-fYv.title\" = \"Smart Quotes\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"hz2-CU-CR7\"; */\n\"hz2-CU-CR7.title\" = \"Check Document Now\";\n\n/* Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\"; */\n\"hz9-B4-Xy5.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"Smaller\"; ObjectID = \"i1d-Er-qST\"; */\n\"i1d-Er-qST.title\" = \"Smaller\";\n\n/* Class = \"NSMenu\"; title = \"Baseline\"; ObjectID = \"ijk-EB-dga\"; */\n\"ijk-EB-dga.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Kern\"; ObjectID = \"jBQ-r6-VK2\"; */\n\"jBQ-r6-VK2.title\" = \"Kern\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"jFq-tB-4Kx\"; */\n\"jFq-tB-4Kx.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"jxT-CU-nIS\"; */\n\"jxT-CU-nIS.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Sidebar\"; ObjectID = \"kIP-vf-haE\"; */\n\"kIP-vf-haE.title\" = \"Show Sidebar\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"mK6-2p-4JG\"; */\n\"mK6-2p-4JG.title\" = \"Check Grammar With Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Ligatures\"; ObjectID = \"o6e-r0-MWq\"; */\n\"o6e-r0-MWq.title\" = \"Ligatures\";\n\n/* Class = \"NSMenu\"; title = \"Open Recent\"; ObjectID = \"oas-Oc-fiZ\"; */\n\"oas-Oc-fiZ.title\" = \"Open Recent\";\n\n/* Class = \"NSMenuItem\"; title = \"Loosen\"; ObjectID = \"ogc-rX-tC1\"; */\n\"ogc-rX-tC1.title\" = \"Loosen\";\n\n/* Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"pa3-QI-u2k\"; */\n\"pa3-QI-u2k.title\" = \"Delete\";\n\n/* Class = \"NSMenuItem\"; title = \"Save…\"; ObjectID = \"pxx-59-PXV\"; */\n\"pxx-59-PXV.title\" = \"Save…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"q09-fT-Sye\"; */\n\"q09-fT-Sye.title\" = \"Find Next\";\n\n/* Class = \"NSMenuItem\"; title = \"Page Setup…\"; ObjectID = \"qIS-W8-SiK\"; */\n\"qIS-W8-SiK.title\" = \"Page Setup…\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"rbD-Rh-wIN\"; */\n\"rbD-Rh-wIN.title\" = \"Check Spelling While Typing\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"rgM-f4-ycn\"; */\n\"rgM-f4-ycn.title\" = \"Smart Dashes\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Toolbar\"; ObjectID = \"snW-S8-Cw5\"; */\n\"snW-S8-Cw5.title\" = \"Show Toolbar\";\n\n/* Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\"; */\n\"tRr-pd-1PS.title\" = \"Data Detectors\";\n\n/* Class = \"NSMenuItem\"; title = \"Open Recent\"; ObjectID = \"tXI-mr-wws\"; */\n\"tXI-mr-wws.title\" = \"Open Recent\";\n\n/* Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"tlD-Oa-oAM\"; */\n\"tlD-Oa-oAM.title\" = \"Kern\";\n\n/* Class = \"NSMenu\"; title = \"DevToys\"; ObjectID = \"uQy-DD-JDr\"; */\n\"uQy-DD-JDr.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"uRl-iY-unG\"; */\n\"uRl-iY-unG.title\" = \"Cut\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Style\"; ObjectID = \"vKC-jM-MkH\"; */\n\"vKC-jM-MkH.title\" = \"Paste Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Ruler\"; ObjectID = \"vLm-3I-IUL\"; */\n\"vLm-3I-IUL.title\" = \"Show Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Clear Menu\"; ObjectID = \"vNY-rz-j42\"; */\n\"vNY-rz-j42.title\" = \"Clear Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\"; */\n\"vmV-6d-7jI.title\" = \"Make Upper Case\";\n\n/* Class = \"NSMenu\"; title = \"Ligatures\"; ObjectID = \"w0m-vy-SC9\"; */\n\"w0m-vy-SC9.title\" = \"Ligatures\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Right\"; ObjectID = \"wb2-vD-lq4\"; */\n\"wb2-vD-lq4.title\" = \"Align Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"wpr-3q-Mcd\"; */\n\"wpr-3q-Mcd.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"x3v-GG-iWU\"; */\n\"x3v-GG-iWU.title\" = \"Copy\";\n\n/* Class = \"NSMenuItem\"; title = \"Use All\"; ObjectID = \"xQD-1f-W4t\"; */\n\"xQD-1f-W4t.title\" = \"Use All\";\n\n/* Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"xrE-MZ-jX0\"; */\n\"xrE-MZ-jX0.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"z6F-FW-3nz\"; */\n\"z6F-FW-3nz.title\" = \"Show Substitutions\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/pt-BR.lproj/Localizable.strings",
    "content": "/*\n  Localizable.strings\n  DevToys\n\n  Created by daniel bertoldi on 2022/02/14.\n  \n*/\n\n// - General -\n\"Configuration\" = \"Configuração\";\n\"Format\" = \"Formatar\";\n\"Pretty\" = \"Embelezar\";\n\"Minified\" = \"Minificar\";\n\"Encoded\" = \"Codificar\";\n\"Decoded\" = \"Decodificar\";\n\"File\" = \"Arquivo\";\n\"Text\" = \"Texto\";\n\"Copy\" = \"Copiar\";\n\"Paste\" = \"Colar\";\n\"Copied!\" = \"Copiado!\";\n\"Pasted!\" = \"Colado\";\n\"Open\" = \"Abrir\";\n\"Export\" = \"Exportar\";\n\"Import\" = \"Importar\";\n\"Input\" = \"Entrada\";\n\"Output\" = \"Saída\";\n\"No selection\" = \"Sem seleção\";\n\"Drop Files Here\" = \"Arraste Os Arquivos Aqui\";\n\"Untitled Tool\" = \"Ferramenta Sem Nome\";\n\"Uppercase\" = \"Maíusculo\";\n\"Hyphens\" = \"Hífens\";\n\"Type\" = \"Tipo\";\n\"Length\" = \"Comprimento\";\n\"Convert\" = \"Converter\";\n\"Information\" = \"Informação\";\n\"Clear\" = \"Limpar\";\n\"Delete\" = \"Deletar\";\n\n// - Category -\n\"category.home\" = \"Menu Principal\";\n\"category.converters\" = \"Conversores\";\n\"category.encoders_decoders\" = \"Codificadores / Decodificadores\";\n\"category.formatters\" = \"Formatadores\";\n\"category.generators\" = \"Geradores\";\n\"category.text\" = \"Texto\";\n\"category.graphic\" = \"Gráficos\";\n\n// - Tool -\n\"tool.home.title\" = \"Menu Principal\";\n\"tool.home.mintitle\" = \"Menu Principal\";\n\"tool.home.description\" = \"Procure por ferramentas aqui.\";\n\n\"tool.jsonyaml.title\" = \"Conversor JSON <> Yaml\";\n\"tool.jsonyaml.mintitle\" = \"JSON <> Yaml\";\n\"tool.jsonyaml.description\" = \"Converta dados em JSON para YAML e vice-versa\";\n\n\"tool.numbase.title\" = \"Conversor de Base Numérica\";\n\"tool.numbase.mintitle\" = \"Base Numérica\";\n\"tool.numbase.description\" = \"Converta números de uma base para outra\";\n\"Format Number\" = \"Formatar Número\";\n\"Decimal\" = \"Decimal\";\n\"Hexdecimal\" = \"Hexadecimal\";\n\"Octal\" = \"Octal\";\n\"Binary\" = \"Binário\";\n\n\"tool.date.title\" = \"Conversor de Data\";\n\"tool.date.mintitle\" = \"Data\";\n\"tool.date.description\" = \"Converte um formato de data para outro\";\n\"Now\" = \"Agora\";\n\"Date\" = \"Data\";\n\"Unix Time\" = \"Tempo Unix\";\n\"ISO 8601\" = \"ISO 8601\";\n\"Calender\" = \"Calendário\";\n\n\"tool.html.title\" = \"Codificador / Decodificador de HTML\";\n\"tool.html.mintitle\" = \"HTML\";\n\"tool.html.description\" = \"Codifica ou decodifica todos os caracteres aplicáveis ao seu HTML correspondente\";\n\n\"tool.url.title\" = \"Codificador / Decodificador de URL\";\n\"tool.url.mintitle\" = \"URL\";\n\"tool.url.description\" = \"Codifica ou decodifica todos os caracteres aplicáveis ao seu URL correspondente\";\n\n\"tool.base64.title\" = \"Codificador / Decodificador de Base64\";\n\"tool.base64.mintitle\" = \"Base64\";\n\"tool.base64.description\" = \"Codifica e decodifica dados em Base64\";\n\"Source Type\" = \"Tipo de Fonte\";\n\"Text Source\" = \"Fonte de Texto\";\n\"File Source\" = \"Fonte de Arquivo\";\n\n\"tool.jwt.title\" = \"Codificador / Decodificador de JWT\";\n\"tool.jwt.mintitle\" = \"JWT\";\n\"tool.jwt.description\" = \"Decodifica um payload e assinatura de um header JWT\";\n\"JWT Token\" = \"Token JWT\";\n\"Header\" = \"Header\";\n\"Payload\" = \"Payload\";\n\n\"tool.jsonformat.title\" = \"Formatador de JSON\";\n\"tool.jsonformat.mintitle\" = \"JSON\";\n\"tool.jsonformat.description\" = \"Indenta ou minifica um JSON\";\n\"Indentation\" = \"Indentação\";\n\"2 Spaces\" = \"2 Espaços\";\n\"4 Spaces\" = \"4 Espaços\";\n\"1 Tab\" = \"1 Tab\";\n\n\"tool.xmlformat.title\" = \"Formatador XML\";\n\"tool.xmlformat.mintitle\" = \"XML\";\n\"tool.xmlformat.description\" = \"Indenta ou minifica um XML\";\n\"HTML Document\" = \"Documento HTML\";\n\"XML Document\" = \"Documento XML\";\n\"Document Type\" = \"Tipo de Documento\";\n\"Auto Fix Document\" = \"Corrigir Documento Automaticamente\";\n\"Pretty Document\" = \"Embelezar Documento\";\n\n\"tool.hashgen.title\" = \"Gerador de Hash\";\n\"tool.hashgen.mintitle\" = \"Hash\";\n\"tool.hashgen.description\" = \"Calcula hashes MD5, SHA1, SHA256 e SHA 512 a partir de um texto\";\n\n\"tool.uuidgen.title\" = \"Gerador de UUID\";\n\"tool.uuidgen.mintitle\" = \"UUID\";\n\"tool.uuidgen.description\" = \"Gera UUIDs\";\n\"Generate UUIDs\" = \"Gerar UUIDs\";\n\n\"tool.ligen.title\" = \"Gerador de Lorem Ipsum\";\n\"tool.ligen.mintitle\" = \"Lorem Ipsum\";\n\"tool.ligen.description\" = \"Gera texto de Lorem Ipsum\";\n\"Type of generating Lorem Ipsum\" = \"Tipo de  geração de Lorem Ipsum\";\n\"Length of generating Lorem Ipsum\" = \"Tamanho do Lorem Ipsum a ser gerado\";\n\"Words\" = \"Palavras\";\n\"Sentences\" = \"Frases\";\n\"Paragraphs\" = \"Parágrafos\";\n\n\"tool.checksum.title\" = \"Gerador de Checksum\";\n\"tool.checksum.mintitle\" = \"Checksum\";\n\"tool.checksum.description\" = \"Gera ou testa o checksum de um arquivo\";\n\"Output Comparer\" = \"Comparador de Saída\";\n\"Hash Algorithm\" = \"Algoritmo de Hash\";\n\"Select which algorithm you want to use\" = \"Selecione qual algoritmo você quer usar\";\n\n\"tool.textinspect.title\" = \"Inspetor de Texto e Conversor de Case\";\n\"tool.textinspect.mintitle\" = \"Inspetor de Texto e Conversor de Case\";\n\"tool.textinspect.description\" = \" Analisa o texto e converte para um case diferente\";\n\"Charactors\" = \"Caracteres\";\n\"Words\" = \"Palavras\";\n\"Lines\" = \"Linhas\";\n\"Bytes\" = \"Bytes\";\n\n\"tool.regex.title\" = \"Testador de Regex\";\n\"tool.regex.mintitle\" = \"Regex\";\n\"tool.regex.description\" = \"Testar expressão regular\";\n\"Reguler expression\" = \"Expressão Regular\";\n\n\"tool.hyphenremove.title\" = \"Removedor de Hifenação\";\n\"tool.hyphenremove.mintitle\" = \"Hifenação\";\n\"tool.hyphenremove.description\" = \"Remove hifenações copiados de um texto PDF\";\n\n\"tool.imageoptim.title\" = \"Compressor de PNG / JPEG\";\n\"tool.imageoptim.mintitle\" = \"Compressor de PNG / JPEG\";\n\"tool.imageoptim.description\" = \"Otimizador sem perdas de PNG e JPEG\";\n\"Optimize Level\" = \"Nível de Otimização\";\n\"Low\" = \"Baixo\";\n\"Medium\" = \"Médio\";\n\"High\" = \"Alto\";\n\"Very High (Slow)\" = \"Muito Alto (Lento)\";\n\n\"tool.pdfgen.title\" = \"Gerador de PDF\";\n\"tool.pdfgen.mintitle\" = \"Gerador de PDF\";\n\"tool.pdfgen.description\" = \"Gera PDF a partir de múltipas imagens\";\n\"Images\" = \"Imagens\";\n\"Size\" = \"Tamanho\";\n\"Generate PDF\" = \"Gerar PDF\";\n\"Page\" = \"Página\";\n\n\"tool.imageconvert.title\" = \"Conversor de Imagem\";\n\"tool.imageconvert.mintitle\" = \"Conversor de Imagem\";\n\"tool.imageconvert.description\" = \"Converte ou redimensiona imagens\";\n\"PNG Format\" = \"Formato PNG\";\n\"JPEG Format\" = \"Formato JPEG\";\n\"TIFF Format\" = \"Formato TIFF\";\n\"GIF Format\" = \"Formato GIF\";\n\"Scale to Fill\" = \"Escalar para preencher\";\n\"Scale to Fit\" = \"Escalar para encaixar\";\n\"Image Format\" = \"Formatar Imagem\";\n\"Resize\" = \"Redimensionar\";\n\"Converted Images\" = \"Imagens Convertidas\";\n\"Scale\" = \"Escalar\";\n\"Size\" = \"Tamanho\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/pt-BR.lproj/Main.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Customize Toolbar…\"; ObjectID = \"1UK-8n-QPP\"; */\n\"1UK-8n-QPP.title\" = \"Customizar Barra de Ferramentas…\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys\"; ObjectID = \"1Xt-HY-uBw\"; */\n\"1Xt-HY-uBw.title\" = \"DevToys\";\n\n/* Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"1b7-l0-nxx\"; */\n\"1b7-l0-nxx.title\" = \"Procurar\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower\"; ObjectID = \"1tx-W0-xDw\"; */\n\"1tx-W0-xDw.title\" = \"Diminuir\";\n\n/* Class = \"NSMenuItem\"; title = \"Raise\"; ObjectID = \"2h7-ER-AoG\"; */\n\"2h7-ER-AoG.title\" = \"Aumentar\";\n\n/* Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"2oI-Rn-ZJC\"; */\n\"2oI-Rn-ZJC.title\" = \"Transformações\";\n\n/* Class = \"NSMenu\"; title = \"Spelling\"; ObjectID = \"3IN-sU-3Bg\"; */\n\"3IN-sU-3Bg.title\" = \"Ortografia\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"3Om-Ey-2VK\"; */\n\"3Om-Ey-2VK.title\" = \"Usar Padrão\";\n\n/* Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"3rS-ZA-NoH\"; */\n\"3rS-ZA-NoH.title\" = \"Fala\";\n\n/* Class = \"NSMenuItem\"; title = \"Tighten\"; ObjectID = \"46P-cB-AYj\"; */\n\"46P-cB-AYj.title\" = \"Apertar\";\n\n/* Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"4EN-yA-p0u\"; */\n\"4EN-yA-p0u.title\" = \"Procurar\";\n\n/* Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"4J7-dP-txa\"; */\n\"4J7-dP-txa.title\" = \"Entrar em Tela Cheia\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit DevToys\"; ObjectID = \"4sb-4s-VLi\"; */\n\"4sb-4s-VLi.title\" = \"Sair do DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"5QF-Oa-p0T\"; */\n\"5QF-Oa-p0T.title\" = \"Editar\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Style\"; ObjectID = \"5Vv-lz-BsD\"; */\n\"5Vv-lz-BsD.title\" = \"Copiar Estilo\";\n\n/* Class = \"NSMenuItem\"; title = \"About DevToys\"; ObjectID = \"5kV-Vb-QxS\"; */\n\"5kV-Vb-QxS.title\" = \"Sobre o DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"6dh-zS-Vam\"; */\n\"6dh-zS-Vam.title\" = \"Refazer\";\n\n/* Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"78Y-hA-62v\"; */\n\"78Y-hA-62v.title\" = \"Corrigir Ortografia Automaticamente\";\n\n/* Class = \"NSMenu\"; title = \"Writing Direction\"; ObjectID = \"8mr-sm-Yjd\"; */\n\"8mr-sm-Yjd.title\" = \"Direção de Escrita\";\n\n/* Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"9ic-FL-obx\"; */\n\"9ic-FL-obx.title\" = \"Substituições\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"9yt-4B-nSM\"; */\n\"9yt-4B-nSM.title\" = \"Copiar/Colar Inteligente\";\n\n/* Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\"; */\n\"AYu-sK-qS6.title\" = \"Menu Principal\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\"; */\n\"BOF-NM-1cW.title\" = \"Preferências\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"BgM-ve-c93\"; */\n\"BgM-ve-c93.title\" = \"\\tEsquerda para Direita\";\n\n/* Class = \"NSMenuItem\"; title = \"Save As…\"; ObjectID = \"Bw7-FT-i3A\"; */\n\"Bw7-FT-i3A.title\" = \"Salvar Como...\";\n\n/* Class = \"NSMenuItem\"; title = \"Close\"; ObjectID = \"DVo-aG-piG\"; */\n\"DVo-aG-piG.title\" = \"Fechar\";\n\n/* Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"Dv1-io-Yv7\"; */\n\"Dv1-io-Yv7.title\" = \"Ortografia e Gramática\";\n\n/* Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"F2S-fz-NVQ\"; */\n\"F2S-fz-NVQ.title\" = \"Ajuda\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys Help\"; ObjectID = \"FKE-Sm-Kum\"; */\n\"FKE-Sm-Kum.title\" = \"Ajuda do DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Text\"; ObjectID = \"Fal-I4-PZk\"; */\n\"Fal-I4-PZk.title\" = \"Texto\";\n\n/* Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"FeM-D8-WVr\"; */\n\"FeM-D8-WVr.title\" = \"Substituições\";\n\n/* Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"GB9-OM-e27\"; */\n\"GB9-OM-e27.title\" = \"Negrito\";\n\n/* Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"GEO-Iw-cKr\"; */\n\"GEO-Iw-cKr.title\" = \"Formatar\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"GUa-eO-cwY\"; */\n\"GUa-eO-cwY.title\" = \"Usar Padrão\";\n\n/* Class = \"NSMenuItem\"; title = \"Font\"; ObjectID = \"Gi5-1S-RQB\"; */\n\"Gi5-1S-RQB.title\" = \"Fonte\";\n\n/* Class = \"NSMenuItem\"; title = \"Writing Direction\"; ObjectID = \"H1b-Si-o9J\"; */\n\"H1b-Si-o9J.title\" = \"Direção de Escrita\";\n\n/* Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"H8h-7b-M4v\"; */\n\"H8h-7b-M4v.title\" = \"Exibir\";\n\n/* Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"HFQ-gK-NFA\"; */\n\"HFQ-gK-NFA.title\" = \"Substituir Texto\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"HFo-cy-zxI\"; */\n\"HFo-cy-zxI.title\" = \"Mostrar Ortografia e Gramática\";\n\n/* Class = \"NSMenu\"; title = \"View\"; ObjectID = \"HyV-fh-RgO\"; */\n\"HyV-fh-RgO.title\" = \"Exibir\";\n\n/* Class = \"NSMenuItem\"; title = \"Subscript\"; ObjectID = \"I0S-gh-46l\"; */\n\"I0S-gh-46l.title\" = \"Subscrito\";\n\n/* Class = \"NSMenuItem\"; title = \"Open…\"; ObjectID = \"IAo-SY-fd9\"; */\n\"IAo-SY-fd9.title\" = \"Abrir...\";\n\n/* Class = \"NSWindow\"; title = \"DevToys\"; ObjectID = \"IQv-IB-iLA\"; */\n\"IQv-IB-iLA.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Justify\"; ObjectID = \"J5U-5w-g23\"; */\n\"J5U-5w-g23.title\" = \"Justificar\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"J7y-lM-qPV\"; */\n\"J7y-lM-qPV.title\" = \"Não Usar Nenhum\";\n\n/* Class = \"NSMenuItem\"; title = \"Revert to Saved\"; ObjectID = \"KaW-ft-85H\"; */\n\"KaW-ft-85H.title\" = \"Reverter Para Salvo\";\n\n/* Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\"; */\n\"Kd2-mp-pUS.title\" = \"Mostrar Tudo\";\n\n/* Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"LE2-aR-0XJ\"; */\n\"LE2-aR-0XJ.title\" = \"Trazer Para Frente\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Ruler\"; ObjectID = \"LVM-kO-fVI\"; */\n\"LVM-kO-fVI.title\" = \"Colar Régua\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"Lbh-J2-qVU\"; */\n\"Lbh-J2-qVU.title\" = \"\\tEsquerda Para Direita\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Ruler\"; ObjectID = \"MkV-Pr-PK5\"; */\n\"MkV-Pr-PK5.title\" = \"Copiar Régua\";\n\n/* Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\"; */\n\"NMo-om-nkz.title\" = \"Serviços\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"Nop-cj-93Q\"; */\n\"Nop-cj-93Q.title\" = \"\\tPadrão\";\n\n/* Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"OY7-WF-poV\"; */\n\"OY7-WF-poV.title\" = \"Minimizar\";\n\n/* Class = \"NSMenuItem\"; title = \"Baseline\"; ObjectID = \"OaQ-X3-Vso\"; */\n\"OaQ-X3-Vso.title\" = \"Linha De Base\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide DevToys\"; ObjectID = \"Olw-nP-bQN\"; */\n\"Olw-nP-bQN.title\" = \"Esconder DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"OwM-mh-QMV\"; */\n\"OwM-mh-QMV.title\" = \"Encontrar Anterior\";\n\n/* Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"Oyz-dy-DGm\"; */\n\"Oyz-dy-DGm.title\" = \"Parar de Falar\";\n\n/* Class = \"NSMenuItem\"; title = \"Bigger\"; ObjectID = \"Ptp-SP-VEL\"; */\n\"Ptp-SP-VEL.title\" = \"Aumentar\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Fonts\"; ObjectID = \"Q5e-8K-NDq\"; */\n\"Q5e-8K-NDq.title\" = \"Mostrar Fontes\";\n\n/* Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"R4o-n2-Eq4\"; */\n\"R4o-n2-Eq4.title\" = \"Zoom\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"RB4-Sm-HuC\"; */\n\"RB4-Sm-HuC.title\" = \"\\tDireita Para Esquerda\";\n\n/* Class = \"NSMenuItem\"; title = \"Superscript\"; ObjectID = \"Rqc-34-cIF\"; */\n\"Rqc-34-cIF.title\" = \"Superescrito\";\n\n/* Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Ruw-6m-B2m\"; */\n\"Ruw-6m-B2m.title\" = \"Selecionar Tudo\";\n\n/* Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"S0p-oC-mLd\"; */\n\"S0p-oC-mLd.title\" = \"Pular Para a Seleção\";\n\n/* Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"Td7-aD-5lo\"; */\n\"Td7-aD-5lo.title\" = \"Janela\";\n\n/* Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"UEZ-Bs-lqG\"; */\n\"UEZ-Bs-lqG.title\" = \"Capitalizar\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"VIY-Ag-zcb\"; */\n\"VIY-Ag-zcb.title\" = \"Centralizar\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\"; */\n\"Vdr-fp-XzO.title\" = \"Esconder Outros\";\n\n/* Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"Vjx-xi-njq\"; */\n\"Vjx-xi-njq.title\" = \"Itálico\";\n\n/* Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"W48-6f-4Dl\"; */\n\"W48-6f-4Dl.title\" = \"Editar\";\n\n/* Class = \"NSMenuItem\"; title = \"Underline\"; ObjectID = \"WRG-CD-K1S\"; */\n\"WRG-CD-K1S.title\" = \"Sublinhado\";\n\n/* Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"Was-JA-tGl\"; */\n\"Was-JA-tGl.title\" = \"Novo\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"WeT-3V-zwk\"; */\n\"WeT-3V-zwk.title\" = \"Colar e Manter Estilo\";\n\n/* Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"Xz5-n4-O0W\"; */\n\"Xz5-n4-O0W.title\" = \"Procurar...\";\n\n/* Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"YEy-JH-Tfz\"; */\n\"YEy-JH-Tfz.title\" = \"Procurar e Substituir...\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"YGs-j5-SAR\"; */\n\"YGs-j5-SAR.title\" = \"\\tPadrão\";\n\n/* Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"Ynk-f8-cLZ\"; */\n\"Ynk-f8-cLZ.title\" = \"Começar a Falar\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Left\"; ObjectID = \"ZM1-6Q-yy1\"; */\n\"ZM1-6Q-yy1.title\" = \"Alinhar à Esquerda\";\n\n/* Class = \"NSMenuItem\"; title = \"Paragraph\"; ObjectID = \"ZvO-Gk-QUH\"; */\n\"ZvO-Gk-QUH.title\" = \"Parágrafo\";\n\n/* Class = \"NSMenuItem\"; title = \"Print…\"; ObjectID = \"aTl-1u-JFS\"; */\n\"aTl-1u-JFS.title\" = \"Imprimir...\";\n\n/* Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"aUF-d1-5bR\"; */\n\"aUF-d1-5bR.title\" = \"Janela\";\n\n/* Class = \"NSMenu\"; title = \"Font\"; ObjectID = \"aXa-aM-Jaq\"; */\n\"aXa-aM-Jaq.title\" = \"Fonte\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"agt-UL-0e3\"; */\n\"agt-UL-0e3.title\" = \"Usar Padrão\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Colors\"; ObjectID = \"bgn-CT-cEk\"; */\n\"bgn-CT-cEk.title\" = \"Mostrar Cores\";\n\n/* Class = \"NSMenu\"; title = \"File\"; ObjectID = \"bib-Uj-vzu\"; */\n\"bib-Uj-vzu.title\" = \"Arquivo\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"buJ-ug-pKt\"; */\n\"buJ-ug-pKt.title\" = \"Usar Seleção Para Procurar\";\n\n/* Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"c8a-y6-VQd\"; */\n\"c8a-y6-VQd.title\" = \"Transformações\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"cDB-IK-hbR\"; */\n\"cDB-IK-hbR.title\" = \"Não Usar Nenhum\";\n\n/* Class = \"NSMenuItem\"; title = \"Selection\"; ObjectID = \"cqv-fj-IhA\"; */\n\"cqv-fj-IhA.title\" = \"Seleção\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"cwL-P1-jid\"; */\n\"cwL-P1-jid.title\" = \"Links Inteligentes\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"d9M-CD-aMd\"; */\n\"d9M-CD-aMd.title\" = \"Tornar Minúsculo\";\n\n/* Class = \"NSMenu\"; title = \"Text\"; ObjectID = \"d9c-me-L2H\"; */\n\"d9c-me-L2H.title\" = \"Texto\";\n\n/* Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"dMs-cI-mzQ\"; */\n\"dMs-cI-mzQ.title\" = \"Arquivo\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"dRJ-4n-Yzg\"; */\n\"dRJ-4n-Yzg.title\" = \"Desfazer\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"gVA-U4-sdL\"; */\n\"gVA-U4-sdL.title\" = \"Colar\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"hQb-2v-fYv\"; */\n\"hQb-2v-fYv.title\" = \"Citações Inteligentes\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"hz2-CU-CR7\"; */\n\"hz2-CU-CR7.title\" = \"Checar Documento Agora\";\n\n/* Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\"; */\n\"hz9-B4-Xy5.title\" = \"Serviços\";\n\n/* Class = \"NSMenuItem\"; title = \"Smaller\"; ObjectID = \"i1d-Er-qST\"; */\n\"i1d-Er-qST.title\" = \"Diminuir\";\n\n/* Class = \"NSMenu\"; title = \"Baseline\"; ObjectID = \"ijk-EB-dga\"; */\n\"ijk-EB-dga.title\" = \"Linha de Base\";\n\n/* Class = \"NSMenuItem\"; title = \"Kern\"; ObjectID = \"jBQ-r6-VK2\"; */\n\"jBQ-r6-VK2.title\" = \"Kern\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"jFq-tB-4Kx\"; */\n\"jFq-tB-4Kx.title\" = \"\\tDireita Para Esquerda\";\n\n/* Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"jxT-CU-nIS\"; */\n\"jxT-CU-nIS.title\" = \"Formatar\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Sidebar\"; ObjectID = \"kIP-vf-haE\"; */\n\"kIP-vf-haE.title\" = \"Mostrar Barra Lateral\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"mK6-2p-4JG\"; */\n\"mK6-2p-4JG.title\" = \"Checar Gramática Com Ortografia\";\n\n/* Class = \"NSMenuItem\"; title = \"Ligatures\"; ObjectID = \"o6e-r0-MWq\"; */\n\"o6e-r0-MWq.title\" = \"Ligações\";\n\n/* Class = \"NSMenu\"; title = \"Open Recent\"; ObjectID = \"oas-Oc-fiZ\"; */\n\"oas-Oc-fiZ.title\" = \"Abrir Recente\";\n\n/* Class = \"NSMenuItem\"; title = \"Loosen\"; ObjectID = \"ogc-rX-tC1\"; */\n\"ogc-rX-tC1.title\" = \"Soltar\";\n\n/* Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"pa3-QI-u2k\"; */\n\"pa3-QI-u2k.title\" = \"Deletar\";\n\n/* Class = \"NSMenuItem\"; title = \"Save…\"; ObjectID = \"pxx-59-PXV\"; */\n\"pxx-59-PXV.title\" = \"Salvar...\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"q09-fT-Sye\"; */\n\"q09-fT-Sye.title\" = \"Encontrar Próximo\";\n\n/* Class = \"NSMenuItem\"; title = \"Page Setup…\"; ObjectID = \"qIS-W8-SiK\"; */\n\"qIS-W8-SiK.title\" = \"Configuração da Página...\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"rbD-Rh-wIN\"; */\n\"rbD-Rh-wIN.title\" = \"Checar Ortografia Enquanto Digita\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"rgM-f4-ycn\"; */\n\"rgM-f4-ycn.title\" = \"Traços Inteligentes\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Toolbar\"; ObjectID = \"snW-S8-Cw5\"; */\n\"snW-S8-Cw5.title\" = \"Mostrar Barra de Ferramentas\";\n\n/* Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\"; */\n\"tRr-pd-1PS.title\" = \"Detectores de Dados\";\n\n/* Class = \"NSMenuItem\"; title = \"Open Recent\"; ObjectID = \"tXI-mr-wws\"; */\n\"tXI-mr-wws.title\" = \"Abrir Recente\";\n\n/* Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"tlD-Oa-oAM\"; */\n\"tlD-Oa-oAM.title\" = \"Kern\";\n\n/* Class = \"NSMenu\"; title = \"DevToys\"; ObjectID = \"uQy-DD-JDr\"; */\n\"uQy-DD-JDr.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"uRl-iY-unG\"; */\n\"uRl-iY-unG.title\" = \"Cortar\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Style\"; ObjectID = \"vKC-jM-MkH\"; */\n\"vKC-jM-MkH.title\" = \"Colar Estilo\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Ruler\"; ObjectID = \"vLm-3I-IUL\"; */\n\"vLm-3I-IUL.title\" = \"Mostrar Régua\";\n\n/* Class = \"NSMenuItem\"; title = \"Clear Menu\"; ObjectID = \"vNY-rz-j42\"; */\n\"vNY-rz-j42.title\" = \"Limpar Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\"; */\n\"vmV-6d-7jI.title\" = \"Tornar Maiúsculo\";\n\n/* Class = \"NSMenu\"; title = \"Ligatures\"; ObjectID = \"w0m-vy-SC9\"; */\n\"w0m-vy-SC9.title\" = \"Ligações\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Right\"; ObjectID = \"wb2-vD-lq4\"; */\n\"wb2-vD-lq4.title\" = \"Alinhar à Direita\";\n\n/* Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"wpr-3q-Mcd\"; */\n\"wpr-3q-Mcd.title\" = \"Ajuda\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"x3v-GG-iWU\"; */\n\"x3v-GG-iWU.title\" = \"Copiar\";\n\n/* Class = \"NSMenuItem\"; title = \"Use All\"; ObjectID = \"xQD-1f-W4t\"; */\n\"xQD-1f-W4t.title\" = \"Usar Todos\";\n\n/* Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"xrE-MZ-jX0\"; */\n\"xrE-MZ-jX0.title\" = \"Fala\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"z6F-FW-3nz\"; */\n\"z6F-FW-3nz.title\" = \"Mostrar Substituições\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/zh-Hans.lproj/Localizable.strings",
    "content": "/*\n  Localizable.strings\n  DevToys\n\n  Created by wibus on 2022/02/13.\n  \n*/\n\n// - General -\n\"Configuration\" = \"配置\";\n\"Format\" = \"格式\";\n\"Pretty\" = \"美化\";\n\"Minified\" = \"压缩\";\n\"Encoded\" = \"编码\";\n\"Decoded\" = \"解码\";\n\"File\" = \"文件\";\n\"Text\" = \"文本\";\n\"Copy\" = \"复制\";\n\"Paste\" = \"黏贴\";\n\"Copied!\" = \"复制!\";\n\"Pasted!\" = \"黏贴!\";\n\"Open\" = \"打开\";\n\"Export\" = \"导出\";\n\"Import\" = \"导入\";\n\"Input\" = \"输入\";\n\"Output\" = \"输出\";\n\"No selection\" = \"无选择\";\n\"Drop Files Here\" = \"将文件拖入此处\";\n\"Untitled Tool\" = \"未命名工具\";\n\"Uppercase\" = \"大写\";\n\"Hyphens\" = \"连字\";\n\"Type\" = \"种类\";\n\"Length\" = \"长度\";\n\"Convert\" = \"转换\";\n\"Information\" = \"信息\";\n\"Clear\" = \"清空\";\n\"Delete\" = \"删除\";\n\n// - Category -\n\"category.home\" = \"首页\";\n\"category.converters\" = \"转换类\";\n\"category.encoders_decoders\" = \"编码 / 解码类\";\n\"category.formatters\" = \"格式类\";\n\"category.generators\" = \"生成类\";\n\"category.text\" = \"文本类\";\n\"category.graphic\" = \"图像类\";\n\n// - Tool -\n\"tool.home.title\" = \"首页\";\n\"tool.home.mintitle\" = \"首页\";\n\"tool.home.description\" = \"在这里搜索所有工具.\";\n\n\"tool.jsonyaml.title\" = \"JSON <> Yaml 转换器\";\n\"tool.jsonyaml.mintitle\" = \"JSON <> Yaml\";\n\"tool.jsonyaml.description\" = \"将json与yaml相互转换\";\n\n\"tool.numbase.title\" = \"数字类型转换器\";\n\"tool.numbase.mintitle\" = \"数字类型转换\";\n\"tool.numbase.description\" = \"将数字从一种类型转换为另一个类型\";\n\"Format Number\" = \"格式化数字\";\n\"Decimal\" = \"十进制\";\n\"Hexdecimal\" = \"十六进制\";\n\"Octal\" = \"八进制\";\n\"Binary\" = \"二进制\";\n\n\"tool.date.title\" = \"日期转换器\";\n\"tool.date.mintitle\" = \"日期\";\n\"tool.date.description\" = \"将日期从一种格式转换为另一种格式\";\n\"Now\" = \"现在时间\";\n\"Date\" = \"时间\";\n\"Unix Time\" = \"Unix 时间\";\n\"ISO 8601\" = \"ISO 8601\";\n\"Calender\" = \"日历\";\n\n\"tool.html.title\" = \"HTML 编码 / 解码\";\n\"tool.html.mintitle\" = \"HTML\";\n\"tool.html.description\" = \"将字符编码或解码为相应的HTML\";\n\n\"tool.url.title\" = \"URL 编码 / 解码\";\n\"tool.url.mintitle\" = \"URL\";\n\"tool.url.description\" = \"将字符编码或解码为相应的URL\";\n\n\"tool.base64.title\" = \"Base64 编码 / 解码\";\n\"tool.base64.mintitle\" = \"Base64\";\n\"tool.base64.description\" = \"编码或解码 Base64 数据\";\n\"Source Type\" = \"数据来源\";\n\"Text Source\" = \"字符串\";\n\"File Source\" = \"文件\";\n\n\"tool.jwt.title\" = \"JWT 编码 / 解码\";\n\"tool.jwt.mintitle\" = \"JWT\";\n\"tool.jwt.description\" = \"解码JWT头部的负载和签名\";\n\"JWT Token\" = \"JWT 密钥\";\n\"Header\" = \"头部\";\n\"Payload\" = \"负载\";\n\n\"tool.jsonformat.title\" = \"JSON 格式器\";\n\"tool.jsonformat.mintitle\" = \"JSON\";\n\"tool.jsonformat.description\" = \"缩进或压缩 json 数据\";\n\"Indentation\" = \"Indentation\";\n\"2 Spaces\" = \"2 Spaces\";\n\"4 Spaces\" = \"4 Spaces\";\n\"1 Tab\" = \"1 Tab\";\n\n\"tool.xmlformat.title\" = \"XML 格式器\";\n\"tool.xmlformat.mintitle\" = \"XML\";\n\"tool.xmlformat.description\" = \"缩进或压缩 XML 数据\";\n\"HTML Document\" = \"HTML 文档\";\n\"XML Document\" = \"XML 文档\";\n\"Document Type\" = \"文档类型\";\n\"Auto Fix Document\" = \"自动修复\";\n\"Pretty Document\" = \"美化\";\n\n\"tool.hashgen.title\" = \"Hash 生成器\";\n\"tool.hashgen.mintitle\" = \"Hash\";\n\"tool.hashgen.description\" = \"从文本数据计算MD5, SHA1, SHA256和SHA 512哈希值\";\n\n\"tool.uuidgen.title\" = \"UUID 生成器\";\n\"tool.uuidgen.mintitle\" = \"UUID\";\n\"tool.uuidgen.description\" = \"生成 UUIDs\";\n\"Generate UUIDs\" = \"生成 UUIDs\";\n\n\"tool.ligen.title\" = \"哑元文本生成器\";\n\"tool.ligen.mintitle\" = \"哑元文本\";\n\"tool.ligen.description\" = \"生成哑元文本占位符文本\";\n\"Type of generating Lorem Ipsum\" = \"生成种类\";\n\"Length of generating Lorem Ipsum\" = \"生成数量\";\n\"Words\" = \"单词\";\n\"Sentences\" = \"句子\";\n\"Paragraphs\" = \"段落\";\n\n\"tool.checksum.title\" = \"校验测试器\";\n\"tool.checksum.mintitle\" = \"校验测试器\";\n\"tool.checksum.description\" = \"生成或测试文件的校验和\";\n\"Output Comparer\" = \"比较输出\";\n\"Hash Algorithm\" = \"散列算法\";\n\"Select which algorithm you want to use\" = \"选择要使用的算法\";\n\n\"tool.checksum.title\" = \"校验测试器\";\n\"tool.checksum.mintitle\" = \"校验测试器\";\n\"tool.checksum.description\" = \"生成或测试文件的校验和\";\n\n\"tool.textinspect.title\" = \"文本检查 & 大小写转换器\";\n\"tool.textinspect.mintitle\" = \"检查 & 大小写 转换器\";\n\"tool.textinspect.description\" = \"分析文本并将其转换为不同的大小写\";\n\"Charactors\" = \"符号\";\n\"Words\" = \"单词\";\n\"Lines\" = \"行数\";\n\"Bytes\" = \"字节数\";\n\n\"tool.regex.title\" = \"正则表达式测试器\";\n\"tool.regex.mintitle\" = \"正则表达式\";\n\"tool.regex.description\" = \"测试正则表达式\";\n\"Reguler expression\" = \"正则表达式\";\n\n\"tool.hyphenremove.title\" = \"连字符号去除器\";\n\"tool.hyphenremove.mintitle\" = \"连字符号\";\n\"tool.hyphenremove.description\" = \"删除从PDF文本复制的连字符\";\n\n\"tool.imageoptim.title\" = \"PNG / JPEG 压缩器\";\n\"tool.imageoptim.mintitle\" = \"PNG / JPEG 压缩器\";\n\"tool.imageoptim.description\" = \"无损的PNG和JPEG压缩器\";\n\"Optimize Level\" = \"压缩级别\";\n\"Low\" = \"低\";\n\"Medium\" = \"中\";\n\"High\" = \"高\";\n\"Very High (Slow)\" = \"优 (慢)\";\n\n\"tool.pdfgen.title\" = \"PDF 生成器\";\n\"tool.pdfgen.mintitle\" = \"PDF 生成器\";\n\"tool.pdfgen.description\" = \"从多个图像生成PDF\";\n\"Images\" = \"图像\";\n\"Size\" = \"大小\";\n\"Generate PDF\" = \"生成 PDF\";\n\"Page\" = \"页面\";\n\n\"tool.imageconvert.title\" = \"Image 转换器\";\n\"tool.imageconvert.mintitle\" = \"Image 转换器\";\n\"tool.imageconvert.description\" = \"转换或调整图像大小\";\n\"PNG Format\" = \"PNG 格式\";\n\"JPEG Format\" = \"JPEG 格式\";\n\"TIFF Format\" = \"TIFF 格式\";\n\"GIF Format\" = \"GIF 格式\";\n\"Scale to Fill\" = \"缩放使充满容器(未必保持长宽比例)\";\n\"Scale to Fit\" = \"保持长宽比缩放\";\n\"Image Format\" = \"图像格式\";\n\"Resize\" = \"调整大小\";\n\"Converted Images\" = \"转换图片\";\n\"Scale\" = \"比例\";\n\"Size\" = \"大小\";\n"
  },
  {
    "path": "DevToys/DevToys/Resource/zh-Hans.lproj/Main.strings",
    "content": "\n/* Class = \"NSMenuItem\"; title = \"Customize Toolbar…\"; ObjectID = \"1UK-8n-QPP\"; */\n\"1UK-8n-QPP.title\" = \"Customize Toolbar…\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys\"; ObjectID = \"1Xt-HY-uBw\"; */\n\"1Xt-HY-uBw.title\" = \"DevToys\";\n\n/* Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"1b7-l0-nxx\"; */\n\"1b7-l0-nxx.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Lower\"; ObjectID = \"1tx-W0-xDw\"; */\n\"1tx-W0-xDw.title\" = \"Lower\";\n\n/* Class = \"NSMenuItem\"; title = \"Raise\"; ObjectID = \"2h7-ER-AoG\"; */\n\"2h7-ER-AoG.title\" = \"Raise\";\n\n/* Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"2oI-Rn-ZJC\"; */\n\"2oI-Rn-ZJC.title\" = \"Transformations\";\n\n/* Class = \"NSMenu\"; title = \"Spelling\"; ObjectID = \"3IN-sU-3Bg\"; */\n\"3IN-sU-3Bg.title\" = \"Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"3Om-Ey-2VK\"; */\n\"3Om-Ey-2VK.title\" = \"Use Default\";\n\n/* Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"3rS-ZA-NoH\"; */\n\"3rS-ZA-NoH.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Tighten\"; ObjectID = \"46P-cB-AYj\"; */\n\"46P-cB-AYj.title\" = \"Tighten\";\n\n/* Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"4EN-yA-p0u\"; */\n\"4EN-yA-p0u.title\" = \"Find\";\n\n/* Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"4J7-dP-txa\"; */\n\"4J7-dP-txa.title\" = \"Enter Full Screen\";\n\n/* Class = \"NSMenuItem\"; title = \"Quit DevToys\"; ObjectID = \"4sb-4s-VLi\"; */\n\"4sb-4s-VLi.title\" = \"Quit DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"5QF-Oa-p0T\"; */\n\"5QF-Oa-p0T.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Style\"; ObjectID = \"5Vv-lz-BsD\"; */\n\"5Vv-lz-BsD.title\" = \"Copy Style\";\n\n/* Class = \"NSMenuItem\"; title = \"About DevToys\"; ObjectID = \"5kV-Vb-QxS\"; */\n\"5kV-Vb-QxS.title\" = \"About DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"6dh-zS-Vam\"; */\n\"6dh-zS-Vam.title\" = \"Redo\";\n\n/* Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"78Y-hA-62v\"; */\n\"78Y-hA-62v.title\" = \"Correct Spelling Automatically\";\n\n/* Class = \"NSMenu\"; title = \"Writing Direction\"; ObjectID = \"8mr-sm-Yjd\"; */\n\"8mr-sm-Yjd.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"9ic-FL-obx\"; */\n\"9ic-FL-obx.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"9yt-4B-nSM\"; */\n\"9yt-4B-nSM.title\" = \"Smart Copy/Paste\";\n\n/* Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\"; */\n\"AYu-sK-qS6.title\" = \"Main Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\"; */\n\"BOF-NM-1cW.title\" = \"Preferences…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"BgM-ve-c93\"; */\n\"BgM-ve-c93.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Save As…\"; ObjectID = \"Bw7-FT-i3A\"; */\n\"Bw7-FT-i3A.title\" = \"Save As…\";\n\n/* Class = \"NSMenuItem\"; title = \"Close\"; ObjectID = \"DVo-aG-piG\"; */\n\"DVo-aG-piG.title\" = \"Close\";\n\n/* Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"Dv1-io-Yv7\"; */\n\"Dv1-io-Yv7.title\" = \"Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"F2S-fz-NVQ\"; */\n\"F2S-fz-NVQ.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"DevToys Help\"; ObjectID = \"FKE-Sm-Kum\"; */\n\"FKE-Sm-Kum.title\" = \"DevToys Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Text\"; ObjectID = \"Fal-I4-PZk\"; */\n\"Fal-I4-PZk.title\" = \"Text\";\n\n/* Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"FeM-D8-WVr\"; */\n\"FeM-D8-WVr.title\" = \"Substitutions\";\n\n/* Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"GB9-OM-e27\"; */\n\"GB9-OM-e27.title\" = \"Bold\";\n\n/* Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"GEO-Iw-cKr\"; */\n\"GEO-Iw-cKr.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"GUa-eO-cwY\"; */\n\"GUa-eO-cwY.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Font\"; ObjectID = \"Gi5-1S-RQB\"; */\n\"Gi5-1S-RQB.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Writing Direction\"; ObjectID = \"H1b-Si-o9J\"; */\n\"H1b-Si-o9J.title\" = \"Writing Direction\";\n\n/* Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"H8h-7b-M4v\"; */\n\"H8h-7b-M4v.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"HFQ-gK-NFA\"; */\n\"HFQ-gK-NFA.title\" = \"Text Replacement\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"HFo-cy-zxI\"; */\n\"HFo-cy-zxI.title\" = \"Show Spelling and Grammar\";\n\n/* Class = \"NSMenu\"; title = \"View\"; ObjectID = \"HyV-fh-RgO\"; */\n\"HyV-fh-RgO.title\" = \"View\";\n\n/* Class = \"NSMenuItem\"; title = \"Subscript\"; ObjectID = \"I0S-gh-46l\"; */\n\"I0S-gh-46l.title\" = \"Subscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Open…\"; ObjectID = \"IAo-SY-fd9\"; */\n\"IAo-SY-fd9.title\" = \"Open…\";\n\n/* Class = \"NSWindow\"; title = \"DevToys\"; ObjectID = \"IQv-IB-iLA\"; */\n\"IQv-IB-iLA.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Justify\"; ObjectID = \"J5U-5w-g23\"; */\n\"J5U-5w-g23.title\" = \"Justify\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"J7y-lM-qPV\"; */\n\"J7y-lM-qPV.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Revert to Saved\"; ObjectID = \"KaW-ft-85H\"; */\n\"KaW-ft-85H.title\" = \"Revert to Saved\";\n\n/* Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\"; */\n\"Kd2-mp-pUS.title\" = \"Show All\";\n\n/* Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"LE2-aR-0XJ\"; */\n\"LE2-aR-0XJ.title\" = \"Bring All to Front\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Ruler\"; ObjectID = \"LVM-kO-fVI\"; */\n\"LVM-kO-fVI.title\" = \"Paste Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"Lbh-J2-qVU\"; */\n\"Lbh-J2-qVU.title\" = \"\\tLeft to Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy Ruler\"; ObjectID = \"MkV-Pr-PK5\"; */\n\"MkV-Pr-PK5.title\" = \"Copy Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\"; */\n\"NMo-om-nkz.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"Nop-cj-93Q\"; */\n\"Nop-cj-93Q.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"OY7-WF-poV\"; */\n\"OY7-WF-poV.title\" = \"Minimize\";\n\n/* Class = \"NSMenuItem\"; title = \"Baseline\"; ObjectID = \"OaQ-X3-Vso\"; */\n\"OaQ-X3-Vso.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide DevToys\"; ObjectID = \"Olw-nP-bQN\"; */\n\"Olw-nP-bQN.title\" = \"Hide DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"OwM-mh-QMV\"; */\n\"OwM-mh-QMV.title\" = \"Find Previous\";\n\n/* Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"Oyz-dy-DGm\"; */\n\"Oyz-dy-DGm.title\" = \"Stop Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Bigger\"; ObjectID = \"Ptp-SP-VEL\"; */\n\"Ptp-SP-VEL.title\" = \"Bigger\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Fonts\"; ObjectID = \"Q5e-8K-NDq\"; */\n\"Q5e-8K-NDq.title\" = \"Show Fonts\";\n\n/* Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"R4o-n2-Eq4\"; */\n\"R4o-n2-Eq4.title\" = \"Zoom\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"RB4-Sm-HuC\"; */\n\"RB4-Sm-HuC.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Superscript\"; ObjectID = \"Rqc-34-cIF\"; */\n\"Rqc-34-cIF.title\" = \"Superscript\";\n\n/* Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Ruw-6m-B2m\"; */\n\"Ruw-6m-B2m.title\" = \"Select All\";\n\n/* Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"S0p-oC-mLd\"; */\n\"S0p-oC-mLd.title\" = \"Jump to Selection\";\n\n/* Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"Td7-aD-5lo\"; */\n\"Td7-aD-5lo.title\" = \"Window\";\n\n/* Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"UEZ-Bs-lqG\"; */\n\"UEZ-Bs-lqG.title\" = \"Capitalize\";\n\n/* Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"VIY-Ag-zcb\"; */\n\"VIY-Ag-zcb.title\" = \"Center\";\n\n/* Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\"; */\n\"Vdr-fp-XzO.title\" = \"Hide Others\";\n\n/* Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"Vjx-xi-njq\"; */\n\"Vjx-xi-njq.title\" = \"Italic\";\n\n/* Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"W48-6f-4Dl\"; */\n\"W48-6f-4Dl.title\" = \"Edit\";\n\n/* Class = \"NSMenuItem\"; title = \"Underline\"; ObjectID = \"WRG-CD-K1S\"; */\n\"WRG-CD-K1S.title\" = \"Underline\";\n\n/* Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"Was-JA-tGl\"; */\n\"Was-JA-tGl.title\" = \"New\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"WeT-3V-zwk\"; */\n\"WeT-3V-zwk.title\" = \"Paste and Match Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"Xz5-n4-O0W\"; */\n\"Xz5-n4-O0W.title\" = \"Find…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"YEy-JH-Tfz\"; */\n\"YEy-JH-Tfz.title\" = \"Find and Replace…\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"YGs-j5-SAR\"; */\n\"YGs-j5-SAR.title\" = \"\\tDefault\";\n\n/* Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"Ynk-f8-cLZ\"; */\n\"Ynk-f8-cLZ.title\" = \"Start Speaking\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Left\"; ObjectID = \"ZM1-6Q-yy1\"; */\n\"ZM1-6Q-yy1.title\" = \"Align Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Paragraph\"; ObjectID = \"ZvO-Gk-QUH\"; */\n\"ZvO-Gk-QUH.title\" = \"Paragraph\";\n\n/* Class = \"NSMenuItem\"; title = \"Print…\"; ObjectID = \"aTl-1u-JFS\"; */\n\"aTl-1u-JFS.title\" = \"Print…\";\n\n/* Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"aUF-d1-5bR\"; */\n\"aUF-d1-5bR.title\" = \"Window\";\n\n/* Class = \"NSMenu\"; title = \"Font\"; ObjectID = \"aXa-aM-Jaq\"; */\n\"aXa-aM-Jaq.title\" = \"Font\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"agt-UL-0e3\"; */\n\"agt-UL-0e3.title\" = \"Use Default\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Colors\"; ObjectID = \"bgn-CT-cEk\"; */\n\"bgn-CT-cEk.title\" = \"Show Colors\";\n\n/* Class = \"NSMenu\"; title = \"File\"; ObjectID = \"bib-Uj-vzu\"; */\n\"bib-Uj-vzu.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"buJ-ug-pKt\"; */\n\"buJ-ug-pKt.title\" = \"Use Selection for Find\";\n\n/* Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"c8a-y6-VQd\"; */\n\"c8a-y6-VQd.title\" = \"Transformations\";\n\n/* Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"cDB-IK-hbR\"; */\n\"cDB-IK-hbR.title\" = \"Use None\";\n\n/* Class = \"NSMenuItem\"; title = \"Selection\"; ObjectID = \"cqv-fj-IhA\"; */\n\"cqv-fj-IhA.title\" = \"Selection\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"cwL-P1-jid\"; */\n\"cwL-P1-jid.title\" = \"Smart Links\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"d9M-CD-aMd\"; */\n\"d9M-CD-aMd.title\" = \"Make Lower Case\";\n\n/* Class = \"NSMenu\"; title = \"Text\"; ObjectID = \"d9c-me-L2H\"; */\n\"d9c-me-L2H.title\" = \"Text\";\n\n/* Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"dMs-cI-mzQ\"; */\n\"dMs-cI-mzQ.title\" = \"File\";\n\n/* Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"dRJ-4n-Yzg\"; */\n\"dRJ-4n-Yzg.title\" = \"Undo\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"gVA-U4-sdL\"; */\n\"gVA-U4-sdL.title\" = \"Paste\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"hQb-2v-fYv\"; */\n\"hQb-2v-fYv.title\" = \"Smart Quotes\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"hz2-CU-CR7\"; */\n\"hz2-CU-CR7.title\" = \"Check Document Now\";\n\n/* Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\"; */\n\"hz9-B4-Xy5.title\" = \"Services\";\n\n/* Class = \"NSMenuItem\"; title = \"Smaller\"; ObjectID = \"i1d-Er-qST\"; */\n\"i1d-Er-qST.title\" = \"Smaller\";\n\n/* Class = \"NSMenu\"; title = \"Baseline\"; ObjectID = \"ijk-EB-dga\"; */\n\"ijk-EB-dga.title\" = \"Baseline\";\n\n/* Class = \"NSMenuItem\"; title = \"Kern\"; ObjectID = \"jBQ-r6-VK2\"; */\n\"jBQ-r6-VK2.title\" = \"Kern\";\n\n/* Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"jFq-tB-4Kx\"; */\n\"jFq-tB-4Kx.title\" = \"\\tRight to Left\";\n\n/* Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"jxT-CU-nIS\"; */\n\"jxT-CU-nIS.title\" = \"Format\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Sidebar\"; ObjectID = \"kIP-vf-haE\"; */\n\"kIP-vf-haE.title\" = \"Show Sidebar\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"mK6-2p-4JG\"; */\n\"mK6-2p-4JG.title\" = \"Check Grammar With Spelling\";\n\n/* Class = \"NSMenuItem\"; title = \"Ligatures\"; ObjectID = \"o6e-r0-MWq\"; */\n\"o6e-r0-MWq.title\" = \"Ligatures\";\n\n/* Class = \"NSMenu\"; title = \"Open Recent\"; ObjectID = \"oas-Oc-fiZ\"; */\n\"oas-Oc-fiZ.title\" = \"Open Recent\";\n\n/* Class = \"NSMenuItem\"; title = \"Loosen\"; ObjectID = \"ogc-rX-tC1\"; */\n\"ogc-rX-tC1.title\" = \"Loosen\";\n\n/* Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"pa3-QI-u2k\"; */\n\"pa3-QI-u2k.title\" = \"Delete\";\n\n/* Class = \"NSMenuItem\"; title = \"Save…\"; ObjectID = \"pxx-59-PXV\"; */\n\"pxx-59-PXV.title\" = \"Save…\";\n\n/* Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"q09-fT-Sye\"; */\n\"q09-fT-Sye.title\" = \"Find Next\";\n\n/* Class = \"NSMenuItem\"; title = \"Page Setup…\"; ObjectID = \"qIS-W8-SiK\"; */\n\"qIS-W8-SiK.title\" = \"Page Setup…\";\n\n/* Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"rbD-Rh-wIN\"; */\n\"rbD-Rh-wIN.title\" = \"Check Spelling While Typing\";\n\n/* Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"rgM-f4-ycn\"; */\n\"rgM-f4-ycn.title\" = \"Smart Dashes\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Toolbar\"; ObjectID = \"snW-S8-Cw5\"; */\n\"snW-S8-Cw5.title\" = \"Show Toolbar\";\n\n/* Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\"; */\n\"tRr-pd-1PS.title\" = \"Data Detectors\";\n\n/* Class = \"NSMenuItem\"; title = \"Open Recent\"; ObjectID = \"tXI-mr-wws\"; */\n\"tXI-mr-wws.title\" = \"Open Recent\";\n\n/* Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"tlD-Oa-oAM\"; */\n\"tlD-Oa-oAM.title\" = \"Kern\";\n\n/* Class = \"NSMenu\"; title = \"DevToys\"; ObjectID = \"uQy-DD-JDr\"; */\n\"uQy-DD-JDr.title\" = \"DevToys\";\n\n/* Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"uRl-iY-unG\"; */\n\"uRl-iY-unG.title\" = \"Cut\";\n\n/* Class = \"NSMenuItem\"; title = \"Paste Style\"; ObjectID = \"vKC-jM-MkH\"; */\n\"vKC-jM-MkH.title\" = \"Paste Style\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Ruler\"; ObjectID = \"vLm-3I-IUL\"; */\n\"vLm-3I-IUL.title\" = \"Show Ruler\";\n\n/* Class = \"NSMenuItem\"; title = \"Clear Menu\"; ObjectID = \"vNY-rz-j42\"; */\n\"vNY-rz-j42.title\" = \"Clear Menu\";\n\n/* Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\"; */\n\"vmV-6d-7jI.title\" = \"Make Upper Case\";\n\n/* Class = \"NSMenu\"; title = \"Ligatures\"; ObjectID = \"w0m-vy-SC9\"; */\n\"w0m-vy-SC9.title\" = \"Ligatures\";\n\n/* Class = \"NSMenuItem\"; title = \"Align Right\"; ObjectID = \"wb2-vD-lq4\"; */\n\"wb2-vD-lq4.title\" = \"Align Right\";\n\n/* Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"wpr-3q-Mcd\"; */\n\"wpr-3q-Mcd.title\" = \"Help\";\n\n/* Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"x3v-GG-iWU\"; */\n\"x3v-GG-iWU.title\" = \"Copy\";\n\n/* Class = \"NSMenuItem\"; title = \"Use All\"; ObjectID = \"xQD-1f-W4t\"; */\n\"xQD-1f-W4t.title\" = \"Use All\";\n\n/* Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"xrE-MZ-jX0\"; */\n\"xrE-MZ-jX0.title\" = \"Speech\";\n\n/* Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"z6F-FW-3nz\"; */\n\"z6F-FW-3nz.title\" = \"Show Substitutions\";\n"
  },
  {
    "path": "DevToys/DevToys/Sidebar/SearchCell.swift",
    "content": "//\n//  SidebarSearchView+.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class SidebarSearchCellController: NSViewController {\n    private let cell = SidebarSearchCell()\n    \n    override func loadView() { self.view = cell }\n        \n    override func chainObjectDidLoad() {\n        self.appModel.$searchQuery\n            .sink{[unowned self] in self.cell.searchView.stringValue = $0 }.store(in: &objectBag)\n        self.cell.searchView.changeStringPublisher.merge(with: self.cell.searchView.endEditingStringPublisher)\n            .sink{[unowned self] in self.appModel.searchQuery = $0 }.store(in: &objectBag)\n    }\n}\n\nfinal class SidebarSearchCell: NSLoadView {\n    \n    static let height: CGFloat = 48\n    \n    let searchView = SidebarSearchField()\n    \n    override func onAwake() {\n        self.addSubview(searchView)\n        self.searchView.snp.makeConstraints{ make in\n            make.height.equalTo(29)\n            make.centerY.equalToSuperview()\n            make.right.left.equalToSuperview()\n        }\n    }\n}\n\nfinal class SidebarSearchField: NSSearchField {\n    override var focusRingMaskBounds: NSRect { bounds }\n    \n    override func drawFocusRingMask() {\n        NSBezierPath(roundedRect: bounds.slimmed(by: 1), xRadius: 4, yRadius: 4).fill()\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Sidebar/SidebarView+.swift",
    "content": "//\n//  ToolmenuViewController.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class SidebarViewController: NSViewController {\n    \n    private let searchViewController = SidebarSearchCellController()\n    private let outlineView = SidebarOutlineView.list()\n    private let scrollView = NSScrollView()\n    \n    @RestorableState(\"toolmenu.initial\") private var isInitial = true\n        \n    @objc func onClick(_ outlineView: NSOutlineView) {\n        self.onSelect(row: outlineView.clickedRow)\n    }\n    \n    private func onSelect(row: Int) {\n        guard let tool = outlineView.item(atRow: row) as? Tool else { return }\n        self.appModel.tool = tool\n    } \n    \n    override func loadView() {\n        self.view = scrollView\n        self.scrollView.documentView = outlineView\n        self.scrollView.drawsBackground = false\n        \n        self.outlineView.setTarget(self, action: #selector(onClick))\n        self.outlineView.outlineTableColumn = self.outlineView.tableColumns[0]\n        self.outlineView.selectionHighlightStyle = .sourceList\n        self.outlineView.floatsGroupRows = false\n        self.addChild(searchViewController)\n    }\n        \n    override func chainObjectDidLoad() {\n        // Datasource uses chainObject, call it in `chainObjectDidLoad`\n        self.outlineView.delegate = self\n        self.outlineView.dataSource = self\n        self.outlineView.autosaveExpandedItems = true\n        self.outlineView.autosaveName = \"sidebar\"\n        if self.isInitial {\n            self.isInitial = false\n            self.outlineView.expandItem(nil, expandChildren: true)\n        }\n    }\n}\n\nfinal private class SidebarOutlineView: NSOutlineView {\n    override func mouseDown(with event: NSEvent) {\n        super.mouseDown(with: event)\n        \n        let row = row(at: event.location(in: self))\n        if row >= 0, let cell = self.view(atColumn: 0, row: row, makeIfNecessary: false) as? SidebarSearchCell,\n           window?.firstResponder !== cell.searchView\n        {\n            window?.makeFirstResponder(cell.searchView)\n        }\n    }\n}\n\nextension SidebarViewController: NSOutlineViewDataSource {\n    func outlineView(_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool {\n        item is ToolCategory\n    }\n    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {\n        item is ToolCategory\n    }\n    func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool {\n        item is Tool\n    }\n    func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {\n        if item == nil {\n            if index == 0 {\n                return ()\n            } else {\n                return appModel.toolManager.flattenRootItems()[index-1]\n            }\n        }\n        guard let category = item as? ToolCategory else { return () }\n        return appModel.toolManager.toolsForCategory(category)[index]\n    }\n    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {\n        if item == nil { return appModel.toolManager.flattenRootItems().count + 1 }\n        guard let category = item as? ToolCategory else { return 0 }\n        return appModel.toolManager.toolsForCategory(category).count\n    }\n    \n    func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {\n        if item is ToolCategory {\n            return ToolCategoryCell.height\n        } else if item is Tool {\n            return ToolMenuCell.height\n        } else {\n            return SidebarSearchCell.height\n        }\n    }\n    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {\n        if let category = item as? ToolCategory {\n            let cell = ToolCategoryCell()\n            cell.title = category.name\n            return cell\n        } else if let tool = item as? Tool {\n            let cell = ToolMenuCell()\n            cell.title = tool.sidebarTitle\n            cell.icon = tool.icon\n            return cell\n        } else if item is Void {\n            return searchViewController.view\n        }\n        \n        return nil\n    }\n    \n    func outlineView(_ outlineView: NSOutlineView, persistentObjectForItem item: Any?) -> Any? {\n        if let category = item as? ToolCategory {\n            return category.identifier\n        } else if let tool = item as? Tool {\n            return tool.identifier\n        }\n        return nil\n    }\n    func outlineView(_ outlineView: NSOutlineView, itemForPersistentObject object: Any) -> Any? {\n        guard let identifier = object as? String else { return nil }\n        if let category = appModel.toolManager.categoryForIdentifier(identifier) { return category }\n        if let tool = appModel.toolManager.toolForIdentifier(identifier) { return tool }\n        return nil\n    }\n}\n\nextension SidebarViewController: NSOutlineViewDelegate {\n    func outlineViewSelectionDidChange(_ notification: Notification) {\n        self.onSelect(row: outlineView.selectedRow)\n    }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Sidebar/ToolCategoryCell.swift",
    "content": "//\n//  ToolCategoryCell.swift\n//  DevToys\n//\n//  Created by yuki on 2022/02/16.\n//\n\nimport CoreUtil\n\nfinal class ToolCategoryCell: NSLoadView {\n    static let height: CGFloat = 21\n    \n    var title: String {\n        get { titleLabel.stringValue } set { titleLabel.stringValue = newValue }\n    }\n    \n    private let titleLabel = NSTextField(labelWithString: \"Title\")\n    \n    override func onAwake() {\n        self.addSubview(titleLabel)\n        self.titleLabel.font = .systemFont(ofSize: 11, weight: .semibold)\n        self.titleLabel.textColor = .tertiaryLabelColor\n        self.titleLabel.snp.makeConstraints{ make in\n            make.left.right.equalToSuperview().inset(8)\n            make.centerY.equalToSuperview()\n        }\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys/Sidebar/ToolMenuCell.swift",
    "content": "//\n//  ToolmenuCell.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class ToolMenuCell: NSLoadView {\n    static let height: CGFloat = 28\n       \n   var title: String {\n       get { titleLabel.stringValue } set { titleLabel.stringValue = newValue }\n   }\n   var icon: NSImage? {\n       get { iconView.image } set { iconView.image = newValue }\n   }\n   \n   private let titleLabel = NSTextField(labelWithString: \"Title\")\n   private let iconView = NSImageView()\n   \n   override func onAwake() {\n       self.snp.makeConstraints{ make in\n           make.height.equalTo(Self.height)\n       }\n       self.addSubview(iconView)\n       self.iconView.snp.makeConstraints{ make in\n           make.size.equalTo(20)\n           make.left.equalTo(8)\n           make.centerY.equalToSuperview()\n       }\n       self.addSubview(titleLabel)\n\n       self.titleLabel.lineBreakMode = .byTruncatingTail\n       self.titleLabel.font = .systemFont(ofSize: 12)\n       self.titleLabel.snp.makeConstraints{ make in\n           make.left.equalTo(self.iconView.snp.right).offset(8)\n           make.right.equalToSuperview().inset(4)\n           make.centerY.equalToSuperview()\n       }\n   }\n}\n"
  },
  {
    "path": "DevToys/DevToys/Sidebar/View/Separator.swift",
    "content": "//\n//  Separator.swift\n//  DevToys\n//\n//  Created by yuki on 2022/01/29.\n//\n\nimport CoreUtil\n\nfinal class SeparatorView: NSLoadView {\n    private let separatorLayer = CALayer.animationDisabled()\n    \n    public override func layout() {\n        super.layout()\n        self.separatorLayer.frame = bounds\n    }\n    \n    public override func updateLayer() {\n        self.separatorLayer.backgroundColor = NSColor.textColor.withAlphaComponent(0.1).cgColor\n    }\n    \n    override public func onAwake() {\n        self.wantsLayer = true\n        self.layer?.addSublayer(separatorLayer)\n        \n        self.snp.makeConstraints{ make in\n            make.height.equalTo(1)\n        }\n    }\n}\n\n"
  },
  {
    "path": "DevToys/DevToys.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 52;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t6B42318827AD1BC0002D135A /* HyphenationRemoverView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B42318727AD1BC0002D135A /* HyphenationRemoverView+.swift */; };\n\t\tB608540B27A66694003BF243 /* SectionButton+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B608540A27A66694003BF243 /* SectionButton+.swift */; };\n\t\tB608541227A66A90003BF243 /* JSONYamlConverterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B608541127A66A90003BF243 /* JSONYamlConverterView+.swift */; };\n\t\tB608541527A66CC9003BF243 /* CoreUtil.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64B1F5E27A4FC1900AC2601 /* CoreUtil.framework */; };\n\t\tB608541627A66CC9003BF243 /* CoreUtil.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B64B1F5E27A4FC1900AC2601 /* CoreUtil.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };\n\t\tB608541B27A672E3003BF243 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = B608541A27A672E3003BF243 /* Yams */; };\n\t\tB608541E27A67B48003BF243 /* NumberBaseConverterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B608541D27A67B48003BF243 /* NumberBaseConverterView+.swift */; };\n\t\tB608542027A67E4D003BF243 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B608541F27A67E4D003BF243 /* TextField.swift */; };\n\t\tB6113ECD27C4B96C00ACC6E8 /* EmptyImageTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6113ECC27C4B96C00ACC6E8 /* EmptyImageTableView.swift */; };\n\t\tB6113ECF27C4BF2300ACC6E8 /* FileConflictAvoider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6113ECE27C4BF2300ACC6E8 /* FileConflictAvoider.swift */; };\n\t\tB6113F0127C4BF7700ACC6E8 /* Identifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6113F0027C4BF7700ACC6E8 /* Identifier.swift */; };\n\t\tB6113F0927C4C6C900ACC6E8 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = B6113F0827C4C6C900ACC6E8 /* Sparkle */; };\n\t\tB61157C027C8C3F9004D77A5 /* JSONSearchView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61157BF27C8C3F9004D77A5 /* JSONSearchView+.swift */; };\n\t\tB61157C327C8C78A004D77A5 /* JSONNormalSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61157C227C8C78A004D77A5 /* JSONNormalSearchView.swift */; };\n\t\tB61157C527C8D77A004D77A5 /* DragImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61157C427C8D77A004D77A5 /* DragImageView.swift */; };\n\t\tB61796C527BCB3090054660E /* ToolCategoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61796C427BCB3090054660E /* ToolCategoryCell.swift */; };\n\t\tB61796C727BCB6F00054660E /* SettingView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61796C627BCB6F00054660E /* SettingView+.swift */; };\n\t\tB61796C927BCB84A0054660E /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61796C827BCB84A0054660E /* Settings.swift */; };\n\t\tB62013B427A9070D00AF5386 /* UUIDGeneratorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62013B327A9070D00AF5386 /* UUIDGeneratorView+.swift */; };\n\t\tB62013B627A90B8900AF5386 /* NumberField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62013B527A90B8900AF5386 /* NumberField.swift */; };\n\t\tB620141C27A917E000AF5386 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = B620141B27A917E000AF5386 /* Button.swift */; };\n\t\tB620141E27A91F6700AF5386 /* LoremIpsumGeneratorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B620141D27A91F6700AF5386 /* LoremIpsumGeneratorView+.swift */; };\n\t\tB620142127A9271500AF5386 /* TextInspectorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B620142027A9271500AF5386 /* TextInspectorView+.swift */; };\n\t\tB620142327A929B400AF5386 /* TagCloudView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B620142227A929B400AF5386 /* TagCloudView.swift */; };\n\t\tB627294F27BFB7680034D70C /* WebpImageExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B627294E27BFB7680034D70C /* WebpImageExporter.swift */; };\n\t\tB627295227BFB8CB0034D70C /* cwebp in Resources */ = {isa = PBXBuildFile; fileRef = B627295127BFB8CB0034D70C /* cwebp */; };\n\t\tB627295727BFCCC40034D70C /* HeicImageExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B627295627BFCCC40034D70C /* HeicImageExporter.swift */; };\n\t\tB63A034B27C2130A009FD2AD /* GifConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63A034A27C2130A009FD2AD /* GifConverter.swift */; };\n\t\tB63A034D27C21A99009FD2AD /* ffmpeg in Resources */ = {isa = PBXBuildFile; fileRef = B63A034C27C21A99009FD2AD /* ffmpeg */; };\n\t\tB63A035027C24BA0009FD2AD /* FFProgressReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63A034F27C24BA0009FD2AD /* FFProgressReport.swift */; };\n\t\tB63A035227C25B29009FD2AD /* FFTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63A035127C25B29009FD2AD /* FFTime.swift */; };\n\t\tB64844FF27B767EC004FE02B /* ToolManager+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64844FE27B767EC004FE02B /* ToolManager+.swift */; };\n\t\tB64AA45027AD0D3900EC436D /* DateConverterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64AA44F27AD0D3900EC436D /* DateConverterView+.swift */; };\n\t\tB64B1E7427A4F5E200AC2601 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1E7327A4F5E200AC2601 /* AppDelegate.swift */; };\n\t\tB64B1E7627A4F5E200AC2601 /* AppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1E7527A4F5E200AC2601 /* AppViewController.swift */; };\n\t\tB64B1E7827A4F5E300AC2601 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B64B1E7727A4F5E300AC2601 /* Assets.xcassets */; };\n\t\tB64B1E7B27A4F5E300AC2601 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B64B1E7927A4F5E300AC2601 /* Main.storyboard */; };\n\t\tB64B1F7227A4FDC800AC2601 /* AppModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F7127A4FDC800AC2601 /* AppModel.swift */; };\n\t\tB64B1F7727A4FF8B00AC2601 /* SidebarView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B1F7627A4FF8B00AC2601 /* SidebarView+.swift */; };\n\t\tB64B201627A5100800AC2601 /* Separator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B201527A5100800AC2601 /* Separator.swift */; };\n\t\tB64B201D27A5219400AC2601 /* SearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B201C27A5219400AC2601 /* SearchCell.swift */; };\n\t\tB64B202027A523A200AC2601 /* ToolMenuCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B201F27A523A200AC2601 /* ToolMenuCell.swift */; };\n\t\tB64B202327A52A2D00AC2601 /* R.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B202227A52A2D00AC2601 /* R.swift */; };\n\t\tB64B209827A532DF00AC2601 /* AppWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64B209727A532DF00AC2601 /* AppWindowController.swift */; };\n\t\tB65DB78027AC0EB400146A3C /* RegexTesterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65DB77F27AC0EB400146A3C /* RegexTesterView+.swift */; };\n\t\tB66536CE27C9BA4000CA1CEC /* Slugify.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66536CD27C9BA4000CA1CEC /* Slugify.swift */; };\n\t\tB66536D027C9C56600CA1CEC /* SQLFormatterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66536CF27C9C56600CA1CEC /* SQLFormatterView+.swift */; };\n\t\tB66850EE27A64D3200A3FE01 /* Page.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66850ED27A64D3200A3FE01 /* Page.swift */; };\n\t\tB66850F227A65FC200A3FE01 /* SwiftJSONFormatter in Frameworks */ = {isa = PBXBuildFile; productRef = B66850F127A65FC200A3FE01 /* SwiftJSONFormatter */; };\n\t\tB66BE8BC27C49AD4003B5ED0 /* AudioFileScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66BE8BB27C49AD4003B5ED0 /* AudioFileScanner.swift */; };\n\t\tB672CFA027AAB8DD00391A5D /* FileDrop.swift in Sources */ = {isa = PBXBuildFile; fileRef = B672CF9F27AAB8DD00391A5D /* FileDrop.swift */; };\n\t\tB673A90227AD0E78005512AB /* DatePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B673A90127AD0E78005512AB /* DatePicker.swift */; };\n\t\tB6789EBA27CA43E200D8B58C /* IconGeneratorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6789EB927CA43E100D8B58C /* IconGeneratorView+.swift */; };\n\t\tB6789EBC27CA48A300D8B58C /* IosIconGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6789EBB27CA48A300D8B58C /* IosIconGenerator.swift */; };\n\t\tB6789EDF27CA5F5D00D8B58C /* IconsetGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6789EDE27CA5F5D00D8B58C /* IconsetGenerator.swift */; };\n\t\tB6789EE127CA5F6900D8B58C /* IcnsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6789EE027CA5F6900D8B58C /* IcnsGenerator.swift */; };\n\t\tB6789EE327CA5F7A00D8B58C /* IconFolderGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6789EE227CA5F7A00D8B58C /* IconFolderGenerator.swift */; };\n\t\tB6789EE527CA5F9500D8B58C /* IconGenerator+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6789EE427CA5F9500D8B58C /* IconGenerator+Model.swift */; };\n\t\tB6789EE727CB334D00D8B58C /* AndroidIconGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6789EE627CB334D00D8B58C /* AndroidIconGenerator.swift */; };\n\t\tB67A4C0827C0BA00009277FB /* ColorPickerHandleLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C0227C0B9FF009277FB /* ColorPickerHandleLayer.swift */; };\n\t\tB67A4C0927C0BA00009277FB /* OpacityBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C0327C0B9FF009277FB /* OpacityBarView.swift */; };\n\t\tB67A4C0A27C0BA00009277FB /* HueBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C0427C0B9FF009277FB /* HueBarView.swift */; };\n\t\tB67A4C0B27C0BA00009277FB /* ColorPickerView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C0527C0B9FF009277FB /* ColorPickerView+.swift */; };\n\t\tB67A4C0C27C0BA00009277FB /* ColorBoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C0627C0B9FF009277FB /* ColorBoxView.swift */; };\n\t\tB67A4C0D27C0BA00009277FB /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C0727C0B9FF009277FB /* Color.swift */; };\n\t\tB67A4C4D27C0EA84009277FB /* ACPixelPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C3F27C0EA84009277FB /* ACPixelPicker.swift */; };\n\t\tB67A4C4E27C0EA84009277FB /* ACOverlayPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4027C0EA84009277FB /* ACOverlayPreview.swift */; };\n\t\tB67A4C4F27C0EA84009277FB /* Ex+NSBezierPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4227C0EA84009277FB /* Ex+NSBezierPath.swift */; };\n\t\tB67A4C5027C0EA84009277FB /* Util+PixelPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4427C0EA84009277FB /* Util+PixelPicker.swift */; };\n\t\tB67A4C5127C0EA84009277FB /* ShowAndHideCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4527C0EA84009277FB /* ShowAndHideCursor.swift */; };\n\t\tB67A4C5227C0EA84009277FB /* ShowAndHideCursor.m in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4627C0EA84009277FB /* ShowAndHideCursor.m */; };\n\t\tB67A4C5327C0EA84009277FB /* Ex+NSColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4727C0EA84009277FB /* Ex+NSColor.swift */; };\n\t\tB67A4C5427C0EA84009277FB /* Ex+CGImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4827C0EA84009277FB /* Ex+CGImage.swift */; };\n\t\tB67A4C5527C0EA84009277FB /* ACOverlayPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4927C0EA84009277FB /* ACOverlayPanel.swift */; };\n\t\tB67A4C5627C0EA84009277FB /* ACOverlayController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4A27C0EA84009277FB /* ACOverlayController.swift */; };\n\t\tB67A4C5727C0EA84009277FB /* ACOverlayController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B67A4C4B27C0EA84009277FB /* ACOverlayController.xib */; };\n\t\tB67A4C5827C0EA84009277FB /* ACOverlayWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4C4C27C0EA84009277FB /* ACOverlayWrapper.swift */; };\n\t\tB67A4CBE27C0EEEF009277FB /* ColorSampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CBD27C0EEEF009277FB /* ColorSampleView.swift */; };\n\t\tB67A4CC027C0F4BA009277FB /* BoxHSBColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CBF27C0F4BA009277FB /* BoxHSBColorPicker.swift */; };\n\t\tB67A4CC327C0F4D4009277FB /* CircleHueBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CC227C0F4D4009277FB /* CircleHueBarView.swift */; };\n\t\tB67A4CC527C0F50D009277FB /* R+ColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CC427C0F50D009277FB /* R+ColorPicker.swift */; };\n\t\tB67A4CC727C0F546009277FB /* CircleBoxHSBColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CC627C0F546009277FB /* CircleBoxHSBColorPicker.swift */; };\n\t\tB67A4CC927C10493009277FB /* SaturationBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CC827C10493009277FB /* SaturationBarView.swift */; };\n\t\tB67A4CCB27C10548009277FB /* BrightnessBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CCA27C10548009277FB /* BrightnessBarView.swift */; };\n\t\tB67A4CCD27C12C09009277FB /* CircleBarsHSBColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67A4CCC27C12C09009277FB /* CircleBarsHSBColorPicker.swift */; };\n\t\tB680A79527A68B35007CB707 /* HTMLDecoderView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A79427A68B35007CB707 /* HTMLDecoderView+.swift */; };\n\t\tB680A79827A69268007CB707 /* HTMLEntities in Frameworks */ = {isa = PBXBuildFile; productRef = B680A79727A69268007CB707 /* HTMLEntities */; };\n\t\tB680A79A27A69324007CB707 /* URLDecoderView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A79927A69324007CB707 /* URLDecoderView+.swift */; };\n\t\tB680A79C27A6947D007CB707 /* Base64DecoderView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A79B27A6947D007CB707 /* Base64DecoderView+.swift */; };\n\t\tB680A83327A8BF7D007CB707 /* TextViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A83227A8BF7D007CB707 /* TextViewSection.swift */; };\n\t\tB680A86827A8D4D1007CB707 /* TextFieldSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A86727A8D4D1007CB707 /* TextFieldSection.swift */; };\n\t\tB680A89A27A8D9DD007CB707 /* Toast.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A89927A8D9DD007CB707 /* Toast.swift */; };\n\t\tB680A8A727A8DD5D007CB707 /* JWTDecoderView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A8A627A8DD5D007CB707 /* JWTDecoderView+.swift */; };\n\t\tB680A8AA27A8E106007CB707 /* HashGeneratorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B680A8A927A8E106007CB707 /* HashGeneratorView+.swift */; };\n\t\tB680A8AD27A8E31C007CB707 /* CryptoSwift in Frameworks */ = {isa = PBXBuildFile; productRef = B680A8AC27A8E31C007CB707 /* CryptoSwift */; };\n\t\tB684EA2627C5EFDB0014802F /* DiffMatchPatch in Frameworks */ = {isa = PBXBuildFile; productRef = B684EA2527C5EFDB0014802F /* DiffMatchPatch */; };\n\t\tB684EA2827C5EFE90014802F /* TextDiffView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684EA2727C5EFE90014802F /* TextDiffView+.swift */; };\n\t\tB684EA2A27C609620014802F /* QRCodeGeneratorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684EA2927C609620014802F /* QRCodeGeneratorView+.swift */; };\n\t\tB69980D427CCCF0A0063F63D /* android_mask.png in Resources */ = {isa = PBXBuildFile; fileRef = B69980D327CCCF0A0063F63D /* android_mask.png */; };\n\t\tB69980D727CCE09A0063F63D /* IcoGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69980D627CCE09A0063F63D /* IcoGenerator.swift */; };\n\t\tB69980D927CCEB320063F63D /* PngIconGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69980D827CCEB320063F63D /* PngIconGenerator.swift */; };\n\t\tB69F0E8327CBC2100032F96A /* folder_back_64_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E7C27CBC20F0032F96A /* folder_back_64_bs.png */; };\n\t\tB69F0E8427CBC2100032F96A /* folder_back_128_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E7D27CBC20F0032F96A /* folder_back_128_bs.png */; };\n\t\tB69F0E8527CBC2100032F96A /* folder_back_256_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E7E27CBC20F0032F96A /* folder_back_256_bs.png */; };\n\t\tB69F0E8627CBC2100032F96A /* folder_back_1024_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E7F27CBC20F0032F96A /* folder_back_1024_bs.png */; };\n\t\tB69F0E8727CBC2100032F96A /* folder_back_32_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8027CBC20F0032F96A /* folder_back_32_bs.png */; };\n\t\tB69F0E8827CBC2100032F96A /* folder_back_16_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8127CBC20F0032F96A /* folder_back_16_bs.png */; };\n\t\tB69F0E8927CBC2100032F96A /* folder_back_512_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8227CBC20F0032F96A /* folder_back_512_bs.png */; };\n\t\tB69F0E9127CBC2340032F96A /* folder_mask2_1024_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8B27CBC2340032F96A /* folder_mask2_1024_bs.png */; };\n\t\tB69F0E9227CBC2340032F96A /* folder_mask2_512_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8C27CBC2340032F96A /* folder_mask2_512_bs.png */; };\n\t\tB69F0E9327CBC2340032F96A /* folder_mask2_16_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8D27CBC2340032F96A /* folder_mask2_16_bs.png */; };\n\t\tB69F0E9427CBC2340032F96A /* folder_mask2_32_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8E27CBC2340032F96A /* folder_mask2_32_bs.png */; };\n\t\tB69F0E9527CBC2340032F96A /* folder_mask2_64_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E8F27CBC2340032F96A /* folder_mask2_64_bs.png */; };\n\t\tB69F0E9627CBC2340032F96A /* folder_mask2_128_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E9027CBC2340032F96A /* folder_mask2_128_bs.png */; };\n\t\tB69F0E9827CBC2800032F96A /* folder_mask2_256_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E9727CBC2800032F96A /* folder_mask2_256_bs.png */; };\n\t\tB69F0E9C27CBC7550032F96A /* folder_top_1024.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E9A27CBC7550032F96A /* folder_top_1024.png */; };\n\t\tB69F0E9D27CBC7550032F96A /* folder_top_512.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0E9B27CBC7550032F96A /* folder_top_512.png */; };\n\t\tB69F0E9F27CC76A50032F96A /* IconImageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69F0E9E27CC76A50032F96A /* IconImageManager.swift */; };\n\t\tB69F0EA627CC7CF40032F96A /* watermark_mask_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0EA427CC7CF40032F96A /* watermark_mask_bs.png */; };\n\t\tB69F0EA727CC7CF40032F96A /* watermark_mask_dark_bs.png in Resources */ = {isa = PBXBuildFile; fileRef = B69F0EA527CC7CF40032F96A /* watermark_mask_dark_bs.png */; };\n\t\tB6A4F2A227CD05F000BBDE7E /* QRCodeReaderView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A4F2A127CD05F000BBDE7E /* QRCodeReaderView+.swift */; };\n\t\tB6A4F2A427CD078100BBDE7E /* ImageDropView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A4F2A327CD078100BBDE7E /* ImageDropView.swift */; };\n\t\tB6A93D3227CBBC97003A6D7F /* IconTemplete+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A93D2F27CBBC97003A6D7F /* IconTemplete+.swift */; };\n\t\tB6A93D3327CBBC97003A6D7F /* IconSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A93D3027CBBC97003A6D7F /* IconSet.swift */; };\n\t\tB6A93D3427CBBC97003A6D7F /* IconTemplete.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A93D3127CBBC97003A6D7F /* IconTemplete.swift */; };\n\t\tB6AC273027AA1373000FD713 /* optipng in Resources */ = {isa = PBXBuildFile; fileRef = B6AC272F27AA1373000FD713 /* optipng */; };\n\t\tB6AC273227AA2BF6000FD713 /* ImageOptimizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AC273127AA2BF6000FD713 /* ImageOptimizer.swift */; };\n\t\tB6AC276527AA3D61000FD713 /* jpegoptim in Resources */ = {isa = PBXBuildFile; fileRef = B6AC276427AA3D61000FD713 /* jpegoptim */; };\n\t\tB6AC276A27AA535A000FD713 /* PDFGeneratorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AC276927AA535A000FD713 /* PDFGeneratorView+.swift */; };\n\t\tB6B5726227AC14B60069DBA7 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5726127AC14B60069DBA7 /* TextView.swift */; };\n\t\tB6B5726427AC14D10069DBA7 /* RegexTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5726327AC14D10069DBA7 /* RegexTextView.swift */; };\n\t\tB6B5728027ACC3AF0069DBA7 /* ChecksumGeneratorView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5727F27ACC3AE0069DBA7 /* ChecksumGeneratorView+.swift */; };\n\t\tB6B5728227ACCF2F0069DBA7 /* XMLFormatterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5728127ACCF2F0069DBA7 /* XMLFormatterView+.swift */; };\n\t\tB6B5728827ACD2F20069DBA7 /* Kanna in Frameworks */ = {isa = PBXBuildFile; productRef = B6B5728727ACD2F20069DBA7 /* Kanna */; };\n\t\tB6B5728A27ACDA420069DBA7 /* ImageConverterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5728927ACDA420069DBA7 /* ImageConverterView+.swift */; };\n\t\tB6B5728C27ACE5600069DBA7 /* ImageConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5728B27ACE5600069DBA7 /* ImageConverter.swift */; };\n\t\tB6B5728F27ACFA6E0069DBA7 /* ImageDropper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5728E27ACFA6D0069DBA7 /* ImageDropper.swift */; };\n\t\tB6BBA90727C392E3000FE7D3 /* AudioConverterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BBA90627C392E3000FE7D3 /* AudioConverterView+.swift */; };\n\t\tB6BBA90927C39528000FE7D3 /* AudioConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BBA90827C39528000FE7D3 /* AudioConverter.swift */; };\n\t\tB6BD80EB27B89EA600152AB9 /* ImageOptimaizerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BD80EA27B89EA600152AB9 /* ImageOptimaizerView.swift */; };\n\t\tB6BD80EF27B8A85400152AB9 /* ToolCategory+Default.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BD80EE27B8A85400152AB9 /* ToolCategory+Default.swift */; };\n\t\tB6BD80F127B8A86100152AB9 /* Tool+Default.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BD80F027B8A86100152AB9 /* Tool+Default.swift */; };\n\t\tB6BD80F427B8AEE700152AB9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6BD80F627B8AEE700152AB9 /* Localizable.strings */; };\n\t\tB6C5292427C20D520019BCB0 /* GifConverterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C5292327C20D520019BCB0 /* GifConverterView+.swift */; };\n\t\tB6C5292727C20DC60019BCB0 /* FFMpegExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C5292627C20DC60019BCB0 /* FFMpegExecutor.swift */; };\n\t\tB6CBFEF927CCA1B000902E56 /* squircle_bg_mask_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEE827CCA1B000902E56 /* squircle_bg_mask_256x256.png */; };\n\t\tB6CBFEFA27CCA1B000902E56 /* squircle_bg_mask_1024x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEE927CCA1B000902E56 /* squircle_bg_mask_1024x1024.png */; };\n\t\tB6CBFEFB27CCA1B000902E56 /* squircle_back_128x128.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEEA27CCA1B000902E56 /* squircle_back_128x128.png */; };\n\t\tB6CBFEFC27CCA1B000902E56 /* squircle_back_1024x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEEB27CCA1B000902E56 /* squircle_back_1024x1024.png */; };\n\t\tB6CBFEFD27CCA1B000902E56 /* squircle_back_16x16.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEEC27CCA1B000902E56 /* squircle_back_16x16.png */; };\n\t\tB6CBFEFE27CCA1B000902E56 /* squircle_mask_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEED27CCA1B000902E56 /* squircle_mask_256x256.png */; };\n\t\tB6CBFEFF27CCA1B000902E56 /* squircle_mask_16x16.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEEE27CCA1B000902E56 /* squircle_mask_16x16.png */; };\n\t\tB6CBFF0027CCA1B000902E56 /* squircle_back_512x512.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEEF27CCA1B000902E56 /* squircle_back_512x512.png */; };\n\t\tB6CBFF0127CCA1B000902E56 /* squircle_mask_64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF027CCA1B000902E56 /* squircle_mask_64x64.png */; };\n\t\tB6CBFF0227CCA1B000902E56 /* squircle_mask_128x128.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF127CCA1B000902E56 /* squircle_mask_128x128.png */; };\n\t\tB6CBFF0327CCA1B000902E56 /* squircle_mask_32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF227CCA1B000902E56 /* squircle_mask_32x32.png */; };\n\t\tB6CBFF0427CCA1B000902E56 /* squircle_bg_mask_512x512.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF327CCA1B000902E56 /* squircle_bg_mask_512x512.png */; };\n\t\tB6CBFF0527CCA1B000902E56 /* squircle_mask_1024x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF427CCA1B000902E56 /* squircle_mask_1024x1024.png */; };\n\t\tB6CBFF0627CCA1B000902E56 /* squircle_back_32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF527CCA1B000902E56 /* squircle_back_32x32.png */; };\n\t\tB6CBFF0727CCA1B000902E56 /* squircle_back_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF627CCA1B000902E56 /* squircle_back_256x256.png */; };\n\t\tB6CBFF0827CCA1B000902E56 /* squircle_back_64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF727CCA1B000902E56 /* squircle_back_64x64.png */; };\n\t\tB6CBFF0927CCA1B000902E56 /* squircle_mask_512x512.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFEF827CCA1B000902E56 /* squircle_mask_512x512.png */; };\n\t\tB6CBFF1727CCA88F00902E56 /* external_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFF0D27CCA88E00902E56 /* external_256x256.png */; };\n\t\tB6CBFF1827CCA88F00902E56 /* external_128x128.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFF0E27CCA88E00902E56 /* external_128x128.png */; };\n\t\tB6CBFF1927CCA88F00902E56 /* external_64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFF0F27CCA88E00902E56 /* external_64x64.png */; };\n\t\tB6CBFF1A27CCA88F00902E56 /* external_16x16.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFF1027CCA88E00902E56 /* external_16x16.png */; };\n\t\tB6CBFF1B27CCA88F00902E56 /* external_32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFF1127CCA88E00902E56 /* external_32x32.png */; };\n\t\tB6CBFF1D27CCA88F00902E56 /* external_512x512.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFF1327CCA88E00902E56 /* external_512x512.png */; };\n\t\tB6CBFF1F27CCA88F00902E56 /* external_1024x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = B6CBFF1527CCA88F00902E56 /* external_1024x1024.png */; };\n\t\tB6D1AEDF27A534960022FED2 /* BodyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEDE27A534960022FED2 /* BodyViewController.swift */; };\n\t\tB6D1AEE427A53A560022FED2 /* HomeView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEE327A53A560022FED2 /* HomeView+.swift */; };\n\t\tB6D1AEE927A545230022FED2 /* Area.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEE827A545230022FED2 /* Area.swift */; };\n\t\tB6D1AEEC27A546810022FED2 /* ControlBackgroundLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEEB27A546810022FED2 /* ControlBackgroundLayer.swift */; };\n\t\tB6D1AEF027A547B90022FED2 /* JSONFormatterView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEEF27A547B90022FED2 /* JSONFormatterView+.swift */; };\n\t\tB6D1AEF427A54C440022FED2 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEF327A54C440022FED2 /* Section.swift */; };\n\t\tB6D1AEF727A54F750022FED2 /* SectionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEF627A54F750022FED2 /* SectionButton.swift */; };\n\t\tB6D1AEFA27A557280022FED2 /* PopupButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEF927A557280022FED2 /* PopupButton.swift */; };\n\t\tB6D1AEFD27A55ED50022FED2 /* CodeTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1AEFC27A55ED50022FED2 /* CodeTextView.swift */; };\n\t\tB6D1AF0627A5603B0022FED2 /* Highlightr in Frameworks */ = {isa = PBXBuildFile; productRef = B6D1AF0527A5603B0022FED2 /* Highlightr */; };\n\t\tB6D88A8B27D07204002E71EA /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D88A8A27D07204002E71EA /* CameraViewController.swift */; };\n\t\tB6E15A9427B6745100DC4D6B /* libimageoptimjpeg.dylib in Resources */ = {isa = PBXBuildFile; fileRef = B6E15A9227B6742300DC4D6B /* libimageoptimjpeg.dylib */; };\n\t\tB6E294B327C3351F00314132 /* FFTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E294B227C3351F00314132 /* FFTask.swift */; };\n\t\tB6E294E527C337F300314132 /* FFThumnailGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E294E427C337F300314132 /* FFThumnailGenerator.swift */; };\n\t\tB6ED863627BFE7DC00A17474 /* DefaultImageExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ED863527BFE7DC00A17474 /* DefaultImageExporter.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tB64B1F5D27A4FC1900AC2601 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = B64B1F5927A4FC1800AC2601 /* CoreUtil.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = B64B1E8F27A4F67000AC2601;\n\t\t\tremoteInfo = CoreUtil;\n\t\t};\n\t\tB64B1F5F27A4FC1F00AC2601 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = B64B1F5927A4FC1800AC2601 /* CoreUtil.xcodeproj */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = B64B1E8E27A4F67000AC2601;\n\t\t\tremoteInfo = CoreUtil;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\tB608541727A66CC9003BF243 /* Embed Frameworks */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t\tB608541627A66CC9003BF243 /* CoreUtil.framework in Embed Frameworks */,\n\t\t\t);\n\t\t\tname = \"Embed Frameworks\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t6B42318727AD1BC0002D135A /* HyphenationRemoverView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"HyphenationRemoverView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB608540A27A66694003BF243 /* SectionButton+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"SectionButton+.swift\"; sourceTree = \"<group>\"; };\n\t\tB608541127A66A90003BF243 /* JSONYamlConverterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"JSONYamlConverterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB608541D27A67B48003BF243 /* NumberBaseConverterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"NumberBaseConverterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB608541F27A67E4D003BF243 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = \"<group>\"; };\n\t\tB6113ECC27C4B96C00ACC6E8 /* EmptyImageTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyImageTableView.swift; sourceTree = \"<group>\"; };\n\t\tB6113ECE27C4BF2300ACC6E8 /* FileConflictAvoider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileConflictAvoider.swift; sourceTree = \"<group>\"; };\n\t\tB6113F0027C4BF7700ACC6E8 /* Identifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Identifier.swift; sourceTree = \"<group>\"; };\n\t\tB61157BF27C8C3F9004D77A5 /* JSONSearchView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"JSONSearchView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB61157C227C8C78A004D77A5 /* JSONNormalSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONNormalSearchView.swift; sourceTree = \"<group>\"; };\n\t\tB61157C427C8D77A004D77A5 /* DragImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DragImageView.swift; sourceTree = \"<group>\"; };\n\t\tB61796C427BCB3090054660E /* ToolCategoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolCategoryCell.swift; sourceTree = \"<group>\"; };\n\t\tB61796C627BCB6F00054660E /* SettingView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"SettingView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB61796C827BCB84A0054660E /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = \"<group>\"; };\n\t\tB62013B327A9070D00AF5386 /* UUIDGeneratorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UUIDGeneratorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB62013B527A90B8900AF5386 /* NumberField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberField.swift; sourceTree = \"<group>\"; };\n\t\tB620141B27A917E000AF5386 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = \"<group>\"; };\n\t\tB620141D27A91F6700AF5386 /* LoremIpsumGeneratorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"LoremIpsumGeneratorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB620142027A9271500AF5386 /* TextInspectorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"TextInspectorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB620142227A929B400AF5386 /* TagCloudView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagCloudView.swift; sourceTree = \"<group>\"; };\n\t\tB627294E27BFB7680034D70C /* WebpImageExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebpImageExporter.swift; sourceTree = \"<group>\"; };\n\t\tB627295127BFB8CB0034D70C /* cwebp */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.executable\"; path = cwebp; sourceTree = \"<group>\"; };\n\t\tB627295627BFCCC40034D70C /* HeicImageExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeicImageExporter.swift; sourceTree = \"<group>\"; };\n\t\tB63A034A27C2130A009FD2AD /* GifConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifConverter.swift; sourceTree = \"<group>\"; };\n\t\tB63A034C27C21A99009FD2AD /* ffmpeg */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.executable\"; path = ffmpeg; sourceTree = \"<group>\"; };\n\t\tB63A034F27C24BA0009FD2AD /* FFProgressReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FFProgressReport.swift; sourceTree = \"<group>\"; };\n\t\tB63A035127C25B29009FD2AD /* FFTime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FFTime.swift; sourceTree = \"<group>\"; };\n\t\tB64844FE27B767EC004FE02B /* ToolManager+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"ToolManager+.swift\"; sourceTree = \"<group>\"; };\n\t\tB64AA44F27AD0D3900EC436D /* DateConverterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"DateConverterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B1E7027A4F5E200AC2601 /* DevToys.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DevToys.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tB64B1E7327A4F5E200AC2601 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\tB64B1E7527A4F5E200AC2601 /* AppViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppViewController.swift; sourceTree = \"<group>\"; };\n\t\tB64B1E7727A4F5E300AC2601 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tB64B1E7A27A4F5E300AC2601 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\tB64B1E7C27A4F5E300AC2601 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tB64B1E7D27A4F5E300AC2601 /* DevToys.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DevToys.entitlements; sourceTree = \"<group>\"; };\n\t\tB64B1F5927A4FC1800AC2601 /* CoreUtil.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = CoreUtil.xcodeproj; path = ../CoreUtil/CoreUtil.xcodeproj; sourceTree = \"<group>\"; };\n\t\tB64B1F7127A4FDC800AC2601 /* AppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppModel.swift; sourceTree = \"<group>\"; };\n\t\tB64B1F7627A4FF8B00AC2601 /* SidebarView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"SidebarView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB64B201527A5100800AC2601 /* Separator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Separator.swift; sourceTree = \"<group>\"; };\n\t\tB64B201C27A5219400AC2601 /* SearchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchCell.swift; sourceTree = \"<group>\"; };\n\t\tB64B201F27A523A200AC2601 /* ToolMenuCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolMenuCell.swift; sourceTree = \"<group>\"; };\n\t\tB64B202227A52A2D00AC2601 /* R.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = R.swift; sourceTree = \"<group>\"; };\n\t\tB64B209727A532DF00AC2601 /* AppWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppWindowController.swift; sourceTree = \"<group>\"; };\n\t\tB65DB77F27AC0EB400146A3C /* RegexTesterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"RegexTesterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB66536CD27C9BA4000CA1CEC /* Slugify.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Slugify.swift; sourceTree = \"<group>\"; };\n\t\tB66536CF27C9C56600CA1CEC /* SQLFormatterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"SQLFormatterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB66850ED27A64D3200A3FE01 /* Page.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Page.swift; sourceTree = \"<group>\"; };\n\t\tB66BE8BB27C49AD4003B5ED0 /* AudioFileScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioFileScanner.swift; sourceTree = \"<group>\"; };\n\t\tB672CF9F27AAB8DD00391A5D /* FileDrop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileDrop.swift; sourceTree = \"<group>\"; };\n\t\tB673A90127AD0E78005512AB /* DatePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePicker.swift; sourceTree = \"<group>\"; };\n\t\tB6789EB927CA43E100D8B58C /* IconGeneratorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"IconGeneratorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6789EBB27CA48A300D8B58C /* IosIconGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosIconGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB6789EDE27CA5F5D00D8B58C /* IconsetGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconsetGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB6789EE027CA5F6900D8B58C /* IcnsGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IcnsGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB6789EE227CA5F7A00D8B58C /* IconFolderGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconFolderGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB6789EE427CA5F9500D8B58C /* IconGenerator+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"IconGenerator+Model.swift\"; sourceTree = \"<group>\"; };\n\t\tB6789EE627CB334D00D8B58C /* AndroidIconGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AndroidIconGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C0227C0B9FF009277FB /* ColorPickerHandleLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPickerHandleLayer.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C0327C0B9FF009277FB /* OpacityBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpacityBarView.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C0427C0B9FF009277FB /* HueBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HueBarView.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C0527C0B9FF009277FB /* ColorPickerView+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"ColorPickerView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB67A4C0627C0B9FF009277FB /* ColorBoxView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorBoxView.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C0727C0B9FF009277FB /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C3F27C0EA84009277FB /* ACPixelPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ACPixelPicker.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C4027C0EA84009277FB /* ACOverlayPreview.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ACOverlayPreview.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C4227C0EA84009277FB /* Ex+NSBezierPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+NSBezierPath.swift\"; sourceTree = \"<group>\"; };\n\t\tB67A4C4327C0EA84009277FB /* ShowAndHideCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShowAndHideCursor.h; sourceTree = \"<group>\"; };\n\t\tB67A4C4427C0EA84009277FB /* Util+PixelPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Util+PixelPicker.swift\"; sourceTree = \"<group>\"; };\n\t\tB67A4C4527C0EA84009277FB /* ShowAndHideCursor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowAndHideCursor.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C4627C0EA84009277FB /* ShowAndHideCursor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShowAndHideCursor.m; sourceTree = \"<group>\"; };\n\t\tB67A4C4727C0EA84009277FB /* Ex+NSColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+NSColor.swift\"; sourceTree = \"<group>\"; };\n\t\tB67A4C4827C0EA84009277FB /* Ex+CGImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"Ex+CGImage.swift\"; sourceTree = \"<group>\"; };\n\t\tB67A4C4927C0EA84009277FB /* ACOverlayPanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ACOverlayPanel.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C4A27C0EA84009277FB /* ACOverlayController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ACOverlayController.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C4B27C0EA84009277FB /* ACOverlayController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ACOverlayController.xib; sourceTree = \"<group>\"; };\n\t\tB67A4C4C27C0EA84009277FB /* ACOverlayWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ACOverlayWrapper.swift; sourceTree = \"<group>\"; };\n\t\tB67A4C5C27C0EB51009277FB /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\tB67A4CBD27C0EEEF009277FB /* ColorSampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorSampleView.swift; sourceTree = \"<group>\"; };\n\t\tB67A4CBF27C0F4BA009277FB /* BoxHSBColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxHSBColorPicker.swift; sourceTree = \"<group>\"; };\n\t\tB67A4CC227C0F4D4009277FB /* CircleHueBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleHueBarView.swift; sourceTree = \"<group>\"; };\n\t\tB67A4CC427C0F50D009277FB /* R+ColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"R+ColorPicker.swift\"; sourceTree = \"<group>\"; };\n\t\tB67A4CC627C0F546009277FB /* CircleBoxHSBColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleBoxHSBColorPicker.swift; sourceTree = \"<group>\"; };\n\t\tB67A4CC827C10493009277FB /* SaturationBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaturationBarView.swift; sourceTree = \"<group>\"; };\n\t\tB67A4CCA27C10548009277FB /* BrightnessBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrightnessBarView.swift; sourceTree = \"<group>\"; };\n\t\tB67A4CCC27C12C09009277FB /* CircleBarsHSBColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleBarsHSBColorPicker.swift; sourceTree = \"<group>\"; };\n\t\tB67A4CCE27C1E010009277FB /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = \"zh-Hans\"; path = \"zh-Hans.lproj/Main.strings\"; sourceTree = \"<group>\"; };\n\t\tB67A4CCF27C1E01C009277FB /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = \"zh-Hans\"; path = \"zh-Hans.lproj/Localizable.strings\"; sourceTree = \"<group>\"; };\n\t\tB67A4CD027C1E036009277FB /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = \"pt-BR\"; path = \"pt-BR.lproj/Main.strings\"; sourceTree = \"<group>\"; };\n\t\tB67A4CD127C1E03C009277FB /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = \"pt-BR\"; path = \"pt-BR.lproj/Localizable.strings\"; sourceTree = \"<group>\"; };\n\t\tB67A4CD427C1E0DC009277FB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = \"<group>\"; };\n\t\tB67A4CD527C1E0DF009277FB /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = \"<group>\"; };\n\t\tB67A4CD727C1E0F1009277FB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = \"<group>\"; };\n\t\tB67A4CD827C1E0F8009277FB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\tB67A4CD927C1E469009277FB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = \"<group>\"; };\n\t\tB67A4CDA27C1E46A009277FB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\tB680A79427A68B35007CB707 /* HTMLDecoderView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"HTMLDecoderView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB680A79927A69324007CB707 /* URLDecoderView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"URLDecoderView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB680A79B27A6947D007CB707 /* Base64DecoderView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Base64DecoderView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB680A83227A8BF7D007CB707 /* TextViewSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewSection.swift; sourceTree = \"<group>\"; };\n\t\tB680A86727A8D4D1007CB707 /* TextFieldSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldSection.swift; sourceTree = \"<group>\"; };\n\t\tB680A89927A8D9DD007CB707 /* Toast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Toast.swift; sourceTree = \"<group>\"; };\n\t\tB680A8A627A8DD5D007CB707 /* JWTDecoderView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"JWTDecoderView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB680A8A927A8E106007CB707 /* HashGeneratorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"HashGeneratorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB684EA2727C5EFE90014802F /* TextDiffView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"TextDiffView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB684EA2927C609620014802F /* QRCodeGeneratorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"QRCodeGeneratorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB69980D327CCCF0A0063F63D /* android_mask.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = android_mask.png; sourceTree = \"<group>\"; };\n\t\tB69980D627CCE09A0063F63D /* IcoGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IcoGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB69980D827CCEB320063F63D /* PngIconGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PngIconGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB69F0E7C27CBC20F0032F96A /* folder_back_64_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_back_64_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E7D27CBC20F0032F96A /* folder_back_128_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_back_128_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E7E27CBC20F0032F96A /* folder_back_256_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_back_256_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E7F27CBC20F0032F96A /* folder_back_1024_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_back_1024_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8027CBC20F0032F96A /* folder_back_32_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_back_32_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8127CBC20F0032F96A /* folder_back_16_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_back_16_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8227CBC20F0032F96A /* folder_back_512_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_back_512_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8B27CBC2340032F96A /* folder_mask2_1024_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_mask2_1024_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8C27CBC2340032F96A /* folder_mask2_512_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_mask2_512_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8D27CBC2340032F96A /* folder_mask2_16_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_mask2_16_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8E27CBC2340032F96A /* folder_mask2_32_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_mask2_32_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E8F27CBC2340032F96A /* folder_mask2_64_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_mask2_64_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E9027CBC2340032F96A /* folder_mask2_128_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_mask2_128_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E9727CBC2800032F96A /* folder_mask2_256_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_mask2_256_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0E9A27CBC7550032F96A /* folder_top_1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_top_1024.png; sourceTree = \"<group>\"; };\n\t\tB69F0E9B27CBC7550032F96A /* folder_top_512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_top_512.png; sourceTree = \"<group>\"; };\n\t\tB69F0E9E27CC76A50032F96A /* IconImageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconImageManager.swift; sourceTree = \"<group>\"; };\n\t\tB69F0EA427CC7CF40032F96A /* watermark_mask_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = watermark_mask_bs.png; sourceTree = \"<group>\"; };\n\t\tB69F0EA527CC7CF40032F96A /* watermark_mask_dark_bs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = watermark_mask_dark_bs.png; sourceTree = \"<group>\"; };\n\t\tB6A4F2A127CD05F000BBDE7E /* QRCodeReaderView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"QRCodeReaderView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6A4F2A327CD078100BBDE7E /* ImageDropView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDropView.swift; sourceTree = \"<group>\"; };\n\t\tB6A93D2F27CBBC97003A6D7F /* IconTemplete+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"IconTemplete+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6A93D3027CBBC97003A6D7F /* IconSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IconSet.swift; sourceTree = \"<group>\"; };\n\t\tB6A93D3127CBBC97003A6D7F /* IconTemplete.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IconTemplete.swift; sourceTree = \"<group>\"; };\n\t\tB6AC272F27AA1373000FD713 /* optipng */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.executable\"; path = optipng; sourceTree = \"<group>\"; };\n\t\tB6AC273127AA2BF6000FD713 /* ImageOptimizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageOptimizer.swift; sourceTree = \"<group>\"; };\n\t\tB6AC276427AA3D61000FD713 /* jpegoptim */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.executable\"; path = jpegoptim; sourceTree = \"<group>\"; };\n\t\tB6AC276927AA535A000FD713 /* PDFGeneratorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"PDFGeneratorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6B5726127AC14B60069DBA7 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = \"<group>\"; };\n\t\tB6B5726327AC14D10069DBA7 /* RegexTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegexTextView.swift; sourceTree = \"<group>\"; };\n\t\tB6B5727F27ACC3AE0069DBA7 /* ChecksumGeneratorView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"ChecksumGeneratorView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6B5728127ACCF2F0069DBA7 /* XMLFormatterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"XMLFormatterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6B5728927ACDA420069DBA7 /* ImageConverterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"ImageConverterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6B5728B27ACE5600069DBA7 /* ImageConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageConverter.swift; sourceTree = \"<group>\"; };\n\t\tB6B5728E27ACFA6D0069DBA7 /* ImageDropper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDropper.swift; sourceTree = \"<group>\"; };\n\t\tB6BBA90627C392E3000FE7D3 /* AudioConverterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"AudioConverterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6BBA90827C39528000FE7D3 /* AudioConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioConverter.swift; sourceTree = \"<group>\"; };\n\t\tB6BD80EA27B89EA600152AB9 /* ImageOptimaizerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageOptimaizerView.swift; sourceTree = \"<group>\"; };\n\t\tB6BD80EE27B8A85400152AB9 /* ToolCategory+Default.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"ToolCategory+Default.swift\"; sourceTree = \"<group>\"; };\n\t\tB6BD80F027B8A86100152AB9 /* Tool+Default.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Tool+Default.swift\"; sourceTree = \"<group>\"; };\n\t\tB6BD80F527B8AEE700152AB9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\tB6BD80F827B8AF1800152AB9 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\tB6C5292327C20D520019BCB0 /* GifConverterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"GifConverterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6C5292627C20DC60019BCB0 /* FFMpegExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FFMpegExecutor.swift; sourceTree = \"<group>\"; };\n\t\tB6CBFEE827CCA1B000902E56 /* squircle_bg_mask_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_bg_mask_256x256.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEE927CCA1B000902E56 /* squircle_bg_mask_1024x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_bg_mask_1024x1024.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEEA27CCA1B000902E56 /* squircle_back_128x128.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_back_128x128.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEEB27CCA1B000902E56 /* squircle_back_1024x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_back_1024x1024.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEEC27CCA1B000902E56 /* squircle_back_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_back_16x16.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEED27CCA1B000902E56 /* squircle_mask_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_mask_256x256.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEEE27CCA1B000902E56 /* squircle_mask_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_mask_16x16.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEEF27CCA1B000902E56 /* squircle_back_512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_back_512x512.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF027CCA1B000902E56 /* squircle_mask_64x64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_mask_64x64.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF127CCA1B000902E56 /* squircle_mask_128x128.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_mask_128x128.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF227CCA1B000902E56 /* squircle_mask_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_mask_32x32.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF327CCA1B000902E56 /* squircle_bg_mask_512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_bg_mask_512x512.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF427CCA1B000902E56 /* squircle_mask_1024x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_mask_1024x1024.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF527CCA1B000902E56 /* squircle_back_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_back_32x32.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF627CCA1B000902E56 /* squircle_back_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_back_256x256.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF727CCA1B000902E56 /* squircle_back_64x64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_back_64x64.png; sourceTree = \"<group>\"; };\n\t\tB6CBFEF827CCA1B000902E56 /* squircle_mask_512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = squircle_mask_512x512.png; sourceTree = \"<group>\"; };\n\t\tB6CBFF0D27CCA88E00902E56 /* external_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = external_256x256.png; sourceTree = \"<group>\"; };\n\t\tB6CBFF0E27CCA88E00902E56 /* external_128x128.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = external_128x128.png; sourceTree = \"<group>\"; };\n\t\tB6CBFF0F27CCA88E00902E56 /* external_64x64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = external_64x64.png; sourceTree = \"<group>\"; };\n\t\tB6CBFF1027CCA88E00902E56 /* external_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = external_16x16.png; sourceTree = \"<group>\"; };\n\t\tB6CBFF1127CCA88E00902E56 /* external_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = external_32x32.png; sourceTree = \"<group>\"; };\n\t\tB6CBFF1327CCA88E00902E56 /* external_512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = external_512x512.png; sourceTree = \"<group>\"; };\n\t\tB6CBFF1527CCA88F00902E56 /* external_1024x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = external_1024x1024.png; sourceTree = \"<group>\"; };\n\t\tB6D1AEDE27A534960022FED2 /* BodyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BodyViewController.swift; sourceTree = \"<group>\"; };\n\t\tB6D1AEE327A53A560022FED2 /* HomeView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"HomeView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6D1AEE827A545230022FED2 /* Area.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Area.swift; sourceTree = \"<group>\"; };\n\t\tB6D1AEEB27A546810022FED2 /* ControlBackgroundLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlBackgroundLayer.swift; sourceTree = \"<group>\"; };\n\t\tB6D1AEEF27A547B90022FED2 /* JSONFormatterView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"JSONFormatterView+.swift\"; sourceTree = \"<group>\"; };\n\t\tB6D1AEF327A54C440022FED2 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = \"<group>\"; };\n\t\tB6D1AEF627A54F750022FED2 /* SectionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionButton.swift; sourceTree = \"<group>\"; };\n\t\tB6D1AEF927A557280022FED2 /* PopupButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupButton.swift; sourceTree = \"<group>\"; };\n\t\tB6D1AEFC27A55ED50022FED2 /* CodeTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeTextView.swift; sourceTree = \"<group>\"; };\n\t\tB6D88A8A27D07204002E71EA /* CameraViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraViewController.swift; sourceTree = \"<group>\"; };\n\t\tB6E15A9227B6742300DC4D6B /* libimageoptimjpeg.dylib */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.dylib\"; path = libimageoptimjpeg.dylib; sourceTree = \"<group>\"; };\n\t\tB6E294B227C3351F00314132 /* FFTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FFTask.swift; sourceTree = \"<group>\"; };\n\t\tB6E294E427C337F300314132 /* FFThumnailGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FFThumnailGenerator.swift; sourceTree = \"<group>\"; };\n\t\tB6ED863527BFE7DC00A17474 /* DefaultImageExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultImageExporter.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tB64B1E6D27A4F5E200AC2601 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB684EA2627C5EFDB0014802F /* DiffMatchPatch in Frameworks */,\n\t\t\t\tB6D1AF0627A5603B0022FED2 /* Highlightr in Frameworks */,\n\t\t\t\tB6113F0927C4C6C900ACC6E8 /* Sparkle in Frameworks */,\n\t\t\t\tB608541527A66CC9003BF243 /* CoreUtil.framework in Frameworks */,\n\t\t\t\tB680A79827A69268007CB707 /* HTMLEntities in Frameworks */,\n\t\t\t\tB608541B27A672E3003BF243 /* Yams in Frameworks */,\n\t\t\t\tB6B5728827ACD2F20069DBA7 /* Kanna in Frameworks */,\n\t\t\t\tB66850F227A65FC200A3FE01 /* SwiftJSONFormatter in Frameworks */,\n\t\t\t\tB680A8AD27A8E31C007CB707 /* CryptoSwift in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tB608541427A66CC9003BF243 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB608542127A67FF7003BF243 /* Convert */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB608541127A66A90003BF243 /* JSONYamlConverterView+.swift */,\n\t\t\t\tB608541D27A67B48003BF243 /* NumberBaseConverterView+.swift */,\n\t\t\t\tB64AA44F27AD0D3900EC436D /* DateConverterView+.swift */,\n\t\t\t);\n\t\t\tpath = Convert;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB608542227A68008003BF243 /* Format */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6D1AEEF27A547B90022FED2 /* JSONFormatterView+.swift */,\n\t\t\t\tB6B5728127ACCF2F0069DBA7 /* XMLFormatterView+.swift */,\n\t\t\t\tB66536CF27C9C56600CA1CEC /* SQLFormatterView+.swift */,\n\t\t\t);\n\t\t\tpath = Format;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB61157C127C8C76A004D77A5 /* JSON Search */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB61157BF27C8C3F9004D77A5 /* JSONSearchView+.swift */,\n\t\t\t\tB61157C227C8C78A004D77A5 /* JSONNormalSearchView.swift */,\n\t\t\t);\n\t\t\tpath = \"JSON Search\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB620141F27A926B400AF5386 /* Text */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB61157C127C8C76A004D77A5 /* JSON Search */,\n\t\t\t\tB620142027A9271500AF5386 /* TextInspectorView+.swift */,\n\t\t\t\tB65DB77F27AC0EB400146A3C /* RegexTesterView+.swift */,\n\t\t\t\t6B42318727AD1BC0002D135A /* HyphenationRemoverView+.swift */,\n\t\t\t\tB684EA2727C5EFE90014802F /* TextDiffView+.swift */,\n\t\t\t);\n\t\t\tpath = Text;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB620145427A9440E00AF5386 /* Graphic */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6AC276927AA535A000FD713 /* PDFGeneratorView+.swift */,\n\t\t\t\tB6A4F2A127CD05F000BBDE7E /* QRCodeReaderView+.swift */,\n\t\t\t\tB6789EB827CA438800D8B58C /* Icon Generator */,\n\t\t\t\tB6AC276827AA532B000FD713 /* Image Optimizer */,\n\t\t\t\tB6B5729027ACFE020069DBA7 /* Image Converter */,\n\t\t\t);\n\t\t\tpath = Graphic;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB63A034927C212FE009FD2AD /* Movie to Gif */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6C5292327C20D520019BCB0 /* GifConverterView+.swift */,\n\t\t\t\tB63A034A27C2130A009FD2AD /* GifConverter.swift */,\n\t\t\t);\n\t\t\tpath = \"Movie to Gif\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1E6727A4F5E200AC2601 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1F5927A4FC1800AC2601 /* CoreUtil.xcodeproj */,\n\t\t\t\tB64B1E7227A4F5E200AC2601 /* DevToys */,\n\t\t\t\tB64B1E7127A4F5E200AC2601 /* Products */,\n\t\t\t\tB608541427A66CC9003BF243 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1E7127A4F5E200AC2601 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1E7027A4F5E200AC2601 /* DevToys.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1E7227A4F5E200AC2601 /* DevToys */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1E7D27A4F5E300AC2601 /* DevToys.entitlements */,\n\t\t\t\tB64B1E7C27A4F5E300AC2601 /* Info.plist */,\n\t\t\t\tB64B1E7327A4F5E200AC2601 /* AppDelegate.swift */,\n\t\t\t\tB67A4C5C27C0EB51009277FB /* Bridging-Header.h */,\n\t\t\t\tB64B1E9D27A4F6A700AC2601 /* Resource */,\n\t\t\t\tB64B1F7027A4FDBC00AC2601 /* Model */,\n\t\t\t\tB64B209A27A532E300AC2601 /* App */,\n\t\t\t\tB64B1F7527A4FF8700AC2601 /* Sidebar */,\n\t\t\t\tB6D1AEE727A544F20022FED2 /* Component */,\n\t\t\t\tB6D1AEDD27A534850022FED2 /* Body */,\n\t\t\t);\n\t\t\tpath = DevToys;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1E9D27A4F6A700AC2601 /* Resource */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1E7927A4F5E300AC2601 /* Main.storyboard */,\n\t\t\t\tB64B1E7727A4F5E300AC2601 /* Assets.xcassets */,\n\t\t\t\tB64B202227A52A2D00AC2601 /* R.swift */,\n\t\t\t\tB6BD80F627B8AEE700152AB9 /* Localizable.strings */,\n\t\t\t);\n\t\t\tpath = Resource;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1F5A27A4FC1800AC2601 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1F5E27A4FC1900AC2601 /* CoreUtil.framework */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1F7027A4FDBC00AC2601 /* Model */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1F7127A4FDC800AC2601 /* AppModel.swift */,\n\t\t\t\tB61796C827BCB84A0054660E /* Settings.swift */,\n\t\t\t\tB64844FE27B767EC004FE02B /* ToolManager+.swift */,\n\t\t\t\tB6BD80EE27B8A85400152AB9 /* ToolCategory+Default.swift */,\n\t\t\t\tB6BD80F027B8A86100152AB9 /* Tool+Default.swift */,\n\t\t\t);\n\t\t\tpath = Model;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B1F7527A4FF8700AC2601 /* Sidebar */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B201427A50FFF00AC2601 /* View */,\n\t\t\t\tB64B1F7627A4FF8B00AC2601 /* SidebarView+.swift */,\n\t\t\t\tB64B201F27A523A200AC2601 /* ToolMenuCell.swift */,\n\t\t\t\tB61796C427BCB3090054660E /* ToolCategoryCell.swift */,\n\t\t\t\tB64B201C27A5219400AC2601 /* SearchCell.swift */,\n\t\t\t);\n\t\t\tpath = Sidebar;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B201427A50FFF00AC2601 /* View */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B201527A5100800AC2601 /* Separator.swift */,\n\t\t\t);\n\t\t\tpath = View;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB64B209A27A532E300AC2601 /* App */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B209727A532DF00AC2601 /* AppWindowController.swift */,\n\t\t\t\tB64B1E7527A4F5E200AC2601 /* AppViewController.swift */,\n\t\t\t);\n\t\t\tpath = App;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB66BE8BD27C49B28003B5ED0 /* Utils */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6D88A8A27D07204002E71EA /* CameraViewController.swift */,\n\t\t\t\tB6113F0027C4BF7700ACC6E8 /* Identifier.swift */,\n\t\t\t\tB6113ECE27C4BF2300ACC6E8 /* FileConflictAvoider.swift */,\n\t\t\t\tB6B5728E27ACFA6D0069DBA7 /* ImageDropper.swift */,\n\t\t\t\tB6C5292527C20DAF0019BCB0 /* ffmpeg */,\n\t\t\t\tB66536CD27C9BA4000CA1CEC /* Slugify.swift */,\n\t\t\t);\n\t\t\tpath = Utils;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6789EB827CA438800D8B58C /* Icon Generator */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6789EB927CA43E100D8B58C /* IconGeneratorView+.swift */,\n\t\t\t\tB6789EE827CB3D6300D8B58C /* Resource */,\n\t\t\t\tB6A93D2E27CBBC97003A6D7F /* Icon Templete */,\n\t\t\t\tB6789EDD27CA5F5400D8B58C /* Generators */,\n\t\t\t);\n\t\t\tpath = \"Icon Generator\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6789EDD27CA5F5400D8B58C /* Generators */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6789EBB27CA48A300D8B58C /* IosIconGenerator.swift */,\n\t\t\t\tB6789EDE27CA5F5D00D8B58C /* IconsetGenerator.swift */,\n\t\t\t\tB6789EE027CA5F6900D8B58C /* IcnsGenerator.swift */,\n\t\t\t\tB6789EE227CA5F7A00D8B58C /* IconFolderGenerator.swift */,\n\t\t\t\tB6789EE427CA5F9500D8B58C /* IconGenerator+Model.swift */,\n\t\t\t\tB6789EE627CB334D00D8B58C /* AndroidIconGenerator.swift */,\n\t\t\t\tB69980D627CCE09A0063F63D /* IcoGenerator.swift */,\n\t\t\t\tB69980D827CCEB320063F63D /* PngIconGenerator.swift */,\n\t\t\t);\n\t\t\tpath = Generators;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6789EE827CB3D6300D8B58C /* Resource */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6A93CC527CB9C0D003A6D7F /* Folder */,\n\t\t\t);\n\t\t\tpath = Resource;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB67A4C0127C0B9FF009277FB /* Color Picker */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB67A4C0727C0B9FF009277FB /* Color.swift */,\n\t\t\t\tB67A4CC427C0F50D009277FB /* R+ColorPicker.swift */,\n\t\t\t\tB67A4C0527C0B9FF009277FB /* ColorPickerView+.swift */,\n\t\t\t\tB67A4C3E27C0EA84009277FB /* Pixel Picker */,\n\t\t\t\tB67A4CC127C0F4BE009277FB /* Components */,\n\t\t\t);\n\t\t\tpath = \"Color Picker\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB67A4C3E27C0EA84009277FB /* Pixel Picker */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB67A4C3F27C0EA84009277FB /* ACPixelPicker.swift */,\n\t\t\t\tB67A4C4027C0EA84009277FB /* ACOverlayPreview.swift */,\n\t\t\t\tB67A4C4127C0EA84009277FB /* Utils */,\n\t\t\t\tB67A4C4927C0EA84009277FB /* ACOverlayPanel.swift */,\n\t\t\t\tB67A4C4A27C0EA84009277FB /* ACOverlayController.swift */,\n\t\t\t\tB67A4C4B27C0EA84009277FB /* ACOverlayController.xib */,\n\t\t\t\tB67A4C4C27C0EA84009277FB /* ACOverlayWrapper.swift */,\n\t\t\t);\n\t\t\tpath = \"Pixel Picker\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB67A4C4127C0EA84009277FB /* Utils */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB67A4C4227C0EA84009277FB /* Ex+NSBezierPath.swift */,\n\t\t\t\tB67A4C4427C0EA84009277FB /* Util+PixelPicker.swift */,\n\t\t\t\tB67A4C4527C0EA84009277FB /* ShowAndHideCursor.swift */,\n\t\t\t\tB67A4C4327C0EA84009277FB /* ShowAndHideCursor.h */,\n\t\t\t\tB67A4C4627C0EA84009277FB /* ShowAndHideCursor.m */,\n\t\t\t\tB67A4C4727C0EA84009277FB /* Ex+NSColor.swift */,\n\t\t\t\tB67A4C4827C0EA84009277FB /* Ex+CGImage.swift */,\n\t\t\t);\n\t\t\tpath = Utils;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB67A4CC127C0F4BE009277FB /* Components */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB67A4CBF27C0F4BA009277FB /* BoxHSBColorPicker.swift */,\n\t\t\t\tB67A4CC627C0F546009277FB /* CircleBoxHSBColorPicker.swift */,\n\t\t\t\tB67A4C0627C0B9FF009277FB /* ColorBoxView.swift */,\n\t\t\t\tB67A4C0227C0B9FF009277FB /* ColorPickerHandleLayer.swift */,\n\t\t\t\tB67A4CBD27C0EEEF009277FB /* ColorSampleView.swift */,\n\t\t\t\tB67A4C0327C0B9FF009277FB /* OpacityBarView.swift */,\n\t\t\t\tB67A4C0427C0B9FF009277FB /* HueBarView.swift */,\n\t\t\t\tB67A4CC227C0F4D4009277FB /* CircleHueBarView.swift */,\n\t\t\t\tB67A4CC827C10493009277FB /* SaturationBarView.swift */,\n\t\t\t\tB67A4CCA27C10548009277FB /* BrightnessBarView.swift */,\n\t\t\t\tB67A4CCC27C12C09009277FB /* CircleBarsHSBColorPicker.swift */,\n\t\t\t);\n\t\t\tpath = Components;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB680A79327A68B2D007CB707 /* Coder */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB680A79427A68B35007CB707 /* HTMLDecoderView+.swift */,\n\t\t\t\tB680A79927A69324007CB707 /* URLDecoderView+.swift */,\n\t\t\t\tB680A79B27A6947D007CB707 /* Base64DecoderView+.swift */,\n\t\t\t\tB680A8A627A8DD5D007CB707 /* JWTDecoderView+.swift */,\n\t\t\t);\n\t\t\tpath = Coder;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB680A8A827A8E0F8007CB707 /* Generator */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB680A8A927A8E106007CB707 /* HashGeneratorView+.swift */,\n\t\t\t\tB62013B327A9070D00AF5386 /* UUIDGeneratorView+.swift */,\n\t\t\t\tB620141D27A91F6700AF5386 /* LoremIpsumGeneratorView+.swift */,\n\t\t\t\tB6B5727F27ACC3AE0069DBA7 /* ChecksumGeneratorView+.swift */,\n\t\t\t\tB684EA2927C609620014802F /* QRCodeGeneratorView+.swift */,\n\t\t\t);\n\t\t\tpath = Generator;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB69F0E7B27CBC20F0032F96A /* folder_back */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB69F0E8127CBC20F0032F96A /* folder_back_16_bs.png */,\n\t\t\t\tB69F0E8027CBC20F0032F96A /* folder_back_32_bs.png */,\n\t\t\t\tB69F0E7C27CBC20F0032F96A /* folder_back_64_bs.png */,\n\t\t\t\tB69F0E7D27CBC20F0032F96A /* folder_back_128_bs.png */,\n\t\t\t\tB69F0E7E27CBC20F0032F96A /* folder_back_256_bs.png */,\n\t\t\t\tB69F0E8227CBC20F0032F96A /* folder_back_512_bs.png */,\n\t\t\t\tB69F0E7F27CBC20F0032F96A /* folder_back_1024_bs.png */,\n\t\t\t);\n\t\t\tpath = folder_back;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB69F0E8A27CBC2340032F96A /* folder_mask */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB69F0E8D27CBC2340032F96A /* folder_mask2_16_bs.png */,\n\t\t\t\tB69F0E8E27CBC2340032F96A /* folder_mask2_32_bs.png */,\n\t\t\t\tB69F0E8F27CBC2340032F96A /* folder_mask2_64_bs.png */,\n\t\t\t\tB69F0E9027CBC2340032F96A /* folder_mask2_128_bs.png */,\n\t\t\t\tB69F0E9727CBC2800032F96A /* folder_mask2_256_bs.png */,\n\t\t\t\tB69F0E8C27CBC2340032F96A /* folder_mask2_512_bs.png */,\n\t\t\t\tB69F0E8B27CBC2340032F96A /* folder_mask2_1024_bs.png */,\n\t\t\t);\n\t\t\tpath = folder_mask;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB69F0E9927CBC7550032F96A /* folder_top */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB69F0E9A27CBC7550032F96A /* folder_top_1024.png */,\n\t\t\t\tB69F0E9B27CBC7550032F96A /* folder_top_512.png */,\n\t\t\t);\n\t\t\tpath = folder_top;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6A93CC527CB9C0D003A6D7F /* Folder */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB69980D327CCCF0A0063F63D /* android_mask.png */,\n\t\t\t\tB6CBFF0B27CCA88100902E56 /* external_drive */,\n\t\t\t\tB69F0EA427CC7CF40032F96A /* watermark_mask_bs.png */,\n\t\t\t\tB69F0EA527CC7CF40032F96A /* watermark_mask_dark_bs.png */,\n\t\t\t\tB6CBFEE727CCA1B000902E56 /* big_sur_icon */,\n\t\t\t\tB69F0E9927CBC7550032F96A /* folder_top */,\n\t\t\t\tB69F0E8A27CBC2340032F96A /* folder_mask */,\n\t\t\t\tB69F0E7B27CBC20F0032F96A /* folder_back */,\n\t\t\t);\n\t\t\tpath = Folder;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6A93D2E27CBBC97003A6D7F /* Icon Templete */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6A93D2F27CBBC97003A6D7F /* IconTemplete+.swift */,\n\t\t\t\tB6A93D3027CBBC97003A6D7F /* IconSet.swift */,\n\t\t\t\tB6A93D3127CBBC97003A6D7F /* IconTemplete.swift */,\n\t\t\t\tB69F0E9E27CC76A50032F96A /* IconImageManager.swift */,\n\t\t\t);\n\t\t\tpath = \"Icon Templete\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6AC276827AA532B000FD713 /* Image Optimizer */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6E15A9227B6742300DC4D6B /* libimageoptimjpeg.dylib */,\n\t\t\t\tB6AC276427AA3D61000FD713 /* jpegoptim */,\n\t\t\t\tB6AC272F27AA1373000FD713 /* optipng */,\n\t\t\t\tB6BD80EA27B89EA600152AB9 /* ImageOptimaizerView.swift */,\n\t\t\t\tB6AC273127AA2BF6000FD713 /* ImageOptimizer.swift */,\n\t\t\t);\n\t\t\tpath = \"Image Optimizer\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6B5729027ACFE020069DBA7 /* Image Converter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6ED863427BFE12400A17474 /* Exporters */,\n\t\t\t\tB6B5728927ACDA420069DBA7 /* ImageConverterView+.swift */,\n\t\t\t\tB6B5728B27ACE5600069DBA7 /* ImageConverter.swift */,\n\t\t\t);\n\t\t\tpath = \"Image Converter\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6BBA90427C391EE000FE7D3 /* Media */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB63A034927C212FE009FD2AD /* Movie to Gif */,\n\t\t\t\tB67A4C0127C0B9FF009277FB /* Color Picker */,\n\t\t\t\tB6BBA90527C392D5000FE7D3 /* Audio Converter */,\n\t\t\t);\n\t\t\tpath = Media;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6BBA90527C392D5000FE7D3 /* Audio Converter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB66BE8BB27C49AD4003B5ED0 /* AudioFileScanner.swift */,\n\t\t\t\tB6BBA90627C392E3000FE7D3 /* AudioConverterView+.swift */,\n\t\t\t\tB6BBA90827C39528000FE7D3 /* AudioConverter.swift */,\n\t\t\t);\n\t\t\tpath = \"Audio Converter\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6C5292527C20DAF0019BCB0 /* ffmpeg */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB63A034C27C21A99009FD2AD /* ffmpeg */,\n\t\t\t\tB6C5292627C20DC60019BCB0 /* FFMpegExecutor.swift */,\n\t\t\t\tB63A034F27C24BA0009FD2AD /* FFProgressReport.swift */,\n\t\t\t\tB63A035127C25B29009FD2AD /* FFTime.swift */,\n\t\t\t\tB6E294B227C3351F00314132 /* FFTask.swift */,\n\t\t\t\tB6E294E427C337F300314132 /* FFThumnailGenerator.swift */,\n\t\t\t);\n\t\t\tpath = ffmpeg;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6CBFEE727CCA1B000902E56 /* big_sur_icon */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6CBFEE827CCA1B000902E56 /* squircle_bg_mask_256x256.png */,\n\t\t\t\tB6CBFEE927CCA1B000902E56 /* squircle_bg_mask_1024x1024.png */,\n\t\t\t\tB6CBFEEA27CCA1B000902E56 /* squircle_back_128x128.png */,\n\t\t\t\tB6CBFEEB27CCA1B000902E56 /* squircle_back_1024x1024.png */,\n\t\t\t\tB6CBFEEC27CCA1B000902E56 /* squircle_back_16x16.png */,\n\t\t\t\tB6CBFEED27CCA1B000902E56 /* squircle_mask_256x256.png */,\n\t\t\t\tB6CBFEEE27CCA1B000902E56 /* squircle_mask_16x16.png */,\n\t\t\t\tB6CBFEEF27CCA1B000902E56 /* squircle_back_512x512.png */,\n\t\t\t\tB6CBFEF027CCA1B000902E56 /* squircle_mask_64x64.png */,\n\t\t\t\tB6CBFEF127CCA1B000902E56 /* squircle_mask_128x128.png */,\n\t\t\t\tB6CBFEF227CCA1B000902E56 /* squircle_mask_32x32.png */,\n\t\t\t\tB6CBFEF327CCA1B000902E56 /* squircle_bg_mask_512x512.png */,\n\t\t\t\tB6CBFEF427CCA1B000902E56 /* squircle_mask_1024x1024.png */,\n\t\t\t\tB6CBFEF527CCA1B000902E56 /* squircle_back_32x32.png */,\n\t\t\t\tB6CBFEF627CCA1B000902E56 /* squircle_back_256x256.png */,\n\t\t\t\tB6CBFEF727CCA1B000902E56 /* squircle_back_64x64.png */,\n\t\t\t\tB6CBFEF827CCA1B000902E56 /* squircle_mask_512x512.png */,\n\t\t\t);\n\t\t\tpath = big_sur_icon;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6CBFF0B27CCA88100902E56 /* external_drive */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6CBFF1027CCA88E00902E56 /* external_16x16.png */,\n\t\t\t\tB6CBFF1127CCA88E00902E56 /* external_32x32.png */,\n\t\t\t\tB6CBFF0F27CCA88E00902E56 /* external_64x64.png */,\n\t\t\t\tB6CBFF0E27CCA88E00902E56 /* external_128x128.png */,\n\t\t\t\tB6CBFF0D27CCA88E00902E56 /* external_256x256.png */,\n\t\t\t\tB6CBFF1327CCA88E00902E56 /* external_512x512.png */,\n\t\t\t\tB6CBFF1527CCA88F00902E56 /* external_1024x1024.png */,\n\t\t\t);\n\t\t\tpath = external_drive;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6D1AEDD27A534850022FED2 /* Body */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB66BE8BD27C49B28003B5ED0 /* Utils */,\n\t\t\t\tB6D1AEDE27A534960022FED2 /* BodyViewController.swift */,\n\t\t\t\tB6D1AEE327A53A560022FED2 /* HomeView+.swift */,\n\t\t\t\tB61796C627BCB6F00054660E /* SettingView+.swift */,\n\t\t\t\tB608542127A67FF7003BF243 /* Convert */,\n\t\t\t\tB680A79327A68B2D007CB707 /* Coder */,\n\t\t\t\tB608542227A68008003BF243 /* Format */,\n\t\t\t\tB680A8A827A8E0F8007CB707 /* Generator */,\n\t\t\t\tB620141F27A926B400AF5386 /* Text */,\n\t\t\t\tB620145427A9440E00AF5386 /* Graphic */,\n\t\t\t\tB6BBA90427C391EE000FE7D3 /* Media */,\n\t\t\t);\n\t\t\tpath = Body;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6D1AEE727A544F20022FED2 /* Component */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB6D1AEE827A545230022FED2 /* Area.swift */,\n\t\t\t\tB6D1AEF327A54C440022FED2 /* Section.swift */,\n\t\t\t\tB6D1AEEB27A546810022FED2 /* ControlBackgroundLayer.swift */,\n\t\t\t\tB6D1AEF627A54F750022FED2 /* SectionButton.swift */,\n\t\t\t\tB608540A27A66694003BF243 /* SectionButton+.swift */,\n\t\t\t\tB680A89927A8D9DD007CB707 /* Toast.swift */,\n\t\t\t\tB6D1AEF927A557280022FED2 /* PopupButton.swift */,\n\t\t\t\tB6D1AEFC27A55ED50022FED2 /* CodeTextView.swift */,\n\t\t\t\tB672CF9F27AAB8DD00391A5D /* FileDrop.swift */,\n\t\t\t\tB66850ED27A64D3200A3FE01 /* Page.swift */,\n\t\t\t\tB608541F27A67E4D003BF243 /* TextField.swift */,\n\t\t\t\tB680A83227A8BF7D007CB707 /* TextViewSection.swift */,\n\t\t\t\tB680A86727A8D4D1007CB707 /* TextFieldSection.swift */,\n\t\t\t\tB62013B527A90B8900AF5386 /* NumberField.swift */,\n\t\t\t\tB620141B27A917E000AF5386 /* Button.swift */,\n\t\t\t\tB620142227A929B400AF5386 /* TagCloudView.swift */,\n\t\t\t\tB6B5726127AC14B60069DBA7 /* TextView.swift */,\n\t\t\t\tB6B5726327AC14D10069DBA7 /* RegexTextView.swift */,\n\t\t\t\tB673A90127AD0E78005512AB /* DatePicker.swift */,\n\t\t\t\tB6113ECC27C4B96C00ACC6E8 /* EmptyImageTableView.swift */,\n\t\t\t\tB61157C427C8D77A004D77A5 /* DragImageView.swift */,\n\t\t\t\tB6A4F2A327CD078100BBDE7E /* ImageDropView.swift */,\n\t\t\t);\n\t\t\tpath = Component;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6ED863427BFE12400A17474 /* Exporters */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB627295127BFB8CB0034D70C /* cwebp */,\n\t\t\t\tB627295627BFCCC40034D70C /* HeicImageExporter.swift */,\n\t\t\t\tB627294E27BFB7680034D70C /* WebpImageExporter.swift */,\n\t\t\t\tB6ED863527BFE7DC00A17474 /* DefaultImageExporter.swift */,\n\t\t\t);\n\t\t\tpath = Exporters;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tB64B1E6F27A4F5E200AC2601 /* DevToys */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = B64B1E8027A4F5E300AC2601 /* Build configuration list for PBXNativeTarget \"DevToys\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tB64B1E6C27A4F5E200AC2601 /* Sources */,\n\t\t\t\tB64B1E6D27A4F5E200AC2601 /* Frameworks */,\n\t\t\t\tB64B1E6E27A4F5E200AC2601 /* Resources */,\n\t\t\t\tB608541727A66CC9003BF243 /* Embed Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tB64B1F6027A4FC1F00AC2601 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = DevToys;\n\t\t\tpackageProductDependencies = (\n\t\t\t\tB6D1AF0527A5603B0022FED2 /* Highlightr */,\n\t\t\t\tB66850F127A65FC200A3FE01 /* SwiftJSONFormatter */,\n\t\t\t\tB608541A27A672E3003BF243 /* Yams */,\n\t\t\t\tB680A79727A69268007CB707 /* HTMLEntities */,\n\t\t\t\tB680A8AC27A8E31C007CB707 /* CryptoSwift */,\n\t\t\t\tB6B5728727ACD2F20069DBA7 /* Kanna */,\n\t\t\t\tB6113F0827C4C6C900ACC6E8 /* Sparkle */,\n\t\t\t\tB684EA2527C5EFDB0014802F /* DiffMatchPatch */,\n\t\t\t);\n\t\t\tproductName = DevToys;\n\t\t\tproductReference = B64B1E7027A4F5E200AC2601 /* DevToys.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tB64B1E6827A4F5E200AC2601 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1240;\n\t\t\t\tLastUpgradeCheck = 1240;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tB64B1E6F27A4F5E200AC2601 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 12.4;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = B64B1E6B27A4F5E200AC2601 /* Build configuration list for PBXProject \"DevToys\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\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\tja,\n\t\t\t\t\"zh-Hans\",\n\t\t\t\t\"pt-BR\",\n\t\t\t\tde,\n\t\t\t\tes,\n\t\t\t);\n\t\t\tmainGroup = B64B1E6727A4F5E200AC2601;\n\t\t\tpackageReferences = (\n\t\t\t\tB6D1AF0427A5603B0022FED2 /* XCRemoteSwiftPackageReference \"Highlightr\" */,\n\t\t\t\tB66850F027A65FC200A3FE01 /* XCRemoteSwiftPackageReference \"SwiftJSONFormatter\" */,\n\t\t\t\tB608541927A672E3003BF243 /* XCRemoteSwiftPackageReference \"Yams\" */,\n\t\t\t\tB680A79627A69268007CB707 /* XCRemoteSwiftPackageReference \"swift-html-entities\" */,\n\t\t\t\tB680A8AB27A8E31C007CB707 /* XCRemoteSwiftPackageReference \"CryptoSwift\" */,\n\t\t\t\tB6B5728627ACD2F20069DBA7 /* XCRemoteSwiftPackageReference \"Kanna\" */,\n\t\t\t\tB6113F0727C4C6C900ACC6E8 /* XCRemoteSwiftPackageReference \"Sparkle\" */,\n\t\t\t\tB684EA2427C5EFDB0014802F /* XCRemoteSwiftPackageReference \"DiffMatchPatch\" */,\n\t\t\t);\n\t\t\tproductRefGroup = B64B1E7127A4F5E200AC2601 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = B64B1F5A27A4FC1800AC2601 /* Products */;\n\t\t\t\t\tProjectRef = B64B1F5927A4FC1800AC2601 /* CoreUtil.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tB64B1E6F27A4F5E200AC2601 /* DevToys */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\tB64B1F5E27A4FC1900AC2601 /* CoreUtil.framework */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.framework;\n\t\t\tpath = CoreUtil.framework;\n\t\t\tremoteRef = B64B1F5D27A4FC1900AC2601 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tB64B1E6E27A4F5E200AC2601 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB69F0E8927CBC2100032F96A /* folder_back_512_bs.png in Resources */,\n\t\t\t\tB6E15A9427B6745100DC4D6B /* libimageoptimjpeg.dylib in Resources */,\n\t\t\t\tB69F0E9C27CBC7550032F96A /* folder_top_1024.png in Resources */,\n\t\t\t\tB69F0E8527CBC2100032F96A /* folder_back_256_bs.png in Resources */,\n\t\t\t\tB63A034D27C21A99009FD2AD /* ffmpeg in Resources */,\n\t\t\t\tB6BD80F427B8AEE700152AB9 /* Localizable.strings in Resources */,\n\t\t\t\tB6CBFF1927CCA88F00902E56 /* external_64x64.png in Resources */,\n\t\t\t\tB6CBFF0827CCA1B000902E56 /* squircle_back_64x64.png in Resources */,\n\t\t\t\tB69F0E8627CBC2100032F96A /* folder_back_1024_bs.png in Resources */,\n\t\t\t\tB6CBFF1D27CCA88F00902E56 /* external_512x512.png in Resources */,\n\t\t\t\tB6CBFF0727CCA1B000902E56 /* squircle_back_256x256.png in Resources */,\n\t\t\t\tB6CBFEFD27CCA1B000902E56 /* squircle_back_16x16.png in Resources */,\n\t\t\t\tB6CBFF1B27CCA88F00902E56 /* external_32x32.png in Resources */,\n\t\t\t\tB69F0E9127CBC2340032F96A /* folder_mask2_1024_bs.png in Resources */,\n\t\t\t\tB6CBFF0027CCA1B000902E56 /* squircle_back_512x512.png in Resources */,\n\t\t\t\tB69F0E9D27CBC7550032F96A /* folder_top_512.png in Resources */,\n\t\t\t\tB627295227BFB8CB0034D70C /* cwebp in Resources */,\n\t\t\t\tB69F0E8827CBC2100032F96A /* folder_back_16_bs.png in Resources */,\n\t\t\t\tB6CBFEFE27CCA1B000902E56 /* squircle_mask_256x256.png in Resources */,\n\t\t\t\tB69F0EA627CC7CF40032F96A /* watermark_mask_bs.png in Resources */,\n\t\t\t\tB69F0E8727CBC2100032F96A /* folder_back_32_bs.png in Resources */,\n\t\t\t\tB69F0EA727CC7CF40032F96A /* watermark_mask_dark_bs.png in Resources */,\n\t\t\t\tB69F0E9427CBC2340032F96A /* folder_mask2_32_bs.png in Resources */,\n\t\t\t\tB69980D427CCCF0A0063F63D /* android_mask.png in Resources */,\n\t\t\t\tB6CBFEFA27CCA1B000902E56 /* squircle_bg_mask_1024x1024.png in Resources */,\n\t\t\t\tB69F0E9227CBC2340032F96A /* folder_mask2_512_bs.png in Resources */,\n\t\t\t\tB6CBFEFB27CCA1B000902E56 /* squircle_back_128x128.png in Resources */,\n\t\t\t\tB6CBFF1727CCA88F00902E56 /* external_256x256.png in Resources */,\n\t\t\t\tB6CBFF0627CCA1B000902E56 /* squircle_back_32x32.png in Resources */,\n\t\t\t\tB6CBFEFF27CCA1B000902E56 /* squircle_mask_16x16.png in Resources */,\n\t\t\t\tB6CBFF0527CCA1B000902E56 /* squircle_mask_1024x1024.png in Resources */,\n\t\t\t\tB6CBFF0927CCA1B000902E56 /* squircle_mask_512x512.png in Resources */,\n\t\t\t\tB6AC276527AA3D61000FD713 /* jpegoptim in Resources */,\n\t\t\t\tB6CBFF0427CCA1B000902E56 /* squircle_bg_mask_512x512.png in Resources */,\n\t\t\t\tB69F0E9327CBC2340032F96A /* folder_mask2_16_bs.png in Resources */,\n\t\t\t\tB6CBFF0327CCA1B000902E56 /* squircle_mask_32x32.png in Resources */,\n\t\t\t\tB6CBFF0127CCA1B000902E56 /* squircle_mask_64x64.png in Resources */,\n\t\t\t\tB6AC273027AA1373000FD713 /* optipng in Resources */,\n\t\t\t\tB6CBFF1827CCA88F00902E56 /* external_128x128.png in Resources */,\n\t\t\t\tB6CBFF1F27CCA88F00902E56 /* external_1024x1024.png in Resources */,\n\t\t\t\tB6CBFEFC27CCA1B000902E56 /* squircle_back_1024x1024.png in Resources */,\n\t\t\t\tB69F0E9627CBC2340032F96A /* folder_mask2_128_bs.png in Resources */,\n\t\t\t\tB6CBFF1A27CCA88F00902E56 /* external_16x16.png in Resources */,\n\t\t\t\tB64B1E7827A4F5E300AC2601 /* Assets.xcassets in Resources */,\n\t\t\t\tB67A4C5727C0EA84009277FB /* ACOverlayController.xib in Resources */,\n\t\t\t\tB69F0E8427CBC2100032F96A /* folder_back_128_bs.png in Resources */,\n\t\t\t\tB6CBFEF927CCA1B000902E56 /* squircle_bg_mask_256x256.png in Resources */,\n\t\t\t\tB64B1E7B27A4F5E300AC2601 /* Main.storyboard in Resources */,\n\t\t\t\tB69F0E8327CBC2100032F96A /* folder_back_64_bs.png in Resources */,\n\t\t\t\tB6CBFF0227CCA1B000902E56 /* squircle_mask_128x128.png in Resources */,\n\t\t\t\tB69F0E9827CBC2800032F96A /* folder_mask2_256_bs.png in Resources */,\n\t\t\t\tB69F0E9527CBC2340032F96A /* folder_mask2_64_bs.png in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tB64B1E6C27A4F5E200AC2601 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB62013B627A90B8900AF5386 /* NumberField.swift in Sources */,\n\t\t\t\tB6BD80EB27B89EA600152AB9 /* ImageOptimaizerView.swift in Sources */,\n\t\t\t\tB684EA2A27C609620014802F /* QRCodeGeneratorView+.swift in Sources */,\n\t\t\t\tB67A4C0D27C0BA00009277FB /* Color.swift in Sources */,\n\t\t\t\tB608541E27A67B48003BF243 /* NumberBaseConverterView+.swift in Sources */,\n\t\t\t\tB680A8AA27A8E106007CB707 /* HashGeneratorView+.swift in Sources */,\n\t\t\t\tB6A4F2A427CD078100BBDE7E /* ImageDropView.swift in Sources */,\n\t\t\t\tB6789EBC27CA48A300D8B58C /* IosIconGenerator.swift in Sources */,\n\t\t\t\tB67A4CC327C0F4D4009277FB /* CircleHueBarView.swift in Sources */,\n\t\t\t\tB67A4CC927C10493009277FB /* SaturationBarView.swift in Sources */,\n\t\t\t\tB64B202027A523A200AC2601 /* ToolMenuCell.swift in Sources */,\n\t\t\t\tB64AA45027AD0D3900EC436D /* DateConverterView+.swift in Sources */,\n\t\t\t\tB6E294E527C337F300314132 /* FFThumnailGenerator.swift in Sources */,\n\t\t\t\tB6C5292727C20DC60019BCB0 /* FFMpegExecutor.swift in Sources */,\n\t\t\t\tB672CFA027AAB8DD00391A5D /* FileDrop.swift in Sources */,\n\t\t\t\tB608540B27A66694003BF243 /* SectionButton+.swift in Sources */,\n\t\t\t\tB67A4C4E27C0EA84009277FB /* ACOverlayPreview.swift in Sources */,\n\t\t\t\tB63A034B27C2130A009FD2AD /* GifConverter.swift in Sources */,\n\t\t\t\tB67A4C0C27C0BA00009277FB /* ColorBoxView.swift in Sources */,\n\t\t\t\tB6B5726427AC14D10069DBA7 /* RegexTextView.swift in Sources */,\n\t\t\t\tB67A4C5227C0EA84009277FB /* ShowAndHideCursor.m in Sources */,\n\t\t\t\tB6A93D3227CBBC97003A6D7F /* IconTemplete+.swift in Sources */,\n\t\t\t\tB69F0E9F27CC76A50032F96A /* IconImageManager.swift in Sources */,\n\t\t\t\tB6789EBA27CA43E200D8B58C /* IconGeneratorView+.swift in Sources */,\n\t\t\t\tB680A83327A8BF7D007CB707 /* TextViewSection.swift in Sources */,\n\t\t\t\tB6B5726227AC14B60069DBA7 /* TextView.swift in Sources */,\n\t\t\t\tB6C5292427C20D520019BCB0 /* GifConverterView+.swift in Sources */,\n\t\t\t\tB66BE8BC27C49AD4003B5ED0 /* AudioFileScanner.swift in Sources */,\n\t\t\t\tB627295727BFCCC40034D70C /* HeicImageExporter.swift in Sources */,\n\t\t\t\tB67A4CC727C0F546009277FB /* CircleBoxHSBColorPicker.swift in Sources */,\n\t\t\t\tB67A4C5827C0EA84009277FB /* ACOverlayWrapper.swift in Sources */,\n\t\t\t\tB67A4C5427C0EA84009277FB /* Ex+CGImage.swift in Sources */,\n\t\t\t\tB620142327A929B400AF5386 /* TagCloudView.swift in Sources */,\n\t\t\t\tB67A4C5627C0EA84009277FB /* ACOverlayController.swift in Sources */,\n\t\t\t\tB6113ECF27C4BF2300ACC6E8 /* FileConflictAvoider.swift in Sources */,\n\t\t\t\tB67A4C0927C0BA00009277FB /* OpacityBarView.swift in Sources */,\n\t\t\t\tB6B5728027ACC3AF0069DBA7 /* ChecksumGeneratorView+.swift in Sources */,\n\t\t\t\tB64B209827A532DF00AC2601 /* AppWindowController.swift in Sources */,\n\t\t\t\tB67A4CC027C0F4BA009277FB /* BoxHSBColorPicker.swift in Sources */,\n\t\t\t\tB673A90227AD0E78005512AB /* DatePicker.swift in Sources */,\n\t\t\t\tB620141C27A917E000AF5386 /* Button.swift in Sources */,\n\t\t\t\tB66536CE27C9BA4000CA1CEC /* Slugify.swift in Sources */,\n\t\t\t\tB6AC273227AA2BF6000FD713 /* ImageOptimizer.swift in Sources */,\n\t\t\t\tB6789EDF27CA5F5D00D8B58C /* IconsetGenerator.swift in Sources */,\n\t\t\t\tB6789EE727CB334D00D8B58C /* AndroidIconGenerator.swift in Sources */,\n\t\t\t\tB67A4C0A27C0BA00009277FB /* HueBarView.swift in Sources */,\n\t\t\t\tB6113F0127C4BF7700ACC6E8 /* Identifier.swift in Sources */,\n\t\t\t\tB65DB78027AC0EB400146A3C /* RegexTesterView+.swift in Sources */,\n\t\t\t\tB6B5728F27ACFA6E0069DBA7 /* ImageDropper.swift in Sources */,\n\t\t\t\tB680A89A27A8D9DD007CB707 /* Toast.swift in Sources */,\n\t\t\t\tB6A4F2A227CD05F000BBDE7E /* QRCodeReaderView+.swift in Sources */,\n\t\t\t\tB6D1AEF727A54F750022FED2 /* SectionButton.swift in Sources */,\n\t\t\t\tB684EA2827C5EFE90014802F /* TextDiffView+.swift in Sources */,\n\t\t\t\tB6789EE127CA5F6900D8B58C /* IcnsGenerator.swift in Sources */,\n\t\t\t\tB63A035027C24BA0009FD2AD /* FFProgressReport.swift in Sources */,\n\t\t\t\tB6A93D3327CBBC97003A6D7F /* IconSet.swift in Sources */,\n\t\t\t\tB6D88A8B27D07204002E71EA /* CameraViewController.swift in Sources */,\n\t\t\t\tB64B1E7627A4F5E200AC2601 /* AppViewController.swift in Sources */,\n\t\t\t\tB67A4C5327C0EA84009277FB /* Ex+NSColor.swift in Sources */,\n\t\t\t\tB6E294B327C3351F00314132 /* FFTask.swift in Sources */,\n\t\t\t\tB6D1AEE927A545230022FED2 /* Area.swift in Sources */,\n\t\t\t\tB64B1F7727A4FF8B00AC2601 /* SidebarView+.swift in Sources */,\n\t\t\t\tB64B202327A52A2D00AC2601 /* R.swift in Sources */,\n\t\t\t\tB6B5728227ACCF2F0069DBA7 /* XMLFormatterView+.swift in Sources */,\n\t\t\t\tB67A4C4F27C0EA84009277FB /* Ex+NSBezierPath.swift in Sources */,\n\t\t\t\tB64B201D27A5219400AC2601 /* SearchCell.swift in Sources */,\n\t\t\t\tB6BD80EF27B8A85400152AB9 /* ToolCategory+Default.swift in Sources */,\n\t\t\t\tB67A4C0827C0BA00009277FB /* ColorPickerHandleLayer.swift in Sources */,\n\t\t\t\tB66850EE27A64D3200A3FE01 /* Page.swift in Sources */,\n\t\t\t\tB61796C527BCB3090054660E /* ToolCategoryCell.swift in Sources */,\n\t\t\t\tB6BD80F127B8A86100152AB9 /* Tool+Default.swift in Sources */,\n\t\t\t\tB6D1AEF427A54C440022FED2 /* Section.swift in Sources */,\n\t\t\t\tB64B1F7227A4FDC800AC2601 /* AppModel.swift in Sources */,\n\t\t\t\tB6D1AEFA27A557280022FED2 /* PopupButton.swift in Sources */,\n\t\t\t\tB69980D727CCE09A0063F63D /* IcoGenerator.swift in Sources */,\n\t\t\t\tB6789EE327CA5F7A00D8B58C /* IconFolderGenerator.swift in Sources */,\n\t\t\t\tB6B5728A27ACDA420069DBA7 /* ImageConverterView+.swift in Sources */,\n\t\t\t\tB67A4CCD27C12C09009277FB /* CircleBarsHSBColorPicker.swift in Sources */,\n\t\t\t\tB69980D927CCEB320063F63D /* PngIconGenerator.swift in Sources */,\n\t\t\t\tB6D1AEF027A547B90022FED2 /* JSONFormatterView+.swift in Sources */,\n\t\t\t\tB64844FF27B767EC004FE02B /* ToolManager+.swift in Sources */,\n\t\t\t\tB620142127A9271500AF5386 /* TextInspectorView+.swift in Sources */,\n\t\t\t\tB64B1E7427A4F5E200AC2601 /* AppDelegate.swift in Sources */,\n\t\t\t\tB620141E27A91F6700AF5386 /* LoremIpsumGeneratorView+.swift in Sources */,\n\t\t\t\tB627294F27BFB7680034D70C /* WebpImageExporter.swift in Sources */,\n\t\t\t\tB61157C027C8C3F9004D77A5 /* JSONSearchView+.swift in Sources */,\n\t\t\t\tB6113ECD27C4B96C00ACC6E8 /* EmptyImageTableView.swift in Sources */,\n\t\t\t\tB6B5728C27ACE5600069DBA7 /* ImageConverter.swift in Sources */,\n\t\t\t\tB67A4C5027C0EA84009277FB /* Util+PixelPicker.swift in Sources */,\n\t\t\t\tB6789EE527CA5F9500D8B58C /* IconGenerator+Model.swift in Sources */,\n\t\t\t\tB6D1AEDF27A534960022FED2 /* BodyViewController.swift in Sources */,\n\t\t\t\tB67A4C5127C0EA84009277FB /* ShowAndHideCursor.swift in Sources */,\n\t\t\t\tB61157C527C8D77A004D77A5 /* DragImageView.swift in Sources */,\n\t\t\t\tB66536D027C9C56600CA1CEC /* SQLFormatterView+.swift in Sources */,\n\t\t\t\tB680A79C27A6947D007CB707 /* Base64DecoderView+.swift in Sources */,\n\t\t\t\tB67A4CC527C0F50D009277FB /* R+ColorPicker.swift in Sources */,\n\t\t\t\tB680A86827A8D4D1007CB707 /* TextFieldSection.swift in Sources */,\n\t\t\t\tB67A4CBE27C0EEEF009277FB /* ColorSampleView.swift in Sources */,\n\t\t\t\tB680A79527A68B35007CB707 /* HTMLDecoderView+.swift in Sources */,\n\t\t\t\tB67A4CCB27C10548009277FB /* BrightnessBarView.swift in Sources */,\n\t\t\t\tB680A8A727A8DD5D007CB707 /* JWTDecoderView+.swift in Sources */,\n\t\t\t\t6B42318827AD1BC0002D135A /* HyphenationRemoverView+.swift in Sources */,\n\t\t\t\tB6BBA90927C39528000FE7D3 /* AudioConverter.swift in Sources */,\n\t\t\t\tB6BBA90727C392E3000FE7D3 /* AudioConverterView+.swift in Sources */,\n\t\t\t\tB61796C727BCB6F00054660E /* SettingView+.swift in Sources */,\n\t\t\t\tB6D1AEE427A53A560022FED2 /* HomeView+.swift in Sources */,\n\t\t\t\tB6AC276A27AA535A000FD713 /* PDFGeneratorView+.swift in Sources */,\n\t\t\t\tB608542027A67E4D003BF243 /* TextField.swift in Sources */,\n\t\t\t\tB6A93D3427CBBC97003A6D7F /* IconTemplete.swift in Sources */,\n\t\t\t\tB67A4C5527C0EA84009277FB /* ACOverlayPanel.swift in Sources */,\n\t\t\t\tB680A79A27A69324007CB707 /* URLDecoderView+.swift in Sources */,\n\t\t\t\tB61157C327C8C78A004D77A5 /* JSONNormalSearchView.swift in Sources */,\n\t\t\t\tB63A035227C25B29009FD2AD /* FFTime.swift in Sources */,\n\t\t\t\tB6ED863627BFE7DC00A17474 /* DefaultImageExporter.swift in Sources */,\n\t\t\t\tB61796C927BCB84A0054660E /* Settings.swift in Sources */,\n\t\t\t\tB67A4C0B27C0BA00009277FB /* ColorPickerView+.swift in Sources */,\n\t\t\t\tB608541227A66A90003BF243 /* JSONYamlConverterView+.swift in Sources */,\n\t\t\t\tB6D1AEFD27A55ED50022FED2 /* CodeTextView.swift in Sources */,\n\t\t\t\tB62013B427A9070D00AF5386 /* UUIDGeneratorView+.swift in Sources */,\n\t\t\t\tB6D1AEEC27A546810022FED2 /* ControlBackgroundLayer.swift in Sources */,\n\t\t\t\tB67A4C4D27C0EA84009277FB /* ACPixelPicker.swift in Sources */,\n\t\t\t\tB64B201627A5100800AC2601 /* Separator.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\tB64B1F6027A4FC1F00AC2601 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = CoreUtil;\n\t\t\ttargetProxy = B64B1F5F27A4FC1F00AC2601 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tB64B1E7927A4F5E300AC2601 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tB64B1E7A27A4F5E300AC2601 /* Base */,\n\t\t\t\tB67A4CCE27C1E010009277FB /* zh-Hans */,\n\t\t\t\tB67A4CD027C1E036009277FB /* pt-BR */,\n\t\t\t\tB67A4CD427C1E0DC009277FB /* en */,\n\t\t\t\tB67A4CD527C1E0DF009277FB /* ja */,\n\t\t\t\tB67A4CD727C1E0F1009277FB /* de */,\n\t\t\t\tB67A4CD927C1E469009277FB /* es */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB6BD80F627B8AEE700152AB9 /* Localizable.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tB6BD80F527B8AEE700152AB9 /* en */,\n\t\t\t\tB6BD80F827B8AF1800152AB9 /* ja */,\n\t\t\t\tB67A4CCF27C1E01C009277FB /* zh-Hans */,\n\t\t\t\tB67A4CD127C1E03C009277FB /* pt-BR */,\n\t\t\t\tB67A4CD827C1E0F8009277FB /* de */,\n\t\t\t\tB67A4CDA27C1E46A009277FB /* es */,\n\t\t\t);\n\t\t\tname = Localizable.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tB64B1E7E27A4F5E300AC2601 /* 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_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\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_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\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 = 10.15;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tB64B1E7F27A4F5E300AC2601 /* 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_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\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_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\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 = 10.15;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tB64B1E8127A4F5E300AC2601 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = DevToys/DevToys.entitlements;\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = 0.0.10;\n\t\t\t\tDEVELOPMENT_TEAM = T5HMUWWK5R;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tINFOPLIST_FILE = DevToys/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\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/DevToys/Body/Media/Image\\\\ Optimizer\",\n\t\t\t\t\t\"$(PROJECT_DIR)/DevToys/Body/Media/Image\\\\ Optimizer\",\n\t\t\t\t\t\"$(PROJECT_DIR)/DevToys/Body/Media/Image\\\\ Optimizer\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMARKETING_VERSION = 0.0.10;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.yuki.DevToys;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_ENFORCE_EXCLUSIVE_ACCESS = off;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"DevToys/Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tB64B1E8227A4F5E300AC2601 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = DevToys/DevToys.entitlements;\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = 0.0.10;\n\t\t\t\tDEVELOPMENT_TEAM = T5HMUWWK5R;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tINFOPLIST_FILE = DevToys/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\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/DevToys/Body/Media/Image\\\\ Optimizer\",\n\t\t\t\t\t\"$(PROJECT_DIR)/DevToys/Body/Media/Image\\\\ Optimizer\",\n\t\t\t\t\t\"$(PROJECT_DIR)/DevToys/Body/Media/Image\\\\ Optimizer\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMARKETING_VERSION = 0.0.10;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.yuki.DevToys;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_ENFORCE_EXCLUSIVE_ACCESS = off;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"DevToys/Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tB64B1E6B27A4F5E200AC2601 /* Build configuration list for PBXProject \"DevToys\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tB64B1E7E27A4F5E300AC2601 /* Debug */,\n\t\t\t\tB64B1E7F27A4F5E300AC2601 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tB64B1E8027A4F5E300AC2601 /* Build configuration list for PBXNativeTarget \"DevToys\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tB64B1E8127A4F5E300AC2601 /* Debug */,\n\t\t\t\tB64B1E8227A4F5E300AC2601 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\n/* Begin XCRemoteSwiftPackageReference section */\n\t\tB608541927A672E3003BF243 /* XCRemoteSwiftPackageReference \"Yams\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/ObuchiYuki/Yams\";\n\t\t\trequirement = {\n\t\t\t\tbranch = main;\n\t\t\t\tkind = branch;\n\t\t\t};\n\t\t};\n\t\tB6113F0727C4C6C900ACC6E8 /* XCRemoteSwiftPackageReference \"Sparkle\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/sparkle-project/Sparkle\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 2.0.0;\n\t\t\t};\n\t\t};\n\t\tB66850F027A65FC200A3FE01 /* XCRemoteSwiftPackageReference \"SwiftJSONFormatter\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/ObuchiYuki/SwiftJSONFormatter\";\n\t\t\trequirement = {\n\t\t\t\tbranch = main;\n\t\t\t\tkind = branch;\n\t\t\t};\n\t\t};\n\t\tB680A79627A69268007CB707 /* XCRemoteSwiftPackageReference \"swift-html-entities\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/Kitura/swift-html-entities.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 4.0.0;\n\t\t\t};\n\t\t};\n\t\tB680A8AB27A8E31C007CB707 /* XCRemoteSwiftPackageReference \"CryptoSwift\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/krzyzanowskim/CryptoSwift.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 1.4.2;\n\t\t\t};\n\t\t};\n\t\tB684EA2427C5EFDB0014802F /* XCRemoteSwiftPackageReference \"DiffMatchPatch\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/ObuchiYuki/DiffMatchPatch\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 1.0.0;\n\t\t\t};\n\t\t};\n\t\tB6B5728627ACD2F20069DBA7 /* XCRemoteSwiftPackageReference \"Kanna\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/tid-kijyun/Kanna.git\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 5.2.7;\n\t\t\t};\n\t\t};\n\t\tB6D1AF0427A5603B0022FED2 /* XCRemoteSwiftPackageReference \"Highlightr\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/raspu/Highlightr\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 2.1.2;\n\t\t\t};\n\t\t};\n/* End XCRemoteSwiftPackageReference section */\n\n/* Begin XCSwiftPackageProductDependency section */\n\t\tB608541A27A672E3003BF243 /* Yams */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B608541927A672E3003BF243 /* XCRemoteSwiftPackageReference \"Yams\" */;\n\t\t\tproductName = Yams;\n\t\t};\n\t\tB6113F0827C4C6C900ACC6E8 /* Sparkle */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B6113F0727C4C6C900ACC6E8 /* XCRemoteSwiftPackageReference \"Sparkle\" */;\n\t\t\tproductName = Sparkle;\n\t\t};\n\t\tB66850F127A65FC200A3FE01 /* SwiftJSONFormatter */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B66850F027A65FC200A3FE01 /* XCRemoteSwiftPackageReference \"SwiftJSONFormatter\" */;\n\t\t\tproductName = SwiftJSONFormatter;\n\t\t};\n\t\tB680A79727A69268007CB707 /* HTMLEntities */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B680A79627A69268007CB707 /* XCRemoteSwiftPackageReference \"swift-html-entities\" */;\n\t\t\tproductName = HTMLEntities;\n\t\t};\n\t\tB680A8AC27A8E31C007CB707 /* CryptoSwift */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B680A8AB27A8E31C007CB707 /* XCRemoteSwiftPackageReference \"CryptoSwift\" */;\n\t\t\tproductName = CryptoSwift;\n\t\t};\n\t\tB684EA2527C5EFDB0014802F /* DiffMatchPatch */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B684EA2427C5EFDB0014802F /* XCRemoteSwiftPackageReference \"DiffMatchPatch\" */;\n\t\t\tproductName = DiffMatchPatch;\n\t\t};\n\t\tB6B5728727ACD2F20069DBA7 /* Kanna */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B6B5728627ACD2F20069DBA7 /* XCRemoteSwiftPackageReference \"Kanna\" */;\n\t\t\tproductName = Kanna;\n\t\t};\n\t\tB6D1AF0527A5603B0022FED2 /* Highlightr */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = B6D1AF0427A5603B0022FED2 /* XCRemoteSwiftPackageReference \"Highlightr\" */;\n\t\t\tproductName = Highlightr;\n\t\t};\n/* End XCSwiftPackageProductDependency section */\n\t};\n\trootObject = B64B1E6827A4F5E200AC2601 /* Project object */;\n}\n"
  },
  {
    "path": "DevToys/DevToys.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "DevToys/DevToys.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": "DevToys/DevToys.xcodeproj/xcshareddata/xcschemes/DevToys.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\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 = \"B64B1E6F27A4F5E200AC2601\"\n               BuildableName = \"DevToys.app\"\n               BlueprintName = \"DevToys\"\n               ReferencedContainer = \"container:DevToys.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"\"\n      selectedLauncherIdentifier = \"Xcode.IDEFoundation.Launcher.PosixSpawn\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <EnvironmentVariables>\n         <EnvironmentVariable\n            key = \"OS_ACTIVITY_MODE\"\n            value = \"disable\"\n            isEnabled = \"YES\">\n         </EnvironmentVariable>\n      </EnvironmentVariables>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"B64B1E6F27A4F5E200AC2601\"\n            BuildableName = \"DevToys.app\"\n            BlueprintName = \"DevToys\"\n            ReferencedContainer = \"container:DevToys.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <EnvironmentVariables>\n         <EnvironmentVariable\n            key = \"OS_ACTIVITY_MODE\"\n            value = \"disable\"\n            isEnabled = \"YES\">\n         </EnvironmentVariable>\n      </EnvironmentVariables>\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 = \"B64B1E6F27A4F5E200AC2601\"\n            BuildableName = \"DevToys.app\"\n            BlueprintName = \"DevToys\"\n            ReferencedContainer = \"container:DevToys.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": "DevToys.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"container:DevToys/DevToys.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:CoreUtil/CoreUtil.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "DevToys.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": "DevToys.xcworkspace/xcshareddata/swiftpm/Package.resolved",
    "content": "{\n  \"object\": {\n    \"pins\": [\n      {\n        \"package\": \"CryptoSwift\",\n        \"repositoryURL\": \"https://github.com/krzyzanowskim/CryptoSwift.git\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"12f2389aca4a07e0dd54c86ec23d0721ed88b8db\",\n          \"version\": \"1.4.3\"\n        }\n      },\n      {\n        \"package\": \"DiffMatchPatch\",\n        \"repositoryURL\": \"https://github.com/ObuchiYuki/DiffMatchPatch\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"5db22e8f9ac588a130f62733105bbe5c5bdd7bc3\",\n          \"version\": \"1.0.3\"\n        }\n      },\n      {\n        \"package\": \"Highlightr\",\n        \"repositoryURL\": \"https://github.com/raspu/Highlightr\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"93199b9e434f04bda956a613af8f571933f9f037\",\n          \"version\": \"2.1.2\"\n        }\n      },\n      {\n        \"package\": \"Kanna\",\n        \"repositoryURL\": \"https://github.com/tid-kijyun/Kanna.git\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"f9e4922223dd0d3dfbf02ca70812cf5531fc0593\",\n          \"version\": \"5.2.7\"\n        }\n      },\n      {\n        \"package\": \"Promise\",\n        \"repositoryURL\": \"https://github.com/ObuchiYuki/Promise.git\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"cf504f07706a11f9cf2af339e9b1ffca2b95d4ac\",\n          \"version\": \"1.0.13\"\n        }\n      },\n      {\n        \"package\": \"SnapKit\",\n        \"repositoryURL\": \"https://github.com/SnapKit/SnapKit.git\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"d458564516e5676af9c70b4f4b2a9178294f1bc6\",\n          \"version\": \"5.0.1\"\n        }\n      },\n      {\n        \"package\": \"Sparkle\",\n        \"repositoryURL\": \"https://github.com/sparkle-project/Sparkle\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"286edd1fa22505a9e54d170e9fd07d775ea233f2\",\n          \"version\": \"2.1.0\"\n        }\n      },\n      {\n        \"package\": \"swift-collections\",\n        \"repositoryURL\": \"https://github.com/apple/swift-collections\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"48254824bb4248676bf7ce56014ff57b142b77eb\",\n          \"version\": \"1.0.2\"\n        }\n      },\n      {\n        \"package\": \"HTMLEntities\",\n        \"repositoryURL\": \"https://github.com/Kitura/swift-html-entities.git\",\n        \"state\": {\n          \"branch\": null,\n          \"revision\": \"3686a2b931be24dd2531307f89e2f1d648c0200e\",\n          \"version\": \"4.0.0\"\n        }\n      },\n      {\n        \"package\": \"SwiftJSONFormatter\",\n        \"repositoryURL\": \"https://github.com/ObuchiYuki/SwiftJSONFormatter\",\n        \"state\": {\n          \"branch\": \"main\",\n          \"revision\": \"65191c3708b2b74e43cac716d14deeb2536865a8\",\n          \"version\": null\n        }\n      },\n      {\n        \"package\": \"Yams\",\n        \"repositoryURL\": \"https://github.com/ObuchiYuki/Yams\",\n        \"state\": {\n          \"branch\": \"main\",\n          \"revision\": \"78957e5f5c026b3a4f2f54498cf18ff3bf42fdf8\",\n          \"version\": null\n        }\n      }\n    ]\n  },\n  \"version\": 1\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2022 ObuchiYuki\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": "# DevToysMac\n\nThis is the mac app version of [DevToys for Windows](https://github.com/veler/DevToys)!\n\n![Dribbble Shot](https://user-images.githubusercontent.com/20896810/154781951-f4c6fa80-2fcc-40fe-a94b-fccfc0f2ccf1.png)\n\n# How to install\n\n## Manually\n- Download the [latest release](https://github.com/ObuchiYuki/DevToysMac/releases/latest).\n- Extract `DevToys.app` from `DevToys.app.zip`\n\n## Homebrew\n- Install [Homebrew](https://brew.sh/). Then install DevToysMac with `brew install --cask devtoys`.\n\n\n\n# Screenshots\n\n### Home\n<img width=\"500\" alt=\"スクリーンショット 2022-01-30 19 01 01\" src=\"https://user-images.githubusercontent.com/20896810/151695286-7984d264-e590-43b8-9ed7-03853967b0e4.png\">\n\n\n### Json <> Yaml Converter\n\n<img width=\"500\" alt=\"スクリーンショット 2022-01-30 19 01 23\" src=\"https://user-images.githubusercontent.com/20896810/151695289-cf2a4c2f-8ca9-4537-a896-5fc944b706ac.png\">\n\n\n### Number Base Converter\n\n<img width=\"500\" alt=\"スクリーンショット 2022-01-30 19 01 41\" src=\"https://user-images.githubusercontent.com/20896810/151695294-88c629d9-514f-4966-a174-1fcec9c29185.png\">\n\n\n### HTML Encoder / Decoder\n\n<img width=\"500\" alt=\"スクリーンショット 2022-01-30 19 02 05\" src=\"https://user-images.githubusercontent.com/20896810/151695300-e0dccd31-b3ac-42e6-904d-d287e56e4e63.png\">\n\n### URL Encoder / Decoder\n\n<img width=\"500\" alt=\"スクリーンショット 2022-01-30 19 02 11\" src=\"https://user-images.githubusercontent.com/20896810/151695305-a88c6106-3086-4289-bd61-8670cd1d1bac.png\">\n\n### Base64 Encoder / Decoder\n\n<img width=\"500\" alt=\"スクリーンショット 2022-01-30 19 02 49\" src=\"https://user-images.githubusercontent.com/20896810/151695317-a821fc62-64b6-4e09-a7dc-cb661f10ee7d.png\">\n\n### JSON Formatter\n\n<img width=\"500\" alt=\"スクリーンショット 2022-01-30 19 04 43\" src=\"https://user-images.githubusercontent.com/20896810/151695321-f996ddc7-27d3-457e-8086-d40848ce8d68.png\">\n\n\nand more...\n"
  },
  {
    "path": "Release Checklist.md",
    "content": "# Release Checklist\n\nThis is the procedure for doing a release.\n\n\n\n1. Update the project version from Xcode's project pane\n\n   Update both Version and Build (Sparkle seems to be referring to the build.)\n\n2. Archive and Notarize app\n   - With Distribute App > Developer ID\n\n3. Create a tag for the release and push that tag.\n\n4. Create a Github release page.\n\n5. Create a zip file of the nolarized app on **local** (not the github page) and upload it to Asset.\n   - The checksum of the zip file will be requested by appcast.\n\n6. Generate appcast file with `generate_appcast` command.\n\n7. Publish release on GitHub.\n\n8. Update generated `appcast.xml` 's `<enclosure url=\"...\">` to release asset URL.\n\n9. Add new `appcast.xml` to git and push.\n\n10. If needed, create `release-note.html` for Sparkle update."
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Document</title>\n</head>\n<body>\n  <h1>Hello World</h1>\n</body>\n</html>"
  },
  {
    "path": "docs/sparkle/appcast.xml",
    "content": "<?xml version=\"1.0\" standalone=\"yes\"?>\n<rss xmlns:sparkle=\"http://www.andymatuschak.org/xml-namespaces/sparkle\" version=\"2.0\">\n    <channel>\n        <title>DevToys</title>\n        <item>\n            <title>0.0.10</title>\n            <pubDate>Sat, 26 Feb 2022 15:33:30 +0900</pubDate>\n            <sparkle:version>0.0.10</sparkle:version>\n            <sparkle:shortVersionString>0.0.10</sparkle:shortVersionString>\n            <sparkle:minimumSystemVersion>10.15</sparkle:minimumSystemVersion>\n            <enclosure url=\"https://github.com/ObuchiYuki/DevToysMac/releases/download/0.0.10/DevToys.app.zip\" length=\"35046183\" type=\"application/octet-stream\" sparkle:edSignature=\"eqiRWLDsRqAPnmDrP257FW/JgzxAdOPXc/GjqcYM41pC56ke+2b3cSLgXxDcxUPO/yms649m2GNKId+E6ZDbDQ==\"/>\n        </item>\n    </channel>\n</rss>"
  }
]