From 4d3b2b4f73980d60008d2995ebd6f98deedef25f Mon Sep 17 00:00:00 2001 From: LinusS1 Date: Sat, 14 Aug 2021 18:06:28 -0700 Subject: [PATCH] Finish everything else --- .gitignore | 4 +- KettleCornService/KettleCornSerivce.plist | 15 + .../KettleCornService.entitlements | 8 + KettleCornService/KettleCornService.swift | 81 ++ .../KettleCornServiceDelegate.swift | 19 + .../KettleCornServiceProtocol.swift | 16 + KettleCornService/main.swift | 14 + KeyPopper Catcher/AppDelegate.swift | 61 ++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 58 ++ .../Assets.xcassets/Contents.json | 6 + KeyPopper Catcher/Base.lproj/Main.storyboard | 684 +++++++++++++ .../KeyPopper Catcher.entitlements | 8 + .../KeyPopper-Catcher-Info.plist | 8 + KeyPopper Catcher/KeyPopperCatcher.plist | 20 + KeyPopper Installer/KeyPopper.pkgproj | 966 ++++++++++++++++++ KeyPopper Installer/install.sh | 5 + KeyPopper Installer/license.rtf | 111 ++ KeyPopper Installer/readme.rtf | 129 +++ KeyPopper.xcodeproj/project.pbxproj | 567 +++++++++- .../xcschemes/KeyPopper Catcher.xcscheme | 78 ++ .../xcschemes/KeyPopper PrefPane.xcscheme | 9 + .../xcschemes/PoppingService.xcscheme | 78 ++ PoppingService/PoppingService.entitlements | 8 + PoppingService/PoppingService.plist | 15 + PoppingService/PoppingService.swift | 50 + PoppingService/PoppingServiceDelegate.swift | 19 + PoppingService/PoppingServiceProtocol.swift | 14 + PoppingService/frog.mp3 | Bin 0 -> 5706 bytes PoppingService/main.swift | 14 + PoppingService/moo.mp3 | Bin 0 -> 35799 bytes PoppingService/pop.mp3 | Bin 0 -> 7174 bytes PrefPane/Info.plist | 4 + PrefPane/KeyPopperPrefPane.swift | 83 +- .../KeyPopperPreferencesTerms.searchTerms | 35 + PrefPane/PoppingSounds.swift | 17 + PrefPane/PrefPane.tiff | 0 37 files changed, 3200 insertions(+), 15 deletions(-) create mode 100644 KettleCornService/KettleCornSerivce.plist create mode 100644 KettleCornService/KettleCornService.entitlements create mode 100644 KettleCornService/KettleCornService.swift create mode 100644 KettleCornService/KettleCornServiceDelegate.swift create mode 100644 KettleCornService/KettleCornServiceProtocol.swift create mode 100644 KettleCornService/main.swift create mode 100644 KeyPopper Catcher/AppDelegate.swift create mode 100644 KeyPopper Catcher/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 KeyPopper Catcher/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 KeyPopper Catcher/Assets.xcassets/Contents.json create mode 100644 KeyPopper Catcher/Base.lproj/Main.storyboard create mode 100644 KeyPopper Catcher/KeyPopper Catcher.entitlements create mode 100644 KeyPopper Catcher/KeyPopper-Catcher-Info.plist create mode 100644 KeyPopper Catcher/KeyPopperCatcher.plist create mode 100644 KeyPopper Installer/KeyPopper.pkgproj create mode 100755 KeyPopper Installer/install.sh create mode 100644 KeyPopper Installer/license.rtf create mode 100644 KeyPopper Installer/readme.rtf create mode 100644 KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper Catcher.xcscheme create mode 100644 KeyPopper.xcodeproj/xcshareddata/xcschemes/PoppingService.xcscheme create mode 100644 PoppingService/PoppingService.entitlements create mode 100644 PoppingService/PoppingService.plist create mode 100644 PoppingService/PoppingService.swift create mode 100644 PoppingService/PoppingServiceDelegate.swift create mode 100644 PoppingService/PoppingServiceProtocol.swift create mode 100644 PoppingService/frog.mp3 create mode 100644 PoppingService/main.swift create mode 100644 PoppingService/moo.mp3 create mode 100644 PoppingService/pop.mp3 create mode 100644 PrefPane/KeyPopperPreferencesTerms.searchTerms create mode 100644 PrefPane/PoppingSounds.swift delete mode 100644 PrefPane/PrefPane.tiff diff --git a/.gitignore b/.gitignore index 0c419d5..e9539b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .DS_Store -KeyPopper.xcodeproj/project.xcworkspace/xcuserdata \ No newline at end of file +KeyPopper.xcodeproj/project.xcworkspace/xcuserdata +/KeyPopper Installer/build +KeyPopper.xcodeproj/xcuserdata/ diff --git a/KettleCornService/KettleCornSerivce.plist b/KettleCornService/KettleCornSerivce.plist new file mode 100644 index 0000000..863b987 --- /dev/null +++ b/KettleCornService/KettleCornSerivce.plist @@ -0,0 +1,15 @@ + + + + + Label + sh.linus.keypopper.KettleCornSerivce + Program + /Library/PreferencePanes/KeyPopper\ PrefPane.prefPane/Contents/XPCServices/KettleCornService + MachServices + + sh.linus.keypopper.KettleCornService.mach + + + + diff --git a/KettleCornService/KettleCornService.entitlements b/KettleCornService/KettleCornService.entitlements new file mode 100644 index 0000000..49ad0bb --- /dev/null +++ b/KettleCornService/KettleCornService.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.automation.apple-events + + + diff --git a/KettleCornService/KettleCornService.swift b/KettleCornService/KettleCornService.swift new file mode 100644 index 0000000..7831596 --- /dev/null +++ b/KettleCornService/KettleCornService.swift @@ -0,0 +1,81 @@ +// +// KettleCornService.swift +// KettleCornService +// +// Created by Linus Skucas on 8/3/21. +// + +import Foundation + +struct SoundState { + private let userDefaults = UserDefaults.init(suiteName: "sh.linus.keypopper")! + + var sound: PoppingSounds { + get { + let soundInt = userDefaults.integer(forKey: "sound") + let sound = PoppingSounds(rawValue: soundInt)! + return sound + } + set { + userDefaults.set(newValue.rawValue, forKey: "sound") + } + } + var enabled: Bool { + get { + let enabled = userDefaults.bool(forKey: "enabled") + return enabled + } + set { + userDefaults.set(newValue, forKey: "enabled") + } + } + static var shared: SoundState = SoundState() +} + +@objc class KettleCornService: NSObject, KettleCornServiceProtocol { +// func hello(_ text: String, withReply reply: @escaping (String) -> Void) { +// reply("Hello, \(text)!") +// } + + var connection: NSXPCConnection! + var service: PoppingServiceProtocol! + + override init() { + super.init() + connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.PoppingService.mach") + connection.remoteObjectInterface = NSXPCInterface(with: PoppingServiceProtocol.self) + connection.resume() + + service = connection.remoteObjectProxyWithErrorHandler { error in + fatalError("Error: \(error.localizedDescription)") + } as! PoppingServiceProtocol + } + + func changeSoundTo(_ soundInt: Int) { + let sound = PoppingSounds(rawValue: soundInt)! + // Store sound + NSLog("Change sound") + SoundState.shared.sound = sound + } + + func changeSoundState(shouldPlaySound: Bool) { + NSLog("Change state") + SoundState.shared.enabled = shouldPlaySound + } + + func boop() { + guard SoundState.shared.enabled else { return } + + switch SoundState.shared.sound { + case .pop: + service.pop() + NSLog("POP") + case .frog: + service.frog() + NSLog("Frog") + case .moo: + service.moo() + NSLog("Moo") + } + } +} diff --git a/KettleCornService/KettleCornServiceDelegate.swift b/KettleCornService/KettleCornServiceDelegate.swift new file mode 100644 index 0000000..8bd6302 --- /dev/null +++ b/KettleCornService/KettleCornServiceDelegate.swift @@ -0,0 +1,19 @@ +// +// KettleCornServiceDelegate.swift +// KettleCornService +// +// Created by Linus Skucas on 8/3/21. +// + +import Foundation + +class KettleCornServiceDelegate: NSObject, NSXPCListenerDelegate { + func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { + let exportedObject = KettleCornService() + newConnection.exportedInterface = NSXPCInterface(with: KettleCornServiceProtocol.self) + newConnection.exportedObject = exportedObject + + newConnection.resume() + return true + } +} diff --git a/KettleCornService/KettleCornServiceProtocol.swift b/KettleCornService/KettleCornServiceProtocol.swift new file mode 100644 index 0000000..1c3ee1a --- /dev/null +++ b/KettleCornService/KettleCornServiceProtocol.swift @@ -0,0 +1,16 @@ +// +// KettleCornServiceProtocol.swift +// KettleCornService +// +// Created by Linus Skucas on 8/3/21. +// + +import Foundation + +@objc(KettleCornServiceProtocol) protocol KettleCornServiceProtocol { +// func hello(_ text: String, withReply reply: @escaping (String) -> Void) + func changeSoundTo(_ soundInt: Int) + func changeSoundState(shouldPlaySound: Bool) + func boop() +} + diff --git a/KettleCornService/main.swift b/KettleCornService/main.swift new file mode 100644 index 0000000..8ac4c08 --- /dev/null +++ b/KettleCornService/main.swift @@ -0,0 +1,14 @@ +// +// main.swift +// KettleCornService +// +// Created by Linus Skucas on 8/3/21. +// + +import Foundation + +let delegate = KettleCornServiceDelegate() +let listener = NSXPCListener(machServiceName: "sh.linus.keypopper.KettleCornService.mach") +listener.delegate = delegate +listener.resume() +RunLoop.main.run() diff --git a/KeyPopper Catcher/AppDelegate.swift b/KeyPopper Catcher/AppDelegate.swift new file mode 100644 index 0000000..1bc922d --- /dev/null +++ b/KeyPopper Catcher/AppDelegate.swift @@ -0,0 +1,61 @@ +// +// AppDelegate.swift +// KeyPopper Catcher +// +// Created by Linus Skucas on 8/13/21. +// + +import Cocoa + +@main +class AppDelegate: NSObject, NSApplicationDelegate { + +// var connection: NSXPCConnection! +// var service: KettleCornServiceProtocol! + + func applicationDidFinishLaunching(_ aNotification: Notification) { + // Insert code here to initialize your application + +// connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.KettleCornService.mach") +// connection.remoteObjectInterface = NSXPCInterface(with: KettleCornServiceProtocol.self) +// connection.resume() +// +// service = connection.remoteObjectProxyWithErrorHandler { error in +// fatalError("Error: \(error.localizedDescription)") +// } as! KettleCornServiceProtocol + + let eventMask = (1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.keyUp.rawValue) + NSLog("gggp") + func cgEventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged? { + let connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.KettleCornService.mach") + connection.remoteObjectInterface = NSXPCInterface(with: KettleCornServiceProtocol.self) + connection.resume() + + let service = connection.remoteObjectProxyWithErrorHandler { error in + fatalError("Error: \(error.localizedDescription)") + } as! KettleCornServiceProtocol + service.boop() + return nil + } + + guard let eventTap = CGEvent.tapCreate(tap: .cgAnnotatedSessionEventTap, place: .headInsertEventTap, options: .listenOnly, eventsOfInterest: CGEventMask(eventMask), callback: cgEventCallback, userInfo: nil) else { + DispatchQueue.main.async { + NSLog("faileddddddddd") + } + return + } + let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0) + CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) + CGEvent.tapEnable(tap: eventTap, enable: true) + CFRunLoopRun() + } + + func applicationWillTerminate(_ aNotification: Notification) { + // Insert code here to tear down your application +// connection.invalidate() + } + + func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } +} diff --git a/KeyPopper Catcher/Assets.xcassets/AccentColor.colorset/Contents.json b/KeyPopper Catcher/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/KeyPopper Catcher/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KeyPopper Catcher/Assets.xcassets/AppIcon.appiconset/Contents.json b/KeyPopper Catcher/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..3f00db4 --- /dev/null +++ b/KeyPopper Catcher/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KeyPopper Catcher/Assets.xcassets/Contents.json b/KeyPopper Catcher/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/KeyPopper Catcher/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KeyPopper Catcher/Base.lproj/Main.storyboard b/KeyPopper Catcher/Base.lproj/Main.storyboard new file mode 100644 index 0000000..d79679d --- /dev/null +++ b/KeyPopper Catcher/Base.lproj/Main.storyboard @@ -0,0 +1,684 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeyPopper Catcher/KeyPopper Catcher.entitlements b/KeyPopper Catcher/KeyPopper Catcher.entitlements new file mode 100644 index 0000000..49ad0bb --- /dev/null +++ b/KeyPopper Catcher/KeyPopper Catcher.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.automation.apple-events + + + diff --git a/KeyPopper Catcher/KeyPopper-Catcher-Info.plist b/KeyPopper Catcher/KeyPopper-Catcher-Info.plist new file mode 100644 index 0000000..6f7ae58 --- /dev/null +++ b/KeyPopper Catcher/KeyPopper-Catcher-Info.plist @@ -0,0 +1,8 @@ + + + + + LSUIElement + + + diff --git a/KeyPopper Catcher/KeyPopperCatcher.plist b/KeyPopper Catcher/KeyPopperCatcher.plist new file mode 100644 index 0000000..a7cb74d --- /dev/null +++ b/KeyPopper Catcher/KeyPopperCatcher.plist @@ -0,0 +1,20 @@ + + + + + ProgramArguments + + /usr/bin/open + -W + /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/SharedSupport/KeyPopper Catcher.app + + KeepAlive + + Label + sh.linus.keypopper.KeyPopper-Catcher + LimitLoadToSessionType + Aqua + RunAtLoad + + + diff --git a/KeyPopper Installer/KeyPopper.pkgproj b/KeyPopper Installer/KeyPopper.pkgproj new file mode 100644 index 0000000..8d53697 --- /dev/null +++ b/KeyPopper Installer/KeyPopper.pkgproj @@ -0,0 +1,966 @@ + + + + + PACKAGES + + + MUST-CLOSE-APPLICATION-ITEMS + + + APPLICATION_ID + com.apple.systempreferences + STATE + + + + MUST-CLOSE-APPLICATIONS + + PACKAGE_FILES + + DEFAULT_INSTALL_LOCATION + / + HIERARCHY + + CHILDREN + + + CHILDREN + + GID + 80 + PATH + Applications + PATH_TYPE + 0 + PERMISSIONS + 509 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 80 + PATH + Application Support + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Automator + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Documentation + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Extensions + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Filesystems + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Frameworks + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Input Methods + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Internet Plug-Ins + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + /Users/linus/Sources/KeyPopper/KettleCornService/KettleCornSerivce.plist + PATH_TYPE + 0 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + /Users/linus/Sources/KeyPopper/KeyPopper Catcher/KeyPopperCatcher.plist + PATH_TYPE + 0 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + /Users/linus/Sources/KeyPopper/PoppingService/PoppingService.plist + PATH_TYPE + 0 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + GID + 0 + PATH + LaunchAgents + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + LaunchDaemons + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + BUNDLE_CAN_DOWNGRADE + + BUNDLE_POSTINSTALL_PATH + + PATH_TYPE + 0 + + BUNDLE_PREINSTALL_PATH + + PATH_TYPE + 0 + + CHILDREN + + GID + 0 + PATH + /Users/linus/Sources/App Release/KeyPopper PrefPane 2021-08-14 16-29-03/Products/Users/linus/Library/PreferencePanes/KeyPopper PrefPane.prefPane + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + GID + 0 + PATH + PreferencePanes + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Preferences + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 80 + PATH + Printers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + PrivilegedHelperTools + PATH_TYPE + 0 + PERMISSIONS + 1005 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickLook + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickTime + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Screen Savers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Scripts + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Services + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Widgets + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + Library + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + Shared + PATH_TYPE + 0 + PERMISSIONS + 1023 + TYPE + 1 + UID + 0 + + + GID + 80 + PATH + Users + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + / + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + PAYLOAD_TYPE + 0 + PRESERVE_EXTENDED_ATTRIBUTES + + SHOW_INVISIBLE + + SPLIT_FORKS + + TREAT_MISSING_FILES_AS_WARNING + + VERSION + 5 + + PACKAGE_SCRIPTS + + POSTINSTALL_PATH + + PATH + /Users/linus/Sources/KeyPopper/KeyPopper Installer/install.sh + PATH_TYPE + 0 + + PREINSTALL_PATH + + PATH_TYPE + 0 + + RESOURCES + + + PACKAGE_SETTINGS + + AUTHENTICATION + 0 + CONCLUSION_ACTION + 0 + FOLLOW_SYMBOLIC_LINKS + + IDENTIFIER + sh.linus.keypopper.installer + LOCATION + 0 + NAME + KeyPopper + OVERWRITE_PERMISSIONS + + PAYLOAD_SIZE + -1 + REFERENCE_PATH + + RELOCATABLE + + USE_HFS+_COMPRESSION + + VERSION + 1.0 + + TYPE + 0 + UUID + 8257C519-F2B7-47D3-BEAF-DEA802FC82CC + + + PROJECT + + PROJECT_COMMENTS + + NOTES + + + + PROJECT_PRESENTATION + + BACKGROUND + + ALIGNMENT + 6 + APPAREANCES + + DARK_AQUA + + LIGHT_AQUA + + ALIGNMENT + 6 + BACKGROUND_PATH + + PATH + /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/PrefPane.tiff + PATH_TYPE + 0 + + CUSTOM + + LAYOUT_DIRECTION + 1 + SCALING + 0 + + + BACKGROUND_PATH + + PATH + /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/PrefPane.tiff + PATH_TYPE + 0 + + CUSTOM + + LAYOUT_DIRECTION + 1 + SCALING + 0 + SHARED_SETTINGS_FOR_ALL_APPAREANCES + + + INSTALLATION_STEPS + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewIntroductionController + INSTALLER_PLUGIN + Introduction + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewReadMeController + INSTALLER_PLUGIN + ReadMe + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewLicenseController + INSTALLER_PLUGIN + License + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewDestinationSelectController + INSTALLER_PLUGIN + TargetSelect + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationTypeController + INSTALLER_PLUGIN + PackageSelection + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationController + INSTALLER_PLUGIN + Install + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewSummaryController + INSTALLER_PLUGIN + Summary + LIST_TITLE_KEY + InstallerSectionTitle + + + INTRODUCTION + + LOCALIZATIONS + + + LICENSE + + LOCALIZATIONS + + + LANGUAGE + English + VALUE + + PATH + /Users/linus/Sources/KeyPopper/KeyPopper Installer/license.rtf + PATH_TYPE + 0 + + + + MODE + 0 + + README + + LOCALIZATIONS + + + LANGUAGE + English + VALUE + + PATH + /Users/linus/Sources/KeyPopper/KeyPopper Installer/readme.rtf + PATH_TYPE + 0 + + + + + TITLE + + LOCALIZATIONS + + + LANGUAGE + English + VALUE + KeyPopper + + + + + PROJECT_REQUIREMENTS + + LIST + + + BEHAVIOR + 3 + DICTIONARY + + IC_REQUIREMENT_OS_DISK_TYPE + 0 + IC_REQUIREMENT_OS_DISTRIBUTION_TYPE + 0 + IC_REQUIREMENT_OS_MINIMUM_VERSION + 101500 + + IC_REQUIREMENT_CHECK_TYPE + 1 + IDENTIFIER + fr.whitebox.Packages.requirement.os + MESSAGE + + + LANGUAGE + English + VALUE + This volume is too old. + + + NAME + Operating System + STATE + + + + RESOURCES + + ROOT_VOLUME_ONLY + + + PROJECT_SETTINGS + + BUILD_FORMAT + 0 + BUILD_PATH + + PATH + build + PATH_TYPE + 1 + + EXCLUDED_FILES + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .DS_Store + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .DS_Store files + PROXY_TOOLTIP + Remove ".DS_Store" files created by the Finder. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .pbdevelopment + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .pbdevelopment files + PROXY_TOOLTIP + Remove ".pbdevelopment" files created by ProjectBuilder or Xcode. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + CVS + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .cvsignore + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .cvspass + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .svn + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .git + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .gitignore + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove SCM metadata + PROXY_TOOLTIP + Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + classes.nib + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + designable.db + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + info.nib + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Optimize nib files + PROXY_TOOLTIP + Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + Resources Disabled + TYPE + 1 + + + PROTECTED + + PROXY_NAME + Remove Resources Disabled folders + PROXY_TOOLTIP + Remove "Resources Disabled" folders. + STATE + + + + SEPARATOR + + + + NAME + KeyPopper + PAYLOAD_ONLY + + TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING + + + + TYPE + 0 + VERSION + 2 + + diff --git a/KeyPopper Installer/install.sh b/KeyPopper Installer/install.sh new file mode 100755 index 0000000..5337f09 --- /dev/null +++ b/KeyPopper Installer/install.sh @@ -0,0 +1,5 @@ +launchctl load /Library/LaunchAgents/KettleCornSerivce.plist +launchctl load /Library/LaunchAgents/PoppingService.plist +launchctl load /Library/LaunchAgents/KeyPopperCatcher.plist + +open "/Library/PreferencePanes/KeyPopper PrefPane.prefPane" \ No newline at end of file diff --git a/KeyPopper Installer/license.rtf b/KeyPopper Installer/license.rtf new file mode 100644 index 0000000..00c74f9 --- /dev/null +++ b/KeyPopper Installer/license.rtf @@ -0,0 +1,111 @@ +{\rtf1\mac\ansicpg10000\cocoartf\nisusversion50201\nisusorigversion50201 {\*\nisusorigdate\yr2021\mo8\dy14\hr17\min34 }{\*\nisussysvers 11.5.0}{\*\nisusorigsysvers 11.5.0}\deff0 +{\*\fonttbl +{\f0\fswiss\fcharset77 SFPro-Regular{\*\falt SF Pro};} +{\f1\fnil\fcharset77 Tahoma-Bold{\*\falt Tahoma};} +{\f2\fswiss\fcharset77 Tahoma;}} +{\colortbl ;\red0\green0\blue0 ;}\nisusrevtypes0\donotshowinsdel1 +{\*\nisustoctable +{\nisustoc\tcf68 {\nisustocname Default TOC}{\*\nisustoctabrep }{\*\nisustocretrep }{\nisustoclevelstyle TOC 1}{\nisustoclevelstyle TOC 2}{\nisustoclevelstyle TOC 3}{\nisustoclevelstyle TOC 4}{\nisustoclevelstyle TOC 5}{\nisustoclevelstyle TOC 6}{\nisustoclevelstyle TOC 7}{\nisustoclevelstyle TOC 8}{\nisustoclevelstyle TOC 9}}\nisusactivetoc68 } +{\*\nisusxetable +{\nisusxe\xef68 {\nisusxename Default Index}{\nisusxeheaderstyle Index Heading}{\nisusxelevelstyle Index 1}{\nisusxelevelstyle Index 2}{\nisusxelevelstyle Index 3}{\nisusxelevelstyle Index 4}{\nisusxelevelstyle Index 5}{\nisusxelevelstyle Index 6}{\nisusxelevelstyle Index 7}{\nisusxelevelstyle Index 8}{\nisusxelevelstyle Index 9}{\*\fldinst INDEX \\k ". " \\g \endash \\e "\tab " \\l ", " \\f D}}\nisusactivexe68 } +{\stylesheet +{\s106\snext106\f0 \ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Normal;} +{\s107\snext106\sbasedon106\f1\fs28\b \ltrpar\pardirnatural\qc\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Title;} +{\s108\nisusnoteplacement2\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle120\nisusnotedocstyletarget1\nisusnoterefstyle121 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Endnote;} +{\s109\nisusnoteplacement0\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle120\nisusnotedocstyletarget1\nisusnoterefstyle121 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\nowidctlpar\keep0\keepn0\pagebb0\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footnote;} +{\s110\snext106\sbasedon106\f1\fs28\b \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl1 Heading 1;} +{\s111\snext106\sbasedon110\f1\fs26\b\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl2 Heading 2;} +{\s112\snext106\sbasedon111\f1\fs26\b\i \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl3 Heading 3;} +{\s113\snext106\sbasedon112\f2\fs26\b0\i0\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl4 Heading 4;} +{\s114\snext106\sbasedon113\f2\fs26\b0\i0\ul \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl5 Heading 5;} +{\s115\snext106\sbasedon114\f2\fs26\b0\i\ul\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl6 Heading 6;} +{\s116\snext116\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Header;} +{\s117\snext117\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footer;} +{\s118\snext118\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li1080\lin1080\fi0\ri1020\rin1020 Block Quote;} +{\*\cs119\b Strong;} +{\*\cs120\super Note Reference;} +{\*\cs121\sbasedon120\nosupersub Note Reference in Note;} +{\*\cs122\i Emphatic;}} +{\*\listtable +{\list\listhybrid {\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li648\lin648\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1008\lin1008\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1368\lin1368\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1728\lin1728\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2088\lin2088\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2448\lin2448\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2808\lin2808\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3168\lin3168\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3528\lin3528\fi-360\ri0\rin0 } +{\listname ;}\listid88001\nisuslistcontnum0 {\*\liststylename Bullet List;}} +{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li576\lin576\fi-576\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li796\lin796\fi-796\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1016\lin1016\fi-1016\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1236\lin1236\fi-1236\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1456\lin1456\fi-1456\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1676\lin1676\fi-1676\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1896\lin1896\fi-1896\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2116\lin2116\fi-2116\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2336\lin2336\fi-2336\ri0\rin0 } +{\listname ;}\listid88002\nisuslistcontnum1 {\*\liststylename Headings;}} +{\list\listhybrid {\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1008\lin1008\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1368\lin1368\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1728\lin1728\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2088\lin2088\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2448\lin2448\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2808\lin2808\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3168\lin3168\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3528\lin3528\fi-360\ri0\rin0 } +{\listname ;}\listid88003\nisuslistcontnum0 {\*\liststylename Lettered List;}} +{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li720\lin720\fi-432\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1080\lin1080\fi-430\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1440\lin1440\fi-430\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1800\lin1800\fi-430\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2160\lin2160\fi-430\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2520\lin2520\fi-430\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2880\lin2880\fi-430\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3240\lin3240\fi-432\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3600\lin3600\fi-432\ri0\rin0 } +{\listname ;}\listid88004\nisuslistcontnum0 {\*\liststylename Number List;}} +{\list\listhybrid {\listlevel\levelnfc1\levelnfcn1\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li360\lin360\fi-360\ri0\rin0 } +{\listlevel\levelnfc3\levelnfcn3\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li720\lin720\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1080\lin1080\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'03);}{\levelnumbers \'01;}\li1440\lin1440\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li1800\lin1800\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2160\lin2160\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'06);}{\levelnumbers \'02;}\li2520\lin2520\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'07);}{\levelnumbers \'02;}\li2880\lin2880\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'08);}{\levelnumbers \'02;}\li3240\lin3240\fi-360\ri0\rin0 } +{\listname ;}\listid88005\nisuslistcontnum0 {\*\liststylename Outline;}} +{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-648\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li868\lin868\fi-868\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1088\lin1088\fi-1088\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1308\lin1308\fi-1308\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1528\lin1528\fi-1528\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1748\lin1748\fi-1748\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1968\lin1968\fi-1968\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2188\lin2188\fi-2188\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2408\lin2408\fi-2408\ri0\rin0 } +{\listname ;}\listid88006\nisuslistcontnum0 {\*\liststylename Tiered List;}}} +{\*\listoverridetable +{\listoverride\listid88001\listoverridecount0\ls1 } +{\listoverride\listid88002\listoverridecount0\ls2 } +{\listoverride\listid88003\listoverridecount0\ls3 } +{\listoverride\listid88004\listoverridecount0\ls4 } +{\listoverride\listid88005\listoverridecount0\ls5 } +{\listoverride\listid88006\listoverridecount0\ls6 }} +\defformat {\info {\*\nisusgmtoffset -7:00}{\author Linus Skucas}{\creatim\yr2021\mo8\dy14\hr17\min34 }{\revtim\yr2021\mo8\dy14\hr17\min35 }\nofpages1 }{\*\userprops }\nisusrulerunits0\nisusstatusbar1\nisusareaid1\viewkind1\viewzk1\nisusviewruler1\nisusviewrulerh1\nisusviewrulerv0\nisusviewtoolbar1\nisusviewtooldrawer1\nisusviewtoolswidth250\nisusviewpagenumtype1\nisusviewrulericons0\donotshowcomments1 +{\*\nisusviewsettings\viewkind4\viewscale125 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\viewkind1\viewzk1 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}{\*\closedtochandles }}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\nisusviewknew102\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\nisusviewknew103\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\nisusviewknew104\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +\nisusareasplitv0 +{\*\nisuswindow\x63\y1006\w1074\actualw1324\h864 } +\nshwinv0\nshwpg1\nisusinlinespell1\nisushyphnone\spltpgpar\nisusselectstart102\nisusselectlength0\ftnstart1\ftnnar\aftnstart1\aftnnar\aenddoc\fet2\ftnbj\paperw12240\paperh15840\margl1440\margr1440\margt1800\margb1800\gutter0\pgnstart1\nocolbal\widowctrl \f0 +\sectd\endnhere\sftnnar\saftnnar\cols1\ltrsect\colbalsxn0\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1800\margbsxn1800\guttersxn0\headery720\footery720\pgnstarts1\pgnrestart\pgndec\sxnstarts1\sxnrestart\sxndec +{\header\plain\pard\s116\ltrpar\pardirnatural\ql\f0\fs24 } +{\footer\plain\pard\s117\ltrpar\pardirnatural\ql\f0\fs24 } +\deftab720 {\*\nisusscroll\nisusarea1\xoffset0\yoffset95 }{\pard\s106\ltrpar\pardirnatural\ql {By using KeyPopper you agree not to sue or take me to court for anything.\par +\par +Thanks for using KeyPopper!\nisusselectcaret\par }}} \ No newline at end of file diff --git a/KeyPopper Installer/readme.rtf b/KeyPopper Installer/readme.rtf new file mode 100644 index 0000000..119805d --- /dev/null +++ b/KeyPopper Installer/readme.rtf @@ -0,0 +1,129 @@ +{\rtf1\mac\ansicpg10000\cocoartf\nisusversion50201\nisusorigversion50201 {\*\nisusorigdate\yr2021\mo8\dy14\hr17\min23 }{\*\nisussysvers 11.5.0}{\*\nisusorigsysvers 11.5.0}\deff0 +{\*\fonttbl +{\f0\fswiss\fcharset77 SFPro-Regular{\*\falt SF Pro};} +{\f1\fswiss\fcharset77 SFPro-Bold{\*\falt SF Pro};} +{\f2\fnil\fcharset77 Tahoma-Bold{\*\falt Tahoma};} +{\f3\fswiss\fcharset77 Tahoma;}} +{\colortbl ;\red0\green0\blue0 ;\red252\green128\blue8 ;}\nisusrevtypes0\donotshowinsdel1 +{\*\nisustoctable +{\nisustoc\tcf68 {\nisustocname Default TOC}{\*\nisustoctabrep }{\*\nisustocretrep }{\nisustoclevelstyle TOC 1}{\nisustoclevelstyle TOC 2}{\nisustoclevelstyle TOC 3}{\nisustoclevelstyle TOC 4}{\nisustoclevelstyle TOC 5}{\nisustoclevelstyle TOC 6}{\nisustoclevelstyle TOC 7}{\nisustoclevelstyle TOC 8}{\nisustoclevelstyle TOC 9}}\nisusactivetoc68 } +{\*\nisusxetable +{\nisusxe\xef68 {\nisusxename Default Index}{\nisusxeheaderstyle Index Heading}{\nisusxelevelstyle Index 1}{\nisusxelevelstyle Index 2}{\nisusxelevelstyle Index 3}{\nisusxelevelstyle Index 4}{\nisusxelevelstyle Index 5}{\nisusxelevelstyle Index 6}{\nisusxelevelstyle Index 7}{\nisusxelevelstyle Index 8}{\nisusxelevelstyle Index 9}{\*\fldinst INDEX \\k ". " \\g \endash \\e "\tab " \\l ", " \\f D}}\nisusactivexe68 } +{\stylesheet +{\s106\snext106\f0 \ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Normal;} +{\s107\snext107\sbasedon106\f0\ltrpar\pardirnatural\qc\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Table Cell;} +{\s108\snext106\sbasedon106\f2\fs28\b \ltrpar\pardirnatural\qc\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Title;} +{\s109\nisusnoteplacement2\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle121\nisusnotedocstyletarget1\nisusnoterefstyle122 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Endnote;} +{\s110\nisusnoteplacement0\nisusnotespanheight1300\nisusnotespanlines5\nisusnotedocrefstyle121\nisusnotedocstyletarget1\nisusnoterefstyle122 {\*\nisusnoterefafter .\'ca}\nisusnotestyletarget2\nisusnotegutterh60 {\*\nisusnotedefaulttext }\nisusnotedivalign2\nisusnotedivpercent25\nisusnotedivoverpercent75 {\*\nisusnotedivstyle\nisusbrdredge\brdrs\brdrw20\brdrcf1 }\sbasedon106\f0\ltrpar\pardirnatural\ql\nowidctlpar\keep0\keepn0\pagebb0\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footnote;} +{\s111\snext106\sbasedon106\f2\fs28\b \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl1 Heading 1;} +{\s112\snext106\sbasedon111\f2\fs26\b\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl2 Heading 2;} +{\s113\snext106\sbasedon112\f2\fs26\b\i \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl3 Heading 3;} +{\s114\snext106\sbasedon113\f3\fs26\b0\i0\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl4 Heading 4;} +{\s115\snext106\sbasedon114\f3\fs26\b0\i0\ul \ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl5 Heading 5;} +{\s116\snext106\sbasedon115\f3\fs26\b0\i\ul\ltrpar\pardirnatural\ql\widctlpar\keepn\sb120\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0\tcf68\tcl6 Heading 6;} +{\s117\snext117\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Header;} +{\s118\snext118\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li0\lin0\fi0\ri0\rin0 Footer;} +{\s119\snext119\sbasedon106\f0\ltrpar\pardirnatural\ql\widctlpar\sb0\sa0\sl240\slmult1\hyphpar1\li1080\lin1080\fi0\ri1020\rin1020 Block Quote;} +{\*\cs120\b Strong;} +{\*\cs121\super Note Reference;} +{\*\cs122\sbasedon121\nosupersub Note Reference in Note;} +{\*\cs123\i Emphatic;}} +{\*\listtable +{\list\listhybrid {\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li648\lin648\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1008\lin1008\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1368\lin1368\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li1728\lin1728\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2088\lin2088\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2448\lin2448\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li2808\lin2808\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3168\lin3168\fi-360\ri0\rin0 } +{\listlevel\levelnfc23\levelnfcn23\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'01\u8226 ?;}{\levelnumbers ;}\li3528\lin3528\fi-360\ri0\rin0 } +{\listname ;}\listid88001\nisuslistcontnum0 {\*\liststylename Bullet List;}} +{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li576\lin576\fi-576\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li796\lin796\fi-796\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1016\lin1016\fi-1016\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1236\lin1236\fi-1236\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1456\lin1456\fi-1456\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1676\lin1676\fi-1676\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1896\lin1896\fi-1896\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2116\lin2116\fi-2116\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2336\lin2336\fi-2336\ri0\rin0 } +{\listname ;}\listid88002\nisuslistcontnum1 {\*\liststylename Headings;}} +{\list\listhybrid {\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1008\lin1008\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1368\lin1368\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1728\lin1728\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2088\lin2088\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2448\lin2448\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2808\lin2808\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3168\lin3168\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3528\lin3528\fi-360\ri0\rin0 } +{\listname ;}\listid88003\nisuslistcontnum0 {\*\liststylename Lettered List;}} +{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li720\lin720\fi-432\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li1080\lin1080\fi-430\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1440\lin1440\fi-430\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'03);}{\levelnumbers \'02;}\li1800\lin1800\fi-430\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li2160\lin2160\fi-430\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2520\lin2520\fi-430\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'06);}{\levelnumbers \'01;}\li2880\lin2880\fi-430\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'07);}{\levelnumbers \'01;}\li3240\lin3240\fi-432\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'08);}{\levelnumbers \'01;}\li3600\lin3600\fi-432\ri0\rin0 } +{\listname ;}\listid88004\nisuslistcontnum0 {\*\liststylename Number List;}} +{\list\listhybrid {\listlevel\levelnfc1\levelnfcn1\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li360\lin360\fi-360\ri0\rin0 } +{\listlevel\levelnfc3\levelnfcn3\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'01.;}{\levelnumbers \'01;}\li720\lin720\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'02.;}{\levelnumbers \'01;}\li1080\lin1080\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'03);}{\levelnumbers \'01;}\li1440\lin1440\fi-360\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'04);}{\levelnumbers \'02;}\li1800\lin1800\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'05);}{\levelnumbers \'02;}\li2160\lin2160\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'06);}{\levelnumbers \'02;}\li2520\lin2520\fi-360\ri0\rin0 } +{\listlevel\levelnfc4\levelnfcn4\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'07);}{\levelnumbers \'02;}\li2880\lin2880\fi-360\ri0\rin0 } +{\listlevel\levelnfc2\levelnfcn2\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'03(\'08);}{\levelnumbers \'02;}\li3240\lin3240\fi-360\ri0\rin0 } +{\listname ;}\listid88005\nisuslistcontnum0 {\*\liststylename Outline;}} +{\list\listhybrid {\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'02\'00.;}{\levelnumbers \'01;}\li648\lin648\fi-648\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'04\'00.\'01.;}{\levelnumbers \'01\'03;}\li868\lin868\fi-868\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers \'01\'03\'05;}\li1088\lin1088\fi-1088\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers \'01\'03\'05\'07;}\li1308\lin1308\fi-1308\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers \'01\'03\'05\'07\'09;}\li1528\lin1528\fi-1528\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b;}\li1748\lin1748\fi-1748\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d;}\li1968\lin1968\fi-1968\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f;}\li2188\lin2188\fi-2188\ri0\rin0 } +{\listlevel\levelnfc0\levelnfcn0\leveljcn0\levelfollow0\levelstartat1\nisuslevelnuminc1\levelspace0\levelindent0 {\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers \'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\li2408\lin2408\fi-2408\ri0\rin0 } +{\listname ;}\listid88006\nisuslistcontnum0 {\*\liststylename Tiered List;}}} +{\*\listoverridetable +{\listoverride\listid88001\listoverridecount1 {\lfolevel\listoverridestartat\levelstartat1\nisuslistsoftoverridestartat }\ls1 } +{\listoverride\listid88001\listoverridecount0\ls2 } +{\listoverride\listid88002\listoverridecount0\ls3 } +{\listoverride\listid88003\listoverridecount0\ls4 } +{\listoverride\listid88004\listoverridecount0\ls5 } +{\listoverride\listid88005\listoverridecount0\ls6 } +{\listoverride\listid88006\listoverridecount0\ls7 }} +\defformat {\info {\*\nisusgmtoffset -7:00}{\author Linus Skucas}{\creatim\yr2021\mo8\dy14\hr17\min23 }{\revtim\yr2021\mo8\dy14\hr17\min34 }\nofpages1 }{\*\userprops }\nisusrulerunits0\nisusstatusbar1\nisusareaid1\viewkind1\viewzk1\nisusviewruler1\nisusviewrulerh1\nisusviewrulerv0\nisusviewtoolbar1\nisusviewtooldrawer1\nisusviewtoolswidth250\nisusviewpagenumtype1\nisusviewrulericons0\donotshowcomments1 +{\*\nisusviewsettings\viewkind4\viewscale125 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\viewkind1\viewzk1 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}{\*\closedtochandles }}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\nisusviewknew102\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\nisusviewknew103\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +{\*\nisusviewsettings\nisusviewknew104\viewscale100 {\nisusnavsettings {\*\visible 0}{\*\width 160}{\*\isOnRightSide 0}{\*\mode toc}{\*\sort location}}{\nisuscommentsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 0}{\*\width 180}{\*\titlebarInfo 2}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}{\nisusrevisionsettings {\*\visible 0}{\*\showPane 1}{\*\isOnRightSide 1}{\*\width 180}{\*\titlebarInfo 4}{\*\showTextHighlighting 1}{\*\showGutterIcons 1}}} +\nisusareasplitv0 +{\*\nisuswindow\x63\y1034\w1074\actualw1324\h864 } +\nshwinv0\nshwpg1\nisusinlinespell1\nisushyphnone\spltpgpar\nisusselectstart542\nisusselectlength1\ftnstart1\ftnnar\aftnstart1\aftnnar\aenddoc\fet2\ftnbj\paperw12240\paperh15840\margl1440\margr1440\margt1800\margb1800\gutter0\pgnstart1\nocolbal\widowctrl \f0 +\sectd\endnhere\sftnnar\saftnnar\cols1\ltrsect\colbalsxn0\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1800\margbsxn1800\guttersxn0\headery720\footery720\pgnstarts1\pgnrestart\pgndec\sxnstarts1\sxnrestart\sxndec +{\header\plain\pard\s117\ltrpar\pardirnatural\ql\f0\fs24 } +{\footer\plain\pard\s118\ltrpar\pardirnatural\ql\f0\fs24 } +\deftab720 {\*\nisusscroll\nisusarea1\xoffset0\yoffset95 }{\pard\s106\ltrpar\pardirnatural\ql {Hello!\par +This will install the KeyPopper software on your computer. KeyPopper does not collect, store, or send your keystrokes anywhere.\par +\par +This installation package will install: \par }} +{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {\f1\b\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls1\ilvl0\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {\f1\b 3 Launch Agents}{\par }} +{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {2 are XPC services for communication\par }} +{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {1 is an app which will be launched whenever your system is started.\par }} +{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {The Launch Agents will be loaded, too.\par }} +{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl0\li648\lin648\fi-360\ri0\rin0\tx288\tx648 {1 Preference Pane\par }} +{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {For controlling the sounds.\par }} +{\listtext {\pard\s106\ltrpar\pardirnatural\ql\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {\bullet\tab }}}{\pard\s106\ltrpar\pardirnatural\ql\ls2\ilvl1\li1008\lin1008\fi-360\ri0\rin0\tx648\tx1008 {This preference pane will be opened right after installation.\par }} +{\pard\s106\ltrpar\pardirnatural\ql {\par +If you want to change the sound or turn off the sound, go to the Preference Pane.\par +{\nisusselected1 \par }}} +{\pard\nisusnos\ltrpar\pardirnatural\ql\nisustableprefix0 }\plain\intbl +\trowd\trqc\nisustrhoffset-53\ltrrow\trrh1500\clheight1500\nisustablepadt0\nisustablepadl20\nisustablepadb100\nisustablepadr20\clvertalc\clbrdrt\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\clbrdrb\brdrs\brdrw20\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clftsWidth3\clwWidth8620\cellx8620 +{{\pard\intbl\s106\ltrpar\pardirnatural\qc {\intbl For KeyPopper to work it must monitor your keystrokes. They will not be sent anywhere. After installation you will be prompted that an app called {\f1\b\cf2\intbl KeyPopper Catcher} wants input monitoring permissions. You must give permissions for KeyPopper to work. \cell }}\row } +\pard\plain {\pard\nisusnos\ltrpar\pardirnatural\ql {\par }}} \ No newline at end of file diff --git a/KeyPopper.xcodeproj/project.pbxproj b/KeyPopper.xcodeproj/project.pbxproj index 8d7fa2b..d20d233 100644 --- a/KeyPopper.xcodeproj/project.pbxproj +++ b/KeyPopper.xcodeproj/project.pbxproj @@ -7,20 +7,177 @@ objects = { /* Begin PBXBuildFile section */ - 1587085826B89CC50082DB8F /* PrefPane.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1587085726B89CC50082DB8F /* PrefPane.tiff */; }; + 151BCD9926C8485900F1EA89 /* KeyPopper Catcher.app in Copy Catcher */ = {isa = PBXBuildFile; fileRef = 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 151BCD9E26C853E800F1EA89 /* PrefPane.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 151BCD9D26C853E700F1EA89 /* PrefPane.tiff */; }; + 151BCDAA26C86FBF00F1EA89 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDA926C86FBF00F1EA89 /* main.swift */; }; + 151BCDAF26C86FFD00F1EA89 /* PoppingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDAE26C86FFD00F1EA89 /* PoppingServiceDelegate.swift */; }; + 151BCDB126C8700800F1EA89 /* PoppingServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */; }; + 151BCDB326C8701100F1EA89 /* PoppingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDB226C8701100F1EA89 /* PoppingService.swift */; }; + 151BCDB826C870CD00F1EA89 /* PoppingService in Copy PoppingService */ = {isa = PBXBuildFile; fileRef = 151BCDA726C86FBF00F1EA89 /* PoppingService */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 151BCDC326C874DB00F1EA89 /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC026C874DB00F1EA89 /* AVKit.framework */; }; + 151BCDC426C874DB00F1EA89 /* AVFAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC126C874DB00F1EA89 /* AVFAudio.framework */; }; + 151BCDC526C874DB00F1EA89 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC226C874DB00F1EA89 /* AVFoundation.framework */; }; + 151BCDC726C8765600F1EA89 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 151BCDC626C8765600F1EA89 /* AppKit.framework */; }; + 151BCDC826C8771E00F1EA89 /* PoppingServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */; }; + 151BCDCC26C87E0200F1EA89 /* pop.mp3 in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 151BCDB926C8711000F1EA89 /* pop.mp3 */; }; + 151BCDCD26C87E0200F1EA89 /* moo.mp3 in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 151BCDBC26C873B600F1EA89 /* moo.mp3 */; }; + 151BCDCE26C87E0200F1EA89 /* frog.mp3 in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 151BCDBE26C874C900F1EA89 /* frog.mp3 */; }; + 1525B06A26BA208000A504EB /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B06926BA208000A504EB /* main.swift */; }; + 1525B06F26BA21FF00A504EB /* KettleCornServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B06E26BA21FF00A504EB /* KettleCornServiceDelegate.swift */; }; + 1525B07126BA227700A504EB /* KettleCornServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */; }; + 1525B07326BA22AD00A504EB /* KettleCornService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07226BA22AD00A504EB /* KettleCornService.swift */; }; + 1525B07A26BA27E000A504EB /* KettleCornService in Copy Services to Bundle */ = {isa = PBXBuildFile; fileRef = 1525B06726BA208000A504EB /* KettleCornService */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 154214B626BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms in Resources */ = {isa = PBXBuildFile; fileRef = 154214B526BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms */; }; + 1542150B26C05E02007E4A08 /* PoppingSounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1542150A26C05E02007E4A08 /* PoppingSounds.swift */; }; + 1542150C26C05E02007E4A08 /* PoppingSounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1542150A26C05E02007E4A08 /* PoppingSounds.swift */; }; + 1542150E26C068FF007E4A08 /* KettleCornServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */; }; 1587085B26B89CC50082DB8F /* KeyPopper.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1587085926B89CC50082DB8F /* KeyPopper.xib */; }; 1587086226B8A04B0082DB8F /* KeyPopperPrefPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1587086126B8A04B0082DB8F /* KeyPopperPrefPane.swift */; }; + 15E014B226C7749100A432BD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15E014B126C7749100A432BD /* AppDelegate.swift */; }; + 15E014B626C7749A00A432BD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 15E014B526C7749A00A432BD /* Assets.xcassets */; }; + 15E014B926C7749A00A432BD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 15E014B726C7749A00A432BD /* Main.storyboard */; }; + 15E014BF26C77BAC00A432BD /* KettleCornServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 151BCD9A26C8485F00F1EA89 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1587083126B89C720082DB8F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 15E014AE26C7749100A432BD; + remoteInfo = "KeyPopper Catcher"; + }; + 151BCDB526C870BB00F1EA89 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1587083126B89C720082DB8F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 151BCDA626C86FBF00F1EA89; + remoteInfo = PoppingService; + }; + 1525B07626BA270600A504EB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1587083126B89C720082DB8F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1525B06626BA208000A504EB; + remoteInfo = KettleCornService; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 151BCD9826C8484200F1EA89 /* Copy Catcher */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 12; + files = ( + 151BCD9926C8485900F1EA89 /* KeyPopper Catcher.app in Copy Catcher */, + ); + name = "Copy Catcher"; + runOnlyForDeploymentPostprocessing = 0; + }; + 151BCDB726C870C600F1EA89 /* Copy PoppingService */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 15; + files = ( + 151BCDB826C870CD00F1EA89 /* PoppingService in Copy PoppingService */, + ); + name = "Copy PoppingService"; + runOnlyForDeploymentPostprocessing = 0; + }; + 151BCDCB26C87DE900F1EA89 /* Copy Sounds */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + 151BCDCC26C87E0200F1EA89 /* pop.mp3 in Copy Sounds */, + 151BCDCD26C87E0200F1EA89 /* moo.mp3 in Copy Sounds */, + 151BCDCE26C87E0200F1EA89 /* frog.mp3 in Copy Sounds */, + ); + name = "Copy Sounds"; + runOnlyForDeploymentPostprocessing = 0; + }; + 1525B07926BA27B600A504EB /* Copy Services to Bundle */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; + dstSubfolderSpec = 16; + files = ( + 1525B07A26BA27E000A504EB /* KettleCornService in Copy Services to Bundle */, + ); + name = "Copy Services to Bundle"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ + 151BCD9426C7846000F1EA89 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; + 151BCD9526C7846000F1EA89 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; + 151BCD9D26C853E700F1EA89 /* PrefPane.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = PrefPane.tiff; path = ../../../../../var/folders/zx/4cfp_v_x17ggn7g72zl77sk40000gn/T/632003889/PrefPane.tiff; sourceTree = ""; }; + 151BCDA226C8566700F1EA89 /* KeyPopperCatcher.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = KeyPopperCatcher.plist; sourceTree = ""; }; + 151BCDA726C86FBF00F1EA89 /* PoppingService */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = PoppingService; sourceTree = BUILT_PRODUCTS_DIR; }; + 151BCDA926C86FBF00F1EA89 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 151BCDAE26C86FFD00F1EA89 /* PoppingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingServiceDelegate.swift; sourceTree = ""; }; + 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingServiceProtocol.swift; sourceTree = ""; }; + 151BCDB226C8701100F1EA89 /* PoppingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingService.swift; sourceTree = ""; }; + 151BCDB426C870A200F1EA89 /* PoppingService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PoppingService.entitlements; sourceTree = ""; }; + 151BCDB926C8711000F1EA89 /* pop.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = pop.mp3; sourceTree = ""; }; + 151BCDBC26C873B600F1EA89 /* moo.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = moo.mp3; sourceTree = ""; }; + 151BCDBE26C874C900F1EA89 /* frog.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = frog.mp3; sourceTree = ""; }; + 151BCDC026C874DB00F1EA89 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; + 151BCDC126C874DB00F1EA89 /* AVFAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFAudio.framework; path = System/Library/Frameworks/AVFAudio.framework; sourceTree = SDKROOT; }; + 151BCDC226C874DB00F1EA89 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 151BCDC626C8765600F1EA89 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + 151BCDC926C87BB900F1EA89 /* PoppingService.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = PoppingService.plist; sourceTree = ""; }; + 1525B06726BA208000A504EB /* KettleCornService */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = KettleCornService; sourceTree = BUILT_PRODUCTS_DIR; }; + 1525B06926BA208000A504EB /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 1525B06E26BA21FF00A504EB /* KettleCornServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KettleCornServiceDelegate.swift; sourceTree = ""; }; + 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KettleCornServiceProtocol.swift; sourceTree = ""; }; + 1525B07226BA22AD00A504EB /* KettleCornService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KettleCornService.swift; sourceTree = ""; }; + 154214B526BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = KeyPopperPreferencesTerms.searchTerms; sourceTree = ""; }; + 1542150A26C05E02007E4A08 /* PoppingSounds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoppingSounds.swift; sourceTree = ""; }; + 1542150D26C06836007E4A08 /* KettleCornSerivce.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = KettleCornSerivce.plist; sourceTree = ""; }; + 1542150F26C0FB37007E4A08 /* KettleCornService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = KettleCornService.entitlements; sourceTree = ""; }; 1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "KeyPopper PrefPane.prefPane"; sourceTree = BUILT_PRODUCTS_DIR; }; - 1587085726B89CC50082DB8F /* PrefPane.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = PrefPane.tiff; sourceTree = ""; }; 1587085A26B89CC50082DB8F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/KeyPopper.xib; sourceTree = ""; }; 1587085C26B89CC50082DB8F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 1587086126B8A04B0082DB8F /* KeyPopperPrefPane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPopperPrefPane.swift; sourceTree = ""; }; + 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "KeyPopper Catcher.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 15E014B126C7749100A432BD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 15E014B526C7749A00A432BD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 15E014B826C7749A00A432BD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 15E014BD26C7750100A432BD /* KeyPopper Catcher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "KeyPopper Catcher.entitlements"; sourceTree = ""; }; + 15E014BE26C7784600A432BD /* KeyPopper-Catcher-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "KeyPopper-Catcher-Info.plist"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 151BCD9326C7844A00F1EA89 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 151BCDA426C86FBF00F1EA89 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 151BCDC326C874DB00F1EA89 /* AVKit.framework in Frameworks */, + 151BCDC726C8765600F1EA89 /* AppKit.framework in Frameworks */, + 151BCDC426C874DB00F1EA89 /* AVFAudio.framework in Frameworks */, + 151BCDC526C874DB00F1EA89 /* AVFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1525B06426BA208000A504EB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1587084E26B89CC50082DB8F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -31,33 +188,97 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 1587083026B89C710082DB8F = { + 151BCDA826C86FBF00F1EA89 /* PoppingService */ = { isa = PBXGroup; children = ( - 1587085226B89CC50082DB8F /* PrefPane */, - 15F9C8D326B8BCC300BF23AA /* Products */, + 151BCDB426C870A200F1EA89 /* PoppingService.entitlements */, + 151BCDA926C86FBF00F1EA89 /* main.swift */, + 151BCDAE26C86FFD00F1EA89 /* PoppingServiceDelegate.swift */, + 151BCDB026C8700800F1EA89 /* PoppingServiceProtocol.swift */, + 151BCDB226C8701100F1EA89 /* PoppingService.swift */, + 151BCDB926C8711000F1EA89 /* pop.mp3 */, + 151BCDBC26C873B600F1EA89 /* moo.mp3 */, + 151BCDBE26C874C900F1EA89 /* frog.mp3 */, + 151BCDC926C87BB900F1EA89 /* PoppingService.plist */, ); + path = PoppingService; sourceTree = ""; }; - 15F9C8D326B8BCC300BF23AA /* Products */ = { + 1525B06826BA208000A504EB /* KettleCornService */ = { isa = PBXGroup; children = ( - 1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */, + 1542150F26C0FB37007E4A08 /* KettleCornService.entitlements */, + 1542150D26C06836007E4A08 /* KettleCornSerivce.plist */, + 1525B06926BA208000A504EB /* main.swift */, + 1525B06E26BA21FF00A504EB /* KettleCornServiceDelegate.swift */, + 1525B07026BA227700A504EB /* KettleCornServiceProtocol.swift */, + 1525B07226BA22AD00A504EB /* KettleCornService.swift */, + ); + path = KettleCornService; + sourceTree = ""; + }; + 1587083026B89C710082DB8F = { + isa = PBXGroup; + children = ( + 1587085226B89CC50082DB8F /* PrefPane */, + 15E014B026C7749100A432BD /* KeyPopper Catcher */, + 1525B06826BA208000A504EB /* KettleCornService */, + 151BCDA826C86FBF00F1EA89 /* PoppingService */, + 15F9C8D326B8BCC300BF23AA /* Products */, + 15E014C026C77EF000A432BD /* Frameworks */, ); - name = Products; sourceTree = ""; }; 1587085226B89CC50082DB8F /* PrefPane */ = { isa = PBXGroup; children = ( 1587086126B8A04B0082DB8F /* KeyPopperPrefPane.swift */, - 1587085726B89CC50082DB8F /* PrefPane.tiff */, + 1542150A26C05E02007E4A08 /* PoppingSounds.swift */, + 151BCD9D26C853E700F1EA89 /* PrefPane.tiff */, 1587085926B89CC50082DB8F /* KeyPopper.xib */, 1587085C26B89CC50082DB8F /* Info.plist */, + 154214B526BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms */, ); path = PrefPane; sourceTree = ""; }; + 15E014B026C7749100A432BD /* KeyPopper Catcher */ = { + isa = PBXGroup; + children = ( + 15E014BE26C7784600A432BD /* KeyPopper-Catcher-Info.plist */, + 151BCDA226C8566700F1EA89 /* KeyPopperCatcher.plist */, + 15E014BD26C7750100A432BD /* KeyPopper Catcher.entitlements */, + 15E014B126C7749100A432BD /* AppDelegate.swift */, + 15E014B526C7749A00A432BD /* Assets.xcassets */, + 15E014B726C7749A00A432BD /* Main.storyboard */, + ); + path = "KeyPopper Catcher"; + sourceTree = ""; + }; + 15E014C026C77EF000A432BD /* Frameworks */ = { + isa = PBXGroup; + children = ( + 151BCDC626C8765600F1EA89 /* AppKit.framework */, + 151BCDC126C874DB00F1EA89 /* AVFAudio.framework */, + 151BCDC226C874DB00F1EA89 /* AVFoundation.framework */, + 151BCDC026C874DB00F1EA89 /* AVKit.framework */, + 151BCD9526C7846000F1EA89 /* CoreFoundation.framework */, + 151BCD9426C7846000F1EA89 /* CoreServices.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 15F9C8D326B8BCC300BF23AA /* Products */ = { + isa = PBXGroup; + children = ( + 1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */, + 1525B06726BA208000A504EB /* KettleCornService */, + 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */, + 151BCDA726C86FBF00F1EA89 /* PoppingService */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -71,6 +292,38 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 151BCDA626C86FBF00F1EA89 /* PoppingService */ = { + isa = PBXNativeTarget; + buildConfigurationList = 151BCDAB26C86FBF00F1EA89 /* Build configuration list for PBXNativeTarget "PoppingService" */; + buildPhases = ( + 151BCDA326C86FBF00F1EA89 /* Sources */, + 151BCDA426C86FBF00F1EA89 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PoppingService; + productName = PoppingService; + productReference = 151BCDA726C86FBF00F1EA89 /* PoppingService */; + productType = "com.apple.product-type.tool"; + }; + 1525B06626BA208000A504EB /* KettleCornService */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1525B06B26BA208000A504EB /* Build configuration list for PBXNativeTarget "KettleCornService" */; + buildPhases = ( + 1525B06326BA208000A504EB /* Sources */, + 1525B06426BA208000A504EB /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KettleCornService; + productName = KettleCornService; + productReference = 1525B06726BA208000A504EB /* KettleCornService */; + productType = "com.apple.product-type.tool"; + }; 1587085026B89CC50082DB8F /* KeyPopper PrefPane */ = { isa = PBXNativeTarget; buildConfigurationList = 1587085D26B89CC50082DB8F /* Build configuration list for PBXNativeTarget "KeyPopper PrefPane" */; @@ -79,16 +332,40 @@ 1587084D26B89CC50082DB8F /* Sources */, 1587084E26B89CC50082DB8F /* Frameworks */, 1587084F26B89CC50082DB8F /* Resources */, + 1525B07926BA27B600A504EB /* Copy Services to Bundle */, + 151BCD9826C8484200F1EA89 /* Copy Catcher */, + 151BCDB726C870C600F1EA89 /* Copy PoppingService */, + 151BCDCB26C87DE900F1EA89 /* Copy Sounds */, ); buildRules = ( ); dependencies = ( + 151BCDB626C870BB00F1EA89 /* PBXTargetDependency */, + 151BCD9B26C8485F00F1EA89 /* PBXTargetDependency */, + 1525B07726BA270600A504EB /* PBXTargetDependency */, ); name = "KeyPopper PrefPane"; productName = PrefPane; productReference = 1587085126B89CC50082DB8F /* KeyPopper PrefPane.prefPane */; productType = "com.apple.product-type.bundle"; }; + 15E014AE26C7749100A432BD /* KeyPopper Catcher */ = { + isa = PBXNativeTarget; + buildConfigurationList = 15E014BA26C7749A00A432BD /* Build configuration list for PBXNativeTarget "KeyPopper Catcher" */; + buildPhases = ( + 15E014AB26C7749100A432BD /* Sources */, + 151BCD9326C7844A00F1EA89 /* Frameworks */, + 15E014AD26C7749100A432BD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "KeyPopper Catcher"; + productName = "KeyPopper Catcher"; + productReference = 15E014AF26C7749100A432BD /* KeyPopper Catcher.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -96,12 +373,22 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1300; LastUpgradeCheck = 1300; TargetAttributes = { + 151BCDA626C86FBF00F1EA89 = { + CreatedOnToolsVersion = 13.0; + }; + 1525B06626BA208000A504EB = { + CreatedOnToolsVersion = 13.0; + }; 1587085026B89CC50082DB8F = { CreatedOnToolsVersion = 13.0; LastSwiftMigration = 1300; }; + 15E014AE26C7749100A432BD = { + CreatedOnToolsVersion = 13.0; + }; }; }; buildConfigurationList = 1587083426B89C720082DB8F /* Build configuration list for PBXProject "KeyPopper" */; @@ -113,11 +400,13 @@ Base, ); mainGroup = 1587083026B89C710082DB8F; - productRefGroup = 1587083B26B89C720082DB8F /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 1587085026B89CC50082DB8F /* KeyPopper PrefPane */, + 15E014AE26C7749100A432BD /* KeyPopper Catcher */, + 1525B06626BA208000A504EB /* KettleCornService */, + 151BCDA626C86FBF00F1EA89 /* PoppingService */, ); }; /* End PBXProject section */ @@ -127,24 +416,87 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 154214B626BF3702007E4A08 /* KeyPopperPreferencesTerms.searchTerms in Resources */, 1587085B26B89CC50082DB8F /* KeyPopper.xib in Resources */, - 1587085826B89CC50082DB8F /* PrefPane.tiff in Resources */, + 151BCD9E26C853E800F1EA89 /* PrefPane.tiff in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 15E014AD26C7749100A432BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 15E014B626C7749A00A432BD /* Assets.xcassets in Resources */, + 15E014B926C7749A00A432BD /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 151BCDA326C86FBF00F1EA89 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 151BCDAF26C86FFD00F1EA89 /* PoppingServiceDelegate.swift in Sources */, + 151BCDB326C8701100F1EA89 /* PoppingService.swift in Sources */, + 151BCDB126C8700800F1EA89 /* PoppingServiceProtocol.swift in Sources */, + 151BCDAA26C86FBF00F1EA89 /* main.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1525B06326BA208000A504EB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1525B07126BA227700A504EB /* KettleCornServiceProtocol.swift in Sources */, + 151BCDC826C8771E00F1EA89 /* PoppingServiceProtocol.swift in Sources */, + 1542150C26C05E02007E4A08 /* PoppingSounds.swift in Sources */, + 1525B06A26BA208000A504EB /* main.swift in Sources */, + 1525B07326BA22AD00A504EB /* KettleCornService.swift in Sources */, + 1525B06F26BA21FF00A504EB /* KettleCornServiceDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1587084D26B89CC50082DB8F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1542150E26C068FF007E4A08 /* KettleCornServiceProtocol.swift in Sources */, 1587086226B8A04B0082DB8F /* KeyPopperPrefPane.swift in Sources */, + 1542150B26C05E02007E4A08 /* PoppingSounds.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 15E014AB26C7749100A432BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 15E014BF26C77BAC00A432BD /* KettleCornServiceProtocol.swift in Sources */, + 15E014B226C7749100A432BD /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 151BCD9B26C8485F00F1EA89 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 15E014AE26C7749100A432BD /* KeyPopper Catcher */; + targetProxy = 151BCD9A26C8485F00F1EA89 /* PBXContainerItemProxy */; + }; + 151BCDB626C870BB00F1EA89 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 151BCDA626C86FBF00F1EA89 /* PoppingService */; + targetProxy = 151BCDB526C870BB00F1EA89 /* PBXContainerItemProxy */; + }; + 1525B07726BA270600A504EB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1525B06626BA208000A504EB /* KettleCornService */; + targetProxy = 1525B07626BA270600A504EB /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 1587085926B89CC50082DB8F /* KeyPopper.xib */ = { isa = PBXVariantGroup; @@ -154,9 +506,81 @@ name = KeyPopper.xib; sourceTree = ""; }; + 15E014B726C7749A00A432BD /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 15E014B826C7749A00A432BD /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 151BCDAC26C86FBF00F1EA89 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = PoppingService/PoppingService.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = P6PV2R9443; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PoppingService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 151BCDAD26C86FBF00F1EA89 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = PoppingService/PoppingService.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = P6PV2R9443; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PoppingService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 1525B06C26BA208000A504EB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = KettleCornService/KettleCornService.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = P6PV2R9443; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.KettleCornService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 1525B06D26BA208000A504EB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = KettleCornService/KettleCornService.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = P6PV2R9443; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.KettleCornService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; 1587084726B89C720082DB8F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -208,7 +632,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -261,7 +685,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; @@ -289,6 +713,7 @@ "@executable_path/../Frameworks", "@loader_path/../Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PrefPane; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -322,6 +747,7 @@ "@executable_path/../Frameworks", "@loader_path/../Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = sh.linus.keypopper.PrefPane; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -333,9 +759,115 @@ }; name = Release; }; + 15E014BB26C7749A00A432BD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "KeyPopper Catcher/KeyPopper Catcher.entitlements"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = P6PV2R9443; + ENABLE_APP_SANDBOX = NO; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_USER_SELECTED_FILES = readonly; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "KeyPopper-Catcher-Info.plist"; + INFOPLIST_KEY_CFBundleExecutable = "KeyPopper Catcher"; + INFOPLIST_KEY_CFBundleName = "KeyPopper Catcher"; + INFOPLIST_KEY_CFBundleVersion = 1; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/lib/system", + "$(SDKROOT)/usr/lib/swift", + "$(SDKROOT)/usr/lib/log", + "$(SDKROOT)/usr/lib/updaters", + "$(SDKROOT)/usr/lib/system/introspection", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "sh.linus.keypopper.KeyPopper-Catcher"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 15E014BC26C7749A00A432BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "KeyPopper Catcher/KeyPopper Catcher.entitlements"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = P6PV2R9443; + ENABLE_APP_SANDBOX = NO; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_USER_SELECTED_FILES = readonly; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "KeyPopper-Catcher-Info.plist"; + INFOPLIST_KEY_CFBundleExecutable = "KeyPopper Catcher"; + INFOPLIST_KEY_CFBundleName = "KeyPopper Catcher"; + INFOPLIST_KEY_CFBundleVersion = 1; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/lib/system", + "$(SDKROOT)/usr/lib/swift", + "$(SDKROOT)/usr/lib/log", + "$(SDKROOT)/usr/lib/updaters", + "$(SDKROOT)/usr/lib/system/introspection", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "sh.linus.keypopper.KeyPopper-Catcher"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 151BCDAB26C86FBF00F1EA89 /* Build configuration list for PBXNativeTarget "PoppingService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 151BCDAC26C86FBF00F1EA89 /* Debug */, + 151BCDAD26C86FBF00F1EA89 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1525B06B26BA208000A504EB /* Build configuration list for PBXNativeTarget "KettleCornService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1525B06C26BA208000A504EB /* Debug */, + 1525B06D26BA208000A504EB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 1587083426B89C720082DB8F /* Build configuration list for PBXProject "KeyPopper" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -354,6 +886,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 15E014BA26C7749A00A432BD /* Build configuration list for PBXNativeTarget "KeyPopper Catcher" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 15E014BB26C7749A00A432BD /* Debug */, + 15E014BC26C7749A00A432BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 1587083126B89C720082DB8F /* Project object */; diff --git a/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper Catcher.xcscheme b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper Catcher.xcscheme new file mode 100644 index 0000000..7833205 --- /dev/null +++ b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper Catcher.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme index cb7284a..e4d5ad0 100644 --- a/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme +++ b/KeyPopper.xcodeproj/xcshareddata/xcschemes/KeyPopper PrefPane.xcscheme @@ -40,6 +40,15 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PoppingService/PoppingService.entitlements b/PoppingService/PoppingService.entitlements new file mode 100644 index 0000000..49ad0bb --- /dev/null +++ b/PoppingService/PoppingService.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.automation.apple-events + + + diff --git a/PoppingService/PoppingService.plist b/PoppingService/PoppingService.plist new file mode 100644 index 0000000..e155310 --- /dev/null +++ b/PoppingService/PoppingService.plist @@ -0,0 +1,15 @@ + + + + + Label + sh.linus.keypopper.PoppingService + Program + /Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/Java/PoppingService + MachServices + + sh.linus.keypopper.PoppingService.mach + + + + diff --git a/PoppingService/PoppingService.swift b/PoppingService/PoppingService.swift new file mode 100644 index 0000000..dec8eea --- /dev/null +++ b/PoppingService/PoppingService.swift @@ -0,0 +1,50 @@ +// +// PoppingService.swift +// PoppingService +// +// Created by Linus Skucas on 8/14/21. +// + +import Foundation +import AVFoundation + +@objc class PoppingService: NSObject, PoppingServiceProtocol { + var popSound: AVAudioPlayer! + var frogSound: AVAudioPlayer! + var mooSound: AVAudioPlayer! + + override init() { + super.init() + let poppingURL = URL(fileURLWithPath: "/Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/pop.mp3") + let mooingURL = URL(fileURLWithPath: "/Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/moo.mp3") + let frogingURL = URL(fileURLWithPath: "/Library/PreferencePanes/KeyPopper PrefPane.prefPane/Contents/Resources/frog.mp3") + + popSound = try! AVAudioPlayer(contentsOf: poppingURL) + popSound.volume = 1.00 + popSound.prepareToPlay() + mooSound = try! AVAudioPlayer(contentsOf: mooingURL) + mooSound.volume = 1.00 + mooSound.prepareToPlay() + frogSound = try! AVAudioPlayer(contentsOf: frogingURL) + frogSound.volume = 1.00 + frogSound.prepareToPlay() + } + + func pop() { + DispatchQueue.main.async { + self.popSound.play() + } + } + + func frog() { + DispatchQueue.main.async { + self.frogSound.play() + } + } + + func moo() { + DispatchQueue.main.async { + self.mooSound.play() + } + } +} diff --git a/PoppingService/PoppingServiceDelegate.swift b/PoppingService/PoppingServiceDelegate.swift new file mode 100644 index 0000000..3d4a10a --- /dev/null +++ b/PoppingService/PoppingServiceDelegate.swift @@ -0,0 +1,19 @@ +// +// PoppingServiceDelegate.swift +// PoppingService +// +// Created by Linus Skucas on 8/14/21. +// + +import Foundation + +class PoppingServiceDelegate: NSObject, NSXPCListenerDelegate { + func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { + let exportedObject = PoppingService() + newConnection.exportedInterface = NSXPCInterface(with: PoppingServiceProtocol.self) + newConnection.exportedObject = exportedObject + + newConnection.resume() + return true + } +} diff --git a/PoppingService/PoppingServiceProtocol.swift b/PoppingService/PoppingServiceProtocol.swift new file mode 100644 index 0000000..c4874b1 --- /dev/null +++ b/PoppingService/PoppingServiceProtocol.swift @@ -0,0 +1,14 @@ +// +// PoppingServiceProtocol.swift +// PoppingService +// +// Created by Linus Skucas on 8/14/21. +// + +import Foundation + +@objc(PoppingService) protocol PoppingServiceProtocol { + func pop() + func frog() + func moo() +} diff --git a/PoppingService/frog.mp3 b/PoppingService/frog.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..abf2d7883c81d1efd23eff6cf5590ce535dc486d GIT binary patch literal 5706 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 literal 0 HcmV?d00001 diff --git a/PoppingService/main.swift b/PoppingService/main.swift new file mode 100644 index 0000000..5dcd855 --- /dev/null +++ b/PoppingService/main.swift @@ -0,0 +1,14 @@ +// +// main.swift +// PoppingService +// +// Created by Linus Skucas on 8/14/21. +// + +import Foundation + +let delegate = PoppingServiceDelegate() +let listener = NSXPCListener(machServiceName: "sh.linus.keypopper.PoppingService.mach") +listener.delegate = delegate +listener.resume() +RunLoop.main.run() diff --git a/PoppingService/moo.mp3 b/PoppingService/moo.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b84c7a8b1188a841c19ea318cb6e118f6e3d9bda GIT binary patch literal 35799 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�hC5{LNx_!J`@ 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Ą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 literal 0 HcmV?d00001 diff --git a/PrefPane/Info.plist b/PrefPane/Info.plist index c47e554..bca694a 100644 --- a/PrefPane/Info.plist +++ b/PrefPane/Info.plist @@ -2,11 +2,15 @@ + NSPrefPaneAllowsXAppleSystemPreferencesURLScheme + CFBundleName KeyPopper NSPrefPaneIconFile PrefPane.tiff NSPrefPaneIconLabel KeyPopper + NSPrefPaneSearchParameters + KeyPopperPreferencesTerms diff --git a/PrefPane/KeyPopperPrefPane.swift b/PrefPane/KeyPopperPrefPane.swift index 361765b..c745d2a 100644 --- a/PrefPane/KeyPopperPrefPane.swift +++ b/PrefPane/KeyPopperPrefPane.swift @@ -7,9 +7,90 @@ import Foundation import PreferencePanes +import SwiftUI +import AppKit + +struct KettleCommunication { + static let shared = KettleCommunication() + var service: KettleCornServiceProtocol! + + init() { + let connection = NSXPCConnection(machServiceName: "sh.linus.keypopper.KettleCornService.mach") + connection.remoteObjectInterface = NSXPCInterface(with: KettleCornServiceProtocol.self) + connection.resume() + + service = connection.remoteObjectProxyWithErrorHandler { error in + fatalError("Error: \(error.localizedDescription)") + } as! KettleCornServiceProtocol + } +} + +struct KeyPopperPrefPaneView: View { + let communication = KettleCommunication.shared + @AppStorage("enabled", store: UserDefaults.init(suiteName: "sh.linus.keypopper")!) var enabled: Bool = false + @State var sound: PoppingSounds = .pop + @AppStorage("sound", store: UserDefaults.init(suiteName: "sh.linus.keypopper")!) var soundInt: Int = 0 + + var body: some View { + Group { + Group { + Form { + Picker(selection: $sound, label: + VStack(alignment: .trailing, spacing: 2) { + Text("Sound") + Image(nsImage: NSImage(named: NSImage.Name("NXHelpIndex"))!) + }, content: { + Text("Popping") + .tag(PoppingSounds.pop) + Text("Mooing") + .tag(PoppingSounds.moo) + Text("Frog Thingying") + .tag(PoppingSounds.frog) + }) + .pickerStyle(.radioGroup) + .padding(.top) + .onChange(of: sound) { newValue in + soundInt = newValue.rawValue + communication.service.changeSoundTo(newValue.rawValue) + } + .onAppear { + sound = PoppingSounds(rawValue: soundInt)! + } + + Toggle(isOn: $enabled) { + HStack { + Text("Enable Sounds") + Image(nsImage: NSImage(named: NSImage.Name("NXFollow"))!) + .resizable() + .frame(width: 30, height: 30, alignment: .center) + } + } + .toggleStyle(.switch) + .onChange(of: enabled) { newValue in + communication.service.changeSoundState(shouldPlaySound: newValue) + } + } + + GroupBox { + HStack(alignment: .center) { + Image(nsImage: NSImage(named: NSImage.Name("NSSecurity"))!) + .resizable() + .scaledToFit() + Text("KeyPopper does not record or send your keystrokes anywhere.") + } + } + .padding(.bottom) + } + .frame(width: 480) + } + .frame(width: 500, height: 200) + } +} + class KeyPopperPrefPane: NSPreferencePane { override func mainViewDidLoad() { - + let keyView = KeyPopperPrefPaneView() + self.mainView = NSHostingView(rootView: keyView) } } diff --git a/PrefPane/KeyPopperPreferencesTerms.searchTerms b/PrefPane/KeyPopperPreferencesTerms.searchTerms new file mode 100644 index 0000000..6233974 --- /dev/null +++ b/PrefPane/KeyPopperPreferencesTerms.searchTerms @@ -0,0 +1,35 @@ + + + + + KeyPopper + + localizableStrings + + + comments + Localizable index words + index + keyboard, keypopper, popper, enable sounds, sounds, sound, keylogger, keys, key, logger, key logger, popping, mooing, frog, froggying, frog thingying, enable + title + KeyPopper + + comments + Localizable index words + index + keyboard, keypopper, popper, enable sounds, sounds, sound, keylogger, keys, key, logger, key logger, enable + title + Enable KeyPopper Sounds + + + comments + Localizable index words + index + keyboard, keypopper, popper, enable sounds, sounds, sound, keylogger, keys, key, logger, key logger, popping, mooing, frog, froggying, frog thingying, enable + title + Change KeyPopper Sound + + + + + diff --git a/PrefPane/PoppingSounds.swift b/PrefPane/PoppingSounds.swift new file mode 100644 index 0000000..5400748 --- /dev/null +++ b/PrefPane/PoppingSounds.swift @@ -0,0 +1,17 @@ +// +// PoppingSounds.swift +// KeyPopper +// +// Created by Linus Skucas on 8/8/21. +// + +import Foundation + +@objc enum PoppingSounds: Int, Identifiable { + var id: Int { + return self.rawValue + } + case pop = 0 + case moo = 1 + case frog = 2 +} diff --git a/PrefPane/PrefPane.tiff b/PrefPane/PrefPane.tiff deleted file mode 100644 index e69de29..0000000