Showing debug info in report

This commit is contained in:
Selim Mustafaev 2021-01-03 14:59:27 +03:00
parent dc8dae9d19
commit 3ce8e2d0ae
11 changed files with 173 additions and 4 deletions

View File

@ -73,6 +73,9 @@
7A813DCB250B5DC900CC93B9 /* LocationPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A813DCA250B5DC900CC93B9 /* LocationPickerController.swift */; }; 7A813DCB250B5DC900CC93B9 /* LocationPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A813DCA250B5DC900CC93B9 /* LocationPickerController.swift */; };
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; }; 7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; };
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */; }; 7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */; };
7A8AB76525A0DB8F00ECF2C1 /* BundleVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8AB76425A0DB8F00ECF2C1 /* BundleVersion.swift */; };
7A8AB76825A0DC8200ECF2C1 /* DebugInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8AB76725A0DC8200ECF2C1 /* DebugInfo.swift */; };
7A8AB76B25A1D95500ECF2C1 /* SourceStatusRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8AB76A25A1D95500ECF2C1 /* SourceStatusRow.swift */; };
7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */; }; 7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */; };
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; }; 7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
7A96AE31246B2FE400297C33 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE30246B2FE400297C33 /* Constants.swift */; }; 7A96AE31246B2FE400297C33 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE30246B2FE400297C33 /* Constants.swift */; };
@ -189,6 +192,9 @@
7A813DCA250B5DC900CC93B9 /* LocationPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPickerController.swift; sourceTree = "<group>"; }; 7A813DCA250B5DC900CC93B9 /* LocationPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPickerController.swift; sourceTree = "<group>"; };
7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResizeImage.swift; sourceTree = "<group>"; }; 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResizeImage.swift; sourceTree = "<group>"; };
7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleReportImage.swift; sourceTree = "<group>"; }; 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleReportImage.swift; sourceTree = "<group>"; };
7A8AB76425A0DB8F00ECF2C1 /* BundleVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleVersion.swift; sourceTree = "<group>"; };
7A8AB76725A0DC8200ECF2C1 /* DebugInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugInfo.swift; sourceTree = "<group>"; };
7A8AB76A25A1D95500ECF2C1 /* SourceStatusRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceStatusRow.swift; sourceTree = "<group>"; };
7A92D0AB240425B100EF3B77 /* ATGMediaBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ATGMediaBrowser.framework; path = Carthage/Build/iOS/ATGMediaBrowser.framework; sourceTree = "<group>"; }; 7A92D0AB240425B100EF3B77 /* ATGMediaBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ATGMediaBrowser.framework; path = Carthage/Build/iOS/ATGMediaBrowser.framework; sourceTree = "<group>"; };
7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleSignInController.swift; sourceTree = "<group>"; }; 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleSignInController.swift; sourceTree = "<group>"; };
7A96AE2E246B2BCD00297C33 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; }; 7A96AE2E246B2BCD00297C33 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; };
@ -266,6 +272,7 @@
7A0B969F257D6D4B000B39AD /* MultilineLabelRow.swift */, 7A0B969F257D6D4B000B39AD /* MultilineLabelRow.swift */,
7A2DE69D2589606A00A113FC /* ImageGridRow.swift */, 7A2DE69D2589606A00A113FC /* ImageGridRow.swift */,
7AE492A0259232F000322D2E /* MultilineLinkRow.swift */, 7AE492A0259232F000322D2E /* MultilineLinkRow.swift */,
7A8AB76A25A1D95500ECF2C1 /* SourceStatusRow.swift */,
); );
path = eureka; path = eureka;
sourceTree = "<group>"; sourceTree = "<group>";
@ -377,6 +384,7 @@
7A0420A925619AEC00034941 /* Osago.swift */, 7A0420A925619AEC00034941 /* Osago.swift */,
7A2DE69725868AC800A113FC /* VehicleAd.swift */, 7A2DE69725868AC800A113FC /* VehicleAd.swift */,
7AF12B1C258C9CFF0090F8B8 /* Cloneable.swift */, 7AF12B1C258C9CFF0090F8B8 /* Cloneable.swift */,
7A8AB76725A0DC8200ECF2C1 /* DebugInfo.swift */,
); );
path = Models; path = Models;
sourceTree = "<group>"; sourceTree = "<group>";
@ -406,6 +414,7 @@
7ADF6C92250B954900F237B2 /* Navigation.swift */, 7ADF6C92250B954900F237B2 /* Navigation.swift */,
7ADF6CA02512244400F237B2 /* MapExt.swift */, 7ADF6CA02512244400F237B2 /* MapExt.swift */,
7AE24C5E251F1B4E00758E39 /* Buttons.swift */, 7AE24C5E251F1B4E00758E39 /* Buttons.swift */,
7A8AB76425A0DB8F00ECF2C1 /* BundleVersion.swift */,
); );
path = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -585,6 +594,7 @@
7A813DC9250B5C9700CC93B9 /* LocationRow.swift in Sources */, 7A813DC9250B5C9700CC93B9 /* LocationRow.swift in Sources */,
7A2DE69B25869ABD00A113FC /* AdsController.swift in Sources */, 7A2DE69B25869ABD00A113FC /* AdsController.swift in Sources */,
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */, 7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
7A8AB76B25A1D95500ECF2C1 /* SourceStatusRow.swift in Sources */,
7A813DC32508EE4F00CC93B9 /* EventCell.swift in Sources */, 7A813DC32508EE4F00CC93B9 /* EventCell.swift in Sources */,
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */, 7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */, 7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */,
@ -629,6 +639,7 @@
7A813DC5250AAF3C00CC93B9 /* LocationEditController.swift in Sources */, 7A813DC5250AAF3C00CC93B9 /* LocationEditController.swift in Sources */,
7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */, 7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */,
7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */, 7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */,
7A8AB76825A0DC8200ECF2C1 /* DebugInfo.swift in Sources */,
7ADF6C9F251201D200F237B2 /* GlobalEventsController.swift in Sources */, 7ADF6C9F251201D200F237B2 /* GlobalEventsController.swift in Sources */,
7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */, 7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */,
7A11470323FDE7E500B424AF /* SceneDelegate.swift in Sources */, 7A11470323FDE7E500B424AF /* SceneDelegate.swift in Sources */,
@ -637,6 +648,7 @@
7A0420AA25619AEC00034941 /* Osago.swift in Sources */, 7A0420AA25619AEC00034941 /* Osago.swift in Sources */,
7A11474423FF06CA00B424AF /* Api.swift in Sources */, 7A11474423FF06CA00B424AF /* Api.swift in Sources */,
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */, 7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */,
7A8AB76525A0DB8F00ECF2C1 /* BundleVersion.swift in Sources */,
7A0420AD2561A0B100034941 /* OsagoController.swift in Sources */, 7A0420AD2561A0B100034941 /* OsagoController.swift in Sources */,
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */, 7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
7A21112A24FC3D7E003BBF6F /* AudioEngine.swift in Sources */, 7A21112A24FC3D7E003BBF6F /* AudioEngine.swift in Sources */,
@ -831,7 +843,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 61; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = 46DTTB8X4S; DEVELOPMENT_TEAM = 46DTTB8X4S;
INFOPLIST_FILE = AutoCat/Info.plist; INFOPLIST_FILE = AutoCat/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
@ -854,7 +866,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 61; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = 46DTTB8X4S; DEVELOPMENT_TEAM = 46DTTB8X4S;
INFOPLIST_FILE = AutoCat/Info.plist; INFOPLIST_FILE = AutoCat/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;

