Drain durable lanes with typed retry policy and localized sync status
26 files changed,
+728
−13
Sources/RastrilloApple/NativeSyncStrings.swift+27 −4Sources/RastrilloApple/OutboxDrainer.swift+147 −8Sources/RastrilloApple/Resources/ar.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/ar.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/bn.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/bn.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/en.lproj/Localizable.strings+11 −1Sources/RastrilloApple/Resources/en.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/es.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/es.lproj/Localizable.stringsdict+38 −0Sources/RastrilloApple/Resources/ga.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/ga.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/hi.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/hi.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/ja.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/ja.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/pt.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/pt.lproj/Localizable.stringsdict+38 −0Sources/RastrilloApple/Resources/ru.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/ru.lproj/Localizable.stringsdict+40 −0Sources/RastrilloApple/Resources/vi.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/vi.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/yue.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/yue.lproj/Localizable.stringsdict+34 −0Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.strings+11 −0Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.stringsdict+34 −0
CI failed — run details
Intent
diff --git a/Sources/RastrilloApple/NativeSyncStrings.swift b/Sources/RastrilloApple/NativeSyncStrings.swift| index 2d81af4..54e2855 100644 |
| --- a/Sources/RastrilloApple/NativeSyncStrings.swift |
| +++ b/Sources/RastrilloApple/NativeSyncStrings.swift |
| @@ -31,10 +31,33 @@ public struct NativeSyncStrings: Sendable { |
| self.offlineDurable = offlineDurable; self.unsentLost = unsentLost |
| } |
| - public static var kit: NativeSyncStrings { kit(localization: "en") } |
| + public static var kit: NativeSyncStrings { kit(localization: Bundle.module.preferredLocalizations.first ?? "en") } |
| public static func kit(localization: String) -> NativeSyncStrings { |
| - NativeSyncStrings(saving: "", retrying: "", offline: { _ in "" }, needsSignIn: { _ in "" }, signIn: "", failed: { _ in "" }, |
| - offlineWaiting: "", offlineDurable: "", unsentLost: "") |
| + let path = Bundle.module.path(forResource: localization, ofType: "lproj") |
| + ?? Bundle.module.path(forResource: "en", ofType: "lproj")! |
| + let bundle = Bundle(path: path)! |
| + @Sendable func text(_ key: String) -> String { bundle.localizedString(forKey: key, value: nil, table: nil) } |
| + @Sendable func plural(_ key: String, _ count: Int) -> String { |
| + String(format: text(key), locale: Locale(identifier: localization), arguments: [count]) |
| + } |
| + return NativeSyncStrings(saving: text("sync.saving"), retrying: text("sync.retrying"), |
| + offline: { plural("sync.offline", $0) }, needsSignIn: { plural("sync.needsSignIn", $0) }, signIn: text("sync.signIn"), |
| + failed: { reason in |
| + switch reason { |
| + case .cannotSaveOnDevice: return text("sync.failed.cannotSave") |
| + case .tooManyUnsent: return text("sync.failed.tooManyUnsent") |
| + case .held: return text("sync.failed.held") |
| + } |
| + }, offlineWaiting: text("offline.waiting"), offlineDurable: text("offline.durable"), unsentLost: text("sync.unsentLost")) |
| + } |
| + public func text(for status: SyncStatus) -> String? { |
| + switch status { |
| + case .saved: return nil |
| + case .saving: return saving |
| + case .retrying: return retrying |
| + case .offline(let count): return offline(count) |
| + case .needsSignIn(let count): return needsSignIn(count) |
| + case .failed(_, let reason): return failed(reason) |
| + } |
| } |
| - public func text(for status: SyncStatus) -> String? { nil } |
| } |
diff --git a/Sources/RastrilloApple/OutboxDrainer.swift b/Sources/RastrilloApple/OutboxDrainer.swift| index 5350a5b..11c08ce 100644 |
| --- a/Sources/RastrilloApple/OutboxDrainer.swift |
| +++ b/Sources/RastrilloApple/OutboxDrainer.swift |
| @@ -61,14 +61,153 @@ import RastrilloNative |
| public private(set) var phase: Phase = .idle |
| public private(set) var summary = OutboxSummary() |
| public private(set) var sessionEnded = false |
| + private let transport: @MainActor () -> NativeTransport? |
| + private let connectivity: NativeConnectivity |
| + private let send: Send |
| + private let maxBatchBytes: Int? |
| + private var backoff: Backoff |
| + private var draining = false |
| + private var worker: Task<Void, Never>? |
| + private var observation: Task<Void, Never>? |
| + private var networkObservation: Task<Void, Never>? |
| + private var timer: Task<Void, Never>? |
| + private var wake: AsyncStream<Void>.Continuation? |
| + private var retryDeadline: TimeInterval? |
| + private var serverDeadline: TimeInterval? |
| + private var now: TimeInterval { ProcessInfo.processInfo.systemUptime } |
| + |
| public init(outbox: Outbox, transport: @escaping @MainActor () -> NativeTransport?, connectivity: NativeConnectivity, |
| - maxBatchBytes: Int? = nil, backoff: Backoff = Backoff(), send: @escaping Send) { self.outbox = outbox } |
| - public func start() {} |
| - public func stop() {} |
| - public func kick() {} |
| - public func retryNow() {} |
| - public func sessionRestored() {} |
| - @discardableResult public func drain() async -> Outcome { .idle } |
| + maxBatchBytes: Int? = nil, backoff: Backoff = Backoff(), send: @escaping Send) { |
| + self.outbox = outbox; self.transport = transport; self.connectivity = connectivity |
| + self.maxBatchBytes = maxBatchBytes; self.backoff = backoff; self.send = send |
| + } |
| + public func start() { |
| + guard worker == nil else { return } |
| + let (events, continuation) = AsyncStream<Void>.makeStream(bufferingPolicy: .bufferingNewest(1)) |
| + wake = continuation |
| + observation = Task { [weak self, outbox] in |
| + for await summary in await outbox.changes { |
| + guard let self else { return } |
| + if self.summary != summary { self.summary = summary; self.kick() } |
| + } |
| + } |
| + let changes = connectivity.changes |
| + networkObservation = Task { [weak self] in |
| + for await _ in changes { |
| + guard let self else { return } |
| + self.backoff.reset(); self.retryDeadline = nil; self.kick() |
| + } |
| + } |
| + worker = Task { [weak self] in |
| + for await _ in events { |
| + guard let self, !Task.isCancelled else { return } |
| + if !self.connectivity.isPathSatisfied { |
| + self.timer?.cancel(); self.timer = nil |
| + self.phase = .waitingForNetwork; continue |
| + } |
| + let deadline = max(self.retryDeadline ?? 0, self.serverDeadline ?? 0) |
| + if deadline > self.now { self.schedule(deadline - self.now); continue } |
| + switch await self.drain() { |
| + case .backingOff(let delay): self.retryDeadline = self.now + delay; self.schedule(delay) |
| + case .rateLimited(let delay): self.schedule(delay) |
| + default: break |
| + } |
| + } |
| + } |
| + kick() |
| + } |
| + private func schedule(_ delay: TimeInterval) { |
| + timer?.cancel() |
| + timer = Task { [weak self] in |
| + do { try await Task.sleep(for: .seconds(delay)) } catch { return } |
| + self?.kick() |
| + } |
| + } |
| + public func stop() { |
| + worker?.cancel(); observation?.cancel(); networkObservation?.cancel(); timer?.cancel(); wake?.finish() |
| + worker = nil; observation = nil; networkObservation = nil; timer = nil; wake = nil |
| + } |
| + public func kick() { wake?.yield() } |
| + public func retryNow() { retryDeadline = nil; backoff.reset(); kick() } |
| + public func sessionRestored() { sessionEnded = false; retryNow() } |
| + private func retry() -> Outcome { phase = .backingOff; return .backingOff(backoff.next()) } |
| + |
| + @discardableResult public func drain() async -> Outcome { |
| + guard !draining else { return .idle } |
| + draining = true |
| + defer { draining = false } |
| + do { try await outbox.load() } |
| + catch { summary = await outbox.summary; phase = .storeUnavailable; return .storeUnavailable } |
| + summary = await outbox.summary |
| + if sessionEnded { phase = .sessionEnded; return .sessionEnded } |
| + if !connectivity.isPathSatisfied { phase = .waitingForNetwork; return .waitingForNetwork } |
| + if let deadline = serverDeadline, deadline > now { phase = .backingOff; return .rateLimited(deadline - now) } |
| + serverDeadline = nil |
| + while !Task.isCancelled { |
| + summary = await outbox.summary |
| + var batch: [OutboxEntry] = [] |
| + do { |
| + for lane in summary.lanes.keys.sorted() { |
| + batch = try await outbox.beginSend(lane: lane, maxBytes: maxBatchBytes) |
| + if !batch.isEmpty { break } |
| + } |
| + } catch { phase = .storeUnavailable; return .storeUnavailable } |
| + guard let first = batch.first else { phase = .idle; return .idle } |
| + let ids = batch.map(\.id) |
| + guard let transport = transport() else { |
| + await outbox.endSend(ids, failed: false); sessionEnded = true; phase = .sessionEnded; return .sessionEnded |
| + } |
| + phase = .sending |
| + do { |
| + let dispositions: [UUID: Disposition] |
| + do { dispositions = try await send(first.lane, batch, transport) } |
| + catch let error as NativeClientError { |
| + let hold: Hold? |
| + switch error { |
| + case .forbidden, .notFound: hold = Hold(.accessLost) |
| + case .conflict(let data): hold = Hold(.conflict(data)) |
| + case .tooLarge: hold = Hold(.tooLarge) |
| + case .rejected(let status, _): hold = Hold(.rejected(String(status))) |
| + default: hold = nil |
| + } |
| + guard let hold else { throw error } |
| + dispositions = Dictionary(uniqueKeysWithValues: ids.map { ($0, .hold(hold)) }) |
| + } |
| + var mustRetry = false; var progressed = false |
| + for entry in batch { |
| + switch dispositions[entry.id] { |
| + case .sent: try await outbox.ack([entry.id]); progressed = true |
| + case .hold(let hold): try await outbox.hold([entry.id], hold); progressed = true |
| + case .retry: await outbox.endSend([entry.id]); mustRetry = true |
| + case nil: break |
| + } |
| + } |
| + await outbox.endSend(ids, failed: false) |
| + summary = await outbox.summary |
| + if mustRetry || !progressed { return retry() } |
| + backoff.reset(); retryDeadline = nil |
| + } catch { |
| + await outbox.endSend(ids); summary = await outbox.summary |
| + switch error { |
| + case NativeClientError.unauthorized: |
| + sessionEnded = true; phase = .sessionEnded; return .sessionEnded |
| + case NativeClientError.offline where !connectivity.isPathSatisfied: |
| + phase = .waitingForNetwork; return .waitingForNetwork |
| + case NativeClientError.rateLimited(let after): |
| + let delay = backoff.next(retryAfter: after); serverDeadline = now + delay |
| + phase = .backingOff; return .rateLimited(delay) |
| + default: return retry() |
| + } |
| + } |
| + if !connectivity.isPathSatisfied { phase = .waitingForNetwork; return .waitingForNetwork } |
| + } |
| + phase = .idle; return .idle |
| + } |
| public func status(lane: String? = nil, localFailure: SyncFailure? = nil, |
| - count: (OutboxSummary) -> Int = { $0.pendingLanes }) -> SyncStatus { .saved } |
| + count: (OutboxSummary) -> Int = { $0.pendingLanes }) -> SyncStatus { |
| + let state = lane.map { summary.only($0) } ?? summary |
| + let offline = transport().map { connectivity.isOffline($0.origin) } ?? !connectivity.isPathSatisfied |
| + return SyncStatus(summary: state, sending: state.inFlight > 0, sessionEnded: sessionEnded, |
| + offline: offline, backingOff: phase == .backingOff, localFailure: localFailure, count: count) |
| + } |
| } |
diff --git a/Sources/RastrilloApple/Resources/ar.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/ar.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..3293509 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ar.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "جارٍ الحفظ…"; |
| +"sync.retrying" = "تعذّر الحفظ · جارٍ إعادة المحاولة…"; |
| +"sync.signIn" = "تسجيل الدخول"; |
| +"sync.failed.cannotSave" = "يتعذّر الحفظ على هذا الجهاز."; |
| +"sync.failed.tooManyUnsent" = "هناك تغييرات كثيرة غير مرسلة لا يمكن الاحتفاظ بها على هذا الجهاز. اتصل للحفظ."; |
| +"sync.failed.held" = "تعذّر حفظ بعض التغييرات."; |
| +"offline.waiting" = "أنت غير متصل. في انتظار الاتصال."; |
| +"offline.durable" = "أنت غير متصل. التغييرات محفوظة على هذا الجهاز وستُرسل عند الاتصال مجددًا."; |
| +"sync.unsentLost" = "تعذّرت قراءة التغييرات غير المرسلة على هذا الجهاز وتمت إزالتها."; |
| +"sync.offline" = "غير متصل · %d قيد الانتظار"; |
| +"sync.needsSignIn" = "سجّل الدخول لإرسال %d قيد الانتظار"; |
diff --git a/Sources/RastrilloApple/Resources/ar.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/ar.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..7354e01 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ar.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>سجّل الدخول لإرسال %d قيد الانتظار</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>غير متصل · %d قيد الانتظار</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/bn.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/bn.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..71594da |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/bn.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "সংরক্ষণ করা হচ্ছে…"; |
| +"sync.retrying" = "সংরক্ষণে সমস্যা · আবার চেষ্টা করা হচ্ছে…"; |
| +"sync.signIn" = "সাইন ইন করুন"; |
| +"sync.failed.cannotSave" = "এই ডিভাইসে সংরক্ষণ করা যাচ্ছে না।"; |
| +"sync.failed.tooManyUnsent" = "এই ডিভাইসে রাখার জন্য অনেক বেশি পরিবর্তন পাঠানো বাকি আছে। সংরক্ষণ করতে সংযোগ করুন।"; |
| +"sync.failed.held" = "কিছু পরিবর্তন সংরক্ষণ করা যায়নি।"; |
| +"offline.waiting" = "আপনি অফলাইনে আছেন। সংযোগের অপেক্ষায়।"; |
| +"offline.durable" = "আপনি অফলাইনে আছেন। পরিবর্তনগুলো এই ডিভাইসে সংরক্ষিত আছে এবং আবার সংযোগ হলে পাঠানো হবে।"; |
| +"sync.unsentLost" = "এই ডিভাইসে না পাঠানো পরিবর্তনগুলো পড়া যায়নি এবং সরিয়ে দেওয়া হয়েছে।"; |
| +"sync.offline" = "অফলাইন · %dটি অপেক্ষমাণ"; |
| +"sync.needsSignIn" = "অপেক্ষমাণ %dটি পাঠাতে সাইন ইন করুন"; |
diff --git a/Sources/RastrilloApple/Resources/bn.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/bn.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..07879af |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/bn.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>অপেক্ষমাণ %dটি পাঠাতে সাইন ইন করুন</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>অফলাইন · %dটি অপেক্ষমাণ</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/en.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/en.lproj/Localizable.strings| index c91be22..a039b03 100644 |
| --- a/Sources/RastrilloApple/Resources/en.lproj/Localizable.strings |
| +++ b/Sources/RastrilloApple/Resources/en.lproj/Localizable.strings |
| @@ -1 +1,11 @@ |
| -"stub" = "stub"; |
| +"sync.saving" = "Saving…"; |
| +"sync.retrying" = "Trouble saving · Retrying…"; |
| +"sync.signIn" = "Sign in"; |
| +"sync.failed.cannotSave" = "Can’t save on this device."; |
| +"sync.failed.tooManyUnsent" = "Too many unsent changes to keep on this device. Connect to save."; |
| +"sync.failed.held" = "Some changes could not be saved."; |
| +"offline.waiting" = "You’re offline. Waiting for a connection."; |
| +"offline.durable" = "You’re offline. Changes are saved on this device and will be sent when you reconnect."; |
| +"sync.unsentLost" = "Unsent changes on this device could not be read and were removed."; |
| +"sync.offline" = "Offline · %d pending"; |
| +"sync.needsSignIn" = "Sign in to send %d pending"; |
diff --git a/Sources/RastrilloApple/Resources/en.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/en.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..9d3436d |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/en.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>Sign in to send %d pending</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>Offline · %d pending</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/es.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/es.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..8040158 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/es.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "Guardando…"; |
| +"sync.retrying" = "Problemas al guardar · Reintentando…"; |
| +"sync.signIn" = "Iniciar sesión"; |
| +"sync.failed.cannotSave" = "No se puede guardar en este dispositivo."; |
| +"sync.failed.tooManyUnsent" = "Hay demasiados cambios sin enviar para guardarlos en este dispositivo. Conéctate para guardar."; |
| +"sync.failed.held" = "No se pudieron guardar algunos cambios."; |
| +"offline.waiting" = "Sin conexión. Esperando una conexión."; |
| +"offline.durable" = "Sin conexión. Los cambios se guardan en este dispositivo y se enviarán cuando vuelvas a conectarte."; |
| +"sync.unsentLost" = "No se pudieron leer los cambios sin enviar de este dispositivo y se eliminaron."; |
| +"sync.offline" = "Sin conexión · %d pendientes"; |
| +"sync.needsSignIn" = "Inicia sesión para enviar %d pendientes"; |
diff --git a/Sources/RastrilloApple/Resources/es.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/es.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..6ecc453 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/es.lproj/Localizable.stringsdict |
| @@ -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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>one</key> |
| + <string>Inicia sesión para enviar %d pendiente</string> |
| + <key>other</key> |
| + <string>Inicia sesión para enviar %d pendientes</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>one</key> |
| + <string>Sin conexión · %d pendiente</string> |
| + <key>other</key> |
| + <string>Sin conexión · %d pendientes</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/ga.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/ga.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..34423ac |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ga.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "Á shábháil…"; |
| +"sync.retrying" = "Fadhb leis an sábháil · Ag triail arís…"; |
| +"sync.signIn" = "Sínigh isteach"; |
| +"sync.failed.cannotSave" = "Ní féidir sábháil ar an ngléas seo."; |
| +"sync.failed.tooManyUnsent" = "Tá an iomarca athruithe gan seoladh le coinneáil ar an ngléas seo. Ceangail chun sábháil."; |
| +"sync.failed.held" = "Níorbh fhéidir roinnt athruithe a shábháil."; |
| +"offline.waiting" = "Tá tú as líne. Ag fanacht le nasc."; |
| +"offline.durable" = "Tá tú as líne. Tá na hathruithe sábháilte ar an ngléas seo agus seolfar iad nuair a athcheanglóidh tú."; |
| +"sync.unsentLost" = "Níorbh fhéidir na hathruithe gan seoladh ar an ngléas seo a léamh agus baineadh iad."; |
| +"sync.offline" = "As líne · %d ar feitheamh"; |
| +"sync.needsSignIn" = "Sínigh isteach chun %d atá ar feitheamh a sheoladh"; |
diff --git a/Sources/RastrilloApple/Resources/ga.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/ga.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..98b3c0f |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ga.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>Sínigh isteach chun %d atá ar feitheamh a sheoladh</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>As líne · %d ar feitheamh</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/hi.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/hi.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..482b18e |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/hi.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "सहेजा जा रहा है…"; |
| +"sync.retrying" = "सहेजने में समस्या · फिर से कोशिश हो रही है…"; |
| +"sync.signIn" = "साइन इन करें"; |
| +"sync.failed.cannotSave" = "इस डिवाइस पर सहेजा नहीं जा सकता।"; |
| +"sync.failed.tooManyUnsent" = "इस डिवाइस पर रखने के लिए बहुत अधिक बदलाव भेजे जाने बाकी हैं। सहेजने के लिए कनेक्ट करें।"; |
| +"sync.failed.held" = "कुछ बदलाव सहेजे नहीं जा सके।"; |
| +"offline.waiting" = "आप ऑफ़लाइन हैं। कनेक्शन की प्रतीक्षा है।"; |
| +"offline.durable" = "आप ऑफ़लाइन हैं। बदलाव इस डिवाइस पर सहेजे गए हैं और दोबारा कनेक्ट होने पर भेजे जाएँगे।"; |
| +"sync.unsentLost" = "इस डिवाइस पर न भेजे गए बदलाव पढ़े नहीं जा सके और हटा दिए गए।"; |
| +"sync.offline" = "ऑफ़लाइन · %d लंबित"; |
| +"sync.needsSignIn" = "%d लंबित बदलाव भेजने के लिए साइन इन करें"; |
diff --git a/Sources/RastrilloApple/Resources/hi.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/hi.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..5667c87 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/hi.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>%d लंबित बदलाव भेजने के लिए साइन इन करें</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>ऑफ़लाइन · %d लंबित</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/ja.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/ja.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..582c4f0 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ja.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "保存中…"; |
| +"sync.retrying" = "保存できません · 再試行中…"; |
| +"sync.signIn" = "サインイン"; |
| +"sync.failed.cannotSave" = "このデバイスに保存できません。"; |
| +"sync.failed.tooManyUnsent" = "このデバイスに保存できる未送信の変更が多すぎます。接続して保存してください。"; |
| +"sync.failed.held" = "一部の変更を保存できませんでした。"; |
| +"offline.waiting" = "オフラインです。接続を待っています。"; |
| +"offline.durable" = "オフラインです。変更はこのデバイスに保存されており、再接続すると送信されます。"; |
| +"sync.unsentLost" = "このデバイスの未送信の変更を読み取れなかったため、削除しました。"; |
| +"sync.offline" = "オフライン · %d 件送信待ち"; |
| +"sync.needsSignIn" = "サインインして送信待ちの %d 件を送信"; |
diff --git a/Sources/RastrilloApple/Resources/ja.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/ja.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..b9b1d09 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ja.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>サインインして送信待ちの %d 件を送信</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>オフライン · %d 件送信待ち</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/pt.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/pt.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..409ee71 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/pt.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "A guardar…"; |
| +"sync.retrying" = "Problemas ao guardar · A tentar novamente…"; |
| +"sync.signIn" = "Iniciar sessão"; |
| +"sync.failed.cannotSave" = "Não é possível guardar neste dispositivo."; |
| +"sync.failed.tooManyUnsent" = "Há demasiadas alterações por enviar para guardar neste dispositivo. Ligue-se para guardar."; |
| +"sync.failed.held" = "Não foi possível guardar algumas alterações."; |
| +"offline.waiting" = "Sem ligação. A aguardar uma ligação."; |
| +"offline.durable" = "Sem ligação. As alterações estão guardadas neste dispositivo e serão enviadas quando voltar a ligar-se."; |
| +"sync.unsentLost" = "Não foi possível ler as alterações por enviar neste dispositivo e foram removidas."; |
| +"sync.offline" = "Sem ligação · %d pendentes"; |
| +"sync.needsSignIn" = "Inicie sessão para enviar %d pendentes"; |
diff --git a/Sources/RastrilloApple/Resources/pt.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/pt.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..0adbbe8 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/pt.lproj/Localizable.stringsdict |
| @@ -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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>one</key> |
| + <string>Inicie sessão para enviar %d pendente</string> |
| + <key>other</key> |
| + <string>Inicie sessão para enviar %d pendentes</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>one</key> |
| + <string>Sem ligação · %d pendente</string> |
| + <key>other</key> |
| + <string>Sem ligação · %d pendentes</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/ru.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/ru.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..6b4c740 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ru.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "Сохранение…"; |
| +"sync.retrying" = "Не удаётся сохранить · Повторная попытка…"; |
| +"sync.signIn" = "Войти"; |
| +"sync.failed.cannotSave" = "Не удаётся сохранить на этом устройстве."; |
| +"sync.failed.tooManyUnsent" = "Слишком много неотправленных изменений для хранения на этом устройстве. Подключитесь к сети для сохранения."; |
| +"sync.failed.held" = "Не удалось сохранить некоторые изменения."; |
| +"offline.waiting" = "Нет подключения. Ожидание сети."; |
| +"offline.durable" = "Нет подключения. Изменения сохранены на этом устройстве и будут отправлены при подключении к сети."; |
| +"sync.unsentLost" = "Не удалось прочитать неотправленные изменения на этом устройстве, и они были удалены."; |
| +"sync.offline" = "Не в сети · %d ожидают отправки"; |
| +"sync.needsSignIn" = "Войдите, чтобы отправить ожидающие изменения: %d"; |
diff --git a/Sources/RastrilloApple/Resources/ru.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/ru.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..c204339 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/ru.lproj/Localizable.stringsdict |
| @@ -0,0 +1,40 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>Войдите, чтобы отправить ожидающие изменения: %d</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>few</key> |
| + <string>Не в сети · %d ожидают отправки</string> |
| + <key>many</key> |
| + <string>Не в сети · %d ожидают отправки</string> |
| + <key>one</key> |
| + <string>Не в сети · %d ожидает отправки</string> |
| + <key>other</key> |
| + <string>Не в сети · %d ожидают отправки</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/vi.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/vi.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..d96fa16 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/vi.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "Đang lưu…"; |
| +"sync.retrying" = "Gặp sự cố khi lưu · Đang thử lại…"; |
| +"sync.signIn" = "Đăng nhập"; |
| +"sync.failed.cannotSave" = "Không thể lưu trên thiết bị này."; |
| +"sync.failed.tooManyUnsent" = "Có quá nhiều thay đổi chưa gửi để lưu trên thiết bị này. Hãy kết nối để lưu."; |
| +"sync.failed.held" = "Không thể lưu một số thay đổi."; |
| +"offline.waiting" = "Bạn đang ngoại tuyến. Đang chờ kết nối."; |
| +"offline.durable" = "Bạn đang ngoại tuyến. Các thay đổi đã được lưu trên thiết bị này và sẽ được gửi khi bạn kết nối lại."; |
| +"sync.unsentLost" = "Không thể đọc các thay đổi chưa gửi trên thiết bị này nên chúng đã bị xóa."; |
| +"sync.offline" = "Ngoại tuyến · %d đang chờ"; |
| +"sync.needsSignIn" = "Đăng nhập để gửi %d mục đang chờ"; |
diff --git a/Sources/RastrilloApple/Resources/vi.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/vi.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..7f20433 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/vi.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>Đăng nhập để gửi %d mục đang chờ</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>Ngoại tuyến · %d đang chờ</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/yue.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/yue.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..8222134 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/yue.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "儲存中…"; |
| +"sync.retrying" = "儲存遇到問題 · 重試中…"; |
| +"sync.signIn" = "登入"; |
| +"sync.failed.cannotSave" = "無法喺呢部裝置儲存。"; |
| +"sync.failed.tooManyUnsent" = "未傳送嘅更改太多,無法保留喺呢部裝置。請連線儲存。"; |
| +"sync.failed.held" = "部分更改無法儲存。"; |
| +"offline.waiting" = "你已離線。等候連線中。"; |
| +"offline.durable" = "你已離線。更改已儲存喺呢部裝置,重新連線後就會傳送。"; |
| +"sync.unsentLost" = "無法讀取呢部裝置上未傳送嘅更改,已將佢哋移除。"; |
| +"sync.offline" = "離線 · %d 項等候傳送"; |
| +"sync.needsSignIn" = "登入以傳送 %d 項等候中嘅更改"; |
diff --git a/Sources/RastrilloApple/Resources/yue.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/yue.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..afc8745 |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/yue.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>登入以傳送 %d 項等候中嘅更改</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>離線 · %d 項等候傳送</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |
diff --git a/Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.strings b/Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.strings| new file mode 100644 |
| index 0000000..0e15cba |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.strings |
| @@ -0,0 +1,11 @@ |
| +"sync.saving" = "正在保存…"; |
| +"sync.retrying" = "保存遇到问题 · 正在重试…"; |
| +"sync.signIn" = "登录"; |
| +"sync.failed.cannotSave" = "无法在此设备上保存。"; |
| +"sync.failed.tooManyUnsent" = "未发送的更改过多,无法保存在此设备上。请联网保存。"; |
| +"sync.failed.held" = "部分更改无法保存。"; |
| +"offline.waiting" = "你已离线。正在等待连接。"; |
| +"offline.durable" = "你已离线。更改已保存在此设备上,重新连接后将发送。"; |
| +"sync.unsentLost" = "无法读取此设备上未发送的更改,已将其移除。"; |
| +"sync.offline" = "离线 · %d 项待发送"; |
| +"sync.needsSignIn" = "登录以发送 %d 项待处理的更改"; |
diff --git a/Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.stringsdict b/Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.stringsdict| new file mode 100644 |
| index 0000000..5345c5f |
| --- /dev/null |
| +++ b/Sources/RastrilloApple/Resources/zh-Hans.lproj/Localizable.stringsdict |
| @@ -0,0 +1,34 @@ |
| +<?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>sync.needsSignIn</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>登录以发送 %d 项待处理的更改</string> |
| + </dict> |
| + </dict> |
| + <key>sync.offline</key> |
| + <dict> |
| + <key>NSStringLocalizedFormatKey</key> |
| + <string>%#@n@</string> |
| + <key>n</key> |
| + <dict> |
| + <key>NSStringFormatSpecTypeKey</key> |
| + <string>NSStringPluralRuleType</string> |
| + <key>NSStringFormatValueTypeKey</key> |
| + <string>d</string> |
| + <key>other</key> |
| + <string>离线 · %d 项待发送</string> |
| + </dict> |
| + </dict> |
| +</dict> |
| +</plist> |