SwiftUI is happening
38
Yggdrasil Backup.xcframework/Info.plist
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>macos-arm64_x86_64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>Yggdrasil.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>macos</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>Yggdrasil.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -10,6 +10,7 @@ import UIKit
|
|||
#elseif canImport(AppKit)
|
||||
import AppKit
|
||||
#endif
|
||||
import SwiftUI
|
||||
import Yggdrasil
|
||||
import NetworkExtension
|
||||
|
||||
|
@ -28,12 +29,14 @@ class PlatformItemSource: NSObject {}
|
|||
#endif
|
||||
|
||||
class ConfigurationProxy: PlatformItemSource {
|
||||
|
||||
private var manager: NETunnelProviderManager?
|
||||
private var json: Data? = nil
|
||||
private var dict: [String: Any]? = nil
|
||||
|
||||
override init() {
|
||||
init(manager: NETunnelProviderManager? = nil) {
|
||||
self.manager = manager
|
||||
super.init()
|
||||
|
||||
self.json = MobileGenerateConfigJSON()
|
||||
do {
|
||||
try self.convertToDict()
|
||||
|
@ -48,8 +51,10 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
self.fix()
|
||||
}
|
||||
|
||||
init(json: Data) throws {
|
||||
init(json: Data, manager: NETunnelProviderManager? = nil) throws {
|
||||
self.manager = manager
|
||||
super.init()
|
||||
|
||||
self.json = json
|
||||
try self.convertToDict()
|
||||
self.fix()
|
||||
|
@ -59,9 +64,10 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
self.set("Listen", to: [] as [String])
|
||||
self.set("AdminListen", to: "none")
|
||||
self.set("IfName", to: "dummy")
|
||||
// self.set("Peers", to: ["tcp://172.22.97.1.5190", "tls://172.22.97.1:5191"])
|
||||
|
||||
if self.get("AutoStart") == nil {
|
||||
self.set("AutoStart", to: ["WiFi": false, "Mobile": false] as [String: Bool])
|
||||
self.set("AutoStart", to: ["Any": false, "WiFi": false, "Mobile": false, "Ethernet": false] as [String: Bool])
|
||||
}
|
||||
|
||||
let multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
||||
|
@ -88,6 +94,7 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
var multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
||||
multicastInterfaces[0]["Beacon"] = newValue
|
||||
self.set("MulticastInterfaces", to: multicastInterfaces)
|
||||
self.trySave()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,10 +110,61 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
var multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
||||
multicastInterfaces[0]["Listen"] = newValue
|
||||
self.set("MulticastInterfaces", to: multicastInterfaces)
|
||||
self.trySave()
|
||||
}
|
||||
}
|
||||
|
||||
func get(_ key: String) -> Any? {
|
||||
public var autoStartAny: Bool {
|
||||
get {
|
||||
return self.get("Any", inSection: "AutoStart") as? Bool ?? false
|
||||
}
|
||||
set {
|
||||
self.set("Any", inSection: "AutoStart", to: newValue)
|
||||
self.trySave()
|
||||
}
|
||||
}
|
||||
|
||||
public var autoStartWiFi: Bool {
|
||||
get {
|
||||
return self.get("WiFi", inSection: "AutoStart") as? Bool ?? false
|
||||
}
|
||||
set {
|
||||
self.set("WiFi", inSection: "AutoStart", to: newValue)
|
||||
self.trySave()
|
||||
}
|
||||
}
|
||||
|
||||
public var autoStartEthernet: Bool {
|
||||
get {
|
||||
return self.get("Ethernet", inSection: "AutoStart") as? Bool ?? false
|
||||
}
|
||||
set {
|
||||
self.set("Ethernet", inSection: "AutoStart", to: newValue)
|
||||
self.trySave()
|
||||
}
|
||||
}
|
||||
|
||||
public var autoStartMobile: Bool {
|
||||
get {
|
||||
return self.get("Mobile", inSection: "AutoStart") as? Bool ?? false
|
||||
}
|
||||
set {
|
||||
self.set("Mobile", inSection: "AutoStart", to: newValue)
|
||||
self.trySave()
|
||||
}
|
||||
}
|
||||
|
||||
public var peers: [String] {
|
||||
get {
|
||||
return self.get("Peers") as? [String] ?? []
|
||||
}
|
||||
set {
|
||||
self.set("Peers", to: newValue)
|
||||
self.trySave()
|
||||
}
|
||||
}
|
||||
|
||||
private func get(_ key: String) -> Any? {
|
||||
if let dict = self.dict {
|
||||
if dict.keys.contains(key) {
|
||||
return dict[key]
|
||||
|
@ -115,7 +173,7 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
return nil
|
||||
}
|
||||
|
||||
func get(_ key: String, inSection section: String) -> Any? {
|
||||
private func get(_ key: String, inSection section: String) -> Any? {
|
||||
if let dict = self.get(section) as? [String: Any] {
|
||||
if dict.keys.contains(key) {
|
||||
return dict[key]
|
||||
|
@ -124,7 +182,7 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
return nil
|
||||
}
|
||||
|
||||
func add(_ value: Any, in key: String) {
|
||||
private func add(_ value: Any, in key: String) {
|
||||
if self.dict != nil {
|
||||
if self.dict![key] as? [Any] != nil {
|
||||
var temp = self.dict![key] as? [Any] ?? []
|
||||
|
@ -134,7 +192,7 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
}
|
||||
}
|
||||
|
||||
func remove(_ value: String, from key: String) {
|
||||
private func remove(_ value: String, from key: String) {
|
||||
if self.dict != nil {
|
||||
if self.dict![key] as? [String] != nil {
|
||||
var temp = self.dict![key] as? [String] ?? []
|
||||
|
@ -146,7 +204,7 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
}
|
||||
}
|
||||
|
||||
func remove(index: Int, from key: String) {
|
||||
private func remove(index: Int, from key: String) {
|
||||
if self.dict != nil {
|
||||
if self.dict![key] as? [Any] != nil {
|
||||
var temp = self.dict![key] as? [Any] ?? []
|
||||
|
@ -156,13 +214,13 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
}
|
||||
}
|
||||
|
||||
func set(_ key: String, to value: Any) {
|
||||
private func set(_ key: String, to value: Any) {
|
||||
if self.dict != nil {
|
||||
self.dict![key] = value
|
||||
}
|
||||
}
|
||||
|
||||
func set(_ key: String, inSection section: String, to value: Any?) {
|
||||
private func set(_ key: String, inSection section: String, to value: Any?) {
|
||||
if self.dict != nil {
|
||||
if self.dict!.keys.contains(section), let value = value {
|
||||
var temp = self.dict![section] as? [String: Any] ?? [:]
|
||||
|
@ -181,6 +239,12 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
}
|
||||
}
|
||||
|
||||
private func trySave() {
|
||||
if var manager = self.manager {
|
||||
try? self.save(to: &manager)
|
||||
}
|
||||
}
|
||||
|
||||
func save(to manager: inout NETunnelProviderManager) throws {
|
||||
self.fix()
|
||||
if let data = self.data() {
|
||||
|
@ -192,6 +256,18 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
|
||||
let disconnectrule = NEOnDemandRuleDisconnect()
|
||||
var rules: [NEOnDemandRule] = [disconnectrule]
|
||||
if self.get("Any", inSection: "AutoStart") as? Bool ?? false {
|
||||
let wifirule = NEOnDemandRuleConnect()
|
||||
wifirule.interfaceTypeMatch = .any
|
||||
rules.insert(wifirule, at: 0)
|
||||
}
|
||||
#if os(macOS)
|
||||
if self.get("Ethernet", inSection: "AutoStart") as? Bool ?? false {
|
||||
let wifirule = NEOnDemandRuleConnect()
|
||||
wifirule.interfaceTypeMatch = .ethernet
|
||||
rules.insert(wifirule, at: 0)
|
||||
}
|
||||
#endif
|
||||
if self.get("WiFi", inSection: "AutoStart") as? Bool ?? false {
|
||||
let wifirule = NEOnDemandRuleConnect()
|
||||
wifirule.interfaceTypeMatch = .wiFi
|
||||
|
@ -214,8 +290,7 @@ class ConfigurationProxy: PlatformItemSource {
|
|||
if let error = error {
|
||||
print(error)
|
||||
} else {
|
||||
print("Save successfully")
|
||||
NotificationCenter.default.post(name: NSNotification.Name.YggdrasilSettingsUpdated, object: self)
|
||||
print("Saved successfully")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -22,46 +22,52 @@ typealias ApplicationDelegateAdaptor = NSApplicationDelegateAdaptor
|
|||
|
||||
class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
||||
var vpnManager: NETunnelProviderManager = NETunnelProviderManager()
|
||||
var yggdrasilConfig: ConfigurationProxy = ConfigurationProxy()
|
||||
let yggdrasilComponent = "eu.neilalexander.yggdrasil.extension"
|
||||
private var adminTimer: DispatchSourceTimer?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: nil, queue: nil, using: { notification in
|
||||
if let conn = notification.object as? NEVPNConnection {
|
||||
self.updateStatus(conn: conn)
|
||||
switch conn.status {
|
||||
case .connected:
|
||||
self.requestSummaryIPC()
|
||||
self.requestStatusIPC()
|
||||
case .disconnecting, .disconnected:
|
||||
self.clearStatus()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.vpnTunnelProviderManagerInit()
|
||||
self.makeIPCRequests()
|
||||
}
|
||||
|
||||
func toggleYggdrasil() {
|
||||
if !self.yggdrasilEnabled {
|
||||
print("Starting VPN tunnel")
|
||||
@Published var yggdrasilEnabled: Bool = false {
|
||||
didSet {
|
||||
if yggdrasilEnabled {
|
||||
if vpnManager.connection.status != .connected && vpnManager.connection.status != .connecting {
|
||||
do {
|
||||
try self.vpnManager.connection.startVPNTunnel()
|
||||
} catch {
|
||||
print("Failed to start VPN tunnel: \(error.localizedDescription)")
|
||||
return
|
||||
}
|
||||
print("Started VPN tunnel")
|
||||
}
|
||||
} else {
|
||||
print("Stopping VPN tunnel")
|
||||
if vpnManager.connection.status != .disconnected && vpnManager.connection.status != .disconnecting {
|
||||
self.vpnManager.connection.stopVPNTunnel()
|
||||
print("Stopped VPN tunnel")
|
||||
}
|
||||
self.yggdrasilEnabled = !self.yggdrasilEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var yggdrasilConfig: ConfigurationProxy? = nil
|
||||
|
||||
private var adminTimer: DispatchSourceTimer?
|
||||
|
||||
@Published var yggdrasilEnabled: Bool = false
|
||||
@Published var yggdrasilConnected: Bool = false
|
||||
|
||||
@Published var yggdrasilPublicKey: String = "N/A"
|
||||
@Published var yggdrasilIP: String = "N/A"
|
||||
@Published var yggdrasilSubnet: String = "N/A"
|
||||
@Published var yggdrasilCoords: String = "[]"
|
||||
|
@ -74,39 +80,42 @@ class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
|||
return Yggdrasil.MobileGetVersion()
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: PlatformApplication) {
|
||||
func becameActive() {
|
||||
print("Application became active")
|
||||
|
||||
if self.adminTimer == nil {
|
||||
self.adminTimer = DispatchSource.makeTimerSource(flags: .strict, queue: DispatchQueue(label: "Admin Queue"))
|
||||
self.adminTimer = DispatchSource.makeTimerSource(flags: .strict, queue: .main)
|
||||
self.adminTimer!.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.seconds(2), leeway: DispatchTimeInterval.seconds(1))
|
||||
self.adminTimer!.setEventHandler {
|
||||
self.makeIPCRequests()
|
||||
self.updateStatus(conn: self.vpnManager.connection)
|
||||
}
|
||||
}
|
||||
if self.adminTimer != nil {
|
||||
self.adminTimer!.resume()
|
||||
}
|
||||
|
||||
self.requestSummaryIPC()
|
||||
self.updateStatus(conn: self.vpnManager.connection)
|
||||
}
|
||||
|
||||
func updateStatus(conn: NEVPNConnection) {
|
||||
if conn.status == .connected {
|
||||
self.makeIPCRequests()
|
||||
} else if conn.status == .disconnecting || conn.status == .disconnected {
|
||||
self.clearStatus()
|
||||
}
|
||||
self.yggdrasilConnected = self.yggdrasilEnabled && self.yggdrasilPeers.count > 0 && self.yggdrasilDHT.count > 0
|
||||
print("Connection status: \(yggdrasilEnabled), \(yggdrasilConnected)")
|
||||
}
|
||||
func becameInactive() {
|
||||
print("Application became inactive")
|
||||
|
||||
func applicationWillResignActive(_ application: PlatformApplication) {
|
||||
if self.adminTimer != nil {
|
||||
self.adminTimer!.suspend()
|
||||
}
|
||||
}
|
||||
|
||||
func becameBackground() {}
|
||||
|
||||
func updateStatus(conn: NEVPNConnection) {
|
||||
if conn.status == .connected {
|
||||
self.requestStatusIPC()
|
||||
} else if conn.status == .disconnecting || conn.status == .disconnected {
|
||||
self.clearStatus()
|
||||
}
|
||||
}
|
||||
|
||||
func vpnTunnelProviderManagerInit() {
|
||||
print("Loading saved managers...")
|
||||
|
||||
|
@ -138,25 +147,24 @@ class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
|||
}
|
||||
|
||||
self.vpnManager.loadFromPreferences(completionHandler: { (error: Error?) in
|
||||
var loadedConfig = false
|
||||
if error == nil {
|
||||
if let vpnConfig = self.vpnManager.protocolConfiguration as? NETunnelProviderProtocol,
|
||||
let confJson = vpnConfig.providerConfiguration!["json"] as? Data {
|
||||
if let loaded = try? ConfigurationProxy(json: confJson) {
|
||||
if let loaded = try? ConfigurationProxy(json: confJson, manager: self.vpnManager) {
|
||||
print("Found existing protocol configuration")
|
||||
self.yggdrasilConfig = loaded
|
||||
loadedConfig = true
|
||||
} else {
|
||||
print("Existing protocol configuration is invalid, ignoring")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.yggdrasilConfig == nil {
|
||||
if !loadedConfig {
|
||||
print("Generating new protocol configuration")
|
||||
self.yggdrasilConfig = ConfigurationProxy()
|
||||
|
||||
if let config = self.yggdrasilConfig {
|
||||
try? config.save(to: &self.vpnManager)
|
||||
}
|
||||
self.yggdrasilConfig = ConfigurationProxy(manager: self.vpnManager)
|
||||
try? self.yggdrasilConfig.save(to: &self.vpnManager)
|
||||
}
|
||||
|
||||
self.vpnManager.localizedDescription = "Yggdrasil"
|
||||
|
@ -165,56 +173,48 @@ class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func makeIPCRequests() {
|
||||
func requestSummaryIPC() {
|
||||
if self.vpnManager.connection.status != .connected {
|
||||
return
|
||||
}
|
||||
if let session = self.vpnManager.connection as? NETunnelProviderSession {
|
||||
try? session.sendProviderMessage("address".data(using: .utf8)!) { (address) in
|
||||
if let address = address {
|
||||
self.yggdrasilIP = String(data: address, encoding: .utf8)!
|
||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
||||
try? session.sendProviderMessage("summary".data(using: .utf8)!) { js in
|
||||
if let js = js, let summary = try? JSONDecoder().decode(YggdrasilSummary.self, from: js) {
|
||||
self.yggdrasilEnabled = true
|
||||
self.yggdrasilIP = summary.address
|
||||
self.yggdrasilSubnet = summary.subnet
|
||||
self.yggdrasilPublicKey = summary.publicKey
|
||||
}
|
||||
}
|
||||
try? session.sendProviderMessage("subnet".data(using: .utf8)!) { (subnet) in
|
||||
if let subnet = subnet {
|
||||
self.yggdrasilSubnet = String(data: subnet, encoding: .utf8)!
|
||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
||||
}
|
||||
}
|
||||
try? session.sendProviderMessage("coords".data(using: .utf8)!) { (coords) in
|
||||
if let coords = coords {
|
||||
self.yggdrasilCoords = String(data: coords, encoding: .utf8)!
|
||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
||||
|
||||
func requestStatusIPC() {
|
||||
if self.vpnManager.connection.status != .connected {
|
||||
return
|
||||
}
|
||||
}
|
||||
try? session.sendProviderMessage("peers".data(using: .utf8)!) { (peers) in
|
||||
if let peers = peers {
|
||||
if let jsonResponse = try? JSONSerialization.jsonObject(with: peers, options: []) as? [[String: Any]] {
|
||||
if let session = self.vpnManager.connection as? NETunnelProviderSession {
|
||||
try? session.sendProviderMessage("status".data(using: .utf8)!) { js in
|
||||
if let js = js, let status = try? JSONDecoder().decode(YggdrasilStatus.self, from: js) {
|
||||
self.yggdrasilCoords = status.coords
|
||||
if let jsonResponse = try? JSONSerialization.jsonObject(with: status.peers, options: []) as? [[String: Any]] {
|
||||
self.yggdrasilPeers = jsonResponse
|
||||
NotificationCenter.default.post(name: .YggdrasilPeersUpdated, object: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
try? session.sendProviderMessage("dht".data(using: .utf8)!) { (peers) in
|
||||
if let peers = peers {
|
||||
if let jsonResponse = try? JSONSerialization.jsonObject(with: peers, options: []) as? [[String: Any]] {
|
||||
if let jsonResponse = try? JSONSerialization.jsonObject(with: status.dht, options: []) as? [[String: Any]] {
|
||||
self.yggdrasilDHT = jsonResponse
|
||||
NotificationCenter.default.post(name: .YggdrasilDHTUpdated, object: nil)
|
||||
}
|
||||
self.yggdrasilConnected = self.yggdrasilEnabled && self.yggdrasilPeers.count > 0 && self.yggdrasilDHT.count > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func clearStatus() {
|
||||
self.yggdrasilConnected = false
|
||||
self.yggdrasilIP = "N/A"
|
||||
self.yggdrasilSubnet = "N/A"
|
||||
self.yggdrasilCoords = "[]"
|
||||
self.yggdrasilPeers = []
|
||||
self.yggdrasilDHT = []
|
||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
||||
NotificationCenter.default.post(name: .YggdrasilPeersUpdated, object: nil)
|
||||
NotificationCenter.default.post(name: .YggdrasilDHTUpdated, object: nil)
|
||||
}
|
||||
}
|
||||
|
|
21
Yggdrasil Network Cross-Platform/IPCResponses.swift
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// IPCResponses.swift
|
||||
// YggdrasilNetwork
|
||||
//
|
||||
// Created by Neil Alexander on 20/02/2019.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct YggdrasilSummary: Codable {
|
||||
var address: String
|
||||
var subnet: String
|
||||
var publicKey: String
|
||||
}
|
||||
|
||||
struct YggdrasilStatus: Codable {
|
||||
var enabled: Bool
|
||||
var coords: String
|
||||
var peers: Data
|
||||
var dht: Data
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// NSNotification.swift
|
||||
// YggdrasilNetwork
|
||||
//
|
||||
// Created by Neil Alexander on 20/02/2019.
|
||||
//
|
||||
|
||||
#if canImport(UIKit)
|
||||
import UIKit
|
||||
#elseif canImport(AppKit)
|
||||
import AppKit
|
||||
#endif
|
||||
|
||||
extension Notification.Name {
|
||||
static let YggdrasilSelfUpdated = Notification.Name("YggdrasilSelfUpdated")
|
||||
static let YggdrasilPeersUpdated = Notification.Name("YggdrasilPeersUpdated")
|
||||
static let YggdrasilSettingsUpdated = Notification.Name("YggdrasilSettingsUpdated")
|
||||
static let YggdrasilDHTUpdated = Notification.Name("YggdrasilDHTUpdated")
|
||||
}
|
|
@ -55,6 +55,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||
if let fd = self.tunnelFileDescriptor {
|
||||
do {
|
||||
try self.yggdrasil.takeOverTUN(fd)
|
||||
NSLog("Yggdrasil taken over TUN successfully")
|
||||
} catch {
|
||||
NSLog("Taking over TUN produced an error: " + error.localizedDescription)
|
||||
err = error
|
||||
|
@ -82,6 +83,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||
NSLog("Yggdrasil completion handler called")
|
||||
completionHandler(nil)
|
||||
}
|
||||
} else {
|
||||
NSLog("Error in Yggdrasil startTunnel: No configuration JSON found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,16 +97,27 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
|
||||
let request = String(data: messageData, encoding: .utf8)
|
||||
switch request {
|
||||
case "address":
|
||||
completionHandler?(self.yggdrasil.getAddressString().data(using: .utf8))
|
||||
case "subnet":
|
||||
completionHandler?(self.yggdrasil.getSubnetString().data(using: .utf8))
|
||||
case "coords":
|
||||
completionHandler?(self.yggdrasil.getCoordsString().data(using: .utf8))
|
||||
case "peers":
|
||||
completionHandler?(self.yggdrasil.getPeersJSON().data(using: .utf8))
|
||||
case "dht":
|
||||
completionHandler?(self.yggdrasil.getDHTJSON().data(using: .utf8))
|
||||
case "summary":
|
||||
let summary = YggdrasilSummary(
|
||||
address: self.yggdrasil.getAddressString(),
|
||||
subnet: self.yggdrasil.getSubnetString(),
|
||||
publicKey: self.yggdrasil.getPublicKeyString()
|
||||
)
|
||||
if let json = try? JSONEncoder().encode(summary) {
|
||||
completionHandler?(json)
|
||||
}
|
||||
|
||||
case "status":
|
||||
let status = YggdrasilStatus(
|
||||
enabled: true,
|
||||
coords: self.yggdrasil.getCoordsString(),
|
||||
peers: self.yggdrasil.getPeersJSON().data(using: .utf8) ?? Data(),
|
||||
dht: self.yggdrasil.getDHTJSON().data(using: .utf8) ?? Data()
|
||||
)
|
||||
if let json = try? JSONEncoder().encode(status) {
|
||||
completionHandler?(json)
|
||||
}
|
||||
|
||||
default:
|
||||
completionHandler?(nil)
|
||||
}
|
||||
|
|
|
@ -20,5 +20,7 @@
|
|||
</array>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// AppDelegate+AppDelegateExtension.h
|
||||
// Yggdrasil Network
|
||||
//
|
||||
// Created by Neil Alexander on 11/01/2019.
|
||||
//
|
||||
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,15 +0,0 @@
|
|||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: CrossPlatformAppDelegate {
|
||||
var window: UIWindow?
|
||||
|
||||
let configDir = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)[0]
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch
|
||||
self.vpnTunnelProviderManagerInit()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "drawing copy-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "drawing copy.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "drawing copy-2.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "drawing copy-3.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "drawing copy-5.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "drawing copy-4.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4 KiB |
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "img1.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "img1w.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "img2.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "img2w.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "img3.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "img3w.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 61 KiB |
|
@ -1,20 +0,0 @@
|
|||
//
|
||||
// Data.swift
|
||||
// YggdrasilNetworkExtension
|
||||
//
|
||||
// Created by Neil on 15/11/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Data {
|
||||
/// This computed value is only needed because of [this](https://github.com/golang/go/issues/33745) issue in the
|
||||
/// golang/go repository. It is a workaround until the problem is solved upstream.
|
||||
///
|
||||
/// The data object is converted into an array of bytes and than returned wrapped in an `NSMutableData` object. In
|
||||
/// thas way Gomobile takes it as it is without copying. The Swift side remains responsible for garbage collection.
|
||||
var mutable: Data {
|
||||
var array = [UInt8](self)
|
||||
return NSMutableData(bytes: &array, length: self.count) as Data
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension UIDevice {
|
||||
/// A Boolean value indicating whether the device has cellular data capabilities (true) or not (false).
|
||||
var hasCellularCapabilites: Bool {
|
||||
var addrs: UnsafeMutablePointer<ifaddrs>?
|
||||
var cursor: UnsafeMutablePointer<ifaddrs>?
|
||||
|
||||
defer { freeifaddrs(addrs) }
|
||||
|
||||
guard getifaddrs(&addrs) == 0 else { return false }
|
||||
cursor = addrs
|
||||
|
||||
while cursor != nil {
|
||||
guard
|
||||
let utf8String = cursor?.pointee.ifa_name,
|
||||
let name = NSString(utf8String: utf8String),
|
||||
name == "pdp_ip0"
|
||||
else {
|
||||
cursor = cursor?.pointee.ifa_next
|
||||
continue
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Yggdrasil</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.text</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Yggdrasil Configuration File</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>eu.neilalexander.yggdrasil.configuration</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>yggconf</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,60 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="YggdrasilNetwork" translatesAutoresizingMaskIntoConstraints="NO" id="3Lc-gG-kep">
|
||||
<rect key="frame" x="28" y="219.5" width="319" height="128"/>
|
||||
<color key="tintColor" systemColor="labelColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="3Lc-gG-kep" secondAttribute="height" multiplier="159:64" id="NYe-AY-mCL"/>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="lIj-gT-vW9"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Experimental" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0Nr-Vm-h9W">
|
||||
<rect key="frame" x="138" y="626" width="99" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="3Lc-gG-kep" secondAttribute="trailing" constant="28" id="J9j-Ek-mVq"/>
|
||||
<constraint firstItem="3Lc-gG-kep" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" constant="-50" id="MLF-C3-5Is"/>
|
||||
<constraint firstItem="3Lc-gG-kep" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="28" id="VpK-lC-s00"/>
|
||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="0Nr-Vm-h9W" secondAttribute="bottom" constant="20" id="WcT-Cw-bXi"/>
|
||||
<constraint firstItem="0Nr-Vm-h9W" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="ZHc-EA-sHG"/>
|
||||
<constraint firstItem="3Lc-gG-kep" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="xej-Yh-XPz"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="52" y="374.66266866566718"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="YggdrasilNetwork" width="480" height="157"/>
|
||||
<systemColor name="labelColor">
|
||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
|
@ -1,674 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="sjP-mj-LKX">
|
||||
<device id="ipad10_9rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Peers-->
|
||||
<scene sceneID="YjI-Ak-tYt">
|
||||
<objects>
|
||||
<tableViewController title="Peers" id="Aro-kj-1Us" customClass="PeersViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="jrG-5P-x67">
|
||||
<rect key="frame" x="0.0" y="0.0" width="704" height="995.5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="configuredPeerPrototype" textLabel="s5X-wa-HWH" style="IBUITableViewCellStyleDefault" id="8Oo-lj-bGn">
|
||||
<rect key="frame" x="20" y="49.5" width="664" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8Oo-lj-bGn" id="l78-DB-hkK">
|
||||
<rect key="frame" x="0.0" y="0.0" width="664" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="(discovered)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="s5X-wa-HWH">
|
||||
<rect key="frame" x="16" y="0.0" width="632" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="discoveredPeerPrototype" textLabel="DBc-bQ-Fql" detailTextLabel="6Zr-Ab-5mg" style="IBUITableViewCellStyleSubtitle" id="GeY-vZ-Kfa">
|
||||
<rect key="frame" x="20" y="93" width="664" height="55.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="GeY-vZ-Kfa" id="CVl-gJ-x3R">
|
||||
<rect key="frame" x="0.0" y="0.0" width="664" height="55.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="(static)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="DBc-bQ-Fql" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
||||
<rect key="frame" x="16" y="10" width="54" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="200:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6Zr-Ab-5mg">
|
||||
<rect key="frame" x="16" y="31.5" width="26" height="14.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="menuPrototype" textLabel="hGp-hS-MXO" style="IBUITableViewCellStyleDefault" id="X8B-Ij-Uxu">
|
||||
<rect key="frame" x="20" y="148.5" width="664" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="X8B-Ij-Uxu" id="VFl-pZ-ioq">
|
||||
<rect key="frame" x="0.0" y="0.0" width="638.5" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Menu item" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hGp-hS-MXO">
|
||||
<rect key="frame" x="16" y="0.0" width="614.5" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="togglePrototype" id="7yi-ur-bht" customClass="ToggleTableViewCell" customModule="YggdrasilNetwork" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="192" width="664" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="7yi-ur-bht" id="xEb-l3-99b">
|
||||
<rect key="frame" x="0.0" y="0.0" width="664" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Toggle item" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ij2-ls-8ZT">
|
||||
<rect key="frame" x="16" y="12.5" width="575" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="MYo-S3-kzH">
|
||||
<rect key="frame" x="599" y="7" width="51" height="31.5"/>
|
||||
</switch>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="MYo-S3-kzH" secondAttribute="bottom" constant="5.5" id="GE4-ve-zue"/>
|
||||
<constraint firstItem="MYo-S3-kzH" firstAttribute="leading" secondItem="ij2-ls-8ZT" secondAttribute="trailing" constant="8" id="HY3-fl-iyt"/>
|
||||
<constraint firstItem="ij2-ls-8ZT" firstAttribute="leading" secondItem="xEb-l3-99b" secondAttribute="leadingMargin" id="K5Q-In-8A5"/>
|
||||
<constraint firstAttribute="trailing" secondItem="MYo-S3-kzH" secondAttribute="trailing" constant="16" id="OfU-Jc-Jh0"/>
|
||||
<constraint firstItem="ij2-ls-8ZT" firstAttribute="centerY" secondItem="MYo-S3-kzH" secondAttribute="centerY" id="g5U-4E-XRi"/>
|
||||
<constraint firstItem="MYo-S3-kzH" firstAttribute="top" secondItem="xEb-l3-99b" secondAttribute="top" constant="7" id="wvd-yp-ouw"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="label" destination="ij2-ls-8ZT" id="4kY-1u-gbw"/>
|
||||
<outlet property="toggle" destination="MYo-S3-kzH" id="WDg-LO-UM4"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<sections/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="Aro-kj-1Us" id="LKO-i9-QW7"/>
|
||||
<outlet property="delegate" destination="Aro-kj-1Us" id="Gth-NL-fBx"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<toolbarItems>
|
||||
<barButtonItem systemItem="add" id="MOW-Lh-hSQ">
|
||||
<connections>
|
||||
<action selector="addNewPeerButtonPressed:" destination="Aro-kj-1Us" id="CS3-Z6-tRA"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</toolbarItems>
|
||||
<navigationItem key="navigationItem" title="Peers" id="4pr-Fq-FKY"/>
|
||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="addButtonItem" destination="MOW-Lh-hSQ" id="2UM-tD-SnA"/>
|
||||
<outlet property="peerTable" destination="jrG-5P-x67" id="RPw-J3-r1C"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="nJT-Ej-FI5" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1761" y="1212"/>
|
||||
</scene>
|
||||
<!--Peers-->
|
||||
<scene sceneID="psN-bH-gYF">
|
||||
<objects>
|
||||
<navigationController title="Peers" id="LPj-bu-hdp" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="ifJ-0T-bJ4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="Aro-kj-1Us" kind="relationship" relationship="rootViewController" id="rED-QI-0E9"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="gCh-Is-VRG" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1761" y="426"/>
|
||||
</scene>
|
||||
<!--Settings-->
|
||||
<scene sceneID="VfF-sj-c5P">
|
||||
<objects>
|
||||
<tableViewController title="Settings" id="FeQ-BB-bF5" customClass="SettingsViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Cd3-Fg-6d3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="1180"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<sections>
|
||||
<tableViewSection headerTitle="Node Info" footerTitle="Information entered here is public and may be shown on network maps." id="su8-4b-N3L">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="nxn-IW-t8I">
|
||||
<rect key="frame" x="20" y="49.5" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="nxn-IW-t8I" id="a0m-Mn-9fE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="250" contentHorizontalAlignment="trailing" contentVerticalAlignment="center" placeholder="None" textAlignment="right" adjustsFontForContentSizeCategory="YES" minimumFontSize="9" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="iRg-tv-diq">
|
||||
<rect key="frame" x="134" y="1" width="310.5" height="43"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="43" id="cRe-aZ-mWa"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="words" keyboardType="alphabet" enablesReturnKeyAutomatically="YES" textContentType="nickname"/>
|
||||
<connections>
|
||||
<action selector="deviceNameEdited:" destination="FeQ-BB-bF5" eventType="editingDidEnd" id="lfQ-f7-dSt"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Device Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="102" translatesAutoresizingMaskIntoConstraints="NO" id="ieL-P9-WNc">
|
||||
<rect key="frame" x="16" y="0.0" width="102" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="2cx-q4-by8"/>
|
||||
<constraint firstAttribute="width" constant="102" id="MVL-qb-gJw"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="iRg-tv-diq" secondAttribute="trailing" constant="15" id="5Ww-uH-INm"/>
|
||||
<constraint firstItem="ieL-P9-WNc" firstAttribute="top" secondItem="a0m-Mn-9fE" secondAttribute="top" id="Hoe-Le-Zln"/>
|
||||
<constraint firstItem="iRg-tv-diq" firstAttribute="leading" secondItem="ieL-P9-WNc" secondAttribute="trailing" constant="16" id="JXX-kn-TTD"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ieL-P9-WNc" secondAttribute="bottom" id="MOQ-cH-sUE"/>
|
||||
<constraint firstItem="iRg-tv-diq" firstAttribute="top" secondItem="a0m-Mn-9fE" secondAttribute="top" constant="1" id="O3n-WK-oyd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="iRg-tv-diq" secondAttribute="bottom" id="heq-bT-FXa"/>
|
||||
<constraint firstItem="ieL-P9-WNc" firstAttribute="leading" secondItem="a0m-Mn-9fE" secondAttribute="leading" constant="16" id="hy7-uL-DHk"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Automatically Start On" footerTitle="Yggdrasil will be started automatically when connected to the above networks." id="bjf-vx-Swh">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" textLabel="NYE-Pu-5Gk" style="IBUITableViewCellStyleDefault" id="pwi-5Y-UxD">
|
||||
<rect key="frame" x="20" y="159.5" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pwi-5Y-UxD" id="631-3X-gfX">
|
||||
<rect key="frame" x="0.0" y="0.0" width="423" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Wi-Fi" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="NYE-Pu-5Gk">
|
||||
<rect key="frame" x="16" y="0.0" width="399" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" textLabel="ZdY-uX-KE6" style="IBUITableViewCellStyleDefault" id="iwW-oY-kqV">
|
||||
<rect key="frame" x="20" y="203.5" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="iwW-oY-kqV" id="Pe0-bO-Sd1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="423" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Mobile Network" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZdY-uX-KE6">
|
||||
<rect key="frame" x="16" y="0.0" width="399" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Public Key" footerTitle="Your public key forms your identity on the network. It is safe to be shared." id="Bqi-0N-6vQ">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" textLabel="SeD-oT-h3h" style="IBUITableViewCellStyleDefault" id="80f-wf-ING">
|
||||
<rect key="frame" x="20" y="327.5" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="80f-wf-ING" id="fed-pT-rbF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Signing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SeD-oT-h3h" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="16"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Backup" id="mD0-CO-qvR">
|
||||
<string key="footerTitle">Configuration will be exported to the Files app. Your configuration contains your private key which is extremely sensitive. You must not share it with others.</string>
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="0zV-IH-vF4" style="IBUITableViewCellStyleDefault" id="IgR-eA-aHt">
|
||||
<rect key="frame" x="20" y="437.5" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="IgR-eA-aHt" id="wsZ-KR-yUu">
|
||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Import configuration" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="0zV-IH-vF4">
|
||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="n0W-r2-Cp7" style="IBUITableViewCellStyleDefault" id="Fgj-Ug-A8R">
|
||||
<rect key="frame" x="20" y="481.5" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Fgj-Ug-A8R" id="l0v-9n-Tzb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Export configuration" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="n0W-r2-Cp7">
|
||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Reset" footerTitle="Resetting will overwrite with newly generated configuration. Your public keys and IP address on the network will change." id="QPd-T4-5id">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="Jc5-vz-oTA" style="IBUITableViewCellStyleDefault" id="Cgi-Yk-esa">
|
||||
<rect key="frame" x="20" y="619.5" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Cgi-Yk-esa" id="qMT-ha-vJK">
|
||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Reset configuration" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Jc5-vz-oTA">
|
||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.81077963080000004" green="0.26273393630000003" blue="0.2154698987" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="FeQ-BB-bF5" id="UKi-St-qym"/>
|
||||
<outlet property="delegate" destination="FeQ-BB-bF5" id="Pbu-nP-u0N"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Settings" id="13i-0q-HI5"/>
|
||||
<connections>
|
||||
<outlet property="autoStartMobileCell" destination="iwW-oY-kqV" id="kDV-jT-IBR"/>
|
||||
<outlet property="autoStartWiFiCell" destination="pwi-5Y-UxD" id="UJo-BZ-aXf"/>
|
||||
<outlet property="deviceNameField" destination="iRg-tv-diq" id="ffH-UY-BAT"/>
|
||||
<outlet property="signingPublicKeyLabel" destination="SeD-oT-h3h" id="5eK-yA-3LM"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="eco-Zl-sgd" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2571" y="1212"/>
|
||||
</scene>
|
||||
<!--Settings-->
|
||||
<scene sceneID="ot0-wd-NE5">
|
||||
<objects>
|
||||
<navigationController title="Settings" id="g4p-RE-Qtl" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="p6Z-I0-Zza">
|
||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="FeQ-BB-bF5" kind="relationship" relationship="rootViewController" id="pga-rT-3Jc"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="tUJ-Lk-YoU" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2571" y="426"/>
|
||||
</scene>
|
||||
<!--Yggdrasil-->
|
||||
<scene sceneID="zY7-dE-7Ay">
|
||||
<objects>
|
||||
<tableViewController title="Yggdrasil" id="s1Q-pC-XBn" customClass="TableViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="vHG-eF-QEu">
|
||||
<rect key="frame" x="0.0" y="0.0" width="420" height="1180"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<sections>
|
||||
<tableViewSection headerTitle="Status" id="Jwl-JP-RuU">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="49H-YI-ie3">
|
||||
<rect key="frame" x="116" y="49.5" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="49H-YI-ie3" id="ZPC-T2-kah">
|
||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enable Yggdrasil" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="alk-ml-y9V">
|
||||
<rect key="frame" x="16" y="12" width="126" height="20"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="trailing" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="qre-Dz-rWw">
|
||||
<rect key="frame" x="223" y="7" width="51" height="31"/>
|
||||
<connections>
|
||||
<action selector="toggleVPNStatus:forEvent:" destination="s1Q-pC-XBn" eventType="valueChanged" id="Mvh-gf-qg0"/>
|
||||
</connections>
|
||||
</switch>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="qre-Dz-rWw" firstAttribute="top" secondItem="ZPC-T2-kah" secondAttribute="top" constant="7" id="6Yd-ne-dsL"/>
|
||||
<constraint firstItem="alk-ml-y9V" firstAttribute="top" secondItem="ZPC-T2-kah" secondAttribute="top" constant="12" id="Du8-1c-XP8"/>
|
||||
<constraint firstAttribute="trailing" secondItem="qre-Dz-rWw" secondAttribute="trailing" constant="16" id="SUT-kR-Vtj"/>
|
||||
<constraint firstAttribute="bottom" secondItem="alk-ml-y9V" secondAttribute="bottom" constant="12" id="Sz7-IF-DrB"/>
|
||||
<constraint firstItem="alk-ml-y9V" firstAttribute="leading" secondItem="ZPC-T2-kah" secondAttribute="leading" constant="16" id="kGE-t0-Aph"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" textLabel="dZv-7O-fZv" style="IBUITableViewCellStyleDefault" id="m9f-Bi-XeH">
|
||||
<rect key="frame" x="116" y="93.5" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="m9f-Bi-XeH" id="utU-J9-9M8">
|
||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="No active connections" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dZv-7O-fZv">
|
||||
<rect key="frame" x="16" y="0.0" width="256" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
|
||||
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Statistics" id="nJf-RJ-qUC">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="0.0" textLabel="MUj-Ni-chU" detailTextLabel="ceY-dc-u9v" style="IBUITableViewCellStyleValue1" id="Ela-vk-pnR">
|
||||
<rect key="frame" x="116" y="187.5" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Ela-vk-pnR" id="fnr-ZG-yiF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="IP" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MUj-Ni-chU">
|
||||
<rect key="frame" x="16" y="12" width="14.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="N/A" textAlignment="right" lineBreakMode="headTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" adjustsFontForContentSizeCategory="YES" id="ceY-dc-u9v" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
||||
<rect key="frame" x="248.5" y="15" width="23.5" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="blue" indentationWidth="10" textLabel="Q8j-k7-HTk" detailTextLabel="MLH-EY-4VQ" style="IBUITableViewCellStyleValue1" id="1BH-o1-n90">
|
||||
<rect key="frame" x="116" y="231.5" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="1BH-o1-n90" id="aLD-3W-BlB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subnet" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Q8j-k7-HTk">
|
||||
<rect key="frame" x="16" y="12" width="54.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="N/A" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="MLH-EY-4VQ" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
||||
<rect key="frame" x="248.5" y="15" width="23.5" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" textLabel="9jY-kM-E6n" detailTextLabel="JYJ-ov-02q" style="IBUITableViewCellStyleValue1" id="g00-iP-grJ">
|
||||
<rect key="frame" x="116" y="275.5" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="g00-iP-grJ" id="C21-9O-H5d">
|
||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Coordinates" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="9jY-kM-E6n">
|
||||
<rect key="frame" x="16" y="12" width="92.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="[]" textAlignment="right" lineBreakMode="headTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" adjustsFontForContentSizeCategory="YES" id="JYJ-ov-02q" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
||||
<rect key="frame" x="261.5" y="15" width="10.5" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Configuration" footerTitle="You must re-enable Yggdrasil after modifying Peers or Settings to make any changes effective." id="gRf-Ts-qeJ">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="blue" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="rT6-UD-Cn5" detailTextLabel="vc0-Rq-wtq" style="IBUITableViewCellStyleValue1" id="qRF-c3-JyG">
|
||||
<rect key="frame" x="116" y="377" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="qRF-c3-JyG" id="gcO-mr-jgp">
|
||||
<rect key="frame" x="0.0" y="0.0" width="262.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Peers" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="rT6-UD-Cn5">
|
||||
<rect key="frame" x="16" y="12" width="43.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="No peers" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="vc0-Rq-wtq">
|
||||
<rect key="frame" x="196" y="15" width="58.5" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="LPj-bu-hdp" kind="showDetail" id="tx6-4f-Vm0"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="blue" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="CPw-Tm-fZl" style="IBUITableViewCellStyleDefault" id="Ugm-vO-zYq">
|
||||
<rect key="frame" x="116" y="421" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Ugm-vO-zYq" id="Jkh-no-wta">
|
||||
<rect key="frame" x="0.0" y="0.0" width="262.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Settings" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="CPw-Tm-fZl">
|
||||
<rect key="frame" x="16" y="0.0" width="238.5" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="g4p-RE-Qtl" kind="showDetail" id="hEo-ra-aPX"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="it5-My-OoQ" detailTextLabel="1mF-wN-xLU" style="IBUITableViewCellStyleValue1" id="SNP-Qf-NZg">
|
||||
<rect key="frame" x="116" y="465" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SNP-Qf-NZg" id="2mC-0D-KCT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Version" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="it5-My-OoQ">
|
||||
<rect key="frame" x="16" y="12" width="57" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Unknown" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1mF-wN-xLU">
|
||||
<rect key="frame" x="211.5" y="15" width="60.5" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="s1Q-pC-XBn" id="ASk-mj-jQP"/>
|
||||
<outlet property="delegate" destination="s1Q-pC-XBn" id="3yd-vi-tqY"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Yggdrasil" leftItemsSupplementBackButton="YES" largeTitleDisplayMode="always" id="zEJ-Ur-D8L">
|
||||
<barButtonItem key="backBarButtonItem" title="Status" id="kru-5r-NnH"/>
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="refresh" id="SK1-2o-4fg">
|
||||
<connections>
|
||||
<action selector="onRefreshButton:" destination="s1Q-pC-XBn" id="Tqe-lm-dDv"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="connectedStatusLabel" destination="dZv-7O-fZv" id="DfM-cR-8VQ"/>
|
||||
<outlet property="statsSelfCoords" destination="JYJ-ov-02q" id="lcM-hA-tsY"/>
|
||||
<outlet property="statsSelfCoordsCell" destination="g00-iP-grJ" id="Ho9-VC-QSe"/>
|
||||
<outlet property="statsSelfIP" destination="ceY-dc-u9v" id="Zob-e3-cVr"/>
|
||||
<outlet property="statsSelfIPCell" destination="Ela-vk-pnR" id="01S-pD-zJc"/>
|
||||
<outlet property="statsSelfPeers" destination="vc0-Rq-wtq" id="usQ-EN-040"/>
|
||||
<outlet property="statsSelfSubnet" destination="MLH-EY-4VQ" id="33U-qS-FUE"/>
|
||||
<outlet property="statsSelfSubnetCell" destination="1BH-o1-n90" id="Njb-oQ-W5C"/>
|
||||
<outlet property="statsVersion" destination="1mF-wN-xLU" id="drW-io-cYk"/>
|
||||
<outlet property="toggleConnect" destination="qre-Dz-rWw" id="Oox-v4-K0x"/>
|
||||
<outlet property="toggleLabel" destination="alk-ml-y9V" id="o4p-Xn-ofm"/>
|
||||
<outlet property="toggleTableView" destination="vHG-eF-QEu" id="iNr-0v-RoB"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Nbt-Cc-GRV" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2571" y="-338"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="VMS-X3-A7G">
|
||||
<objects>
|
||||
<viewController id="j4D-sS-gKL" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="eFY-KL-QD6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="1180"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.10000000000000001" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="YggdrasilNetwork" translatesAutoresizingMaskIntoConstraints="NO" id="pD8-7E-1Fb">
|
||||
<rect key="frame" x="100" y="511" width="299.5" height="98"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="pD8-7E-1Fb" secondAttribute="height" multiplier="480:157" id="60u-Jo-0oL"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="99T-rn-Aup"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="pD8-7E-1Fb" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="99T-rn-Aup" secondAttribute="leading" constant="100" id="ByQ-oN-wNr"/>
|
||||
<constraint firstItem="99T-rn-Aup" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="pD8-7E-1Fb" secondAttribute="trailing" constant="100" id="b14-Ic-a2R"/>
|
||||
<constraint firstItem="pD8-7E-1Fb" firstAttribute="centerX" secondItem="eFY-KL-QD6" secondAttribute="centerX" id="kZ4-ij-5GT"/>
|
||||
<constraint firstItem="pD8-7E-1Fb" firstAttribute="centerY" secondItem="eFY-KL-QD6" secondAttribute="centerY" constant="-30" id="xxi-aE-iPO"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Z9V-gc-NxA" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1474" y="-1008"/>
|
||||
</scene>
|
||||
<!--Yggdrasil-->
|
||||
<scene sceneID="NHm-je-2CC">
|
||||
<objects>
|
||||
<navigationController title="Yggdrasil" id="Dz7-et-ljx" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="uxo-U2-UUS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="420" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="6hK-6f-rI2">
|
||||
<rect key="frame" x="100" y="0.0" width="0.0" height="0.0"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</toolbar>
|
||||
<connections>
|
||||
<segue destination="s1Q-pC-XBn" kind="relationship" relationship="rootViewController" id="foA-iq-EPh"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="nYt-zg-2Gb" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1762" y="-337"/>
|
||||
</scene>
|
||||
<!--Split View Controller-->
|
||||
<scene sceneID="9co-Q0-BvB">
|
||||
<objects>
|
||||
<splitViewController modalPresentationStyle="pageSheet" allowDoubleColumnStyle="YES" preferredDisplayMode="beside" behavior="tile" presentsWithGesture="NO" id="sjP-mj-LKX" customClass="SplitViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<connections>
|
||||
<segue destination="Dz7-et-ljx" kind="relationship" relationship="masterViewController" id="QfQ-La-EfI"/>
|
||||
<segue destination="j4D-sS-gKL" kind="relationship" relationship="detailViewController" id="RcM-Sy-h8j"/>
|
||||
</connections>
|
||||
</splitViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Fe3-ey-WRA" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="811" y="-5"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="YggdrasilNetwork" width="480" height="157"/>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
|
@ -1,52 +0,0 @@
|
|||
//
|
||||
// CopyableLabel.swift
|
||||
// YggdrasilNetwork
|
||||
//
|
||||
// Created by Neil Alexander on 26/02/2019.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class CopyableLabel: UILabel {
|
||||
override public var canBecomeFirstResponder: Bool {
|
||||
get {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
self.isUserInteractionEnabled = true
|
||||
self.addGestureRecognizer(UILongPressGestureRecognizer(
|
||||
target: self,
|
||||
action: #selector(showMenu(sender:))
|
||||
))
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
self.isUserInteractionEnabled = true
|
||||
self.addGestureRecognizer(UILongPressGestureRecognizer(
|
||||
target: self,
|
||||
action: #selector(showMenu(sender:))
|
||||
))
|
||||
}
|
||||
|
||||
override func copy(_ sender: Any?) {
|
||||
UIPasteboard.general.string = text
|
||||
UIMenuController.shared.setMenuVisible(false, animated: true)
|
||||
}
|
||||
|
||||
@objc func showMenu(sender: Any?) {
|
||||
self.becomeFirstResponder()
|
||||
let menu = UIMenuController.shared
|
||||
if !menu.isMenuVisible {
|
||||
menu.setTargetRect(bounds, in: self)
|
||||
menu.setMenuVisible(true, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
|
||||
return (action == #selector(copy(_:)))
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// ToggleTableViewCell.swift
|
||||
// YggdrasilNetwork
|
||||
//
|
||||
// Created by Neil Alexander on 07/01/2019.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class ToggleTableViewCell: UITableViewCell {
|
||||
|
||||
@IBOutlet weak var label: UILabel!
|
||||
@IBOutlet weak var toggle: UISwitch!
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
// Initialization code
|
||||
}
|
||||
|
||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||
super.setSelected(selected, animated: animated)
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
}
|
|
@ -1,286 +0,0 @@
|
|||
//
|
||||
// PeersViewController.swift
|
||||
// YggdrasilNetwork
|
||||
//
|
||||
// Created by Neil Alexander on 07/01/2019.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import NetworkExtension
|
||||
import CoreTelephony
|
||||
|
||||
class PeersViewController: UITableViewController {
|
||||
var app = UIApplication.shared.delegate as! AppDelegate
|
||||
var config: [String: Any]? = nil
|
||||
|
||||
@IBOutlet var peerTable: UITableView!
|
||||
@IBOutlet weak var addButtonItem: UIBarButtonItem!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if let proto = self.app.vpnManager.protocolConfiguration as? NETunnelProviderProtocol {
|
||||
config = proto.providerConfiguration ?? nil
|
||||
}
|
||||
|
||||
self.navigationItem.rightBarButtonItems = [
|
||||
self.editButtonItem,
|
||||
self.addButtonItem
|
||||
]
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilPeersUpdated), name: NSNotification.Name.YggdrasilPeersUpdated, object: nil)
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.YggdrasilPeersUpdated, object: nil)
|
||||
}
|
||||
|
||||
@objc func onYggdrasilPeersUpdated(notification: NSNotification) {
|
||||
peerTable.reloadData()
|
||||
}
|
||||
|
||||
// MARK: - Table view data source
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 3
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
switch section {
|
||||
case 0: return app.yggdrasilPeers.count
|
||||
case 1:
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
if let peers = config.get("Peers") as? [String] {
|
||||
return peers.count
|
||||
}
|
||||
}
|
||||
return 0
|
||||
case 2:
|
||||
return 2
|
||||
default: return 0
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
switch indexPath.section {
|
||||
case 0:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "discoveredPeerPrototype", for: indexPath)
|
||||
let peers = app.yggdrasilPeers.sorted { (a, b) -> Bool in
|
||||
return (a["Port"] as! Int) < (b["Port"] as! Int)
|
||||
}
|
||||
|
||||
if indexPath.row < peers.count {
|
||||
let value = peers[indexPath.row]
|
||||
let proto = value["Protocol"] as? String ?? "tcp"
|
||||
let remote = value["Remote"] as? String ?? "unknown"
|
||||
let prio = value["Priority"] as? Int ?? 0
|
||||
|
||||
cell.textLabel?.text = "\(value["IP"] ?? "(unknown)")"
|
||||
cell.detailTextLabel?.text = "\(proto.uppercased()): \(remote)"
|
||||
}
|
||||
return cell
|
||||
case 1:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "configuredPeerPrototype", for: indexPath)
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
if let peers = config.get("Peers") as? [String] {
|
||||
cell.textLabel?.text = peers[indexPath.last!]
|
||||
} else {
|
||||
cell.textLabel?.text = "(unknown)"
|
||||
}
|
||||
}
|
||||
return cell
|
||||
case 2:
|
||||
switch indexPath.last {
|
||||
case 0:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell
|
||||
cell.isUserInteractionEnabled = true
|
||||
cell.label?.text = "Discoverable over multicast"
|
||||
cell.label?.isEnabled = true
|
||||
cell.toggle?.addTarget(self, action: #selector(toggledMulticastBeacons), for: .valueChanged)
|
||||
cell.toggle?.isEnabled = true
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
cell.toggle?.isOn = config.multicastBeacons
|
||||
}
|
||||
return cell
|
||||
case 1:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell
|
||||
cell.isUserInteractionEnabled = true
|
||||
cell.label?.text = "Search for multicast peers"
|
||||
cell.label?.isEnabled = true
|
||||
cell.toggle?.addTarget(self, action: #selector(toggledMulticastListen), for: .valueChanged)
|
||||
cell.toggle?.isEnabled = true
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
cell.toggle?.isOn = config.multicastListen
|
||||
}
|
||||
return cell
|
||||
default:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "menuPrototype", for: indexPath)
|
||||
cell.isUserInteractionEnabled = false
|
||||
cell.textLabel?.text = "Unknown"
|
||||
cell.textLabel?.isEnabled = true
|
||||
return cell
|
||||
}
|
||||
default:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "configuredPeerPrototype", for: indexPath)
|
||||
cell.textLabel?.text = "(unknown)"
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
func format(bytes: Double) -> String {
|
||||
guard bytes > 0 else {
|
||||
return "0 bytes"
|
||||
}
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/18650828
|
||||
let suffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
|
||||
let k: Double = 1000
|
||||
let i = floor(log(bytes) / log(k))
|
||||
|
||||
// Format number with thousands separator and everything below 1 GB with no decimal places.
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.maximumFractionDigits = i < 3 ? 0 : 1
|
||||
numberFormatter.numberStyle = .decimal
|
||||
|
||||
let numberString = numberFormatter.string(from: NSNumber(value: bytes / pow(k, i))) ?? "Unknown"
|
||||
let suffix = suffixes[Int(i)]
|
||||
return "\(numberString) \(suffix)"
|
||||
}
|
||||
|
||||
@objc func toggledMulticastBeacons(_ sender: UISwitch) {
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
config.multicastBeacons = sender.isOn
|
||||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func toggledMulticastListen(_ sender: UISwitch) {
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
config.multicastListen = sender.isOn
|
||||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
switch section {
|
||||
case 0:
|
||||
if self.app.yggdrasilPeers.count > 0 {
|
||||
return "Connected Peers"
|
||||
}
|
||||
return "No peers currently connected"
|
||||
case 1:
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
if let peers = config.get("Peers") as? [String] {
|
||||
if peers.count > 0 {
|
||||
return "Configured Peers"
|
||||
}
|
||||
}
|
||||
}
|
||||
return "No peers currently configured"
|
||||
case 2:
|
||||
return "Peer Connectivity"
|
||||
default: return "(Unknown)"
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
|
||||
switch section {
|
||||
case 1:
|
||||
return "Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer."
|
||||
case 2:
|
||||
var str = "Multicast peers will be discovered on the same Wi-Fi network or via USB."
|
||||
if UIDevice.current.hasCellularCapabilites {
|
||||
str += " Data charges may apply when using mobile data. You can prevent mobile data usage in the device settings."
|
||||
}
|
||||
return str
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
||||
return indexPath.first == 1
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
|
||||
switch indexPath.first {
|
||||
case 0:
|
||||
return [UITableViewRowAction(style: UITableViewRowAction.Style.default, title: "Disconnect", handler: { (action, index) in
|
||||
|
||||
})]
|
||||
case 1:
|
||||
return [UITableViewRowAction(style: UITableViewRowAction.Style.normal, title: "Remove", handler: { (action, index) in
|
||||
print(action, index)
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
config.remove(index: index.last!, from: "Peers")
|
||||
do {
|
||||
try config.save(to: &self.app.vpnManager)
|
||||
tableView.reloadSections(IndexSet(integer: 1), with: UITableView.RowAnimation.automatic)
|
||||
} catch {
|
||||
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
||||
self.parent?.present(alert, animated: true, completion: nil)
|
||||
print("Error removing: \(error)")
|
||||
}
|
||||
}
|
||||
})]
|
||||
default:
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
switch indexPath.first {
|
||||
case 2:
|
||||
if let last = indexPath.last, last == 2 {
|
||||
UIApplication.shared.open(NSURL(string:UIApplication.openSettingsURLString)! as URL, options: [:]) { (result) in
|
||||
NSLog("Result " + result.description)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
}
|
||||
|
||||
@IBAction func addNewPeerButtonPressed(_ sender: UIBarButtonItem) {
|
||||
let alert = UIAlertController(title: "Add Configured Peer", message: """
|
||||
Enter the full URI of the peer to add. Yggdrasil will automatically connect to this peer when started.
|
||||
""", preferredStyle: UIAlertController.Style.alert)
|
||||
let action = UIAlertAction(title: "Add", style: .default) { (alertAction) in
|
||||
let textField = alert.textFields![0] as UITextField
|
||||
if let text = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines) {
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
if let peers = config.get("Peers") as? [String], !peers.contains(text) {
|
||||
config.add(text, in: "Peers")
|
||||
do {
|
||||
try config.save(to: &self.app.vpnManager)
|
||||
if let index = config.get("Peers") as? [String] {
|
||||
self.peerTable.insertRows(at: [IndexPath(indexes: [1, index.count-1])], with: .automatic)
|
||||
self.peerTable.reloadSections(IndexSet(integer: 1), with: UITableView.RowAnimation.automatic)
|
||||
}
|
||||
} catch {
|
||||
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
||||
self.parent?.present(alert, animated: true, completion: nil)
|
||||
print("Add error: \(error)")
|
||||
}
|
||||
} else {
|
||||
let alert = UIAlertController(title: "Error", message: "Peer already exists", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
||||
self.parent?.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let cancel = UIAlertAction(title: "Cancel", style: .cancel)
|
||||
alert.addTextField { (textField) in
|
||||
textField.placeholder = "tcp://hostname:port"
|
||||
}
|
||||
alert.addAction(action)
|
||||
alert.addAction(cancel)
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
//
|
||||
// SettingsTableViewController.swift
|
||||
// YggdrasilNetwork
|
||||
//
|
||||
// Created by Neil Alexander on 03/01/2019.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import NetworkExtension
|
||||
|
||||
class SettingsViewController: UITableViewController, UIDocumentBrowserViewControllerDelegate {
|
||||
var app = UIApplication.shared.delegate as! AppDelegate
|
||||
|
||||
@IBOutlet weak var deviceNameField: UITextField!
|
||||
|
||||
@IBOutlet weak var signingPublicKeyLabel: UILabel!
|
||||
|
||||
@IBOutlet weak var autoStartWiFiCell: UITableViewCell!
|
||||
@IBOutlet weak var autoStartMobileCell: UITableViewCell!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
deviceNameField.text = config.get("name", inSection: "NodeInfo") as? String ?? ""
|
||||
signingPublicKeyLabel.text = config.get("PublicKey") as? String ?? config.get("SigningPublicKey") as? String ?? "Unknown"
|
||||
|
||||
autoStartWiFiCell.accessoryType = config.get("WiFi", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none
|
||||
autoStartMobileCell.accessoryType = config.get("Mobile", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func deviceNameEdited(_ sender: UITextField) {
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
config.set("name", inSection: "NodeInfo", to: sender.text)
|
||||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
switch indexPath.first {
|
||||
case 1:
|
||||
let settings = [
|
||||
"WiFi",
|
||||
"Mobile"
|
||||
]
|
||||
if let cell = tableView.cellForRow(at: indexPath) {
|
||||
cell.accessoryType = cell.accessoryType == .checkmark ? .none : .checkmark
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
config.set(settings[indexPath.last!], inSection: "AutoStart", to: cell.accessoryType == .checkmark)
|
||||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
switch indexPath.last {
|
||||
case 0: // import
|
||||
if #available(iOS 11.0, *) {
|
||||
let open = UIDocumentBrowserViewController(forOpeningFilesWithContentTypes: ["eu.neilalexander.yggdrasil.configuration"])
|
||||
open.delegate = self
|
||||
open.allowsDocumentCreation = false
|
||||
open.allowsPickingMultipleItems = false
|
||||
open.additionalTrailingNavigationBarButtonItems = [ UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelDocumentBrowser)) ]
|
||||
self.present(open, animated: true, completion: nil)
|
||||
} else {
|
||||
let alert = UIAlertController(title: "Import Configuration", message: "Not supported on this version of iOS!", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
case 1: // export
|
||||
if let config = self.app.yggdrasilConfig, let data = config.data() {
|
||||
var fileURL: URL?
|
||||
var fileDir: URL?
|
||||
do {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd"
|
||||
let date = dateFormatter.string(from: Date())
|
||||
fileDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||
fileURL = fileDir?.appendingPathComponent("Yggdrasil Backup \(date).yggconf")
|
||||
try? data.write(to: fileURL!)
|
||||
} catch {
|
||||
break
|
||||
}
|
||||
if let dir = fileDir {
|
||||
let sharedurl = dir.absoluteString.replacingOccurrences(of: "file://", with: "shareddocuments://")
|
||||
let furl: URL = URL(string: sharedurl)!
|
||||
UIApplication.shared.open(furl, options: [:], completionHandler: nil)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
case 4:
|
||||
let alert = UIAlertController(title: "Warning", message: "This operation will reset your configuration and generate new keys. This is not reversible unless your configuration has been exported. Changes will not take effect until the next time Yggdrasil is restarted.", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "Reset", style: .destructive, handler: { action in
|
||||
self.app.yggdrasilConfig = ConfigurationProxy()
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
try? config.save(to: &self.app.vpnManager)
|
||||
self.viewDidLoad()
|
||||
}}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
default:
|
||||
break
|
||||
}
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
}
|
||||
|
||||
@objc func cancelDocumentBrowser() {
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) {
|
||||
do {
|
||||
if let url = documentURLs.first {
|
||||
let data = try Data(contentsOf: url)
|
||||
let conf = try ConfigurationProxy(json: data)
|
||||
try conf.save(to: &self.app.vpnManager)
|
||||
self.app.yggdrasilConfig = conf
|
||||
|
||||
controller.dismiss(animated: true, completion: nil)
|
||||
let alert = UIAlertController(title: "Import Configuration", message: "Configuration file has been imported.", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
} catch {
|
||||
controller.dismiss(animated: true, completion: nil)
|
||||
let alert = UIAlertController(title: "Import Failed", message: "Unable to import this configuration file.", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
self.viewDidLoad()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
//
|
||||
// SplitViewController.swift
|
||||
// YggdrasilNetwork
|
||||
//
|
||||
// Created by Neil Alexander on 02/01/2019.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SplitViewController: UISplitViewController, UISplitViewControllerDelegate {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.delegate = self
|
||||
self.preferredDisplayMode = .allVisible
|
||||
}
|
||||
|
||||
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@available(iOS 14.0,*)
|
||||
func splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column {
|
||||
return .primary
|
||||
}
|
||||
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
import UIKit
|
||||
import NetworkExtension
|
||||
import Yggdrasil
|
||||
|
||||
class TableViewController: UITableViewController {
|
||||
var app = UIApplication.shared.delegate as! AppDelegate
|
||||
|
||||
@IBOutlet var connectedStatusLabel: UILabel!
|
||||
|
||||
@IBOutlet var toggleTableView: UITableView!
|
||||
@IBOutlet var toggleLabel: UILabel!
|
||||
@IBOutlet var toggleConnect: UISwitch!
|
||||
|
||||
@IBOutlet weak var statsSelfIPCell: UITableViewCell!
|
||||
@IBOutlet weak var statsSelfSubnetCell: UITableViewCell!
|
||||
@IBOutlet weak var statsSelfCoordsCell: UITableViewCell!
|
||||
|
||||
@IBOutlet var statsSelfIP: UILabel!
|
||||
@IBOutlet var statsSelfSubnet: UILabel!
|
||||
@IBOutlet var statsSelfCoords: UILabel!
|
||||
@IBOutlet var statsSelfPeers: UILabel!
|
||||
|
||||
@IBOutlet var statsVersion: UILabel!
|
||||
|
||||
override func viewDidLoad() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSelfUpdated), name: NSNotification.Name.YggdrasilSelfUpdated, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilPeersUpdated), name: NSNotification.Name.YggdrasilPeersUpdated, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilDHTUpdated), name: NSNotification.Name.YggdrasilDHTUpdated, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSettingsUpdated), name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil)
|
||||
}
|
||||
|
||||
@IBAction func onRefreshButton(_ sender: UIButton) {
|
||||
sender.isEnabled = false
|
||||
app.makeIPCRequests()
|
||||
sender.isEnabled = true
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
//NotificationCenter.default.addObserver(self, selector: #selector(TableViewController.VPNStatusDidChange(_:)), name: NSNotification.Name.NEVPNStatusDidChange, object: nil)
|
||||
|
||||
if let row = self.tableView.indexPathForSelectedRow {
|
||||
self.tableView.deselectRow(at: row, animated: true)
|
||||
}
|
||||
|
||||
self.statsVersion.text = Yggdrasil.MobileGetVersion()
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
//NotificationCenter.default.removeObserver(self, name: NSNotification.Name.NEVPNStatusDidChange, object: nil)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
self.onYggdrasilSelfUpdated(notification: NSNotification.init(name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil))
|
||||
}
|
||||
|
||||
override func viewWillLayoutSubviews() {
|
||||
self.onYggdrasilSelfUpdated(notification: NSNotification.init(name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil))
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
if let row = self.tableView.indexPathForSelectedRow {
|
||||
self.tableView.deselectRow(at: row, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func onYggdrasilSettingsUpdated(notification: NSNotification) {
|
||||
toggleLabel.isEnabled = !app.vpnManager.isOnDemandEnabled
|
||||
toggleConnect.isEnabled = !app.vpnManager.isOnDemandEnabled
|
||||
|
||||
if let footer = toggleTableView.footerView(forSection: 0) {
|
||||
if let label = footer.textLabel {
|
||||
label.text = app.vpnManager.isOnDemandEnabled ? "Yggdrasil is configured to automatically start and stop based on available connectivity." : "Yggdrasil is configured to start and stop manually."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateConnectedStatus() {
|
||||
if self.app.vpnManager.connection.status == .connected {
|
||||
if app.yggdrasilDHT.count > 0 {
|
||||
connectedStatusLabel.text = "Enabled"
|
||||
connectedStatusLabel.textColor = UIColor(red: 0.37, green: 0.79, blue: 0.35, alpha: 1.0)
|
||||
} else {
|
||||
connectedStatusLabel.text = "No connectivity"
|
||||
connectedStatusLabel.textColor = UIColor.red
|
||||
}
|
||||
} else {
|
||||
connectedStatusLabel.text = "Not enabled"
|
||||
connectedStatusLabel.textColor = UIColor.systemGray
|
||||
}
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
}
|
||||
|
||||
@objc func onYggdrasilSelfUpdated(notification: NSNotification) {
|
||||
statsSelfIP.text = app.yggdrasilIP
|
||||
statsSelfSubnet.text = app.yggdrasilSubnet
|
||||
statsSelfCoords.text = app.yggdrasilCoords
|
||||
|
||||
statsSelfIPCell.layoutSubviews()
|
||||
statsSelfSubnetCell.layoutSubviews()
|
||||
statsSelfCoordsCell.layoutSubviews()
|
||||
|
||||
let status = self.app.vpnManager.connection.status
|
||||
toggleConnect.isOn = status == .connecting || status == .connected
|
||||
|
||||
self.updateConnectedStatus()
|
||||
}
|
||||
|
||||
@objc func onYggdrasilDHTUpdated(notification: NSNotification) {
|
||||
self.updateConnectedStatus()
|
||||
}
|
||||
|
||||
@objc func onYggdrasilPeersUpdated(notification: NSNotification) {
|
||||
let peercount = app.yggdrasilPeers.count
|
||||
if peercount <= 0 {
|
||||
statsSelfPeers.text = "No peers"
|
||||
} else if peercount == 1 {
|
||||
statsSelfPeers.text = "\(peercount) peer"
|
||||
} else {
|
||||
statsSelfPeers.text = "\(peercount) peers"
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func toggleVPNStatus(_ sender: UISwitch, forEvent event: UIEvent) {
|
||||
if sender.isOn {
|
||||
do {
|
||||
try self.app.vpnManager.connection.startVPNTunnel()
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
} else {
|
||||
self.app.vpnManager.connection.stopVPNTunnel()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,72 +3,54 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 52;
|
||||
objectVersion = 55;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3913E9C021DD3A51001E0EC7 /* SplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3913E9BF21DD3A51001E0EC7 /* SplitViewController.swift */; };
|
||||
391B72A82A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */; };
|
||||
3939196B21E35A7C009320F3 /* PeersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939196A21E35A7C009320F3 /* PeersViewController.swift */; };
|
||||
3939196D21E39313009320F3 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939196C21E39313009320F3 /* UIDevice.swift */; };
|
||||
3939197321E39815009320F3 /* ToggleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939197221E39815009320F3 /* ToggleTableViewCell.swift */; };
|
||||
394A1EB321DEA46400D9F553 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 394A1EB221DEA46400D9F553 /* SettingsViewController.swift */; };
|
||||
3952ADB729945AF700B3835D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
||||
3952ADB829945AF700B3835D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
||||
3952ADBA29945AFA00B3835D /* CrossPlatformAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */; };
|
||||
39682A392225AD15004FB670 /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39682A382225AD15004FB670 /* CopyableLabel.swift */; };
|
||||
3996AF38270328080070947D /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
||||
3996AF39270328080070947D /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
||||
39AE88392319C93F0010FFF6 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39AE88382319C93F0010FFF6 /* NetworkExtension.framework */; };
|
||||
39B51A4A2997062E0059D29D /* PeersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B51A492997062E0059D29D /* PeersView.swift */; };
|
||||
39B51A4B29994F240059D29D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
||||
39B51A4C29994F350059D29D /* CrossPlatformAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */; };
|
||||
39B51A4D299951D60059D29D /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; };
|
||||
39BF9FC62A2F5FA7000E7269 /* PacketTunnelProvider+FileDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39BF9FC52A2F5FA7000E7269 /* PacketTunnelProvider+FileDescriptor.swift */; };
|
||||
39B51A4D299951D60059D29D /* IPCResponses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* IPCResponses.swift */; };
|
||||
39BF9FC72A2F6FFD000E7269 /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
||||
39CC924C221DEDCE004960DC /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; };
|
||||
39CC924D221DEDD3004960DC /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; };
|
||||
39CC924D221DEDD3004960DC /* IPCResponses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* IPCResponses.swift */; };
|
||||
39F0205E2996CD760093F603 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0205D2996CD760093F603 /* Application.swift */; };
|
||||
39F020602996CD760093F603 /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0205F2996CD760093F603 /* StatusView.swift */; };
|
||||
39F020622996CD770093F603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39F020612996CD770093F603 /* Assets.xcassets */; };
|
||||
39F020662996CD770093F603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39F020652996CD770093F603 /* Preview Assets.xcassets */; };
|
||||
39F0206B2996CF260093F603 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0206A2996CF260093F603 /* SettingsView.swift */; };
|
||||
E593CE6F1DF8FC3C00D7265D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE6E1DF8FC3C00D7265D /* AppDelegate.swift */; };
|
||||
E593CE711DF8FC3C00D7265D /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE701DF8FC3C00D7265D /* TableViewController.swift */; };
|
||||
E593CE741DF8FC3C00D7265D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E593CE721DF8FC3C00D7265D /* Main.storyboard */; };
|
||||
E593CE761DF8FC3C00D7265D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E593CE751DF8FC3C00D7265D /* Assets.xcassets */; };
|
||||
E593CE791DF8FC3C00D7265D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E593CE771DF8FC3C00D7265D /* LaunchScreen.storyboard */; };
|
||||
39F99B342A48F6E50045BD10 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39AE88382319C93F0010FFF6 /* NetworkExtension.framework */; };
|
||||
39F99B382A48F74F0045BD10 /* YggdrasilNetworkExtension.appex in CopyFiles */ = {isa = PBXBuildFile; fileRef = E593CE971DF905AF00D7265D /* YggdrasilNetworkExtension.appex */; platformFilters = (ios, macos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
E593CE9C1DF905AF00D7265D /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE9B1DF905AF00D7265D /* PacketTunnelProvider.swift */; };
|
||||
E593CEA01DF905AF00D7265D /* YggdrasilNetworkExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = E593CE971DF905AF00D7265D /* YggdrasilNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
E593CE9E1DF905AF00D7265D /* PBXContainerItemProxy */ = {
|
||||
39F99B352A48F70F0045BD10 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = E593CE631DF8FC3C00D7265D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = E593CE961DF905AF00D7265D;
|
||||
remoteInfo = NEPacketTunnelVPNDemoTunnel;
|
||||
remoteInfo = YggdrasilNetworkExtension;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
E593CEA41DF905B000D7265D /* Embed Foundation Extensions */ = {
|
||||
39F99B372A48F7380045BD10 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
E593CEA01DF905AF00D7265D /* YggdrasilNetworkExtension.appex in Embed Foundation Extensions */,
|
||||
39F99B382A48F74F0045BD10 /* YggdrasilNetworkExtension.appex in CopyFiles */,
|
||||
);
|
||||
name = "Embed Foundation Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilNetworkExtension.entitlements; sourceTree = "<group>"; };
|
||||
3913E99E21DB9B41001E0EC7 /* YggdrasilNetwork.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilNetwork.entitlements; sourceTree = "<group>"; };
|
||||
3913E9BF21DD3A51001E0EC7 /* SplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewController.swift; sourceTree = "<group>"; };
|
||||
391B72A52A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PacketTunnelProvider+FileDescriptor.h"; sourceTree = "<group>"; };
|
||||
391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PacketTunnelProvider+FileDescriptor.swift"; sourceTree = "<group>"; };
|
||||
|
@ -84,9 +66,7 @@
|
|||
39AE88382319C93F0010FFF6 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
|
||||
39B51A492997062E0059D29D /* PeersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeersView.swift; sourceTree = "<group>"; };
|
||||
39BF9FC12A2E9E51000E7269 /* YggdrasilNetworkExtension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YggdrasilNetworkExtension-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
39BF9FC22A2E9E52000E7269 /* PacketTunnelProvider+FileDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PacketTunnelProvider+FileDescriptor.h"; sourceTree = "<group>"; };
|
||||
39BF9FC52A2F5FA7000E7269 /* PacketTunnelProvider+FileDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PacketTunnelProvider+FileDescriptor.swift"; sourceTree = "<group>"; };
|
||||
39CC924B221DEDCE004960DC /* NSNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSNotification.swift; sourceTree = "<group>"; };
|
||||
39CC924B221DEDCE004960DC /* IPCResponses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPCResponses.swift; sourceTree = "<group>"; };
|
||||
39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YggdrasilSwiftUI.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
39F0205D2996CD760093F603 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||
39F0205F2996CD760093F603 /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = "<group>"; };
|
||||
|
@ -94,7 +74,6 @@
|
|||
39F020632996CD770093F603 /* YggdrasilSwiftUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilSwiftUI.entitlements; sourceTree = "<group>"; };
|
||||
39F020652996CD770093F603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
39F0206A2996CF260093F603 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||
E593CE6B1DF8FC3C00D7265D /* YggdrasilNetwork.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YggdrasilNetwork.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E593CE6E1DF8FC3C00D7265D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
E593CE701DF8FC3C00D7265D /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
|
||||
E593CE731DF8FC3C00D7265D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
|
@ -111,19 +90,11 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
39F99B342A48F6E50045BD10 /* NetworkExtension.framework in Frameworks */,
|
||||
39BF9FC72A2F6FFD000E7269 /* Yggdrasil.xcframework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E593CE681DF8FC3C00D7265D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3996AF38270328080070947D /* Yggdrasil.xcframework in Frameworks */,
|
||||
39AE88392319C93F0010FFF6 /* NetworkExtension.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E593CE941DF905AF00D7265D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -185,7 +156,7 @@
|
|||
children = (
|
||||
3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */,
|
||||
3952ADB629945AF700B3835D /* ConfigurationProxy.swift */,
|
||||
39CC924B221DEDCE004960DC /* NSNotification.swift */,
|
||||
39CC924B221DEDCE004960DC /* IPCResponses.swift */,
|
||||
);
|
||||
name = "Yggdrasil Network Core";
|
||||
path = "Yggdrasil Network Cross-Platform";
|
||||
|
@ -226,8 +197,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
3952ADB529945AE900B3835D /* Yggdrasil Network Core */,
|
||||
3913E99E21DB9B41001E0EC7 /* YggdrasilNetwork.entitlements */,
|
||||
3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */,
|
||||
E593CE981DF905AF00D7265D /* Yggdrasil Network Extension */,
|
||||
E593CE6D1DF8FC3C00D7265D /* Yggdrasil Network iOS */,
|
||||
39F0205C2996CD760093F603 /* YggdrasilSwiftUI */,
|
||||
|
@ -239,7 +208,6 @@
|
|||
E593CE6C1DF8FC3C00D7265D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E593CE6B1DF8FC3C00D7265D /* YggdrasilNetwork.app */,
|
||||
E593CE971DF905AF00D7265D /* YggdrasilNetworkExtension.appex */,
|
||||
39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */,
|
||||
);
|
||||
|
@ -266,6 +234,7 @@
|
|||
E593CE9B1DF905AF00D7265D /* PacketTunnelProvider.swift */,
|
||||
391B72A52A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.h */,
|
||||
391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */,
|
||||
3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */,
|
||||
391B72A72A2FD90100896278 /* YggdrasilNetworkExtension-Bridging-Header.h */,
|
||||
E593CE9D1DF905AF00D7265D /* Info.plist */,
|
||||
39BF9FC12A2E9E51000E7269 /* YggdrasilNetworkExtension-Bridging-Header.h */,
|
||||
|
@ -283,35 +252,18 @@
|
|||
39F020572996CD760093F603 /* Sources */,
|
||||
39F020582996CD760093F603 /* Frameworks */,
|
||||
39F020592996CD760093F603 /* Resources */,
|
||||
39F99B372A48F7380045BD10 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
39F99B362A48F70F0045BD10 /* PBXTargetDependency */,
|
||||
);
|
||||
name = YggdrasilSwiftUI;
|
||||
productName = YggdrasilSwiftUI;
|
||||
productReference = 39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
E593CE6A1DF8FC3C00D7265D /* YggdrasilNetwork */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E593CE7D1DF8FC3C00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetwork" */;
|
||||
buildPhases = (
|
||||
E593CE671DF8FC3C00D7265D /* Sources */,
|
||||
E593CE681DF8FC3C00D7265D /* Frameworks */,
|
||||
E593CE691DF8FC3C00D7265D /* Resources */,
|
||||
E593CEA41DF905B000D7265D /* Embed Foundation Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
E593CE9F1DF905AF00D7265D /* PBXTargetDependency */,
|
||||
);
|
||||
name = YggdrasilNetwork;
|
||||
productName = NEPacketTunnelVPNDemo;
|
||||
productReference = E593CE6B1DF8FC3C00D7265D /* YggdrasilNetwork.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E593CEA31DF905AF00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetworkExtension" */;
|
||||
|
@ -335,31 +287,14 @@
|
|||
E593CE631DF8FC3C00D7265D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = YES;
|
||||
LastSwiftUpdateCheck = 1420;
|
||||
LastUpgradeCheck = 1420;
|
||||
LastUpgradeCheck = 1430;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
39F0205A2996CD760093F603 = {
|
||||
CreatedOnToolsVersion = 14.2;
|
||||
};
|
||||
E593CE6A1DF8FC3C00D7265D = {
|
||||
CreatedOnToolsVersion = 8.1;
|
||||
LastSwiftMigration = 1030;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplicationGroups.iOS = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.NetworkExtensions.iOS = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.VPNLite = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.iCloud = {
|
||||
enabled = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
E593CE961DF905AF00D7265D = {
|
||||
CreatedOnToolsVersion = 8.1;
|
||||
LastSwiftMigration = 1430;
|
||||
|
@ -390,7 +325,6 @@
|
|||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
E593CE6A1DF8FC3C00D7265D /* YggdrasilNetwork */,
|
||||
E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */,
|
||||
39F0205A2996CD760093F603 /* YggdrasilSwiftUI */,
|
||||
);
|
||||
|
@ -407,16 +341,6 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E593CE691DF8FC3C00D7265D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E593CE791DF8FC3C00D7265D /* LaunchScreen.storyboard in Resources */,
|
||||
E593CE761DF8FC3C00D7265D /* Assets.xcassets in Resources */,
|
||||
E593CE741DF8FC3C00D7265D /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E593CE951DF905AF00D7265D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -435,35 +359,17 @@
|
|||
39F0206B2996CF260093F603 /* SettingsView.swift in Sources */,
|
||||
39B51A4A2997062E0059D29D /* PeersView.swift in Sources */,
|
||||
39F020602996CD760093F603 /* StatusView.swift in Sources */,
|
||||
39B51A4D299951D60059D29D /* NSNotification.swift in Sources */,
|
||||
39B51A4D299951D60059D29D /* IPCResponses.swift in Sources */,
|
||||
39B51A4C29994F350059D29D /* CrossPlatformAppDelegate.swift in Sources */,
|
||||
39F0205E2996CD760093F603 /* Application.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E593CE671DF8FC3C00D7265D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3939196B21E35A7C009320F3 /* PeersViewController.swift in Sources */,
|
||||
3939197321E39815009320F3 /* ToggleTableViewCell.swift in Sources */,
|
||||
3939196D21E39313009320F3 /* UIDevice.swift in Sources */,
|
||||
394A1EB321DEA46400D9F553 /* SettingsViewController.swift in Sources */,
|
||||
E593CE711DF8FC3C00D7265D /* TableViewController.swift in Sources */,
|
||||
3952ADBA29945AFA00B3835D /* CrossPlatformAppDelegate.swift in Sources */,
|
||||
3952ADB729945AF700B3835D /* ConfigurationProxy.swift in Sources */,
|
||||
39682A392225AD15004FB670 /* CopyableLabel.swift in Sources */,
|
||||
E593CE6F1DF8FC3C00D7265D /* AppDelegate.swift in Sources */,
|
||||
3913E9C021DD3A51001E0EC7 /* SplitViewController.swift in Sources */,
|
||||
39CC924C221DEDCE004960DC /* NSNotification.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E593CE931DF905AF00D7265D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
39CC924D221DEDD3004960DC /* NSNotification.swift in Sources */,
|
||||
39CC924D221DEDD3004960DC /* IPCResponses.swift in Sources */,
|
||||
E593CE9C1DF905AF00D7265D /* PacketTunnelProvider.swift in Sources */,
|
||||
3952ADB829945AF700B3835D /* ConfigurationProxy.swift in Sources */,
|
||||
391B72A82A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift in Sources */,
|
||||
|
@ -473,10 +379,14 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
E593CE9F1DF905AF00D7265D /* PBXTargetDependency */ = {
|
||||
39F99B362A48F70F0045BD10 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
platformFilters = (
|
||||
ios,
|
||||
macos,
|
||||
);
|
||||
target = E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */;
|
||||
targetProxy = E593CE9E1DF905AF00D7265D /* PBXContainerItemProxy */;
|
||||
targetProxy = 39F99B352A48F70F0045BD10 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
|
@ -505,6 +415,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
|
@ -512,12 +423,14 @@
|
|||
CODE_SIGN_ENTITLEMENTS = YggdrasilSwiftUI/YggdrasilSwiftUI.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"YggdrasilSwiftUI/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Yggdrasil;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
||||
|
@ -535,13 +448,16 @@
|
|||
MARKETING_VERSION = 1.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil.YggdrasilSwiftUI;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 16.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -550,6 +466,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
|
@ -557,12 +474,14 @@
|
|||
CODE_SIGN_ENTITLEMENTS = YggdrasilSwiftUI/YggdrasilSwiftUI.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"YggdrasilSwiftUI/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Yggdrasil;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
||||
|
@ -579,13 +498,16 @@
|
|||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil.YggdrasilSwiftUI;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = auto;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 16.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
@ -711,72 +633,6 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
E593CE7E1DF8FC3C00D7265D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = YggdrasilNetwork.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network iOS/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E593CE7F1DF8FC3C00D7265D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = YggdrasilNetwork.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network iOS/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E593CEA11DF905AF00D7265D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -801,7 +657,6 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil.extension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Yggdrasil Network Extension/YggdrasilNetworkExtension-Bridging-Header.h";
|
||||
|
@ -864,15 +719,6 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E593CE7D1DF8FC3C00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetwork" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E593CE7E1DF8FC3C00D7265D /* Debug */,
|
||||
E593CE7F1DF8FC3C00D7265D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E593CEA31DF905AF00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetworkExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1420"
|
||||
LastUpgradeVersion = "1430"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1420"
|
||||
LastUpgradeVersion = "1430"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
|
@ -84,7 +84,6 @@
|
|||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
|
68
Yggdrasil.xcframework/Info.plist
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>macos-arm64_x86_64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>Yggdrasil.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>macos</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_x86_64-maccatalyst</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>Yggdrasil.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>maccatalyst</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>Yggdrasil.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_x86_64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>Yggdrasil.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider</string>
|
||||
</array>
|
||||
<key>com.apple.developer.networking.vpn.api</key>
|
||||
<array>
|
||||
<string>allow-vpn</string>
|
||||
</array>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.eu.neilalexander.yggdrasil</string>
|
||||
</array>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -10,20 +10,21 @@ import NetworkExtension
|
|||
|
||||
@main
|
||||
struct Application: App {
|
||||
@State private var selection: String? = "Status"
|
||||
|
||||
#if os(iOS)
|
||||
@UIApplicationDelegateAdaptor(CrossPlatformAppDelegate.self) static var appDelegate: CrossPlatformAppDelegate
|
||||
#elseif os(macOS)
|
||||
@NSApplicationDelegateAdaptor(CrossPlatformAppDelegate.self) static var appDelegate: CrossPlatformAppDelegate
|
||||
#endif
|
||||
|
||||
@State private var selection: String? = "Status"
|
||||
@State private var config: ConfigurationProxy = ConfigurationProxy()
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
NavigationSplitView {
|
||||
List(selection: $selection) {
|
||||
NavigationLink(destination: StatusView(yggdrasilConfiguration: $config)) {
|
||||
NavigationLink(destination: StatusView()) {
|
||||
HStack {
|
||||
Image(systemName: "info.circle")
|
||||
.foregroundColor(.accentColor)
|
||||
|
@ -50,11 +51,30 @@ struct Application: App {
|
|||
}
|
||||
.listStyle(.sidebar)
|
||||
.navigationSplitViewColumnWidth(200)
|
||||
|
||||
Image("YggdrasilLogo")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.foregroundColor(.primary)
|
||||
.opacity(0.1)
|
||||
.padding(.all, 24.0)
|
||||
} detail: {
|
||||
StatusView(yggdrasilConfiguration: $config)
|
||||
StatusView()
|
||||
}
|
||||
.navigationTitle("Yggdrasil")
|
||||
.navigationSplitViewStyle(.automatic)
|
||||
.onChange(of: scenePhase) { phase in
|
||||
switch phase {
|
||||
case .background:
|
||||
Application.appDelegate.becameBackground()
|
||||
case .inactive:
|
||||
Application.appDelegate.becameInactive()
|
||||
case .active:
|
||||
Application.appDelegate.becameActive()
|
||||
@unknown default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
#if os(macOS)
|
||||
.windowStyle(.hiddenTitleBar)
|
||||
|
|
|
@ -1,6 +1,33 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "display-p3",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.522",
|
||||
"green" : "0.656",
|
||||
"red" : "0.370"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "display-p3",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.718",
|
||||
"green" : "0.896",
|
||||
"red" : "0.514"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "drawing copy-1.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "drawing copy.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "drawing copy-2.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "drawing copy-3.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "drawing copy-5.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"filename" : "drawing copy-4.png",
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4 KiB |
|
@ -1,58 +1,73 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "drawing copy-4 1.png",
|
||||
"filename" : "icon_512x512@2x 1.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"filename" : "icon-1024.png",
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_16x16.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_16x16@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_32x32.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_32x32@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_128x128.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_128x128@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_256x256.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_256x256@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"filename" : "icon_512x512 1.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"filename" : "drawing copy-4.png",
|
||||
"filename" : "icon_512x512@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
|
|
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 73 KiB |
27
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ygg-neilalexander.svg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "ygg-neilalexander 1.svg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "ygg-neilalexander 2.svg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true,
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
157
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/ygg-neilalexander 1.svg
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="drawing.svg"
|
||||
inkscape:version="0.91 r13725"
|
||||
version="1.1"
|
||||
id="svg4240"
|
||||
viewBox="0 0 981.96461 321.60015"
|
||||
height="90.762711mm"
|
||||
width="277.13223mm">
|
||||
<defs
|
||||
id="defs4242" />
|
||||
<sodipodi:namedview
|
||||
fit-margin-bottom="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-top="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-width="2048"
|
||||
showgrid="false"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="13.914395"
|
||||
inkscape:cx="751.6295"
|
||||
inkscape:zoom="0.66468037"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base" />
|
||||
<metadata
|
||||
id="metadata4245">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(383.92494,-160.49328)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2"
|
||||
transform="translate(383.92494,-160.49328)">
|
||||
<path
|
||||
style="fill:#000000"
|
||||
d="m 352.74397,478.24119 c 0.92103,-3.76903 11.87131,-30.48993 21.5083,-52.48465 9.86344,-22.51152 9.67726,-21.6278 6.92943,-32.89221 -3.42997,-14.06075 -3.22164,-36.95243 0.44688,-49.10642 13.24423,-43.87864 47.63362,-73.61698 122.30718,-105.76556 24.32504,-10.47245 37.67777,-17.18807 47.80968,-24.04538 17.86083,-12.08828 36.4402,-33.06424 42.38057,-47.84736 1.25285,-3.11781 2.66096,-5.64051 3.12912,-5.60598 1.46014,0.10767 0.73701,44.30167 -0.9768,59.69719 -10.61597,95.36545 -42.95689,157.39345 -96.20598,184.51751 -30.73114,15.65385 -79.17559,21.45357 -101.74118,12.18037 -3.19081,-1.31125 -6.5492,-2.38408 -7.46311,-2.38408 -3.43636,0 -15.75824,32.89925 -19.29523,51.51802 -1.09802,5.78003 -2.76237,13.70787 -3.00898,14.91667 -5.50064,-0.0422 -0.35371,-0.0119 -8.18026,-0.0119 l -8.29605,0 z"
|
||||
id="path4918"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssssscssssscscs" />
|
||||
<g
|
||||
style="font-style:normal;font-weight:normal;font-size:150px;line-height:86.00000143%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4920"
|
||||
transform="translate(-2,0)">
|
||||
<path
|
||||
d="m -345.34994,319.70594 -36.575,-55.6875 21.725,0 23.925,38.775 24.2,-38.775 20.625,0 -36.575,55.6875 0,41.6625 -17.325,0 0,-41.6625 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5638"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -202.55678,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5640"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -102.05346,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5642"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -90.037646,264.01844 38.3625,0 q 9.625,0 18.5625,3.025 8.9375,2.8875 15.8125,8.9375 6.875,6.05 11,15.2625 4.125,9.075 4.125,21.45 0,12.5125 -4.8125,21.725 -4.675,9.075 -12.2375,15.125 -7.425,5.9125 -16.6375,8.9375 -9.075,2.8875 -17.875,2.8875 l -36.3,0 0,-97.35 z m 30.25,81.675 q 8.1125,0 15.2625,-1.7875 7.2875,-1.925 12.65,-5.775 5.3625,-3.9875 8.3875,-10.175 3.1625,-6.325 3.1625,-15.2625 0,-8.8 -2.75,-15.125 -2.75,-6.325 -7.7,-10.175 -4.8125,-3.9875 -11.55,-5.775 -6.6,-1.925 -14.575,-1.925 l -15.8125,0 0,66 12.925,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5644"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 7.511578,264.01844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.687502,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775002,7.15 -16.637502,8.6625 l 25.850002,43.0375 -20.900002,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5646"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 126.82369,264.01844 14.9875,0 41.9375,97.35 -19.8,0 -9.075,-22.275 -42.2125,0 -8.8,22.275 -19.3875,0 42.35,-97.35 z m 22,60.225 -14.9875,-39.6 -15.2625,39.6 30.25,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5648"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 239.7639,284.91844 q -2.75,-3.9875 -7.425,-5.775 -4.5375,-1.925 -9.625,-1.925 -3.025,0 -5.9125,0.6875 -2.75,0.6875 -5.0875,2.2 -2.2,1.5125 -3.575,3.9875 -1.375,2.3375 -1.375,5.6375 0,4.95 3.4375,7.5625 3.4375,2.6125 8.525,4.5375 5.0875,1.925 11.1375,3.7125 6.05,1.7875 11.1375,4.95 5.0875,3.1625 8.525,8.3875 3.4375,5.225 3.4375,13.8875 0,7.8375 -2.8875,13.75 -2.8875,5.775 -7.8375,9.625 -4.8125,3.85 -11.275,5.775 -6.4625,1.925 -13.6125,1.925 -9.075,0 -17.4625,-3.025 -8.3875,-3.025 -14.4375,-10.175 l 13.0625,-12.65 q 3.1625,4.8125 8.25,7.5625 5.225,2.6125 11,2.6125 3.025,0 6.05,-0.825 3.025,-0.825 5.5,-2.475 2.475,-1.65 3.9875,-4.125 1.5125,-2.6125 1.5125,-5.9125 0,-5.3625 -3.4375,-8.25 -3.4375,-2.8875 -8.525,-4.8125 -5.0875,-2.0625 -11.1375,-3.85 -6.05,-1.7875 -11.1375,-4.8125 -5.0875,-3.1625 -8.525,-8.25 -3.4375,-5.225 -3.4375,-13.8875 0,-7.5625 3.025,-13.0625 3.1625,-5.5 8.1125,-9.075 5.0875,-3.7125 11.55,-5.5 6.4625,-1.7875 13.2,-1.7875 7.7,0 14.85,2.3375 7.2875,2.3375 13.0625,7.7 l -12.65,13.3375 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5650"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 264.21257,264.01844 17.325,0 0,97.35 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5652"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 296.37837,264.01844 17.325,0 0,81.675 41.3875,0 0,15.675 -58.7125,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5654"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -369.13744,382.26844 22.9625,0 47.1625,72.325 0.275,0 0,-72.325 17.325,0 0,97.35 -22,0 -48.125,-74.6625 -0.275,0 0,74.6625 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5656"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -270.48568,382.26844 64.4875,0 0,15.675 -47.1625,0 0,23.925 44.6875,0 0,15.675 -44.6875,0 0,26.4 49.6375,0 0,15.675 -66.9625,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5658"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -165.14057,397.94344 -29.8375,0 0,-15.675 77,0 0,15.675 -29.8375,0 0,81.675 -17.325,0 0,-81.675 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5660"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -111.36694,382.26844 18.974997,0 18.2875,70.125 0.275,0 21.8625,-70.125 17.05,0 21.45,70.125 0.275,0 19.1125,-70.125 17.6,0 -28.3250004,97.35 -16.4999996,0 -22.55,-74.1125 -0.275,0 -22.55,74.1125 -15.95,0 -28.737497,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5662"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 24.435016,431.35594 q 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.412504,-0.1375 20.900004,3.4375 9.4875,3.4375 16.3625,10.175 6.875,6.7375 10.725,16.225 3.85,9.4875 3.85,21.175 0,11.4125 -3.85,20.7625 -3.85,9.35 -10.725,16.0875 -6.875,6.7375 -16.3625,10.5875 -9.4875,3.7125 -20.900004,3.85 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 z m 18.15,-1.1 q 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 7.5625,0 13.750004,-2.75 6.1875,-2.75 10.5875,-7.5625 4.4,-4.8125 6.7375,-11.4125 2.475,-6.6 2.475,-14.4375 0,-7.2875 -2.475,-13.6125 -2.3375,-6.325 -6.7375,-11 -4.4,-4.8125 -10.5875,-7.425 -6.187504,-2.75 -13.750004,-2.75 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5664"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 137.68287,382.26844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.6875,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775,7.15 -16.6375,8.6625 l 25.85,43.0375 -20.9,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5666"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 221.50746,382.26844 17.325,0 0,41.25 0.825,0 40.2875,-41.25 23.375,0 -45.5125,44.9625 48.5375,52.3875 -24.3375,0 -42.2125,-47.85 -0.9625,0 0,47.85 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5668"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
157
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/ygg-neilalexander 2.svg
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="drawing.svg"
|
||||
inkscape:version="0.91 r13725"
|
||||
version="1.1"
|
||||
id="svg4240"
|
||||
viewBox="0 0 981.96461 321.60015"
|
||||
height="90.762711mm"
|
||||
width="277.13223mm">
|
||||
<defs
|
||||
id="defs4242" />
|
||||
<sodipodi:namedview
|
||||
fit-margin-bottom="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-top="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-width="2048"
|
||||
showgrid="false"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="13.914395"
|
||||
inkscape:cx="751.6295"
|
||||
inkscape:zoom="0.66468037"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base" />
|
||||
<metadata
|
||||
id="metadata4245">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(383.92494,-160.49328)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2"
|
||||
transform="translate(383.92494,-160.49328)">
|
||||
<path
|
||||
style="fill:#000000"
|
||||
d="m 352.74397,478.24119 c 0.92103,-3.76903 11.87131,-30.48993 21.5083,-52.48465 9.86344,-22.51152 9.67726,-21.6278 6.92943,-32.89221 -3.42997,-14.06075 -3.22164,-36.95243 0.44688,-49.10642 13.24423,-43.87864 47.63362,-73.61698 122.30718,-105.76556 24.32504,-10.47245 37.67777,-17.18807 47.80968,-24.04538 17.86083,-12.08828 36.4402,-33.06424 42.38057,-47.84736 1.25285,-3.11781 2.66096,-5.64051 3.12912,-5.60598 1.46014,0.10767 0.73701,44.30167 -0.9768,59.69719 -10.61597,95.36545 -42.95689,157.39345 -96.20598,184.51751 -30.73114,15.65385 -79.17559,21.45357 -101.74118,12.18037 -3.19081,-1.31125 -6.5492,-2.38408 -7.46311,-2.38408 -3.43636,0 -15.75824,32.89925 -19.29523,51.51802 -1.09802,5.78003 -2.76237,13.70787 -3.00898,14.91667 -5.50064,-0.0422 -0.35371,-0.0119 -8.18026,-0.0119 l -8.29605,0 z"
|
||||
id="path4918"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssssscssssscscs" />
|
||||
<g
|
||||
style="font-style:normal;font-weight:normal;font-size:150px;line-height:86.00000143%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4920"
|
||||
transform="translate(-2,0)">
|
||||
<path
|
||||
d="m -345.34994,319.70594 -36.575,-55.6875 21.725,0 23.925,38.775 24.2,-38.775 20.625,0 -36.575,55.6875 0,41.6625 -17.325,0 0,-41.6625 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5638"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -202.55678,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5640"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -102.05346,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5642"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -90.037646,264.01844 38.3625,0 q 9.625,0 18.5625,3.025 8.9375,2.8875 15.8125,8.9375 6.875,6.05 11,15.2625 4.125,9.075 4.125,21.45 0,12.5125 -4.8125,21.725 -4.675,9.075 -12.2375,15.125 -7.425,5.9125 -16.6375,8.9375 -9.075,2.8875 -17.875,2.8875 l -36.3,0 0,-97.35 z m 30.25,81.675 q 8.1125,0 15.2625,-1.7875 7.2875,-1.925 12.65,-5.775 5.3625,-3.9875 8.3875,-10.175 3.1625,-6.325 3.1625,-15.2625 0,-8.8 -2.75,-15.125 -2.75,-6.325 -7.7,-10.175 -4.8125,-3.9875 -11.55,-5.775 -6.6,-1.925 -14.575,-1.925 l -15.8125,0 0,66 12.925,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5644"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 7.511578,264.01844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.687502,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775002,7.15 -16.637502,8.6625 l 25.850002,43.0375 -20.900002,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5646"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 126.82369,264.01844 14.9875,0 41.9375,97.35 -19.8,0 -9.075,-22.275 -42.2125,0 -8.8,22.275 -19.3875,0 42.35,-97.35 z m 22,60.225 -14.9875,-39.6 -15.2625,39.6 30.25,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5648"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 239.7639,284.91844 q -2.75,-3.9875 -7.425,-5.775 -4.5375,-1.925 -9.625,-1.925 -3.025,0 -5.9125,0.6875 -2.75,0.6875 -5.0875,2.2 -2.2,1.5125 -3.575,3.9875 -1.375,2.3375 -1.375,5.6375 0,4.95 3.4375,7.5625 3.4375,2.6125 8.525,4.5375 5.0875,1.925 11.1375,3.7125 6.05,1.7875 11.1375,4.95 5.0875,3.1625 8.525,8.3875 3.4375,5.225 3.4375,13.8875 0,7.8375 -2.8875,13.75 -2.8875,5.775 -7.8375,9.625 -4.8125,3.85 -11.275,5.775 -6.4625,1.925 -13.6125,1.925 -9.075,0 -17.4625,-3.025 -8.3875,-3.025 -14.4375,-10.175 l 13.0625,-12.65 q 3.1625,4.8125 8.25,7.5625 5.225,2.6125 11,2.6125 3.025,0 6.05,-0.825 3.025,-0.825 5.5,-2.475 2.475,-1.65 3.9875,-4.125 1.5125,-2.6125 1.5125,-5.9125 0,-5.3625 -3.4375,-8.25 -3.4375,-2.8875 -8.525,-4.8125 -5.0875,-2.0625 -11.1375,-3.85 -6.05,-1.7875 -11.1375,-4.8125 -5.0875,-3.1625 -8.525,-8.25 -3.4375,-5.225 -3.4375,-13.8875 0,-7.5625 3.025,-13.0625 3.1625,-5.5 8.1125,-9.075 5.0875,-3.7125 11.55,-5.5 6.4625,-1.7875 13.2,-1.7875 7.7,0 14.85,2.3375 7.2875,2.3375 13.0625,7.7 l -12.65,13.3375 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5650"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 264.21257,264.01844 17.325,0 0,97.35 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5652"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 296.37837,264.01844 17.325,0 0,81.675 41.3875,0 0,15.675 -58.7125,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5654"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -369.13744,382.26844 22.9625,0 47.1625,72.325 0.275,0 0,-72.325 17.325,0 0,97.35 -22,0 -48.125,-74.6625 -0.275,0 0,74.6625 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5656"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -270.48568,382.26844 64.4875,0 0,15.675 -47.1625,0 0,23.925 44.6875,0 0,15.675 -44.6875,0 0,26.4 49.6375,0 0,15.675 -66.9625,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5658"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -165.14057,397.94344 -29.8375,0 0,-15.675 77,0 0,15.675 -29.8375,0 0,81.675 -17.325,0 0,-81.675 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5660"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -111.36694,382.26844 18.974997,0 18.2875,70.125 0.275,0 21.8625,-70.125 17.05,0 21.45,70.125 0.275,0 19.1125,-70.125 17.6,0 -28.3250004,97.35 -16.4999996,0 -22.55,-74.1125 -0.275,0 -22.55,74.1125 -15.95,0 -28.737497,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5662"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 24.435016,431.35594 q 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.412504,-0.1375 20.900004,3.4375 9.4875,3.4375 16.3625,10.175 6.875,6.7375 10.725,16.225 3.85,9.4875 3.85,21.175 0,11.4125 -3.85,20.7625 -3.85,9.35 -10.725,16.0875 -6.875,6.7375 -16.3625,10.5875 -9.4875,3.7125 -20.900004,3.85 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 z m 18.15,-1.1 q 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 7.5625,0 13.750004,-2.75 6.1875,-2.75 10.5875,-7.5625 4.4,-4.8125 6.7375,-11.4125 2.475,-6.6 2.475,-14.4375 0,-7.2875 -2.475,-13.6125 -2.3375,-6.325 -6.7375,-11 -4.4,-4.8125 -10.5875,-7.425 -6.187504,-2.75 -13.750004,-2.75 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5664"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 137.68287,382.26844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.6875,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775,7.15 -16.6375,8.6625 l 25.85,43.0375 -20.9,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5666"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 221.50746,382.26844 17.325,0 0,41.25 0.825,0 40.2875,-41.25 23.375,0 -45.5125,44.9625 48.5375,52.3875 -24.3375,0 -42.2125,-47.85 -0.9625,0 0,47.85 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5668"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
157
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/ygg-neilalexander.svg
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="drawing.svg"
|
||||
inkscape:version="0.91 r13725"
|
||||
version="1.1"
|
||||
id="svg4240"
|
||||
viewBox="0 0 981.96461 321.60015"
|
||||
height="90.762711mm"
|
||||
width="277.13223mm">
|
||||
<defs
|
||||
id="defs4242" />
|
||||
<sodipodi:namedview
|
||||
fit-margin-bottom="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-top="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-width="2048"
|
||||
showgrid="false"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="13.914395"
|
||||
inkscape:cx="751.6295"
|
||||
inkscape:zoom="0.66468037"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base" />
|
||||
<metadata
|
||||
id="metadata4245">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(383.92494,-160.49328)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2"
|
||||
transform="translate(383.92494,-160.49328)">
|
||||
<path
|
||||
style="fill:#000000"
|
||||
d="m 352.74397,478.24119 c 0.92103,-3.76903 11.87131,-30.48993 21.5083,-52.48465 9.86344,-22.51152 9.67726,-21.6278 6.92943,-32.89221 -3.42997,-14.06075 -3.22164,-36.95243 0.44688,-49.10642 13.24423,-43.87864 47.63362,-73.61698 122.30718,-105.76556 24.32504,-10.47245 37.67777,-17.18807 47.80968,-24.04538 17.86083,-12.08828 36.4402,-33.06424 42.38057,-47.84736 1.25285,-3.11781 2.66096,-5.64051 3.12912,-5.60598 1.46014,0.10767 0.73701,44.30167 -0.9768,59.69719 -10.61597,95.36545 -42.95689,157.39345 -96.20598,184.51751 -30.73114,15.65385 -79.17559,21.45357 -101.74118,12.18037 -3.19081,-1.31125 -6.5492,-2.38408 -7.46311,-2.38408 -3.43636,0 -15.75824,32.89925 -19.29523,51.51802 -1.09802,5.78003 -2.76237,13.70787 -3.00898,14.91667 -5.50064,-0.0422 -0.35371,-0.0119 -8.18026,-0.0119 l -8.29605,0 z"
|
||||
id="path4918"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssssscssssscscs" />
|
||||
<g
|
||||
style="font-style:normal;font-weight:normal;font-size:150px;line-height:86.00000143%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4920"
|
||||
transform="translate(-2,0)">
|
||||
<path
|
||||
d="m -345.34994,319.70594 -36.575,-55.6875 21.725,0 23.925,38.775 24.2,-38.775 20.625,0 -36.575,55.6875 0,41.6625 -17.325,0 0,-41.6625 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5638"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -202.55678,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5640"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -102.05346,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5642"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -90.037646,264.01844 38.3625,0 q 9.625,0 18.5625,3.025 8.9375,2.8875 15.8125,8.9375 6.875,6.05 11,15.2625 4.125,9.075 4.125,21.45 0,12.5125 -4.8125,21.725 -4.675,9.075 -12.2375,15.125 -7.425,5.9125 -16.6375,8.9375 -9.075,2.8875 -17.875,2.8875 l -36.3,0 0,-97.35 z m 30.25,81.675 q 8.1125,0 15.2625,-1.7875 7.2875,-1.925 12.65,-5.775 5.3625,-3.9875 8.3875,-10.175 3.1625,-6.325 3.1625,-15.2625 0,-8.8 -2.75,-15.125 -2.75,-6.325 -7.7,-10.175 -4.8125,-3.9875 -11.55,-5.775 -6.6,-1.925 -14.575,-1.925 l -15.8125,0 0,66 12.925,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5644"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 7.511578,264.01844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.687502,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775002,7.15 -16.637502,8.6625 l 25.850002,43.0375 -20.900002,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5646"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 126.82369,264.01844 14.9875,0 41.9375,97.35 -19.8,0 -9.075,-22.275 -42.2125,0 -8.8,22.275 -19.3875,0 42.35,-97.35 z m 22,60.225 -14.9875,-39.6 -15.2625,39.6 30.25,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5648"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 239.7639,284.91844 q -2.75,-3.9875 -7.425,-5.775 -4.5375,-1.925 -9.625,-1.925 -3.025,0 -5.9125,0.6875 -2.75,0.6875 -5.0875,2.2 -2.2,1.5125 -3.575,3.9875 -1.375,2.3375 -1.375,5.6375 0,4.95 3.4375,7.5625 3.4375,2.6125 8.525,4.5375 5.0875,1.925 11.1375,3.7125 6.05,1.7875 11.1375,4.95 5.0875,3.1625 8.525,8.3875 3.4375,5.225 3.4375,13.8875 0,7.8375 -2.8875,13.75 -2.8875,5.775 -7.8375,9.625 -4.8125,3.85 -11.275,5.775 -6.4625,1.925 -13.6125,1.925 -9.075,0 -17.4625,-3.025 -8.3875,-3.025 -14.4375,-10.175 l 13.0625,-12.65 q 3.1625,4.8125 8.25,7.5625 5.225,2.6125 11,2.6125 3.025,0 6.05,-0.825 3.025,-0.825 5.5,-2.475 2.475,-1.65 3.9875,-4.125 1.5125,-2.6125 1.5125,-5.9125 0,-5.3625 -3.4375,-8.25 -3.4375,-2.8875 -8.525,-4.8125 -5.0875,-2.0625 -11.1375,-3.85 -6.05,-1.7875 -11.1375,-4.8125 -5.0875,-3.1625 -8.525,-8.25 -3.4375,-5.225 -3.4375,-13.8875 0,-7.5625 3.025,-13.0625 3.1625,-5.5 8.1125,-9.075 5.0875,-3.7125 11.55,-5.5 6.4625,-1.7875 13.2,-1.7875 7.7,0 14.85,2.3375 7.2875,2.3375 13.0625,7.7 l -12.65,13.3375 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5650"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 264.21257,264.01844 17.325,0 0,97.35 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5652"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 296.37837,264.01844 17.325,0 0,81.675 41.3875,0 0,15.675 -58.7125,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5654"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -369.13744,382.26844 22.9625,0 47.1625,72.325 0.275,0 0,-72.325 17.325,0 0,97.35 -22,0 -48.125,-74.6625 -0.275,0 0,74.6625 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5656"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -270.48568,382.26844 64.4875,0 0,15.675 -47.1625,0 0,23.925 44.6875,0 0,15.675 -44.6875,0 0,26.4 49.6375,0 0,15.675 -66.9625,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5658"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -165.14057,397.94344 -29.8375,0 0,-15.675 77,0 0,15.675 -29.8375,0 0,81.675 -17.325,0 0,-81.675 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5660"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m -111.36694,382.26844 18.974997,0 18.2875,70.125 0.275,0 21.8625,-70.125 17.05,0 21.45,70.125 0.275,0 19.1125,-70.125 17.6,0 -28.3250004,97.35 -16.4999996,0 -22.55,-74.1125 -0.275,0 -22.55,74.1125 -15.95,0 -28.737497,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5662"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 24.435016,431.35594 q 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.412504,-0.1375 20.900004,3.4375 9.4875,3.4375 16.3625,10.175 6.875,6.7375 10.725,16.225 3.85,9.4875 3.85,21.175 0,11.4125 -3.85,20.7625 -3.85,9.35 -10.725,16.0875 -6.875,6.7375 -16.3625,10.5875 -9.4875,3.7125 -20.900004,3.85 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 z m 18.15,-1.1 q 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 7.5625,0 13.750004,-2.75 6.1875,-2.75 10.5875,-7.5625 4.4,-4.8125 6.7375,-11.4125 2.475,-6.6 2.475,-14.4375 0,-7.2875 -2.475,-13.6125 -2.3375,-6.325 -6.7375,-11 -4.4,-4.8125 -10.5875,-7.425 -6.187504,-2.75 -13.750004,-2.75 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5664"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 137.68287,382.26844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.6875,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775,7.15 -16.6375,8.6625 l 25.85,43.0375 -20.9,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5666"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 221.50746,382.26844 17.325,0 0,41.25 0.825,0 40.2875,-41.25 23.375,0 -45.5125,44.9625 48.5375,52.3875 -24.3375,0 -42.2125,-47.85 -0.9625,0 0,47.85 -17.325,0 0,-97.35 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||
id="path5668"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
|
@ -8,18 +8,32 @@
|
|||
import SwiftUI
|
||||
|
||||
struct PeersView: View {
|
||||
@State private var peers = ["Paul", "Taylor", "Adele"]
|
||||
// @Binding public var yggdrasilConfiguration: ConfigurationProxy
|
||||
@ObservedObject private var appDelegate = Application.appDelegate
|
||||
|
||||
@State private var multicastAdvertise = false
|
||||
@State private var multicastListen = false
|
||||
@State private var peers = ["Paul", "Taylor", "Adele"]
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
Section(content: {
|
||||
ForEach(peers, id: \.self) { peer in
|
||||
ForEach(Array(appDelegate.yggdrasilConfig.peers.enumerated()), id: \.offset) { index, peer in
|
||||
HStack() {
|
||||
Text(peer)
|
||||
//TextField("", text: $yggdrasilConfiguration.peers[index])
|
||||
// .multilineTextAlignment(.leading)
|
||||
#if os(macOS)
|
||||
Spacer()
|
||||
Button(role: .destructive) {
|
||||
print("Deleting")
|
||||
} label: {
|
||||
Image(systemName: "xmark.circle.fill")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
.onDelete(perform: delete)
|
||||
|
||||
Text("Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer. Data charges may apply when using mobile data.")
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(.gray)
|
||||
|
@ -28,7 +42,7 @@ struct PeersView: View {
|
|||
})
|
||||
|
||||
Section(content: {
|
||||
Toggle(isOn: $multicastAdvertise) {
|
||||
Toggle(isOn: $appDelegate.yggdrasilConfig.multicastBeacons) {
|
||||
VStack(alignment: .leading) {
|
||||
Text("Discoverable over multicast")
|
||||
Text("Make your device discoverable to other Yggdrasil nodes on the same Wi-Fi network.")
|
||||
|
@ -36,7 +50,7 @@ struct PeersView: View {
|
|||
.foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
Toggle(isOn: $multicastListen) {
|
||||
Toggle(isOn: $appDelegate.yggdrasilConfig.multicastListen) {
|
||||
VStack(alignment: .leading) {
|
||||
Text("Search for multicast peers")
|
||||
Text("Automatically connect to discoverable Yggdrasil nodes on the same Wi-Fi network.")
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
import SwiftUI
|
||||
|
||||
struct SettingsView: View {
|
||||
@State private var deviceName = ""
|
||||
//@Binding public var yggdrasilConfiguration: ConfigurationProxy
|
||||
@ObservedObject private var appDelegate = Application.appDelegate
|
||||
|
||||
@State private var autoStartOnWiFi = false
|
||||
@State private var autoStartOnCellular = false
|
||||
@State private var deviceName = ""
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
@ -22,8 +22,14 @@ struct SettingsView: View {
|
|||
})
|
||||
|
||||
Section(content: {
|
||||
Toggle("Wi-Fi", isOn: $autoStartOnWiFi)
|
||||
Toggle("Mobile Network", isOn: $autoStartOnCellular)
|
||||
Toggle("Any network connection", isOn: $appDelegate.yggdrasilConfig.autoStartAny)
|
||||
Toggle("Wi-Fi networks", isOn: $appDelegate.yggdrasilConfig.autoStartWiFi)
|
||||
#if os(macOS)
|
||||
Toggle("Ethernet networks", isOn: $appDelegate.yggdrasilConfig.autoStartEthernet)
|
||||
#endif
|
||||
#if os(iOS)
|
||||
Toggle("Mobile data", isOn: $appDelegate.yggdrasilConfig.autoStartMobile)
|
||||
#endif
|
||||
}, header: {
|
||||
Text("Automatically start when connected to")
|
||||
})
|
||||
|
@ -36,6 +42,7 @@ struct SettingsView: View {
|
|||
#if os(macOS)
|
||||
.buttonStyle(.link)
|
||||
#endif
|
||||
.foregroundColor(.accentColor)
|
||||
Text("Import configuration from another device, including the public key and Yggdrasil IP address.")
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(.gray)
|
||||
|
@ -48,6 +55,7 @@ struct SettingsView: View {
|
|||
#if os(macOS)
|
||||
.buttonStyle(.link)
|
||||
#endif
|
||||
.foregroundColor(.accentColor)
|
||||
Text("Configuration will be exported as a file. Your configuration contains your private key which is extremely sensitive. Do not share it with anyone.")
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(.gray)
|
||||
|
|
|
@ -14,8 +14,6 @@ typealias MyListStyle = SidebarListStyle
|
|||
#endif
|
||||
|
||||
struct StatusView: View {
|
||||
@Binding public var yggdrasilConfiguration: ConfigurationProxy
|
||||
|
||||
@ObservedObject private var appDelegate = Application.appDelegate
|
||||
|
||||
@State private var statusBadgeColor: SwiftUI.Color = .gray
|
||||
|
@ -35,9 +33,9 @@ struct StatusView: View {
|
|||
if !appDelegate.yggdrasilEnabled {
|
||||
return "Not enabled"
|
||||
} else if !appDelegate.yggdrasilConnected {
|
||||
return "Not connected"
|
||||
return "No peers connected"
|
||||
} else {
|
||||
return "Connected"
|
||||
return "Connected to \(appDelegate.yggdrasilPeers.count) peer(s)"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +44,6 @@ struct StatusView: View {
|
|||
Section(content: {
|
||||
VStack(alignment: .leading) {
|
||||
Toggle("Enable Yggdrasil", isOn: $appDelegate.yggdrasilEnabled)
|
||||
.onTapGesture {
|
||||
appDelegate.toggleYggdrasil()
|
||||
}
|
||||
HStack {
|
||||
Image(systemName: "circlebadge.fill")
|
||||
.foregroundColor(statusBadgeColor)
|
||||
|
@ -58,6 +53,12 @@ struct StatusView: View {
|
|||
.onChange(of: appDelegate.yggdrasilEnabled) { newValue in
|
||||
statusBadgeColor = getStatusBadgeColor()
|
||||
}
|
||||
.onChange(of: appDelegate.yggdrasilConnected) { newValue in
|
||||
statusBadgeColor = getStatusBadgeColor()
|
||||
}
|
||||
.onChange(of: appDelegate.yggdrasilPeers.count) { newValue in
|
||||
statusBadgeColor = getStatusBadgeColor()
|
||||
}
|
||||
Text(statusBadgeText)
|
||||
.foregroundColor(.gray)
|
||||
.font(.system(size: 11))
|
||||
|
@ -67,6 +68,12 @@ struct StatusView: View {
|
|||
.onChange(of: appDelegate.yggdrasilEnabled) { newValue in
|
||||
statusBadgeText = getStatusBadgeText()
|
||||
}
|
||||
.onChange(of: appDelegate.yggdrasilConnected) { newValue in
|
||||
statusBadgeText = getStatusBadgeText()
|
||||
}
|
||||
.onChange(of: appDelegate.yggdrasilPeers.count) { newValue in
|
||||
statusBadgeText = getStatusBadgeText()
|
||||
}
|
||||
}
|
||||
}
|
||||
HStack {
|
||||
|
@ -83,29 +90,38 @@ struct StatusView: View {
|
|||
Spacer()
|
||||
Text(appDelegate.yggdrasilIP)
|
||||
.foregroundColor(Color.gray)
|
||||
.truncationMode(.head)
|
||||
.lineLimit(1)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
HStack {
|
||||
Text("Subnet")
|
||||
Spacer()
|
||||
Text(appDelegate.yggdrasilSubnet)
|
||||
.foregroundColor(Color.gray)
|
||||
.truncationMode(.head)
|
||||
.lineLimit(1)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
HStack {
|
||||
Text("Coordinates")
|
||||
Spacer()
|
||||
Text(appDelegate.yggdrasilCoords)
|
||||
.foregroundColor(Color.gray)
|
||||
.truncationMode(.tail)
|
||||
.lineLimit(1)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
/*
|
||||
HStack {
|
||||
Text("Public Key")
|
||||
Spacer()
|
||||
Text("N/A")
|
||||
Text(appDelegate.yggdrasilPublicKey)
|
||||
.foregroundColor(Color.gray)
|
||||
.font(.system(size: 15, design: .monospaced))
|
||||
.font(.system(size: 13, design: .monospaced))
|
||||
.truncationMode(.tail)
|
||||
.lineLimit(1)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
*/
|
||||
})
|
||||
}
|
||||
.formStyle(.grouped)
|
||||
|
@ -118,8 +134,6 @@ struct StatusView: View {
|
|||
|
||||
struct StatusView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
@State var config = ConfigurationProxy()
|
||||
|
||||
StatusView(yggdrasilConfiguration: $config)
|
||||
StatusView()
|
||||
}
|
||||
}
|
||||
|
|