View File

@ -25,7 +25,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let config = Realm.Configuration( let config = Realm.Configuration(
schemaVersion: 28, schemaVersion: 29,
migrationBlock: { migration, oldSchemaVersion in migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion <= 3 { if oldSchemaVersion <= 3 {
var numbers: [String] = [] var numbers: [String] = []

View File

@ -125,12 +125,25 @@ class ReportController: FormViewController, MediaBrowserViewControllerDataSource
controller.ads = self.vehicle?.ads.toArray() ?? [] controller.ads = self.vehicle?.ads.toArray() ?? []
self.navigationController?.pushViewController(controller, animated: true) self.navigationController?.pushViewController(controller, animated: true)
} }
if Settings.shared.showDebugInfo {
self.form +++ Section(NSLocalizedString("Debug info", comment: "noun"))
<<< SourceStatusRow("DebugAutocod") { $0.title = NSLocalizedString("Autocod", comment: "") }
<<< SourceStatusRow("DebugVin01Vin") { $0.title = NSLocalizedString("Vin01 (VIN)", comment: "") }
<<< SourceStatusRow("DebugVin01Base") { $0.title = NSLocalizedString("Vin01 (base)", comment: "base report") }
<<< SourceStatusRow("DebugVin01History") { $0.title = NSLocalizedString("Vin01 (history)", comment: "GIBDD registration history") }
<<< SourceStatusRow("DebugNomerogram") { $0.title = NSLocalizedString("Nomerogram", comment: "") }
}
} }
func row(_ tag: String) -> LabelRow? { func row(_ tag: String) -> LabelRow? {
self.form.rowBy(tag: tag) as? LabelRow self.form.rowBy(tag: tag) as? LabelRow
} }
func sourceStatusRow(_ tag: String) -> SourceStatusRow? {
self.form.rowBy(tag: tag) as? SourceStatusRow
}
func updateReport() { func updateReport() {
self.row("Model")?.value = self.vehicle?.brand?.name?.original ?? "<unknown>" self.row("Model")?.value = self.vehicle?.brand?.name?.original ?? "<unknown>"
self.row("Year")?.value = String(self.vehicle?.year ?? 0) self.row("Year")?.value = String(self.vehicle?.year ?? 0)
@ -158,6 +171,14 @@ class ReportController: FormViewController, MediaBrowserViewControllerDataSource
self.row("Owners")?.value = String(self.vehicle?.ownershipPeriods.count ?? 0) self.row("Owners")?.value = String(self.vehicle?.ownershipPeriods.count ?? 0)
self.row("Photos")?.value = String(self.vehicle?.photos.count ?? 0) self.row("Photos")?.value = String(self.vehicle?.photos.count ?? 0)
self.row("Ads")?.value = String(self.vehicle?.ads.count ?? 0) self.row("Ads")?.value = String(self.vehicle?.ads.count ?? 0)
if let dInfo = self.vehicle?.debugInfo {
self.sourceStatusRow("DebugAutocod")?.value = dInfo.autocod
self.sourceStatusRow("DebugVin01Vin")?.value = dInfo.vin01vin
self.sourceStatusRow("DebugVin01Base")?.value = dInfo.vin01base
self.sourceStatusRow("DebugVin01History")?.value = dInfo.vin01history
self.sourceStatusRow("DebugNomerogram")?.value = dInfo.nomerogram
}
} }
func stringFromBool(_ value: Bool?, yes: String, no: String) -> String { func stringFromBool(_ value: Bool?, yes: String, no: String) -> String {

View File

@ -7,6 +7,12 @@ class SettingsController: FormViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
form +++ Section()
<<< LabelRow() { row in
row.title = NSLocalizedString("Version", comment: "")
row.value = Bundle.main.fullVersion
}
form +++ Section(NSLocalizedString("Profile", comment: "")) form +++ Section(NSLocalizedString("Profile", comment: ""))
<<< LabelRow("AutoCatAccount") { row in <<< LabelRow("AutoCatAccount") { row in
row.title = NSLocalizedString("AutoCat Account", comment: "") row.title = NSLocalizedString("AutoCat Account", comment: "")

View File

@ -0,0 +1,16 @@
import Foundation
extension Bundle {
var versionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
var buildNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String
}
var fullVersion: String? {
guard let version = self.versionNumber, let build = self.buildNumber else { return nil }
return version + "." + build
}
}

View File

@ -11,3 +11,16 @@ extension UIViewController {
view.endEditing(true) view.endEditing(true)
} }
} }
extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}

View File

@ -0,0 +1,15 @@
import Foundation
import RealmSwift
class DebugInfo: Object, Decodable {
@objc dynamic var autocod: DebugInfoEntry!
@objc dynamic var vin01vin: DebugInfoEntry!
@objc dynamic var vin01base: DebugInfoEntry!
@objc dynamic var vin01history: DebugInfoEntry!
@objc dynamic var nomerogram: DebugInfoEntry!
}
class DebugInfoEntry: Object, Decodable {
@objc dynamic var fields: Int64 = 0
@objc dynamic var error: String?
}

View File

@ -43,7 +43,7 @@ class Settings {
var showDebugInfo: Bool = false { var showDebugInfo: Bool = false {
didSet { didSet {
Settings.defaults.set(self.recordBeep, forKey: "showDebugInfo") Settings.defaults.set(self.showDebugInfo, forKey: "showDebugInfo")
Settings.defaults.synchronize() Settings.defaults.synchronize()
} }
} }

View File

@ -183,6 +183,7 @@ class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable {
var events = List<VehicleEvent>() var events = List<VehicleEvent>()
var osagoContracts = List<Osago>() var osagoContracts = List<Osago>()
var ads = List<VehicleAd>() var ads = List<VehicleAd>()
@objc dynamic var debugInfo: DebugInfo?
var differenceIdentifier: String { self.number } var differenceIdentifier: String { self.number }
@ -212,6 +213,7 @@ class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable {
case events case events
case osagoContracts case osagoContracts
case ads case ads
case debugInfo
} }
required init(from decoder: Decoder) throws { required init(from decoder: Decoder) throws {
@ -232,6 +234,7 @@ class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable {
self.isJapanese = RealmOptional(try container.decodeIfPresent(Bool.self, forKey: .isJapanese)) self.isJapanese = RealmOptional(try container.decodeIfPresent(Bool.self, forKey: .isJapanese))
self.addedDate = (try container.decode(TimeInterval.self, forKey: .addedDate))/1000 self.addedDate = (try container.decode(TimeInterval.self, forKey: .addedDate))/1000
self.addedBy = try container.decode(String.self, forKey: .addedBy) self.addedBy = try container.decode(String.self, forKey: .addedBy)
self.debugInfo = try container.decodeIfPresent(DebugInfo.self, forKey: .debugInfo)
if let photosArray = try container.decodeIfPresent([VehiclePhoto].self, forKey: .photos) { if let photosArray = try container.decodeIfPresent([VehiclePhoto].self, forKey: .photos) {
self.photos.append(objectsIn: photosArray) self.photos.append(objectsIn: photosArray)

View File

@ -0,0 +1,56 @@
import UIKit
import Eureka
class SourceStatusCell: Cell<DebugInfoEntry>, CellType {
private var circle: UIImageView!
required init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func setup() {
super.setup()
self.selectionStyle = .none
self.circle = UIImageView(frame: .zero)
self.circle.translatesAutoresizingMaskIntoConstraints = false
self.circle.image = UIImage(systemName: "circle.fill")
self.contentView.addSubview(self.circle)
NSLayoutConstraint.activate([
self.circle.trailingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.trailingAnchor),
self.circle.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor)
])
}
override func update() {
super.update()
self.detailTextLabel?.text = nil
if let value = row.value {
self.circle.tintColor = value.error == nil ? .systemGreen : .systemRed
//self.accessoryType = value.error == nil ? .none : .disclosureIndicator
} else {
self.circle.tintColor = .systemGray
//self.accessoryType = .none
}
}
}
final class SourceStatusRow: Row<SourceStatusCell>, RowType {
required init(tag: String?) {
super.init(tag: tag)
cellProvider = CellProvider<SourceStatusCell>()
self.onCellSelection { cell, row in
if let error = row.value?.error, let controller = cell.parentViewController {
let alert = UIAlertController(title: row.title, message: error, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
controller.present(alert, animated: true)
}
}
}
}

View File

@ -43,6 +43,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"AutoCat Account" = "Аккаунт в АвтоКот"; "AutoCat Account" = "Аккаунт в АвтоКот";
/* No comment provided by engineer. */
"Autocod" = "Автокод";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Beep before record" = "Звуковой сигнал перед записью"; "Beep before record" = "Звуковой сигнал перед записью";
@ -94,6 +97,12 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Date and time" = "Дата и время"; "Date and time" = "Дата и время";
/* No comment provided by engineer. */
"Debug" = "Отладка";
/* noun */
"Debug info" = "Отладочная информация";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Default region" = "Регион по умолчанию"; "Default region" = "Регион по умолчанию";
@ -193,6 +202,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"No" = "Нет"; "No" = "Нет";
/* No comment provided by engineer. */
"Nomerogram" = "Номерограм";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"now" = "Настоящий момент"; "now" = "Настоящий момент";
@ -289,6 +301,9 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Shortened numbers" = "Укороченные номера"; "Shortened numbers" = "Укороченные номера";
/* No comment provided by engineer. */
"Show debug info" = "Показывать отладочную информацию";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Show on map" = "Показать на карте"; "Show on map" = "Показать на карте";
@ -325,9 +340,21 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Vehicle usage region" = "Транспортное средство используется в регионе"; "Vehicle usage region" = "Транспортное средство используется в регионе";
/* No comment provided by engineer. */
"Version" = "Версия";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"VIN" = "VIN"; "VIN" = "VIN";
/* base report */
"Vin01 (base)" = "Vin01 (базовый отчет)";
/* GIBDD registration history */
"Vin01 (history)" = "Vin01 (история регистраций)";
/* No comment provided by engineer. */
"Vin01 (VIN)" = "Vin01 (VIN)";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Volume (cm³)" = "Объем (см³)"; "Volume (cm³)" = "Объем (см³)";