diff --git a/NotificationService/Serialization.m b/NotificationService/Serialization.m
index 00a0621e3e..f7eea7807e 100644
--- a/NotificationService/Serialization.m
+++ b/NotificationService/Serialization.m
@@ -3,7 +3,7 @@
@implementation Serialization
- (NSUInteger)currentLayer {
- return 109;
+ return 110;
}
- (id _Nullable)parseMessage:(NSData * _Nullable)data {
diff --git a/Telegram-iOS/Resources/Compass.tgs b/Telegram-iOS/Resources/Compass.tgs
new file mode 100644
index 0000000000..d9ec83eb77
Binary files /dev/null and b/Telegram-iOS/Resources/Compass.tgs differ
diff --git a/Telegram-iOS/Resources/Dice_1.tgs b/Telegram-iOS/Resources/Dice_1.tgs
new file mode 100644
index 0000000000..e078e6b6de
Binary files /dev/null and b/Telegram-iOS/Resources/Dice_1.tgs differ
diff --git a/Telegram-iOS/Resources/Dice_2.tgs b/Telegram-iOS/Resources/Dice_2.tgs
new file mode 100644
index 0000000000..c350c4d88c
Binary files /dev/null and b/Telegram-iOS/Resources/Dice_2.tgs differ
diff --git a/Telegram-iOS/Resources/Dice_3.tgs b/Telegram-iOS/Resources/Dice_3.tgs
new file mode 100644
index 0000000000..388043434d
Binary files /dev/null and b/Telegram-iOS/Resources/Dice_3.tgs differ
diff --git a/Telegram-iOS/Resources/Dice_4.tgs b/Telegram-iOS/Resources/Dice_4.tgs
new file mode 100644
index 0000000000..0cc05f7cea
Binary files /dev/null and b/Telegram-iOS/Resources/Dice_4.tgs differ
diff --git a/Telegram-iOS/Resources/Dice_5.tgs b/Telegram-iOS/Resources/Dice_5.tgs
new file mode 100644
index 0000000000..2005eef2f4
Binary files /dev/null and b/Telegram-iOS/Resources/Dice_5.tgs differ
diff --git a/Telegram-iOS/Resources/Dice_6.tgs b/Telegram-iOS/Resources/Dice_6.tgs
new file mode 100644
index 0000000000..6c298dde36
Binary files /dev/null and b/Telegram-iOS/Resources/Dice_6.tgs differ
diff --git a/Telegram-iOS/en.lproj/Localizable.strings b/Telegram-iOS/en.lproj/Localizable.strings
index c2aade54e4..67b8058d9d 100644
--- a/Telegram-iOS/en.lproj/Localizable.strings
+++ b/Telegram-iOS/en.lproj/Localizable.strings
@@ -5284,3 +5284,22 @@ Any member of this group will be able to see messages in the channel.";
"Map.PlacesInThisArea" = "Places In This Area";
"Conversation.LiveLocationYouAndOther" = "**You** and %@";
+
+"PeopleNearby.MakeVisible" = "Make Myself Visible";
+"PeopleNearby.MakeInvisible" = "Stop Showing Me";
+
+"PeopleNearby.ShowMorePeople_0" = "Show %@ More People";
+"PeopleNearby.ShowMorePeople_1" = "Show %@ More People";
+"PeopleNearby.ShowMorePeople_2" = "Show %@ More People";
+"PeopleNearby.ShowMorePeople_3_10" = "Show %@ More People";
+"PeopleNearby.ShowMorePeople_many" = "Show %@ More People";
+"PeopleNearby.ShowMorePeople_any" = "Show %@ More People";
+
+"PeopleNearby.VisibleUntil" = "visible until %@";
+
+"PeopleNearby.MakeVisibleTitle" = "Make Myself Visible";
+"PeopleNearby.MakeVisibleDescription" = "Allow people nearby to view your profile for 24 hours?\n\nYour phone number will remain hidden.";
+
+"PeopleNearby.DiscoverDescription" = "Exchange contact info with people nearby\nand find new friends.";
+
+"Time.TomorrowAt" = "tomorrow at %@";
diff --git a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift
index f21f09f4a8..173646c596 100644
--- a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift
+++ b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift
@@ -42,9 +42,15 @@ public enum AnimatedStickerMode {
case direct
}
+public enum AnimatedStickerPlaybackPosition {
+ case start
+ case end
+}
+
public enum AnimatedStickerPlaybackMode {
case once
case loop
+ case still(AnimatedStickerPlaybackPosition)
}
private final class AnimatedStickerFrame {
@@ -72,6 +78,7 @@ private protocol AnimatedStickerFrameSource: class {
var frameCount: Int { get }
func takeFrame() -> AnimatedStickerFrame?
+ func skipToEnd()
}
private final class AnimatedStickerFrameSourceWrapper {
@@ -244,6 +251,9 @@ private final class AnimatedStickerCachedFrameSource: AnimatedStickerFrameSource
self.data = data
self.dataComplete = complete
}
+
+ func skipToEnd() {
+ }
}
private final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource {
@@ -289,6 +299,10 @@ private final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource
}
return AnimatedStickerFrame(data: frameData, type: .argb, width: self.width, height: self.height, bytesPerRow: self.bytesPerRow, index: frameIndex, isLastFrame: frameIndex == self.frameCount - 1)
}
+
+ func skipToEnd() {
+ self.currentFrame = self.frameCount - 1
+ }
}
private final class AnimatedStickerFrameQueue {
@@ -383,7 +397,7 @@ public final class AnimatedStickerNode: ASDisplayNode {
private var renderer: (AnimationRenderer & ASDisplayNode)?
- private var isPlaying: Bool = false
+ public var isPlaying: Bool = false
private var canDisplayFirstFrame: Bool = false
private var playbackMode: AnimatedStickerPlaybackMode = .loop
@@ -456,7 +470,9 @@ public final class AnimatedStickerNode: ASDisplayNode {
if let directData = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) {
strongSelf.directData = (directData, path, width, height)
}
- if strongSelf.isPlaying {
+ if case let .still(position) = playbackMode {
+ strongSelf.seekTo(position)
+ } else if strongSelf.isPlaying {
strongSelf.play()
} else if strongSelf.canDisplayFirstFrame {
strongSelf.play(firstFrame: true)
@@ -597,11 +613,11 @@ public final class AnimatedStickerNode: ASDisplayNode {
self.reportedStarted = false
self.timer.swap(nil)?.invalidate()
if self.playToCompletionOnStop {
- self.seekToStart()
+ self.seekTo(.start)
}
}
- public func seekToStart() {
+ public func seekTo(_ position: AnimatedStickerPlaybackPosition) {
self.isPlaying = false
let directData = self.directData
@@ -612,6 +628,9 @@ public final class AnimatedStickerNode: ASDisplayNode {
var maybeFrameSource: AnimatedStickerFrameSource?
if let directData = directData {
maybeFrameSource = AnimatedStickerDirectFrameSource(queue: queue, data: directData.0, width: directData.2, height: directData.3)
+ if position == .end {
+ maybeFrameSource?.skipToEnd()
+ }
} else if let (cachedData, cachedDataComplete) = cachedData {
if #available(iOS 9.0, *) {
maybeFrameSource = AnimatedStickerCachedFrameSource(queue: queue, data: cachedData, complete: cachedDataComplete, notifyUpdated: {})
diff --git a/submodules/CallListUI/Sources/CallListController.swift b/submodules/CallListUI/Sources/CallListController.swift
index 8de824eba8..974cd94fc7 100644
--- a/submodules/CallListUI/Sources/CallListController.swift
+++ b/submodules/CallListUI/Sources/CallListController.swift
@@ -59,7 +59,12 @@ public final class CallListController: ViewController {
if case .tab = self.mode {
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed))
- let icon = UIImage(bundleImageName: "Chat List/Tabs/IconCalls")
+ let icon: UIImage?
+ if useSpecialTabBarIcons() {
+ icon = UIImage(bundleImageName: "Chat List/Tabs/Holiday/IconCalls")
+ } else {
+ icon = UIImage(bundleImageName: "Chat List/Tabs/IconCalls")
+ }
self.tabBarItem.title = self.presentationData.strings.Calls_TabTitle
self.tabBarItem.image = icon
self.tabBarItem.selectedImage = icon
diff --git a/submodules/Charts/BUCK b/submodules/Charts/BUCK
new file mode 100644
index 0000000000..79bf8180b8
--- /dev/null
+++ b/submodules/Charts/BUCK
@@ -0,0 +1,31 @@
+load("//Config:buck_rule_macros.bzl", "static_library")
+
+static_library(
+ name = "Charts",
+ srcs = glob([
+ "Sources/**/*.swift",
+ ]),
+ deps = [
+ "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared",
+ "//submodules/AsyncDisplayKit:AsyncDisplayKit#shared",
+ "//submodules/Display:Display#shared",
+ "//submodules/Postbox:Postbox#shared",
+ "//submodules/TelegramCore:TelegramCore#shared",
+ "//submodules/SyncCore:SyncCore#shared",
+ "//submodules/TelegramPresentationData:TelegramPresentationData",
+ "//submodules/TelegramUIPreferences:TelegramUIPreferences",
+ "//submodules/AccountContext:AccountContext",
+ "//submodules/ItemListUI:ItemListUI",
+ "//submodules/AvatarNode:AvatarNode",
+ "//submodules/TelegramStringFormatting:TelegramStringFormatting",
+ "//submodules/AlertUI:AlertUI",
+ "//submodules/PresentationDataUtils:PresentationDataUtils",
+ "//submodules/TelegramNotices:TelegramNotices",
+ "//submodules/MergeLists:MergeLists",
+ "//submodules/AppBundle:AppBundle",
+ ],
+ frameworks = [
+ "$SDKROOT/System/Library/Frameworks/Foundation.framework",
+ "$SDKROOT/System/Library/Frameworks/UIKit.framework",
+ ],
+)
diff --git a/submodules/Charts/Info.plist b/submodules/Charts/Info.plist
new file mode 100644
index 0000000000..e1fe4cfb7b
--- /dev/null
+++ b/submodules/Charts/Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+
+
diff --git a/submodules/Charts/Sources/Chart Screen/ChartDetailsView.swift b/submodules/Charts/Sources/Chart Screen/ChartDetailsView.swift
new file mode 100644
index 0000000000..7232c594c3
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartDetailsView.swift
@@ -0,0 +1,258 @@
+//
+// ChartDetailsView.swift
+// GraphTest
+//
+// Created by Andrew Solovey on 14/03/2019.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private let cornerRadius: CGFloat = 5
+private let verticalMargins: CGFloat = 8
+private var labelHeight: CGFloat = 18
+private var margin: CGFloat = 10
+private var prefixLabelWidth: CGFloat = 27
+private var textLabelWidth: CGFloat = 60
+private var valueLabelWidth: CGFloat = 65
+
+struct ChartDetailsViewModel {
+ struct Value {
+ let prefix: String?
+ let title: String
+ let value: String
+ let color: UIColor
+ let visible: Bool
+ }
+
+ var title: String
+ var showArrow: Bool
+ var showPrefixes: Bool
+ var values: [Value]
+ var totalValue: Value?
+ var tapAction: (() -> Void)?
+
+ static let blank = ChartDetailsViewModel(title: "", showArrow: false, showPrefixes: false, values: [], totalValue: nil, tapAction: nil)
+}
+
+class ChartDetailsView: UIControl {
+ let titleLabel = UILabel()
+ let arrowView = UIImageView()
+
+ var prefixViews: [UILabel] = []
+ var labelsViews: [UILabel] = []
+ var valuesViews: [UILabel] = []
+
+ private var viewModel: ChartDetailsViewModel?
+ private var colorMode: ColorMode = .day
+
+ static func fromNib() -> ChartDetailsView {
+ return Bundle.main.loadNibNamed("ChartDetailsView", owner: nil, options: nil)?.first as! ChartDetailsView
+ }
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ layer.cornerRadius = cornerRadius
+ clipsToBounds = true
+
+ addTarget(self, action: #selector(didTap), for: .touchUpInside)
+ titleLabel.font = UIFont.systemFont(ofSize: 12, weight: .bold)
+ arrowView.image = UIImage.arrowRight
+ arrowView.contentMode = .scaleAspectFill
+
+ addSubview(titleLabel)
+ addSubview(arrowView)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ func setup(viewModel: ChartDetailsViewModel, animated: Bool) {
+ self.viewModel = viewModel
+
+ titleLabel.setText(viewModel.title, animated: animated)
+ titleLabel.setVisible(!viewModel.title.isEmpty, animated: animated)
+ arrowView.setVisible(viewModel.showArrow, animated: animated)
+
+ let width: CGFloat = margin * 2 + (viewModel.showPrefixes ? (prefixLabelWidth + margin) : 0) + textLabelWidth + valueLabelWidth
+ var y: CGFloat = verticalMargins
+
+ if (!viewModel.title.isEmpty || viewModel.showArrow) {
+ titleLabel.frame = CGRect(x: margin, y: y, width: width, height: labelHeight)
+ arrowView.frame = CGRect(x: width - 6 - margin, y: margin, width: 6, height: 10)
+ y += labelHeight
+ }
+ let labelsCount: Int = viewModel.values.count + ((viewModel.totalValue == nil) ? 0 : 1)
+
+ setLabelsCount(array: &prefixViews,
+ count: viewModel.showPrefixes ? labelsCount : 0,
+ font: UIFont.systemFont(ofSize: 12, weight: .bold))
+ setLabelsCount(array: &labelsViews,
+ count: labelsCount,
+ font: UIFont.systemFont(ofSize: 12, weight: .regular),
+ textAlignment: .left)
+ setLabelsCount(array: &valuesViews,
+ count: labelsCount,
+ font: UIFont.systemFont(ofSize: 12, weight: .bold))
+
+ UIView.perform(animated: animated, animations: {
+ for (index, value) in viewModel.values.enumerated() {
+ var x: CGFloat = margin
+ if viewModel.showPrefixes {
+ let prefixLabel = self.prefixViews[index]
+ prefixLabel.textColor = self.colorMode.chartDetailsTextColor
+ prefixLabel.setText(value.prefix, animated: false)
+ prefixLabel.frame = CGRect(x: x, y: y, width: prefixLabelWidth, height: labelHeight)
+ x += prefixLabelWidth + margin
+ prefixLabel.alpha = value.visible ? 1 : 0
+ }
+ let titleLabel = self.labelsViews[index]
+ titleLabel.setTextColor(self.colorMode.chartDetailsTextColor, animated: false)
+ titleLabel.setText(value.title, animated: false)
+ titleLabel.frame = CGRect(x: x, y: y, width: textLabelWidth, height: labelHeight)
+ titleLabel.alpha = value.visible ? 1 : 0
+ x += textLabelWidth
+
+ let valueLabel = self.valuesViews[index]
+ valueLabel.setTextColor(value.color, animated: false)
+ valueLabel.setText(value.value, animated: false)
+ valueLabel.frame = CGRect(x: x, y: y, width: valueLabelWidth, height: labelHeight)
+ valueLabel.alpha = value.visible ? 1 : 0
+
+ if value.visible {
+ y += labelHeight
+ }
+ }
+ if let value = viewModel.totalValue {
+ var x: CGFloat = margin
+ if viewModel.showPrefixes {
+ let prefixLabel = self.prefixViews[viewModel.values.count]
+ prefixLabel.textColor = self.colorMode.chartDetailsTextColor
+ prefixLabel.setText(value.prefix, animated: false)
+ prefixLabel.frame = CGRect(x: x, y: y, width: prefixLabelWidth, height: labelHeight)
+ prefixLabel.alpha = value.visible ? 1 : 0
+ x += prefixLabelWidth + margin
+ }
+ let titleLabel = self.labelsViews[viewModel.values.count]
+ titleLabel.setTextColor(self.colorMode.chartDetailsTextColor, animated: false)
+ titleLabel.setText(value.title, animated: false)
+ titleLabel.frame = CGRect(x: x, y: y, width: textLabelWidth, height: labelHeight)
+ titleLabel.alpha = value.visible ? 1 : 0
+ x += textLabelWidth
+
+ let valueLabel = self.valuesViews[viewModel.values.count]
+ valueLabel.setTextColor(self.colorMode.chartDetailsTextColor, animated: false)
+ valueLabel.setText(value.value, animated: false)
+ valueLabel.frame = CGRect(x: x, y: y, width: valueLabelWidth, height: labelHeight)
+ valueLabel.alpha = value.visible ? 1 : 0
+ }
+ })
+ }
+
+ override var intrinsicContentSize: CGSize {
+ if let viewModel = viewModel {
+ let height = ((!viewModel.title.isEmpty || viewModel.showArrow) ? labelHeight : 0) +
+ (CGFloat(viewModel.values.filter({ $0.visible }).count) * labelHeight) +
+ (viewModel.totalValue?.visible == true ? labelHeight : 0) +
+ verticalMargins * 2
+ let width: CGFloat = margin * 2 +
+ (viewModel.showPrefixes ? (prefixLabelWidth + margin) : 0) +
+ textLabelWidth +
+ valueLabelWidth
+
+ return CGSize(width: width,
+ height: height)
+ } else {
+ return CGSize(width: 140,
+ height: labelHeight + verticalMargins)
+ }
+ }
+
+ @objc private func didTap() {
+ viewModel?.tapAction?()
+ }
+
+ func setLabelsCount(array: inout [UILabel],
+ count: Int,
+ font: UIFont,
+ textAlignment: NSTextAlignment = .right) {
+ while array.count > count {
+ let subview = array.removeLast()
+ subview.removeFromSuperview()
+ }
+ while array.count < count {
+ let label = UILabel()
+ label.font = font
+ label.adjustsFontSizeToFitWidth = true
+ label.minimumScaleFactor = 0.5
+ label.textAlignment = textAlignment
+ addSubview(label)
+ array.append(label)
+ }
+ }
+}
+
+extension ChartDetailsView: ColorModeContainer {
+ func apply(colorMode: ColorMode, animated: Bool) {
+ self.colorMode = colorMode
+ self.titleLabel.setTextColor(colorMode.chartDetailsTextColor, animated: animated)
+ if let viewModel = self.viewModel {
+ self.setup(viewModel: viewModel, animated: animated)
+ }
+ UIView.perform(animated: animated) {
+ self.arrowView.tintColor = colorMode.chartDetailsArrowColor
+ self.backgroundColor = colorMode.chartDetailsViewColor
+ }
+ }
+}
+
+// MARK: UIStackView+removeAllArrangedSubviews
+public extension UIStackView {
+ func setLabelsCount(_ count: Int,
+ font: UIFont,
+ huggingPriority: UILayoutPriority,
+ textAlignment: NSTextAlignment = .right) {
+ while arrangedSubviews.count > count {
+ let subview = arrangedSubviews.last!
+ removeArrangedSubview(subview)
+ subview.removeFromSuperview()
+ }
+ while arrangedSubviews.count < count {
+ let label = UILabel()
+ label.font = font
+ label.textAlignment = textAlignment
+ label.setContentHuggingPriority(huggingPriority, for: .horizontal)
+ label.setContentHuggingPriority(huggingPriority, for: .vertical)
+ label.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 999), for: .horizontal)
+ label.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 999), for: .vertical)
+ addArrangedSubview(label)
+ }
+ }
+
+ func label(at index: Int) -> UILabel {
+ return arrangedSubviews[index] as! UILabel
+ }
+
+ func removeAllArrangedSubviews() {
+ for subview in arrangedSubviews {
+ removeArrangedSubview(subview)
+ subview.removeFromSuperview()
+ }
+ }
+}
+
+// MARK: UIStackView+addArrangedSubviews
+public extension UIStackView {
+ func addArrangedSubviews(_ views: [UIView]) {
+ views.forEach({ addArrangedSubview($0) })
+ }
+}
+
+// MARK: UIStackView+insertArrangedSubviews
+public extension UIStackView {
+ func insertArrangedSubviews(_ views: [UIView], at index: Int) {
+ views.reversed().forEach({ insertArrangedSubview($0, at: index) })
+ }
+}
diff --git a/submodules/Charts/Sources/Chart Screen/ChartStackSection.swift b/submodules/Charts/Sources/Chart Screen/ChartStackSection.swift
new file mode 100644
index 0000000000..bef1a574f4
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartStackSection.swift
@@ -0,0 +1,199 @@
+//
+// ChartStackSection.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private enum Constants {
+ static let chartViewHeightFraction: CGFloat = 0.55
+}
+
+class ChartStackSection: UIView, ColorModeContainer {
+ var chartView: ChartView
+ var rangeView: RangeChartView
+ var visibilityView: ChartVisibilityView
+ var sectionContainerView: UIView
+ var separators: [UIView] = []
+
+ var headerLabel: UILabel!
+ var titleLabel: UILabel!
+ var backButton: UIButton!
+
+ var controller: BaseChartController!
+
+ init() {
+ sectionContainerView = UIView()
+ chartView = ChartView()
+ rangeView = RangeChartView()
+ visibilityView = ChartVisibilityView()
+ headerLabel = UILabel()
+ titleLabel = UILabel()
+ backButton = UIButton()
+
+ super.init(frame: CGRect())
+
+ self.addSubview(sectionContainerView)
+ sectionContainerView.addSubview(chartView)
+ sectionContainerView.addSubview(rangeView)
+ sectionContainerView.addSubview(visibilityView)
+
+ headerLabel.font = UIFont.systemFont(ofSize: 14, weight: .regular)
+ titleLabel.font = UIFont.systemFont(ofSize: 14, weight: .bold)
+ visibilityView.clipsToBounds = true
+ backButton.isExclusiveTouch = true
+
+ backButton.setVisible(false, animated: false)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+
+ headerLabel.font = UIFont.systemFont(ofSize: 14, weight: .regular)
+ titleLabel.font = UIFont.systemFont(ofSize: 14, weight: .bold)
+ visibilityView.clipsToBounds = true
+ backButton.isExclusiveTouch = true
+
+ backButton.setVisible(false, animated: false)
+ }
+
+ func apply(colorMode: ColorMode, animated: Bool) {
+ UIView.perform(animated: animated && self.isVisibleInWindow) {
+ self.backgroundColor = colorMode.tableBackgroundColor
+
+ self.sectionContainerView.backgroundColor = colorMode.chartBackgroundColor
+ self.rangeView.backgroundColor = colorMode.chartBackgroundColor
+ self.visibilityView.backgroundColor = colorMode.chartBackgroundColor
+
+ self.backButton.tintColor = colorMode.actionButtonColor
+ self.backButton.setTitleColor(colorMode.actionButtonColor, for: .normal)
+
+ for separator in self.separators {
+ separator.backgroundColor = colorMode.tableSeparatorColor
+ }
+ }
+
+ if rangeView.isVisibleInWindow || chartView.isVisibleInWindow {
+ chartView.loadDetailsViewIfNeeded()
+ chartView.apply(colorMode: colorMode, animated: animated && chartView.isVisibleInWindow)
+ controller.apply(colorMode: colorMode, animated: animated)
+ rangeView.apply(colorMode: colorMode, animated: animated && rangeView.isVisibleInWindow)
+ } else {
+ DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval.random(in: 0...0.1)) {
+ self.chartView.loadDetailsViewIfNeeded()
+ self.controller.apply(colorMode: colorMode, animated: false)
+ self.chartView.apply(colorMode: colorMode, animated: false)
+ self.rangeView.apply(colorMode: colorMode, animated: false)
+ }
+ }
+
+ self.titleLabel.setTextColor(colorMode.chartTitleColor, animated: animated && titleLabel.isVisibleInWindow)
+ self.headerLabel.setTextColor(colorMode.sectionTitleColor, animated: animated && headerLabel.isVisibleInWindow)
+ }
+
+ @IBAction func didTapBackButton() {
+ controller.didTapZoomOut()
+ }
+
+ func setBackButtonVisible(_ visible: Bool, animated: Bool) {
+ backButton.setVisible(visible, animated: animated)
+ layoutIfNeeded(animated: animated)
+ }
+
+ func updateToolViews(animated: Bool) {
+ rangeView.setRange(controller.currentChartHorizontalRangeFraction, animated: animated)
+ rangeView.setRangePaging(enabled: controller.isChartRangePagingEnabled,
+ minimumSize: controller.minimumSelectedChartRange)
+ visibilityView.setVisible(controller.drawChartVisibity, animated: animated)
+ if controller.drawChartVisibity {
+ visibilityView.isExpanded = true
+ visibilityView.items = controller.actualChartsCollection.chartValues.map { value in
+ return ChartVisibilityItem(title: value.name, color: value.color)
+ }
+ visibilityView.setItemsSelection(controller.actualChartVisibility)
+ visibilityView.setNeedsLayout()
+ visibilityView.layoutIfNeeded()
+ } else {
+ visibilityView.isExpanded = false
+ }
+ superview?.superview?.layoutIfNeeded(animated: animated)
+ }
+
+ override func layoutSubviews() {
+ super.layoutSubviews()
+
+ let bounds = self.bounds
+ self.sectionContainerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: 350.0))
+ self.chartView.frame = CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: 250.0))
+ self.rangeView.frame = CGRect(origin: CGPoint(x: 0.0, y: 250.0), size: CGSize(width: bounds.width, height: 48.0))
+ self.visibilityView.frame = CGRect(origin: CGPoint(x: 0.0, y: 308.0), size: CGSize(width: bounds.width, height: 122.0))
+ }
+
+ func setup(controller: BaseChartController, title: String) {
+ self.controller = controller
+ self.headerLabel.text = title
+
+ // Chart
+ chartView.renderers = controller.mainChartRenderers
+ chartView.userDidSelectCoordinateClosure = { [unowned self] point in
+ self.controller.chartInteractionDidBegin(point: point)
+ }
+ chartView.userDidDeselectCoordinateClosure = { [unowned self] in
+ self.controller.chartInteractionDidEnd()
+ }
+ controller.cartViewBounds = { [unowned self] in
+ return self.chartView.bounds
+ }
+ controller.chartFrame = { [unowned self] in
+ return self.chartView.chartFrame
+ }
+ controller.setDetailsViewModel = { [unowned self] viewModel, animated in
+ self.chartView.setDetailsViewModel(viewModel: viewModel, animated: animated)
+ }
+ controller.setDetailsChartVisibleClosure = { [unowned self] visible, animated in
+ self.chartView.setDetailsChartVisible(visible, animated: animated)
+ }
+ controller.setDetailsViewPositionClosure = { [unowned self] position in
+ self.chartView.detailsViewPosition = position
+ }
+ controller.setChartTitleClosure = { [unowned self] title, animated in
+ self.titleLabel.setText(title, animated: animated)
+ }
+ controller.setBackButtonVisibilityClosure = { [unowned self] visible, animated in
+ self.setBackButtonVisible(visible, animated: animated)
+ }
+ controller.refreshChartToolsClosure = { [unowned self] animated in
+ self.updateToolViews(animated: animated)
+ }
+
+ // Range view
+ rangeView.chartView.renderers = controller.navigationRenderers
+ rangeView.rangeDidChangeClosure = { range in
+ controller.updateChartRange(range)
+ }
+ rangeView.touchedOutsideClosure = {
+ controller.cancelChartInteraction()
+ }
+ controller.chartRangeUpdatedClosure = { [unowned self] (range, animated) in
+ self.rangeView.setRange(range, animated: animated)
+ }
+ controller.chartRangePagingClosure = { [unowned self] (isEnabled, pageSize) in
+ self.rangeView.setRangePaging(enabled: isEnabled, minimumSize: pageSize)
+ }
+
+ // Visibility view
+ visibilityView.selectionCallbackClosure = { [unowned self] visibility in
+ self.controller.updateChartsVisibility(visibility: visibility, animated: true)
+ }
+
+ controller.initializeChart()
+ updateToolViews(animated: false)
+ }
+}
diff --git a/submodules/Charts/Sources/Chart Screen/ChartStackSection.xib b/submodules/Charts/Sources/Chart Screen/ChartStackSection.xib
new file mode 100644
index 0000000000..fc883dd96c
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartStackSection.xib
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/submodules/Charts/Sources/Chart Screen/ChartView.swift b/submodules/Charts/Sources/Chart Screen/ChartView.swift
new file mode 100644
index 0000000000..39b93d9fa0
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartView.swift
@@ -0,0 +1,158 @@
+//
+// ChartView.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+public protocol ChartViewRenderer: class {
+ var containerViews: [UIView] { get set }
+ func render(context: CGContext, bounds: CGRect, chartFrame: CGRect)
+}
+
+class ChartView: UIView {
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ setupView()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+
+ setupView()
+ }
+
+ var chartInsets: UIEdgeInsets = UIEdgeInsets(top: 40, left: 16, bottom: 35, right: 16) {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+
+ var renderers: [ChartViewRenderer] = [] {
+ willSet {
+ renderers.forEach { $0.containerViews.removeAll(where: { $0 == self }) }
+ }
+ didSet {
+ renderers.forEach { $0.containerViews.append(self) }
+ setNeedsDisplay()
+ }
+ }
+
+ var chartFrame: CGRect {
+ let chartBound = self.bounds
+ return CGRect(x: chartInsets.left,
+ y: chartInsets.top,
+ width: max(1, chartBound.width - chartInsets.left - chartInsets.right),
+ height: max(1, chartBound.height - chartInsets.top - chartInsets.bottom))
+ }
+
+ override func draw(_ rect: CGRect) {
+ guard let context = UIGraphicsGetCurrentContext() else { return }
+ let chartBounds = self.bounds
+ let chartFrame = self.chartFrame
+
+ for renderer in renderers {
+ renderer.render(context: context, bounds: chartBounds, chartFrame: chartFrame)
+ }
+ }
+
+ var userDidSelectCoordinateClosure: ((CGPoint) -> Void)?
+ var userDidDeselectCoordinateClosure: (() -> Void)?
+
+ override func touchesBegan(_ touches: Set, with event: UIEvent?) {
+ if let point = touches.first?.location(in: self) {
+ let fractionPoint = CGPoint(x: (point.x - chartFrame.origin.x) / chartFrame.width,
+ y: (point.y - chartFrame.origin.y) / chartFrame.height)
+ userDidSelectCoordinateClosure?(fractionPoint)
+ }
+ }
+
+ override func touchesMoved(_ touches: Set, with event: UIEvent?) {
+ if let point = touches.first?.location(in: self) {
+ let fractionPoint = CGPoint(x: (point.x - chartFrame.origin.x) / chartFrame.width,
+ y: (point.y - chartFrame.origin.y) / chartFrame.height)
+ userDidSelectCoordinateClosure?(fractionPoint)
+ }
+ }
+
+ override func touchesEnded(_ touches: Set, with event: UIEvent?) {
+ userDidDeselectCoordinateClosure?()
+ }
+
+ override func touchesCancelled(_ touches: Set, with event: UIEvent?) {
+ userDidDeselectCoordinateClosure?()
+ }
+
+ // MARK: Details View
+
+ private var detailsView: ChartDetailsView!
+ private var maxDetailsViewWidth: CGFloat = 0
+ func loadDetailsViewIfNeeded() {
+ if detailsView == nil {
+ let detailsView = ChartDetailsView(frame: bounds)
+ addSubview(detailsView)
+ detailsView.alpha = 0
+ self.detailsView = detailsView
+ }
+ }
+
+ private var detailsTableTopOffset: CGFloat = 5
+ private var detailsTableLeftOffset: CGFloat = 8
+ private var isDetailsViewVisible: Bool = false
+
+ var detailsViewPosition: CGFloat = 0 {
+ didSet {
+ loadDetailsViewIfNeeded()
+ let detailsViewSize = detailsView.intrinsicContentSize
+ maxDetailsViewWidth = max(maxDetailsViewWidth, detailsViewSize.width)
+ if maxDetailsViewWidth + detailsTableLeftOffset > detailsViewPosition {
+ detailsView.frame = CGRect(x: min(detailsViewPosition + detailsTableLeftOffset, bounds.width - maxDetailsViewWidth),
+ y: chartInsets.top + detailsTableTopOffset,
+ width: maxDetailsViewWidth,
+ height: detailsViewSize.height)
+ } else {
+ detailsView.frame = CGRect(x: detailsViewPosition - maxDetailsViewWidth - detailsTableLeftOffset,
+ y: chartInsets.top + detailsTableTopOffset,
+ width: maxDetailsViewWidth,
+ height: detailsViewSize.height)
+ }
+ }
+ }
+
+ func setDetailsChartVisible(_ visible: Bool, animated: Bool) {
+ guard isDetailsViewVisible != visible else {
+ return
+ }
+ isDetailsViewVisible = visible
+ loadDetailsViewIfNeeded()
+ detailsView.setVisible(visible, animated: animated)
+ if !visible {
+ maxDetailsViewWidth = 0
+ }
+ }
+
+ func setDetailsViewModel(viewModel: ChartDetailsViewModel, animated: Bool) {
+ loadDetailsViewIfNeeded()
+ detailsView.setup(viewModel: viewModel, animated: animated)
+ UIView.perform(animated: animated, animations: {
+ let position = self.detailsViewPosition
+ self.detailsViewPosition = position
+ })
+ }
+
+ func setupView() {
+ backgroundColor = .clear
+ layer.drawsAsynchronously = true
+ }
+}
+
+
+extension ChartView: ColorModeContainer {
+ func apply(colorMode: ColorMode, animated: Bool) {
+ detailsView?.apply(colorMode: colorMode, animated: animated && (detailsView?.isVisibleInWindow ?? false))
+ }
+}
diff --git a/submodules/Charts/Sources/Chart Screen/ChartVisibilityItemView.swift b/submodules/Charts/Sources/Chart Screen/ChartVisibilityItemView.swift
new file mode 100644
index 0000000000..2476526f1a
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartVisibilityItemView.swift
@@ -0,0 +1,95 @@
+//
+// ChartVisibilityItemCell.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class ChartVisibilityItemView: UIView {
+ static let textFont = UIFont.systemFont(ofSize: 14, weight: .medium)
+
+ let checkButton: UIButton = UIButton(type: .system)
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ setupView()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ }
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ setupView()
+ }
+
+ func setupView() {
+ checkButton.frame = bounds
+ checkButton.titleLabel?.font = ChartVisibilityItemView.textFont
+ checkButton.layer.cornerRadius = 6
+ checkButton.layer.masksToBounds = true
+ checkButton.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
+ let pressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(didRecognizedLongPress(recognizer:)))
+ pressRecognizer.cancelsTouchesInView = true
+ checkButton.addGestureRecognizer(pressRecognizer)
+ addSubview(checkButton)
+ }
+
+ var tapClosure: (() -> Void)?
+ var longTapClosure: (() -> Void)?
+
+ private func updateStyle(animated: Bool) {
+ guard let item = item else {
+ return
+ }
+ UIView.perform(animated: animated, animations: {
+ if self.isChecked {
+ self.checkButton.setTitleColor(.white, for: .normal)
+ self.checkButton.backgroundColor = item.color
+ self.checkButton.layer.borderColor = nil
+ self.checkButton.layer.borderWidth = 0
+ self.checkButton.setTitle("✓ " + item.title, for: .normal)
+ } else {
+ self.checkButton.backgroundColor = .clear
+ self.checkButton.layer.borderColor = item.color.cgColor
+ self.checkButton.layer.borderWidth = 1
+ self.checkButton.setTitleColor(item.color, for: .normal)
+ self.checkButton.setTitle(item.title, for: .normal)
+ }
+
+ })
+ }
+
+ override func layoutSubviews() {
+ super.layoutSubviews()
+
+ checkButton.frame = bounds
+ }
+
+ @objc private func didTapButton() {
+ tapClosure?()
+ }
+
+ @objc private func didRecognizedLongPress(recognizer: UIGestureRecognizer) {
+ if recognizer.state == .began {
+ longTapClosure?()
+ }
+ }
+
+ var item: ChartVisibilityItem? = nil {
+ didSet {
+ updateStyle(animated: false)
+ }
+ }
+
+ private(set) var isChecked: Bool = true
+ func setChecked(isChecked: Bool, animated: Bool) {
+ self.isChecked = isChecked
+ updateStyle(animated: true)
+ }
+}
diff --git a/submodules/Charts/Sources/Chart Screen/ChartVisibilityView.swift b/submodules/Charts/Sources/Chart Screen/ChartVisibilityView.swift
new file mode 100644
index 0000000000..fda3c3901f
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartVisibilityView.swift
@@ -0,0 +1,147 @@
+//
+// ChartVisibilityView.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private enum Constants {
+ static let itemHeight: CGFloat = 30
+ static let itemSpacing: CGFloat = 8
+ static let labelTextApproxInsets: CGFloat = 40
+ static let insets = UIEdgeInsets(top: 0, left: 16, bottom: 16, right: 16)
+}
+
+struct ChartVisibilityItem {
+ var title: String
+ var color: UIColor
+}
+
+class ChartVisibilityView: UIView {
+ var items: [ChartVisibilityItem] = [] {
+ didSet {
+ selectedItems = items.map { _ in true }
+ while selectionViews.count > selectedItems.count {
+ selectionViews.last?.removeFromSuperview()
+ selectionViews.removeLast()
+ }
+ while selectionViews.count < selectedItems.count {
+ let view = ChartVisibilityItemView(frame: bounds)
+ addSubview(view)
+ selectionViews.append(view)
+ }
+
+ for (index, item) in items.enumerated() {
+ let view = selectionViews[index]
+ view.item = item
+ view.tapClosure = { [weak self] in
+ guard let self = self else { return }
+ self.setItemSelected(!self.selectedItems[index], at: index, animated: true)
+ self.notifyItemSelection()
+ }
+
+ view.longTapClosure = { [weak self] in
+ guard let self = self else { return }
+ let hasSelectedItem = self.selectedItems.enumerated().contains(where: { $0.element && $0.offset != index })
+ if hasSelectedItem {
+ for (itemIndex, _) in self.items.enumerated() {
+ self.setItemSelected(itemIndex == index, at: itemIndex, animated: true)
+ }
+ } else {
+ for (itemIndex, _) in self.items.enumerated() {
+ self.setItemSelected(true, at: itemIndex, animated: true)
+ }
+ }
+ self.notifyItemSelection()
+ }
+ }
+ }
+ }
+
+ private (set) var selectedItems: [Bool] = []
+ var isExpanded: Bool = true {
+ didSet {
+ invalidateIntrinsicContentSize()
+ setNeedsUpdateConstraints()
+ }
+ }
+
+ private var selectionViews: [ChartVisibilityItemView] = []
+
+ private func generateItemsFrames(frame: CGRect) -> [CGRect] {
+ var previousPoint = CGPoint(x: Constants.insets.left, y: Constants.insets.top)
+ var frames: [CGRect] = []
+
+ for item in items {
+ let labelSize = (item.title as NSString).size(withAttributes: [.font: ChartVisibilityItemView.textFont])
+ let width = (labelSize.width + Constants.labelTextApproxInsets).rounded(.up)
+ if previousPoint.x + width < (frame.width - Constants.insets.left - Constants.insets.right) {
+ frames.append(CGRect(origin: previousPoint, size: CGSize(width: width, height: Constants.itemHeight)))
+ } else if previousPoint.x <= Constants.insets.left {
+ frames.append(CGRect(origin: previousPoint, size: CGSize(width: width, height: Constants.itemHeight)))
+ } else {
+ previousPoint.y += Constants.itemHeight + Constants.itemSpacing
+ previousPoint.x = Constants.insets.left
+ frames.append(CGRect(origin: previousPoint, size: CGSize(width: width, height: Constants.itemHeight)))
+ }
+ previousPoint.x += width + Constants.itemSpacing
+ }
+
+ return frames
+ }
+
+ var selectionCallbackClosure: (([Bool]) -> Void)?
+
+ func setItemSelected(_ selected: Bool, at index: Int, animated: Bool) {
+ self.selectedItems[index] = selected
+ self.selectionViews[index].setChecked(isChecked: selected, animated: animated)
+ }
+
+ func setItemsSelection(_ selection: [Bool]) {
+ assert(selection.count == items.count)
+ self.selectedItems = selection
+ for (index, selected) in self.selectedItems.enumerated() {
+ selectionViews[index].setChecked(isChecked: selected, animated: false)
+ }
+ }
+
+ private func notifyItemSelection() {
+ selectionCallbackClosure?(selectedItems)
+ }
+
+ override func layoutSubviews() {
+ super.layoutSubviews()
+
+ updateFrames()
+ }
+
+ private func updateFrames() {
+ for (index, frame) in generateItemsFrames(frame: bounds).enumerated() {
+ selectionViews[index].frame = frame
+ }
+ }
+
+ override var intrinsicContentSize: CGSize {
+ guard isExpanded else {
+ var size = self.bounds.size
+ size.height = 0
+ return size
+ }
+ let frames = generateItemsFrames(frame: UIScreen.main.bounds)
+ guard let lastFrame = frames.last else { return .zero }
+ let size = CGSize(width: frame.width, height: lastFrame.maxY + Constants.insets.bottom)
+ return size
+ }
+}
+
+extension ChartVisibilityView: ColorModeContainer {
+ func apply(colorMode: ColorMode, animated: Bool) {
+ UIView.perform(animated: animated) {
+ self.backgroundColor = colorMode.chartBackgroundColor
+ self.tintColor = colorMode.descriptionActionColor
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Chart Screen/ChartsDataLoader.swift b/submodules/Charts/Sources/Chart Screen/ChartsDataLoader.swift
new file mode 100644
index 0000000000..085e4689bd
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartsDataLoader.swift
@@ -0,0 +1,51 @@
+//
+// ChartsDataLoader.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/8/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import Foundation
+
+enum ChartsDataType: String {
+ case generalLines = "1"
+ case twoAxisLines = "2"
+ case stackedBars = "3"
+ case dailyBars = "4"
+ case percentPie = "5"
+}
+
+private enum Constants {
+ static let overviewFilename = "overview.json"
+ static let dataDir = "data"
+}
+
+class ChartsDataLoader {
+ static var documentDirectoryURL: URL {
+ let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
+ let documentsDirectory = paths[0]
+ return documentsDirectory
+ }
+
+ static func overviewData(type: ChartsDataType, extraCopiesCount: Int = 0, sync: Bool = false, success: @escaping (ChartsCollection) -> Void) {
+ let path = Bundle.main.bundleURL
+ .appendingPathComponent(Constants.dataDir)
+ .appendingPathComponent(type.rawValue)
+ .appendingPathComponent(Constants.overviewFilename)
+ ChartsDataManager().readChart(file: path, extraCopiesCount: extraCopiesCount, sync: sync, success: success, failure: { _ in })
+ }
+
+ static func detaildData(type: ChartsDataType, extraCopiesCount: Int = 0, date: Date, success: @escaping (ChartsCollection) -> Void, failure: @escaping (Error) -> Void) {
+ let dateComponents = Calendar.utc.dateComponents([.day, .month, .year], from: date)
+ let yearMonth = String(format: "%04d-%02d", dateComponents.year ?? 0, dateComponents.month ?? 0)
+ let day = String(format: "%02d.json", dateComponents.day ?? 0)
+
+ let path = Bundle.main.bundleURL
+ .appendingPathComponent(Constants.dataDir)
+ .appendingPathComponent(type.rawValue)
+ .appendingPathComponent(yearMonth)
+ .appendingPathComponent(day)
+ ChartsDataManager().readChart(file: path, extraCopiesCount: extraCopiesCount, sync: false, success: success, failure: failure)
+ }
+}
diff --git a/submodules/Charts/Sources/Chart Screen/ChartsStackViewController.swift b/submodules/Charts/Sources/Chart Screen/ChartsStackViewController.swift
new file mode 100644
index 0000000000..e8c22e6453
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/ChartsStackViewController.swift
@@ -0,0 +1,222 @@
+//
+// ChartsStackViewController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class ChartsStackViewController: UIViewController {
+ @IBOutlet private var stackView: UIStackView!
+ @IBOutlet private var scrollView: UIScrollView!
+ @IBOutlet private var psLabel: UILabel!
+ @IBOutlet private var ppsLabel: UILabel!
+ @IBOutlet private var animationButton: ChartVisibilityItemView!
+
+ private var sections: [ChartStackSection] = []
+
+ private var colorMode: ColorMode = .night
+ private var colorModeButton: UIBarButtonItem!
+ private var performFastAnimation: Bool = false
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ title = "Statistics"
+ colorModeButton = UIBarButtonItem(title: colorMode.switchTitle, style: .plain, target: self, action: #selector(didTapSwitchColorMode))
+ navigationItem.rightBarButtonItem = colorModeButton
+
+ apply(colorMode: colorMode, animated: false)
+
+ self.navigationController?.navigationBar.barStyle = .black
+ self.navigationController?.navigationBar.isTranslucent = false
+
+ self.view.isUserInteractionEnabled = false
+ animationButton.backgroundColor = .clear
+ animationButton.tapClosure = { [weak self] in
+ guard let self = self else { return }
+ self.setSlowAnimationEnabled(!self.animationButton.isChecked)
+ }
+ self.setSlowAnimationEnabled(false)
+
+ loadChart1()
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+
+ DispatchQueue.main.async {
+ self.view.setNeedsUpdateConstraints()
+ self.view.setNeedsLayout()
+ }
+ }
+
+ func loadChart1() {
+ ChartsDataLoader.overviewData(type: .generalLines, sync: true, success: { collection in
+ let generalLinesChartController = GeneralLinesChartController(chartsCollection: collection)
+ self.addSection(controller: generalLinesChartController, title: "FOLLOWERS")
+ generalLinesChartController.getDetailsData = { date, completion in
+ ChartsDataLoader.detaildData(type: .generalLines, date: date, success: { collection in
+ completion(collection)
+ }, failure: { error in
+ completion(nil)
+ })
+ }
+ DispatchQueue.main.async {
+ self.loadChart2()
+ }
+ })
+ }
+
+ func loadChart2() {
+ ChartsDataLoader.overviewData(type: .twoAxisLines, success: { collection in
+ let twoAxisLinesChartController = TwoAxisLinesChartController(chartsCollection: collection)
+ self.addSection(controller: twoAxisLinesChartController, title: "INTERACTIONS")
+ twoAxisLinesChartController.getDetailsData = { date, completion in
+ ChartsDataLoader.detaildData(type: .twoAxisLines, date: date, success: { collection in
+ completion(collection)
+ }, failure: { error in
+ completion(nil)
+ })
+ }
+ DispatchQueue.main.async {
+ self.loadChart3()
+ }
+ })
+ }
+
+ func loadChart3() {
+ ChartsDataLoader.overviewData(type: .stackedBars, success: { collection in
+ let stackedBarsChartController = StackedBarsChartController(chartsCollection: collection)
+ self.addSection(controller: stackedBarsChartController, title: "FRUITS")
+ stackedBarsChartController.getDetailsData = { date, completion in
+ ChartsDataLoader.detaildData(type: .stackedBars, date: date, success: { collection in
+ completion(collection)
+ }, failure: { error in
+ completion(nil)
+ })
+ }
+ DispatchQueue.main.async {
+ self.loadChart4()
+ }
+ })
+ }
+
+ func loadChart4() {
+ ChartsDataLoader.overviewData(type: .dailyBars, success: { collection in
+ let dailyBarsChartController = DailyBarsChartController(chartsCollection: collection)
+ self.addSection(controller: dailyBarsChartController, title: "VIEWS")
+ dailyBarsChartController.getDetailsData = { date, completion in
+ ChartsDataLoader.detaildData(type: .dailyBars, date: date, success: { collection in
+ completion(collection)
+ }, failure: { error in
+ completion(nil)
+ })
+ }
+ DispatchQueue.main.async {
+ self.loadChart5()
+ }
+ })
+ }
+
+ func loadChart5() {
+ ChartsDataLoader.overviewData(type: .percentPie, success: { collection in
+ let percentPieChartController = PercentPieChartController(chartsCollection: collection)
+ self.addSection(controller: percentPieChartController, title: "MORE FRUITS")
+ self.finalizeChartsLoading()
+ })
+ }
+
+ func setSlowAnimationEnabled(_ isEnabled: Bool) {
+ animationButton.setChecked(isChecked: isEnabled, animated: true)
+ if isEnabled {
+ TimeInterval.animationDurationMultipler = 5
+ } else {
+ TimeInterval.animationDurationMultipler = 1
+ }
+ }
+
+ func finalizeChartsLoading() {
+ self.view.isUserInteractionEnabled = true
+ }
+
+ func addSection(controller: BaseChartController, title: String) {
+ let section = Bundle.main.loadNibNamed("ChartStackSection", owner: nil, options: nil)?.first as! ChartStackSection
+ section.frame = UIScreen.main.bounds
+ section.layoutIfNeeded()
+ section.setup(controller: controller, title: title)
+ section.apply(colorMode: colorMode, animated: false)
+ stackView.addArrangedSubview(section)
+ sections.append(section)
+ }
+
+ override var preferredStatusBarStyle: UIStatusBarStyle {
+ return (colorMode == .day) ? .default : .lightContent
+ }
+
+ override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
+ return .fade
+ }
+
+ @objc private func didTapSwitchColorMode() {
+ self.colorMode = self.colorMode == .day ? .night : .day
+ apply(colorMode: self.colorMode, animated: !performFastAnimation)
+ colorModeButton.title = colorMode.switchTitle
+ }
+}
+
+extension ChartsStackViewController: UIScrollViewDelegate {
+ func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
+ performFastAnimation = decelerate
+ }
+
+ func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
+ performFastAnimation = false
+ }
+}
+
+extension ChartsStackViewController: ColorModeContainer {
+ func apply(colorMode: ColorMode, animated: Bool) {
+
+ UIView.perform(animated: animated) {
+ self.psLabel.setTextColor(colorMode.sectionTitleColor, animated: animated && self.psLabel.isVisibleInWindow)
+ self.ppsLabel.setTextColor(colorMode.sectionTitleColor, animated: animated && self.ppsLabel.isVisibleInWindow)
+ self.animationButton.item = ChartVisibilityItem(title: "Enable slow animations",
+ color: colorMode.sectionTitleColor)
+
+ self.view.backgroundColor = colorMode.tableBackgroundColor
+
+ if (animated) {
+ let animation = CATransition()
+ animation.timingFunction = CAMediaTimingFunction.init(name: .linear)
+ animation.type = .fade
+ animation.duration = .defaultDuration
+ self.navigationController?.navigationBar.layer.add(animation, forKey: "kCATransitionColorFade")
+ }
+
+ self.navigationController?.navigationBar.tintColor = colorMode.actionButtonColor
+ self.navigationController?.navigationBar.barTintColor = colorMode.chartBackgroundColor
+ self.navigationController?.navigationBar.titleTextAttributes = [.font: UIFont.systemFont(ofSize: 17, weight: .medium),
+ .foregroundColor: colorMode.viewTintColor]
+ self.view.layoutIfNeeded()
+ }
+ self.setNeedsStatusBarAppearanceUpdate()
+
+ for section in sections {
+ section.apply(colorMode: colorMode, animated: animated && section.isVisibleInWindow)
+ }
+ }
+}
+
+extension ColorMode {
+ var switchTitle: String {
+ switch self {
+ case .day:
+ return "Night Mode"
+ case .night:
+ return "Day Mode"
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Chart Screen/RangeChartView.swift b/submodules/Charts/Sources/Chart Screen/RangeChartView.swift
new file mode 100644
index 0000000000..91089c1de8
--- /dev/null
+++ b/submodules/Charts/Sources/Chart Screen/RangeChartView.swift
@@ -0,0 +1,291 @@
+//
+// RangeChartView.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+import UIKit
+
+private enum Constants {
+ static let cropIndocatorLineWidth: CGFloat = 1
+ static let markerSelectionRange: CGFloat = 25
+ static let defaultMinimumRangeDistance: CGFloat = 0.05
+ static let titntAreaWidth: CGFloat = 10
+ static let horizontalContentMargin: CGFloat = 16
+ static let cornerRadius: CGFloat = 5
+}
+
+class RangeChartView: UIControl {
+ private enum Marker {
+ case lower
+ case upper
+ case center
+ }
+ public var lowerBound: CGFloat = 0 {
+ didSet {
+ setNeedsLayout()
+ }
+ }
+ public var upperBound: CGFloat = 1 {
+ didSet {
+ setNeedsLayout()
+ }
+ }
+ public var selectionColor: UIColor = .blue
+ public var defaultColor: UIColor = .lightGray
+
+ public var minimumRangeDistance: CGFloat = Constants.defaultMinimumRangeDistance
+
+ private let lowerBoundTintView = UIView()
+ private let upperBoundTintView = UIView()
+ private let cropFrameView = UIImageView()
+
+ private var selectedMarker: Marker?
+ private var selectedMarkerHorizontalOffet: CGFloat = 0
+ private var isBoundCropHighlighted: Bool = false
+ private var isRangePagingEnabled: Bool = false
+
+ public let chartView = ChartView()
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ layoutMargins = UIEdgeInsets(top: Constants.cropIndocatorLineWidth,
+ left: Constants.horizontalContentMargin,
+ bottom: Constants.cropIndocatorLineWidth,
+ right: Constants.horizontalContentMargin)
+
+ self.setup()
+ }
+
+ func setup() {
+ isMultipleTouchEnabled = false
+
+ chartView.chartInsets = .zero
+ chartView.backgroundColor = .clear
+
+ addSubview(chartView)
+ addSubview(lowerBoundTintView)
+ addSubview(upperBoundTintView)
+ addSubview(cropFrameView)
+ cropFrameView.isUserInteractionEnabled = false
+ chartView.isUserInteractionEnabled = false
+ lowerBoundTintView.isUserInteractionEnabled = false
+ upperBoundTintView.isUserInteractionEnabled = false
+
+ chartView.layer.cornerRadius = 5
+ upperBoundTintView.layer.cornerRadius = 5
+ lowerBoundTintView.layer.cornerRadius = 5
+
+ chartView.layer.masksToBounds = true
+ upperBoundTintView.layer.masksToBounds = true
+ lowerBoundTintView.layer.masksToBounds = true
+
+ layoutViews()
+ }
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+
+ self.setup()
+ }
+
+ public var rangeDidChangeClosure: ((ClosedRange) -> Void)?
+ public var touchedOutsideClosure: (() -> Void)?
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ }
+
+ func setRangePaging(enabled: Bool, minimumSize: CGFloat) {
+ isRangePagingEnabled = enabled
+ minimumRangeDistance = minimumSize
+ }
+
+ func setRange(_ range: ClosedRange, animated: Bool) {
+ UIView.perform(animated: animated) {
+ self.lowerBound = range.lowerBound
+ self.upperBound = range.upperBound
+ self.layoutIfNeeded()
+ }
+ }
+
+ override func layoutSubviews() {
+ super.layoutSubviews()
+
+ layoutViews()
+ }
+
+ override var isEnabled: Bool {
+ get {
+ return super.isEnabled
+ }
+ set {
+ if newValue == false {
+ selectedMarker = nil
+ }
+ super.isEnabled = newValue
+ }
+ }
+
+ // MARK: - Touches
+
+ override func touchesBegan(_ touches: Set, with event: UIEvent?) {
+ guard isEnabled else { return }
+ guard let point = touches.first?.location(in: self) else { return }
+
+ if abs(locationInView(for: upperBound) - point.x + Constants.markerSelectionRange / 2) < Constants.markerSelectionRange {
+ selectedMarker = .upper
+ selectedMarkerHorizontalOffet = point.x - locationInView(for: upperBound)
+ isBoundCropHighlighted = true
+ } else if abs(locationInView(for: lowerBound) - point.x - Constants.markerSelectionRange / 2) < Constants.markerSelectionRange {
+ selectedMarker = .lower
+ selectedMarkerHorizontalOffet = point.x - locationInView(for: lowerBound)
+ isBoundCropHighlighted = true
+ } else if point.x > locationInView(for: lowerBound) && point.x < locationInView(for: upperBound) {
+ selectedMarker = .center
+ selectedMarkerHorizontalOffet = point.x - locationInView(for: lowerBound)
+ isBoundCropHighlighted = true
+ } else {
+ selectedMarker = nil
+ return
+ }
+
+ sendActions(for: .touchDown)
+ }
+
+ override func touchesMoved(_ touches: Set, with event: UIEvent?) {
+ guard isEnabled else { return }
+ guard let selectedMarker = selectedMarker else { return }
+ guard let point = touches.first?.location(in: self) else { return }
+
+ let horizontalPosition = point.x - selectedMarkerHorizontalOffet
+ let fraction = fractionFor(offsetX: horizontalPosition)
+ updateMarkerOffset(selectedMarker, fraction: fraction)
+
+ sendActions(for: .valueChanged)
+ }
+
+ override func touchesEnded(_ touches: Set, with event: UIEvent?) {
+ guard isEnabled else { return }
+ guard let selectedMarker = selectedMarker else {
+ touchedOutsideClosure?()
+ return
+ }
+ guard let point = touches.first?.location(in: self) else { return }
+
+ let horizontalPosition = point.x - selectedMarkerHorizontalOffet
+ let fraction = fractionFor(offsetX: horizontalPosition)
+ updateMarkerOffset(selectedMarker, fraction: fraction)
+
+ self.selectedMarker = nil
+ self.isBoundCropHighlighted = false
+ if bounds.contains(point) {
+ sendActions(for: .touchUpInside)
+ } else {
+ sendActions(for: .touchUpOutside)
+ }
+ rangeDidChangeClosure?(lowerBound...upperBound)
+ }
+
+ override func touchesCancelled(_ touches: Set, with event: UIEvent?) {
+ self.selectedMarker = nil
+ self.isBoundCropHighlighted = false
+ sendActions(for: .touchCancel)
+ }
+}
+
+private extension RangeChartView {
+ var contentFrame: CGRect {
+ return CGRect(x: layoutMargins.right,
+ y: layoutMargins.top,
+ width: (bounds.width - layoutMargins.right - layoutMargins.left),
+ height: bounds.height - layoutMargins.top - layoutMargins.bottom)
+ }
+
+ func locationInView(for fraction: CGFloat) -> CGFloat {
+ return contentFrame.minX + contentFrame.width * fraction
+ }
+
+ func locationInView(for fraction: Double) -> CGFloat {
+ return locationInView(for: CGFloat(fraction))
+ }
+
+ func fractionFor(offsetX: CGFloat) -> CGFloat {
+ guard contentFrame.width > 0 else {
+ return 0
+ }
+
+ return crop(0, CGFloat((offsetX - contentFrame.minX ) / contentFrame.width), 1)
+ }
+
+ private func updateMarkerOffset(_ marker: Marker, fraction: CGFloat, notifyDelegate: Bool = true) {
+ let fractionToCount: CGFloat
+ if isRangePagingEnabled {
+ guard let minValue = stride(from: CGFloat(0.0), through: CGFloat(1.0), by: minimumRangeDistance).min(by: { abs($0 - fraction) < abs($1 - fraction) }) else { return }
+ fractionToCount = minValue
+ } else {
+ fractionToCount = fraction
+ }
+
+ switch marker {
+ case .lower:
+ lowerBound = min(fractionToCount, upperBound - minimumRangeDistance)
+ case .upper:
+ upperBound = max(fractionToCount, lowerBound + minimumRangeDistance)
+ case .center:
+ let distance = upperBound - lowerBound
+ lowerBound = max(0, min(fractionToCount, 1 - distance))
+ upperBound = lowerBound + distance
+ }
+ if notifyDelegate {
+ rangeDidChangeClosure?(lowerBound...upperBound)
+ }
+ UIView.animate(withDuration: isRangePagingEnabled ? 0.1 : 0) {
+ self.layoutIfNeeded()
+ }
+ }
+
+ // MARK: - Layout
+
+ func layoutViews() {
+ cropFrameView.frame = CGRect(x: locationInView(for: lowerBound),
+ y: contentFrame.minY - Constants.cropIndocatorLineWidth,
+ width: locationInView(for: upperBound) - locationInView(for: lowerBound),
+ height: contentFrame.height + Constants.cropIndocatorLineWidth * 2)
+
+ if chartView.frame != contentFrame {
+ chartView.frame = contentFrame
+ }
+
+ lowerBoundTintView.frame = CGRect(x: contentFrame.minX,
+ y: contentFrame.minY,
+ width: max(0, locationInView(for: lowerBound) - contentFrame.minX + Constants.titntAreaWidth),
+ height: contentFrame.height)
+
+ upperBoundTintView.frame = CGRect(x: locationInView(for: upperBound) - Constants.titntAreaWidth,
+ y: contentFrame.minY,
+ width: max(0, contentFrame.maxX - locationInView(for: upperBound) + Constants.titntAreaWidth),
+ height: contentFrame.height)
+ }
+}
+
+extension RangeChartView: ColorModeContainer {
+ func apply(colorMode: ColorMode, animated: Bool) {
+ let colusre = {
+ self.lowerBoundTintView.backgroundColor = colorMode.rangeViewTintColor
+ self.upperBoundTintView.backgroundColor = colorMode.rangeViewTintColor
+ }
+
+ self.cropFrameView.setImage(colorMode.rangeCropImage, animated: animated)
+
+ // self.chartView.apply(colorMode: colorMode, animated: animated)
+
+ if animated {
+ UIView.animate(withDuration: .defaultDuration, animations: colusre)
+ } else {
+ colusre()
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/ChartNode.swift b/submodules/Charts/Sources/ChartNode.swift
new file mode 100644
index 0000000000..b6c6da436c
--- /dev/null
+++ b/submodules/Charts/Sources/ChartNode.swift
@@ -0,0 +1,48 @@
+import Foundation
+import UIKit
+import Display
+import AsyncDisplayKit
+import AppBundle
+
+public final class ChartNode: ASDisplayNode {
+ private var chartView: ChartStackSection {
+ return self.view as! ChartStackSection
+ }
+
+ public override init() {
+ super.init()
+
+ self.setViewBlock({
+ return ChartStackSection()
+ })
+ }
+
+ public override func didLoad() {
+ super.didLoad()
+
+ self.view.disablesInteractiveTransitionGestureRecognizer = true
+ }
+
+ public func setup(_ data: String, bar: Bool = false) {
+ if let data = data.data(using: .utf8) {
+ ChartsDataManager().readChart(data: data, extraCopiesCount: 0, sync: true, success: { [weak self] collection in
+ let controller: BaseChartController
+ if bar {
+ controller = DailyBarsChartController(chartsCollection: collection)
+ } else {
+ controller = GeneralLinesChartController(chartsCollection: collection)
+ }
+ if let strongSelf = self {
+ strongSelf.chartView.setup(controller: controller, title: "")
+ strongSelf.chartView.apply(colorMode: .day, animated: false)
+ }
+ }) { error in
+
+ }
+ }
+ }
+
+ required public init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/submodules/Charts/Sources/Charts Reader/ChartsCollection.swift b/submodules/Charts/Sources/Charts Reader/ChartsCollection.swift
new file mode 100644
index 0000000000..f3ecd8215d
--- /dev/null
+++ b/submodules/Charts/Sources/Charts Reader/ChartsCollection.swift
@@ -0,0 +1,91 @@
+//
+// ChardData.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+struct ChartsCollection {
+ struct Chart {
+ var color: UIColor
+ var name: String
+ var values: [Double]
+ }
+
+ var axisValues: [Date]
+ var chartValues: [Chart]
+
+ static let blank = ChartsCollection(axisValues: [], chartValues: [])
+ var isBlank: Bool {
+ return axisValues.isEmpty || chartValues.isEmpty
+ }
+}
+
+extension ChartsCollection {
+ public init(from decodedData: [String: Any]) throws {
+ guard let columns = decodedData["columns"] as? [[Any]] else {
+ throw ChartsError.generalConversion("Unable to get columns from: \(decodedData)")
+ }
+ guard let types = decodedData["types"] as? [String: String] else {
+ throw ChartsError.generalConversion("Unable to get types from: \(decodedData)")
+ }
+ guard let names = decodedData["names"] as? [String: String] else {
+ throw ChartsError.generalConversion("Unable to get names from: \(decodedData)")
+ }
+ guard let colors = decodedData["colors"] as? [String: String] else {
+ throw ChartsError.generalConversion("Unable to get colors from: \(decodedData)")
+ }
+
+// chart.colors – Color for each variable in 6-hex-digit format (e.g. "#AAAAAA").
+// chart.names – Name for each variable.
+// chart.percentage – true for percentage based values.
+// chart.stacked – true for values stacking on top of each other.
+// chart.y_scaled – true for charts with 2 Y axes.
+
+ var axixValuesToSetup: [Date] = []
+ var chartToSetup: [Chart] = []
+ for column in columns {
+ guard let columnId = column.first as? String else {
+ throw ChartsError.generalConversion("Unable to get column name from: \(column)")
+ }
+ guard let typeString = types[columnId], let type = ColumnType(rawValue: typeString) else {
+ throw ChartsError.generalConversion("Unable to get column type from: \(types) - \(columnId)")
+ }
+ switch type {
+ case .axix:
+ axixValuesToSetup = try column.dropFirst().map { Date(timeIntervalSince1970: try Convert.doubleFrom($0) / 1000) }
+ case .chart, .bar, .area:
+ guard let colorString = colors[columnId],
+ let color = UIColor(hexString: colorString) else {
+ throw ChartsError.generalConversion("Unable to get color name from: \(colors) - \(columnId)")
+ }
+ guard let name = names[columnId] else {
+ throw ChartsError.generalConversion("Unable to get column name from: \(names) - \(columnId)")
+ }
+ let values = try column.dropFirst().map { try Convert.doubleFrom($0) }
+ chartToSetup.append(Chart(color: color,
+ name: name,
+ values: values))
+ }
+ }
+
+ guard axixValuesToSetup.isEmpty == false,
+ chartToSetup.isEmpty == false,
+ chartToSetup.firstIndex(where: { $0.values.count != axixValuesToSetup.count }) == nil else {
+ throw ChartsError.generalConversion("Saniazing: Invalid number of items: \(axixValuesToSetup), \(chartToSetup)")
+ }
+ self.axisValues = axixValuesToSetup
+ self.chartValues = chartToSetup
+ }
+}
+
+private enum ColumnType: String {
+ case axix = "x"
+ case chart = "line"
+ case area = "area"
+ case bar = "bar"
+}
diff --git a/submodules/Charts/Sources/Charts Reader/ChartsDataManager.swift b/submodules/Charts/Sources/Charts Reader/ChartsDataManager.swift
new file mode 100644
index 0000000000..1a32f9bcee
--- /dev/null
+++ b/submodules/Charts/Sources/Charts Reader/ChartsDataManager.swift
@@ -0,0 +1,191 @@
+//
+// ChartsDataManager.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import Foundation
+
+class ChartsDataManager {
+ func readChart(item: [String: Any], extraCopiesCount: Int = 0, sync: Bool, success: @escaping (ChartsCollection) -> Void, failure: @escaping (Error) -> Void) {
+ let workItem: (() -> Void) = {
+ do {
+ var collection = try ChartsCollection(from: item)
+ for _ in 0.. Void, failure: @escaping (Error) -> Void) {
+ let workItem: (() -> Void) = {
+ do {
+ let decoded = try JSONSerialization.jsonObject(with: data, options: [])
+ guard let item = decoded as? [String: Any] else {
+ throw ChartsError.invalidJson
+ }
+ var collection = try ChartsCollection(from: item)
+ for _ in 0.. Void, failure: @escaping (Error) -> Void) {
+ let workItem: (() -> Void) = {
+ do {
+ let data = try Data(contentsOf: file)
+ let decoded = try JSONSerialization.jsonObject(with: data, options: [])
+ guard let item = decoded as? [String: Any] else {
+ throw ChartsError.invalidJson
+ }
+ var collection = try ChartsCollection(from: item)
+ for _ in 0.. Void, failure: @escaping (Error) -> Void) {
+ let workItem: (() -> Void) = {
+ do {
+ let data = try Data(contentsOf: file)
+ let decoded = try JSONSerialization.jsonObject(with: data, options: [])
+ guard let items = decoded as? [[String: Any]] else {
+ throw ChartsError.invalidJson
+ }
+ var collections = try items.map { try ChartsCollection(from: $0) }
+ for _ in 0.. Double {
+ guard let double = try doubleFrom(value, lenientCast: false) else {
+ throw ChartsError.generalConversion("Unable to cast \(String(describing: value)) to \(Double.self)")
+ }
+ return double
+ }
+
+ public static func doubleFrom(_ value: Any?, lenientCast: Bool = false) throws -> Double? {
+ guard let value = value else {
+ return nil
+ }
+ if let intValue = value as? Int {
+ return Double(intValue)
+ } else if let floatValue = value as? Float {
+ return Double(floatValue)
+ } else if let int64Value = value as? Int64 {
+ return Double(int64Value)
+ } else if let intValue = value as? Int {
+ return Double(intValue)
+ } else if let stringValue = value as? String {
+ if let doubleValue = Double(stringValue) {
+ return doubleValue
+ }
+ }
+ if lenientCast {
+ return nil
+ } else {
+ throw ChartsError.generalConversion("Unable to cast \(String(describing: value)) to \(Double.self)")
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts.h b/submodules/Charts/Sources/Charts.h
new file mode 100644
index 0000000000..89573b3f16
--- /dev/null
+++ b/submodules/Charts/Sources/Charts.h
@@ -0,0 +1,19 @@
+//
+// StatisticsUI.h
+// StatisticsUI
+//
+// Created by Peter on 8/13/19.
+// Copyright © 2019 Telegram Messenger LLP. All rights reserved.
+//
+
+#import
+
+//! Project version number for StatisticsUI.
+FOUNDATION_EXPORT double StatisticsUIVersionNumber;
+
+//! Project version string for StatisticsUI.
+FOUNDATION_EXPORT const unsigned char StatisticsUIVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import
+
+
diff --git a/submodules/Charts/Sources/Charts/Controllers/BaseChartController.swift b/submodules/Charts/Sources/Charts/Controllers/BaseChartController.swift
new file mode 100644
index 0000000000..7f91e50ea5
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/BaseChartController.swift
@@ -0,0 +1,166 @@
+//
+// BaseChartController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+enum BaseConstants {
+ static let defaultRange: ClosedRange = 0...1
+ static let minimumAxisYLabelsDistance: CGFloat = 90
+ static let monthDayDateFormatter = DateFormatter.utc(format: "MMM d")
+ static let timeDateFormatter = DateFormatter.utc(format: "HH:mm")
+ static let headerFullRangeFormatter: DateFormatter = {
+ let formatter = DateFormatter.utc()
+ formatter.calendar = Calendar.utc
+ formatter.dateStyle = .long
+ return formatter
+ }()
+ static let headerMediumRangeFormatter: DateFormatter = {
+ let formatter = DateFormatter.utc()
+ formatter.dateStyle = .medium
+ return formatter
+ }()
+ static let headerFullZoomedFormatter: DateFormatter = {
+ let formatter = DateFormatter.utc()
+ formatter.dateStyle = .full
+ return formatter
+ }()
+
+ static let verticalBaseAnchors: [CGFloat] = [8, 5, 2.5, 2, 1]
+ static let defaultVerticalBaseAnchor: CGFloat = 1
+
+ static let mainChartLineWidth: CGFloat = 2
+ static let previewChartLineWidth: CGFloat = 1
+
+ static let previewLinesChartOptimizationLevel: CGFloat = 1.5
+ static let linesChartOptimizationLevel: CGFloat = 1.0
+ static let barsChartOptimizationLevel: CGFloat = 0.75
+
+ static let defaultRangePresetLength = TimeInterval.day * 60
+
+ static let chartNumberFormatter: ScalesNumberFormatter = {
+ let numberFormatter = ScalesNumberFormatter()
+ numberFormatter.allowsFloats = true
+ numberFormatter.numberStyle = .decimal
+ numberFormatter.usesGroupingSeparator = true
+ numberFormatter.groupingSeparator = " "
+ numberFormatter.minimumIntegerDigits = 1
+ numberFormatter.minimumFractionDigits = 0
+ numberFormatter.maximumFractionDigits = 2
+ return numberFormatter
+ }()
+
+ static let detailsNumberFormatter: NumberFormatter = {
+ let detailsNumberFormatter = NumberFormatter()
+ detailsNumberFormatter.allowsFloats = false
+ detailsNumberFormatter.numberStyle = .decimal
+ detailsNumberFormatter.usesGroupingSeparator = true
+ detailsNumberFormatter.groupingSeparator = " "
+ return detailsNumberFormatter
+ }()
+}
+
+class BaseChartController: ColorModeContainer {
+ //let performanceRenderer = PerformanceRenderer()
+ var initialChartsCollection: ChartsCollection
+ var isZoomed: Bool = false
+
+ var chartTitle: String = ""
+
+ init(chartsCollection: ChartsCollection) {
+ self.initialChartsCollection = chartsCollection
+ }
+
+ var mainChartRenderers: [ChartViewRenderer] {
+ fatalError("Abstract")
+ }
+
+ var navigationRenderers: [ChartViewRenderer] {
+ fatalError("Abstract")
+ }
+
+ var cartViewBounds: (() -> CGRect) = { fatalError() }
+ var chartFrame: (() -> CGRect) = { fatalError() }
+
+ func initializeChart() {
+ fatalError("Abstract")
+ }
+
+ func chartInteractionDidBegin(point: CGPoint) {
+ fatalError("Abstract")
+ }
+
+ func chartInteractionDidEnd() {
+ fatalError("Abstract")
+ }
+
+ func cancelChartInteraction() {
+ fatalError("Abstract")
+ }
+
+ func didTapZoomOut() {
+ fatalError("Abstract")
+ }
+
+ func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ fatalError("Abstract")
+ }
+
+ var currentHorizontalRange: ClosedRange {
+ fatalError("Abstract")
+ }
+
+ var isChartRangePagingEnabled: Bool = false
+ var minimumSelectedChartRange: CGFloat = 0.05
+ var chartRangePagingClosure: ((Bool, CGFloat) -> Void)? // isEnabled, PageSize
+ func setChartRangePagingEnabled(isEnabled: Bool, minimumSelectionSize: CGFloat) {
+ isChartRangePagingEnabled = isEnabled
+ minimumSelectedChartRange = minimumSelectionSize
+ chartRangePagingClosure?(isChartRangePagingEnabled, minimumSelectedChartRange)
+ }
+
+ var chartRangeUpdatedClosure: ((ClosedRange, Bool) -> Void)?
+ var currentChartHorizontalRangeFraction: ClosedRange {
+ fatalError("Abstract")
+ }
+
+ func updateChartRange(_ rangeFraction: ClosedRange) {
+ fatalError("Abstract")
+ }
+
+ var actualChartVisibility: [Bool] {
+ fatalError("Abstract")
+ }
+
+ var actualChartsCollection: ChartsCollection {
+ fatalError("Abstract")
+ }
+
+ var drawChartVisibity: Bool {
+ return true
+ }
+
+ var drawChartNavigation: Bool {
+ return true
+ }
+
+ var setDetailsViewPositionClosure: ((CGFloat) -> Void)?
+ var setDetailsChartVisibleClosure: ((Bool, Bool) -> Void)?
+ var setDetailsViewModel: ((ChartDetailsViewModel, Bool) -> Void)?
+ var getDetailsData: ((Date, @escaping (ChartsCollection?) -> Void) -> Void)?
+ var setChartTitleClosure: ((String, Bool) -> Void)?
+ var setBackButtonVisibilityClosure: ((Bool, Bool) -> Void)?
+ var refreshChartToolsClosure: ((Bool) -> Void)?
+
+ func didTapZoomIn(date: Date) {
+ fatalError("Abstract")
+ }
+
+ func apply(colorMode: ColorMode, animated: Bool) {
+
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/GeneralChartComponentController.swift b/submodules/Charts/Sources/Charts/Controllers/GeneralChartComponentController.swift
new file mode 100644
index 0000000000..284be92d3b
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/GeneralChartComponentController.swift
@@ -0,0 +1,328 @@
+//
+// GeneralChartComponentController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+enum GeneralChartComponentConstants {
+ static let defaultInitialRangeLength = CGFloat(TimeInterval.day * 60)
+ static let defaultZoomedRangeLength = CGFloat(TimeInterval.day)
+}
+
+class GeneralChartComponentController: ColorModeContainer {
+ var chartsCollection: ChartsCollection = ChartsCollection.blank
+ var chartVisibility: [Bool] = []
+ var lastChartInteractionPoint: CGPoint = .zero
+ var isChartInteractionBegun: Bool = false
+ var isChartInteracting: Bool = false
+ let isZoomed: Bool
+
+ var colorMode: ColorMode = .day
+ var totalHorizontalRange: ClosedRange = BaseConstants.defaultRange
+ var totalVerticalRange: ClosedRange = BaseConstants.defaultRange
+ var initialHorizontalRange: ClosedRange = BaseConstants.defaultRange
+ var initialVerticalRange: ClosedRange = BaseConstants.defaultRange
+
+ var cartViewBounds: (() -> CGRect) = { fatalError() }
+ var chartFrame: (() -> CGRect) = { fatalError() }
+
+ init(isZoomed: Bool) {
+ self.isZoomed = isZoomed
+ }
+
+ func initialize(chartsCollection: ChartsCollection,
+ initialDate: Date,
+ totalHorizontalRange: ClosedRange,
+ totalVerticalRange: ClosedRange) {
+ self.chartsCollection = chartsCollection
+ self.chartVisibility = Array(repeating: true, count: chartsCollection.chartValues.count)
+ self.totalHorizontalRange = totalHorizontalRange
+ self.totalVerticalRange = totalVerticalRange
+ self.initialHorizontalRange = totalHorizontalRange
+ self.initialVerticalRange = totalVerticalRange
+
+ didLoad()
+ setupInitialChartRange(initialDate: initialDate)
+ }
+
+ func didLoad() {
+ hideDetailsView(animated: false)
+ }
+ func willAppear(animated: Bool) {
+ updateChartRangeTitle(animated: animated)
+ setupChartRangePaging()
+ }
+ func willDisappear(animated: Bool) {
+ }
+
+ func setupInitialChartRange(initialDate: Date) {
+ guard let first = chartsCollection.axisValues.first?.timeIntervalSince1970,
+ let last = chartsCollection.axisValues.last?.timeIntervalSince1970 else { return }
+
+ let rangeStart = CGFloat(first)
+ let rangeEnd = CGFloat(last)
+
+ if isZoomed {
+ let initalDate = CGFloat(initialDate.timeIntervalSince1970)
+
+ initialHorizontalRange = max(initalDate, rangeStart)...min(initalDate + GeneralChartComponentConstants.defaultZoomedRangeLength, rangeEnd)
+ initialVerticalRange = totalVerticalRange
+ } else {
+ initialHorizontalRange = max(rangeStart, rangeEnd - GeneralChartComponentConstants.defaultInitialRangeLength)...rangeEnd
+ initialVerticalRange = totalVerticalRange
+ }
+ }
+ func setupChartRangePaging() {
+ chartRangePagingClosure?(false, 0.05)
+ }
+
+ var visibleHorizontalMainChartRange: ClosedRange {
+ return currentMainRangeRenderer.verticalRange.current
+ }
+ var visibleVerticalMainChartRange: ClosedRange {
+ return currentMainRangeRenderer.verticalRange.current
+ }
+ var currentHorizontalMainChartRange: ClosedRange {
+ return currentMainRangeRenderer.horizontalRange.end
+ }
+ var currentVerticalMainChartRange: ClosedRange {
+ return currentMainRangeRenderer.verticalRange.end
+ }
+ var currentMainRangeRenderer: BaseChartRenderer {
+ fatalError("Abstract")
+ }
+
+ var visiblePreviewHorizontalRange: ClosedRange {
+ return currentPreviewRangeRenderer.verticalRange.current
+ }
+ var visiblePreviewVerticalRange: ClosedRange {
+ return currentPreviewRangeRenderer.verticalRange.current
+ }
+ var currentPreviewHorizontalRange: ClosedRange {
+ return currentPreviewRangeRenderer.horizontalRange.end
+ }
+ var currentPreviewVerticalRange: ClosedRange {
+ return currentPreviewRangeRenderer.verticalRange.end
+ }
+ var currentPreviewRangeRenderer: BaseChartRenderer {
+ fatalError("Abstract")
+ }
+
+ var mainChartRenderers: [ChartViewRenderer] {
+ fatalError("Abstract")
+ }
+ var previewRenderers: [ChartViewRenderer] {
+ fatalError("Abstract")
+ }
+
+ func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ self.chartVisibility = visibility
+ if isChartInteractionBegun {
+ chartInteractionDidBegin(point: lastChartInteractionPoint)
+ }
+ }
+
+ var currentChartHorizontalRangeFraction: ClosedRange {
+ let lowerPercent = (currentHorizontalMainChartRange.lowerBound - totalHorizontalRange.lowerBound) / totalHorizontalRange.distance
+ let upperPercent = (currentHorizontalMainChartRange.upperBound - totalHorizontalRange.lowerBound) / totalHorizontalRange.distance
+ return lowerPercent...upperPercent
+ }
+
+ func chartRangeFractionDidUpdated(_ rangeFraction: ClosedRange) {
+ let horizontalRange = ClosedRange(uncheckedBounds:
+ (lower: totalHorizontalRange.lowerBound + rangeFraction.lowerBound * totalHorizontalRange.distance,
+ upper: totalHorizontalRange.lowerBound + rangeFraction.upperBound * totalHorizontalRange.distance))
+ chartRangeDidUpdated(horizontalRange)
+ updateChartRangeTitle(animated: true)
+ }
+
+ func chartRangeDidUpdated(_ updatedRange: ClosedRange) {
+ hideDetailsView(animated: true)
+
+ if isChartInteractionBegun {
+ chartInteractionDidBegin(point: lastChartInteractionPoint)
+ }
+ }
+
+ // MARK: - Details & Interaction
+ func findClosestDateTo(dateToFind: Date) -> (Date, Int)? {
+ guard chartsCollection.axisValues.count > 0 else { return nil }
+ var closestDate = chartsCollection.axisValues[0]
+ var minIndex = 0
+ for (index, date) in chartsCollection.axisValues.enumerated() {
+ if abs(dateToFind.timeIntervalSince(date)) < abs(dateToFind.timeIntervalSince(closestDate)) {
+ closestDate = date
+ minIndex = index
+ }
+ }
+ return (closestDate, minIndex)
+ }
+
+ func chartInteractionDidBegin(point: CGPoint) {
+ let chartFrame = self.chartFrame()
+ guard chartFrame.width > 0 else { return }
+ let horizontalRange = currentHorizontalMainChartRange
+ let dateToFind = Date(timeIntervalSince1970: TimeInterval(horizontalRange.distance * point.x + horizontalRange.lowerBound))
+ guard let (closestDate, minIndex) = findClosestDateTo(dateToFind: dateToFind) else { return }
+
+ let chartWasInteracting = isChartInteractionBegun
+ lastChartInteractionPoint = point
+ isChartInteractionBegun = true
+ isChartInteracting = true
+
+ let chartValue: CGFloat = CGFloat(closestDate.timeIntervalSince1970)
+ let detailsViewPosition = (chartValue - horizontalRange.lowerBound) / horizontalRange.distance * chartFrame.width + chartFrame.minX
+ showDetailsView(at: chartValue, detailsViewPosition: detailsViewPosition, dataIndex: minIndex, date: closestDate, animted: chartWasInteracting)
+ }
+
+ func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) {
+ setDetailsViewModel?(chartDetailsViewModel(closestDate: date, pointIndex: dataIndex), animted)
+ setDetailsChartVisibleClosure?(true, true)
+ setDetailsViewPositionClosure?(detailsViewPosition)
+ }
+
+ func chartInteractionDidEnd() {
+ isChartInteracting = false
+ }
+
+ func hideDetailsView(animated: Bool) {
+ isChartInteractionBegun = false
+ setDetailsChartVisibleClosure?(false, animated)
+ }
+
+ var visibleDetailsChartValues: [ChartsCollection.Chart] {
+ let visibleCharts: [ChartsCollection.Chart] = chartVisibility.enumerated().compactMap { args in
+ args.element ? chartsCollection.chartValues[args.offset] : nil
+ }
+ return visibleCharts
+ }
+
+ var updatePreviewRangeClosure: ((ClosedRange, Bool) -> Void)?
+ var zoomInOnDateClosure: ((Date) -> Void)?
+ var setChartTitleClosure: ((String, Bool) -> Void)?
+ var setDetailsViewPositionClosure: ((CGFloat) -> Void)?
+ var setDetailsChartVisibleClosure: ((Bool, Bool) -> Void)?
+ var setDetailsViewModel: ((ChartDetailsViewModel, Bool) -> Void)?
+ var chartRangePagingClosure: ((Bool, CGFloat) -> Void)? // isEnabled, PageSize
+
+ func apply(colorMode: ColorMode, animated: Bool) {
+ self.colorMode = colorMode
+ }
+
+// MARK: - Helpers
+ var prevoiusHorizontalStrideInterval: Int = -1
+ func updateHorizontalLimitLabels(horizontalScalesRenderer: HorizontalScalesRenderer,
+ horizontalRange: ClosedRange,
+ scaleType: ChartScaleType,
+ forceUpdate: Bool,
+ animated: Bool) {
+ let scaleTimeInterval: TimeInterval
+ if chartsCollection.axisValues.count >= 1 {
+ scaleTimeInterval = chartsCollection.axisValues[1].timeIntervalSince1970 - chartsCollection.axisValues[0].timeIntervalSince1970
+ } else {
+ scaleTimeInterval = scaleType.timeInterval
+ }
+
+ let numberOfItems = horizontalRange.distance / CGFloat(scaleTimeInterval)
+ let maximumNumberOfItems = chartFrame().width / scaleType.minimumAxisXDistance
+ let tempStride = max(1, Int((numberOfItems / maximumNumberOfItems).rounded(.up)))
+ var strideInterval = 1
+ while strideInterval < tempStride {
+ strideInterval *= 2
+ }
+
+ if forceUpdate || (strideInterval != prevoiusHorizontalStrideInterval && strideInterval > 0) {
+ var labels: [LinesChartLabel] = []
+ for index in stride(from: chartsCollection.axisValues.count - 1, to: -1, by: -strideInterval).reversed() {
+ let date = chartsCollection.axisValues[index]
+ labels.append(LinesChartLabel(value: CGFloat(date.timeIntervalSince1970),
+ text: scaleType.dateFormatter.string(from: date)))
+ }
+ prevoiusHorizontalStrideInterval = strideInterval
+ horizontalScalesRenderer.setup(labels: labels, animated: animated)
+ }
+ }
+
+ func verticalLimitsLabels(verticalRange: ClosedRange) -> (ClosedRange, [LinesChartLabel]) {
+ let ditance = verticalRange.distance
+ let chartHeight = chartFrame().height
+
+ guard ditance > 0, chartHeight > 0 else { return (BaseConstants.defaultRange, []) }
+
+ let approximateNumberOfChartValues = (chartHeight / BaseConstants.minimumAxisYLabelsDistance)
+
+ var numberOfOffsetsPerItem = ditance / approximateNumberOfChartValues
+ var multiplier: CGFloat = 1.0
+ while numberOfOffsetsPerItem > 10 {
+ numberOfOffsetsPerItem /= 10
+ multiplier *= 10
+ }
+ var dividor: CGFloat = 1.0
+ var maximumNumberOfDecimals = 2
+ while numberOfOffsetsPerItem < 1 {
+ numberOfOffsetsPerItem *= 10
+ dividor *= 10
+ maximumNumberOfDecimals += 1
+ }
+
+ var base: CGFloat = BaseConstants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor
+ base = base * multiplier / dividor
+
+ var verticalLabels: [LinesChartLabel] = []
+ var verticalValue = (verticalRange.lowerBound / base).rounded(.down) * base
+ let lowerBound = verticalValue
+
+ let numberFormatter = BaseConstants.chartNumberFormatter
+ numberFormatter.maximumFractionDigits = maximumNumberOfDecimals
+ while verticalValue < verticalRange.upperBound {
+ let text: String = numberFormatter.string(from: NSNumber(value: Double(verticalValue))) ?? ""
+
+ verticalLabels.append(LinesChartLabel(value: verticalValue, text: text))
+ verticalValue += base
+ }
+ let updatedRange = lowerBound...verticalValue
+
+ return (updatedRange, verticalLabels)
+ }
+
+ func chartDetailsViewModel(closestDate: Date, pointIndex: Int) -> ChartDetailsViewModel {
+ let values: [ChartDetailsViewModel.Value] = chartsCollection.chartValues.enumerated().map { arg in
+ let (index, component) = arg
+ return ChartDetailsViewModel.Value(prefix: nil,
+ title: component.name,
+ value: BaseConstants.detailsNumberFormatter.string(from: NSNumber(value: component.values[pointIndex])) ?? "",
+ color: component.color,
+ visible: chartVisibility[index])
+ }
+ let dateString: String
+ if isZoomed {
+ dateString = BaseConstants.timeDateFormatter.string(from: closestDate)
+ } else {
+ dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
+ }
+ let viewModel = ChartDetailsViewModel(title: dateString,
+ showArrow: !self.isZoomed,
+ showPrefixes: false,
+ values: values,
+ totalValue: nil,
+ tapAction: { [weak self] in
+ self?.zoomInOnDateClosure?(closestDate) })
+ return viewModel
+ }
+
+ func updateChartRangeTitle(animated: Bool) {
+ let fromDate = Date(timeIntervalSince1970: TimeInterval(currentHorizontalMainChartRange.lowerBound) + 1)
+ let toDate = Date(timeIntervalSince1970: TimeInterval(currentHorizontalMainChartRange.upperBound))
+ if Calendar.utc.startOfDay(for: fromDate) == Calendar.utc.startOfDay(for: toDate) {
+ let stirng = BaseConstants.headerFullZoomedFormatter.string(from: fromDate)
+ self.setChartTitleClosure?(stirng, animated)
+ } else {
+ let stirng = "\(BaseConstants.headerMediumRangeFormatter.string(from: fromDate)) - \(BaseConstants.headerMediumRangeFormatter.string(from: toDate))"
+ self.setChartTitleClosure?(stirng, animated)
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Lines/BaseLinesChartController.swift b/submodules/Charts/Sources/Charts/Controllers/Lines/BaseLinesChartController.swift
new file mode 100644
index 0000000000..60d5069d10
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Lines/BaseLinesChartController.swift
@@ -0,0 +1,236 @@
+//
+// BaseLinesChartController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/14/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class BaseLinesChartController: BaseChartController {
+ var chartVisibility: [Bool]
+ var zoomChartVisibility: [Bool]
+ var lastChartInteractionPoint: CGPoint = .zero
+ var isChartInteractionBegun: Bool = false
+
+ var initialChartRange: ClosedRange = BaseConstants.defaultRange
+ var zoomedChartRange: ClosedRange = BaseConstants.defaultRange
+
+ override init(chartsCollection: ChartsCollection) {
+ self.chartVisibility = Array(repeating: true, count: chartsCollection.chartValues.count)
+ self.zoomChartVisibility = []
+ super.init(chartsCollection: chartsCollection)
+ }
+
+ func setupChartCollection(chartsCollection: ChartsCollection, animated: Bool, isZoomed: Bool) {
+ if animated {
+ TimeInterval.setDefaultSuration(.expandAnimationDuration)
+ DispatchQueue.main.asyncAfter(deadline: .now() + .expandAnimationDuration) {
+ TimeInterval.setDefaultSuration(.osXDuration)
+ }
+ }
+
+ self.initialChartsCollection = chartsCollection
+ self.isZoomed = isZoomed
+
+ self.setBackButtonVisibilityClosure?(isZoomed, animated)
+
+ updateChartRangeTitle(animated: animated)
+ }
+
+ func updateChartRangeTitle(animated: Bool) {
+ let fromDate = Date(timeIntervalSince1970: TimeInterval(zoomedChartRange.lowerBound) + .hour)
+ let toDate = Date(timeIntervalSince1970: TimeInterval(zoomedChartRange.upperBound))
+ if Calendar.utc.startOfDay(for: fromDate) == Calendar.utc.startOfDay(for: toDate) {
+ let stirng = BaseConstants.headerFullZoomedFormatter.string(from: fromDate)
+ self.setChartTitleClosure?(stirng, animated)
+ } else {
+ let stirng = "\(BaseConstants.headerMediumRangeFormatter.string(from: fromDate)) - \(BaseConstants.headerMediumRangeFormatter.string(from: toDate))"
+ self.setChartTitleClosure?(stirng, animated)
+ }
+ }
+
+ override func chartInteractionDidBegin(point: CGPoint) {
+ lastChartInteractionPoint = point
+ isChartInteractionBegun = true
+ }
+
+ override func chartInteractionDidEnd() {
+
+ }
+
+ override func cancelChartInteraction() {
+ isChartInteractionBegun = false
+ }
+
+ override func updateChartRange(_ rangeFraction: ClosedRange) {
+
+ }
+
+ override var actualChartVisibility: [Bool] {
+ return isZoomed ? zoomChartVisibility : chartVisibility
+ }
+
+ override var actualChartsCollection: ChartsCollection {
+ return initialChartsCollection
+ }
+
+ var visibleChartValues: [ChartsCollection.Chart] {
+ let visibleCharts: [ChartsCollection.Chart] = actualChartVisibility.enumerated().compactMap { args in
+ args.element ? initialChartsCollection.chartValues[args.offset] : nil
+ }
+ return visibleCharts
+ }
+
+
+ func chartDetailsViewModel(closestDate: Date, pointIndex: Int) -> ChartDetailsViewModel {
+ let values: [ChartDetailsViewModel.Value] = actualChartsCollection.chartValues.enumerated().map { arg in
+ let (index, component) = arg
+ return ChartDetailsViewModel.Value(prefix: nil,
+ title: component.name,
+ value: BaseConstants.detailsNumberFormatter.string(from: component.values[pointIndex]),
+ color: component.color,
+ visible: actualChartVisibility[index])
+ }
+ let dateString: String
+ if isZoomed {
+ dateString = BaseConstants.timeDateFormatter.string(from: closestDate)
+ } else {
+ dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
+ }
+ let viewModel = ChartDetailsViewModel(title: dateString,
+ showArrow: !self.isZoomed,
+ showPrefixes: false,
+ values: values,
+ totalValue: nil,
+ tapAction: { [weak self] in self?.didTapZoomIn(date: closestDate) })
+ return viewModel
+ }
+
+ override func didTapZoomIn(date: Date) {
+ guard isZoomed == false else { return }
+ cancelChartInteraction()
+ self.getDetailsData?(date, { updatedCollection in
+ if let updatedCollection = updatedCollection {
+ self.initialChartRange = self.currentHorizontalRange
+ if let startDate = updatedCollection.axisValues.first,
+ let endDate = updatedCollection.axisValues.last {
+ self.zoomedChartRange = CGFloat(max(date.timeIntervalSince1970, startDate.timeIntervalSince1970))...CGFloat(min(date.timeIntervalSince1970 + .day - .hour, endDate.timeIntervalSince1970))
+ } else {
+ self.zoomedChartRange = CGFloat(date.timeIntervalSince1970)...CGFloat(date.timeIntervalSince1970 + .day - 1)
+ }
+ self.setupChartCollection(chartsCollection: updatedCollection, animated: true, isZoomed: true)
+ }
+ })
+ }
+
+ func horizontalLimitsLabels(horizontalRange: ClosedRange,
+ scaleType: ChartScaleType,
+ prevoiusHorizontalStrideInterval: Int) -> (Int, [LinesChartLabel])? {
+ let numberOfItems = horizontalRange.distance / CGFloat(scaleType.timeInterval)
+ let maximumNumberOfItems = chartFrame().width / scaleType.minimumAxisXDistance
+ let tempStride = max(1, Int((numberOfItems / maximumNumberOfItems).rounded(.up)))
+ var strideInterval = 1
+ while strideInterval < tempStride {
+ strideInterval *= 2
+ }
+
+ if strideInterval != prevoiusHorizontalStrideInterval && strideInterval > 0 {
+ var labels: [LinesChartLabel] = []
+ for index in stride(from: initialChartsCollection.axisValues.count - 1, to: -1, by: -strideInterval).reversed() {
+ let date = initialChartsCollection.axisValues[index]
+ labels.append(LinesChartLabel(value: CGFloat(date.timeIntervalSince1970),
+ text: scaleType.dateFormatter.string(from: date)))
+ }
+ return (strideInterval, labels)
+ }
+ return nil
+ }
+
+ func findClosestDateTo(dateToFind: Date) -> (Date, Int)? {
+ guard initialChartsCollection.axisValues.count > 0 else { return nil }
+ var closestDate = initialChartsCollection.axisValues[0]
+ var minIndex = 0
+ for (index, date) in initialChartsCollection.axisValues.enumerated() {
+ if abs(dateToFind.timeIntervalSince(date)) < abs(dateToFind.timeIntervalSince(closestDate)) {
+ closestDate = date
+ minIndex = index
+ }
+ }
+ return (closestDate, minIndex)
+ }
+
+ func verticalLimitsLabels(verticalRange: ClosedRange) -> (ClosedRange, [LinesChartLabel]) {
+ let ditance = verticalRange.distance
+ let chartHeight = chartFrame().height
+
+ guard ditance > 0, chartHeight > 0 else { return (BaseConstants.defaultRange, []) }
+
+ let approximateNumberOfChartValues = (chartHeight / BaseConstants.minimumAxisYLabelsDistance)
+
+ var numberOfOffsetsPerItem = ditance / approximateNumberOfChartValues
+ var multiplier: CGFloat = 1.0
+ while numberOfOffsetsPerItem > 10 {
+ numberOfOffsetsPerItem /= 10
+ multiplier *= 10
+ }
+ var dividor: CGFloat = 1.0
+ var maximumNumberOfDecimals = 2
+ while numberOfOffsetsPerItem < 1 {
+ numberOfOffsetsPerItem *= 10
+ dividor *= 10
+ maximumNumberOfDecimals += 1
+ }
+
+ var base: CGFloat = BaseConstants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor
+ base = base * multiplier / dividor
+
+ var verticalLabels: [LinesChartLabel] = []
+ var verticalValue = (verticalRange.lowerBound / base).rounded(.down) * base
+ let lowerBound = verticalValue
+
+ let numberFormatter = BaseConstants.chartNumberFormatter
+ numberFormatter.maximumFractionDigits = maximumNumberOfDecimals
+ while verticalValue < verticalRange.upperBound {
+ let text: String = numberFormatter.string(from: NSNumber(value: Double(verticalValue))) ?? ""
+
+ verticalLabels.append(LinesChartLabel(value: verticalValue, text: text))
+ verticalValue += base
+ }
+ let updatedRange = lowerBound...verticalValue
+
+ return (updatedRange, verticalLabels)
+ }
+}
+
+enum ChartScaleType {
+ case day
+ case hour
+ case minutes5
+}
+
+extension ChartScaleType {
+ var timeInterval: TimeInterval {
+ switch self {
+ case .day: return .day
+ case .hour: return .hour
+ case .minutes5: return .minute * 5
+ }
+ }
+
+ var minimumAxisXDistance: CGFloat {
+ switch self {
+ case .day: return 50
+ case .hour: return 40
+ case .minutes5: return 40
+ }
+ }
+ var dateFormatter: DateFormatter {
+ switch self {
+ case .day: return BaseConstants.monthDayDateFormatter
+ case .hour: return BaseConstants.timeDateFormatter
+ case .minutes5: return BaseConstants.timeDateFormatter
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift b/submodules/Charts/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift
new file mode 100644
index 0000000000..3d52888d72
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift
@@ -0,0 +1,247 @@
+//
+// LinesChartController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private enum Constants {
+ static let defaultRange: ClosedRange = 0...1
+}
+
+class GeneralLinesChartController: BaseLinesChartController {
+ private let initialChartCollection: ChartsCollection
+
+ private let mainLinesRenderer = LinesChartRenderer()
+ private let horizontalScalesRenderer = HorizontalScalesRenderer()
+ private let verticalScalesRenderer = VerticalScalesRenderer()
+ private let verticalLineRenderer = VerticalLinesRenderer()
+ private let lineBulletsRenerer = LineBulletsRenerer()
+
+ private let previewLinesRenderer = LinesChartRenderer()
+
+ private var totalVerticalRange: ClosedRange = Constants.defaultRange
+ private var totalHorizontalRange: ClosedRange = Constants.defaultRange
+
+ private var prevoiusHorizontalStrideInterval: Int = 1
+
+ private (set) var chartLines: [LinesChartRenderer.LineData] = []
+
+ override init(chartsCollection: ChartsCollection) {
+ self.initialChartCollection = chartsCollection
+ self.mainLinesRenderer.lineWidth = 2
+ self.mainLinesRenderer.optimizationLevel = BaseConstants.linesChartOptimizationLevel
+ self.previewLinesRenderer.optimizationLevel = BaseConstants.previewLinesChartOptimizationLevel
+
+ self.lineBulletsRenerer.isEnabled = false
+
+ super.init(chartsCollection: chartsCollection)
+ self.zoomChartVisibility = chartVisibility
+ }
+
+ override func setupChartCollection(chartsCollection: ChartsCollection, animated: Bool, isZoomed: Bool) {
+ super.setupChartCollection(chartsCollection: chartsCollection, animated: animated, isZoomed: isZoomed)
+
+ self.chartLines = chartsCollection.chartValues.map { chart in
+ let points = chart.values.enumerated().map({ (arg) -> CGPoint in
+ return CGPoint(x: chartsCollection.axisValues[arg.offset].timeIntervalSince1970,
+ y: arg.element)
+ })
+ return LinesChartRenderer.LineData(color: chart.color, points: points)
+ }
+
+ self.prevoiusHorizontalStrideInterval = -1
+ self.totalVerticalRange = LinesChartRenderer.LineData.verticalRange(lines: chartLines) ?? Constants.defaultRange
+ self.totalHorizontalRange = LinesChartRenderer.LineData.horizontalRange(lines: chartLines) ?? Constants.defaultRange
+ self.lineBulletsRenerer.bullets = self.chartLines.map { LineBulletsRenerer.Bullet(coordinate: $0.points.first ?? .zero,
+ color: $0.color)}
+
+ let chartRange: ClosedRange
+ if isZoomed {
+ chartRange = zoomedChartRange
+ } else {
+ chartRange = initialChartRange
+ }
+
+ self.previewLinesRenderer.setup(horizontalRange: totalHorizontalRange, animated: animated)
+ self.previewLinesRenderer.setup(verticalRange: totalVerticalRange, animated: animated)
+
+ self.mainLinesRenderer.setLines(lines: chartLines, animated: animated)
+ self.previewLinesRenderer.setLines(lines: chartLines, animated: animated)
+
+ updateHorizontalLimists(horizontalRange: chartRange, animated: animated)
+ updateMainChartHorizontalRange(range: chartRange, animated: animated)
+ updateVerticalLimitsAndRange(horizontalRange: chartRange, animated: animated)
+
+ self.chartRangeUpdatedClosure?(currentChartHorizontalRangeFraction, animated)
+ }
+
+ override func initializeChart() {
+ if let first = initialChartCollection.axisValues.first?.timeIntervalSince1970,
+ let last = initialChartCollection.axisValues.last?.timeIntervalSince1970 {
+ initialChartRange = CGFloat(max(first, last - BaseConstants.defaultRangePresetLength))...CGFloat(last)
+ }
+ setupChartCollection(chartsCollection: initialChartCollection, animated: false, isZoomed: false)
+ }
+
+ override var mainChartRenderers: [ChartViewRenderer] {
+ return [//performanceRenderer,
+ mainLinesRenderer,
+ horizontalScalesRenderer,
+ verticalScalesRenderer,
+ verticalLineRenderer,
+ lineBulletsRenerer
+ ]
+ }
+
+ override var navigationRenderers: [ChartViewRenderer] {
+ return [previewLinesRenderer]
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ chartVisibility = visibility
+ zoomChartVisibility = visibility
+ for (index, isVisible) in visibility.enumerated() {
+ mainLinesRenderer.setLineVisible(isVisible, at: index, animated: animated)
+ previewLinesRenderer.setLineVisible(isVisible, at: index, animated: animated)
+ lineBulletsRenerer.setLineVisible(isVisible, at: index, animated: animated)
+ }
+
+ updateVerticalLimitsAndRange(horizontalRange: currentHorizontalRange, animated: true)
+
+ if isChartInteractionBegun {
+ chartInteractionDidBegin(point: lastChartInteractionPoint)
+ }
+ }
+
+ override func chartInteractionDidBegin(point: CGPoint) {
+ let horizontalRange = mainLinesRenderer.horizontalRange.current
+ let chartFrame = self.chartFrame()
+ guard chartFrame.width > 0 else { return }
+ let chartInteractionWasBegin = isChartInteractionBegun
+
+ let dateToFind = Date(timeIntervalSince1970: TimeInterval(horizontalRange.distance * point.x + horizontalRange.lowerBound))
+ guard let (closestDate, minIndex) = findClosestDateTo(dateToFind: dateToFind) else { return }
+
+ super.chartInteractionDidBegin(point: point)
+
+ self.lineBulletsRenerer.bullets = chartLines.compactMap { chart in
+ return LineBulletsRenerer.Bullet(coordinate: chart.points[minIndex], color: chart.color)
+ }
+ self.lineBulletsRenerer.isEnabled = true
+
+ let chartValue: CGFloat = CGFloat(closestDate.timeIntervalSince1970)
+ let detailsViewPosition = (chartValue - horizontalRange.lowerBound) / horizontalRange.distance * chartFrame.width + chartFrame.minX
+ self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex), chartInteractionWasBegin)
+ self.setDetailsChartVisibleClosure?(true, true)
+ self.setDetailsViewPositionClosure?(detailsViewPosition)
+ self.verticalLineRenderer.values = [chartValue]
+ }
+
+
+ override var currentChartHorizontalRangeFraction: ClosedRange {
+ let lowerPercent = (currentHorizontalRange.lowerBound - totalHorizontalRange.lowerBound) / totalHorizontalRange.distance
+ let upperPercent = (currentHorizontalRange.upperBound - totalHorizontalRange.lowerBound) / totalHorizontalRange.distance
+ return lowerPercent...upperPercent
+ }
+
+ override var currentHorizontalRange: ClosedRange {
+ return mainLinesRenderer.horizontalRange.end
+ }
+
+ override func cancelChartInteraction() {
+ super.cancelChartInteraction()
+ self.lineBulletsRenerer.isEnabled = false
+
+ self.setDetailsChartVisibleClosure?(false, true)
+ self.verticalLineRenderer.values = []
+ }
+
+ override func didTapZoomOut() {
+ cancelChartInteraction()
+ self.setupChartCollection(chartsCollection: initialChartCollection, animated: true, isZoomed: false)
+ }
+
+ var visibleCharts: [LinesChartRenderer.LineData] {
+ let visibleCharts: [LinesChartRenderer.LineData] = chartVisibility.enumerated().compactMap { args in
+ args.element ? chartLines[args.offset] : nil
+ }
+ return visibleCharts
+ }
+
+ override func updateChartRange(_ rangeFraction: ClosedRange) {
+ cancelChartInteraction()
+
+ let horizontalRange = ClosedRange(uncheckedBounds:
+ (lower: totalHorizontalRange.lowerBound + rangeFraction.lowerBound * totalHorizontalRange.distance,
+ upper: totalHorizontalRange.lowerBound + rangeFraction.upperBound * totalHorizontalRange.distance))
+
+ zoomedChartRange = horizontalRange
+ updateChartRangeTitle(animated: true)
+
+ updateMainChartHorizontalRange(range: horizontalRange, animated: false)
+ updateHorizontalLimists(horizontalRange: horizontalRange, animated: true)
+ updateVerticalLimitsAndRange(horizontalRange: horizontalRange, animated: true)
+ }
+
+ func updateMainChartHorizontalRange(range: ClosedRange, animated: Bool) {
+ mainLinesRenderer.setup(horizontalRange: range, animated: animated)
+ horizontalScalesRenderer.setup(horizontalRange: range, animated: animated)
+ verticalScalesRenderer.setup(horizontalRange: range, animated: animated)
+ verticalLineRenderer.setup(horizontalRange: range, animated: animated)
+ lineBulletsRenerer.setup(horizontalRange: range, animated: animated)
+ }
+
+ func updateMainChartVerticalRange(range: ClosedRange, animated: Bool) {
+ mainLinesRenderer.setup(verticalRange: range, animated: animated)
+ horizontalScalesRenderer.setup(verticalRange: range, animated: animated)
+ verticalScalesRenderer.setup(verticalRange: range, animated: animated)
+ verticalLineRenderer.setup(verticalRange: range, animated: animated)
+ lineBulletsRenerer.setup(verticalRange: range, animated: animated)
+ }
+
+ func updateHorizontalLimists(horizontalRange: ClosedRange, animated: Bool) {
+ if let (stride, labels) = horizontalLimitsLabels(horizontalRange: horizontalRange,
+ scaleType: isZoomed ? .hour : .day,
+ prevoiusHorizontalStrideInterval: prevoiusHorizontalStrideInterval) {
+ self.horizontalScalesRenderer.setup(labels: labels, animated: animated)
+ self.prevoiusHorizontalStrideInterval = stride
+ }
+ }
+
+ func updateVerticalLimitsAndRange(horizontalRange: ClosedRange, animated: Bool) {
+ if let verticalRange = LinesChartRenderer.LineData.verticalRange(lines: visibleCharts,
+ calculatingRange: horizontalRange,
+ addBounds: true) {
+
+
+ let (range, labels) = verticalLimitsLabels(verticalRange: verticalRange)
+
+ if verticalScalesRenderer.verticalRange.end != range {
+ verticalScalesRenderer.setup(verticalLimitsLabels: labels, animated: animated)
+ updateMainChartVerticalRange(range: range, animated: animated)
+ }
+ verticalScalesRenderer.setVisible(true, animated: animated)
+ } else {
+ verticalScalesRenderer.setVisible(false, animated: animated)
+ }
+
+ guard let previewVerticalRange = LinesChartRenderer.LineData.verticalRange(lines: visibleCharts) else { return }
+
+ if previewLinesRenderer.verticalRange.end != previewVerticalRange {
+ previewLinesRenderer.setup(verticalRange: previewVerticalRange, animated: animated)
+ }
+ }
+
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.axisXColor = colorMode.chartStrongLinesColor
+ verticalScalesRenderer.horizontalLinesColor = colorMode.chartHelperLinesColor
+ lineBulletsRenerer.setInnerColor(colorMode.chartBackgroundColor, animated: animated)
+ verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift b/submodules/Charts/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift
new file mode 100644
index 0000000000..251e76271e
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift
@@ -0,0 +1,306 @@
+//
+// TwoAxisLinesChartController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private enum Constants {
+ static let verticalBaseAnchors: [CGFloat] = [8, 5, 4, 2.5, 2, 1]
+ static let defaultRange: ClosedRange = 0...1
+}
+
+class TwoAxisLinesChartController: BaseLinesChartController {
+ class GraphController {
+ let mainLinesRenderer = LinesChartRenderer()
+ let verticalScalesRenderer = VerticalScalesRenderer()
+ let lineBulletsRenerer = LineBulletsRenerer()
+ let previewLinesRenderer = LinesChartRenderer()
+
+ var chartLines: [LinesChartRenderer.LineData] = []
+
+ var totalVerticalRange: ClosedRange = Constants.defaultRange
+
+ init() {
+ self.mainLinesRenderer.lineWidth = 2
+ self.previewLinesRenderer.lineWidth = 1
+ self.lineBulletsRenerer.isEnabled = false
+
+ self.mainLinesRenderer.optimizationLevel = BaseConstants.linesChartOptimizationLevel
+ self.previewLinesRenderer.optimizationLevel = BaseConstants.previewLinesChartOptimizationLevel
+ }
+
+ func updateMainChartVerticalRange(range: ClosedRange, animated: Bool) {
+ mainLinesRenderer.setup(verticalRange: range, animated: animated)
+ verticalScalesRenderer.setup(verticalRange: range, animated: animated)
+ lineBulletsRenerer.setup(verticalRange: range, animated: animated)
+ }
+ }
+
+ private var graphControllers: [GraphController] = []
+ private let verticalLineRenderer = VerticalLinesRenderer()
+ private let horizontalScalesRenderer = HorizontalScalesRenderer()
+
+ var totalHorizontalRange: ClosedRange = Constants.defaultRange
+
+ private let initialChartCollection: ChartsCollection
+
+ private var prevoiusHorizontalStrideInterval: Int = 1
+
+ override init(chartsCollection: ChartsCollection) {
+ self.initialChartCollection = chartsCollection
+ graphControllers = chartsCollection.chartValues.map { _ in GraphController() }
+
+ super.init(chartsCollection: chartsCollection)
+ self.zoomChartVisibility = chartVisibility
+ }
+
+ override func setupChartCollection(chartsCollection: ChartsCollection, animated: Bool, isZoomed: Bool) {
+ super.setupChartCollection(chartsCollection: chartsCollection, animated: animated, isZoomed: isZoomed)
+
+ for (index, controller) in self.graphControllers.enumerated() {
+ let chart = chartsCollection.chartValues[index]
+ let points = chart.values.enumerated().map({ (arg) -> CGPoint in
+ return CGPoint(x: chartsCollection.axisValues[arg.offset].timeIntervalSince1970,
+ y: arg.element)
+ })
+ let chartLines = [LinesChartRenderer.LineData(color: chart.color, points: points)]
+ controller.chartLines = [LinesChartRenderer.LineData(color: chart.color, points: points)]
+ controller.verticalScalesRenderer.labelsColor = chart.color
+ controller.totalVerticalRange = LinesChartRenderer.LineData.verticalRange(lines: chartLines) ?? Constants.defaultRange
+ self.totalHorizontalRange = LinesChartRenderer.LineData.horizontalRange(lines: chartLines) ?? Constants.defaultRange
+ controller.lineBulletsRenerer.bullets = chartLines.map { LineBulletsRenerer.Bullet(coordinate: $0.points.first ?? .zero,
+ color: $0.color) }
+ controller.previewLinesRenderer.setup(horizontalRange: self.totalHorizontalRange, animated: animated)
+ controller.previewLinesRenderer.setup(verticalRange: controller.totalVerticalRange, animated: animated)
+ controller.mainLinesRenderer.setLines(lines: chartLines, animated: animated)
+ controller.previewLinesRenderer.setLines(lines: chartLines, animated: animated)
+
+ controller.verticalScalesRenderer.setHorizontalLinesVisible((index == 0), animated: animated)
+ controller.verticalScalesRenderer.isRightAligned = (index != 0)
+ }
+
+ self.prevoiusHorizontalStrideInterval = -1
+
+ let chartRange: ClosedRange
+ if isZoomed {
+ chartRange = zoomedChartRange
+ } else {
+ chartRange = initialChartRange
+ }
+
+ updateHorizontalLimists(horizontalRange: chartRange, animated: animated)
+ updateMainChartHorizontalRange(range: chartRange, animated: animated)
+ updateVerticalLimitsAndRange(horizontalRange: chartRange, animated: animated)
+
+ self.chartRangeUpdatedClosure?(currentChartHorizontalRangeFraction, animated)
+ }
+
+ override func initializeChart() {
+ if let first = initialChartCollection.axisValues.first?.timeIntervalSince1970,
+ let last = initialChartCollection.axisValues.last?.timeIntervalSince1970 {
+ initialChartRange = CGFloat(max(first, last - BaseConstants.defaultRangePresetLength))...CGFloat(last)
+ }
+ setupChartCollection(chartsCollection: initialChartCollection, animated: false, isZoomed: false)
+ }
+
+ override var mainChartRenderers: [ChartViewRenderer] {
+ return graphControllers.map { $0.mainLinesRenderer } +
+ graphControllers.flatMap { [$0.verticalScalesRenderer, $0.lineBulletsRenerer] } +
+ [horizontalScalesRenderer, verticalLineRenderer,
+// performanceRenderer
+ ]
+ }
+
+ override var navigationRenderers: [ChartViewRenderer] {
+ return graphControllers.map { $0.previewLinesRenderer }
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ chartVisibility = visibility
+ zoomChartVisibility = visibility
+ let firstIndex = visibility.firstIndex(where: { $0 })
+ for (index, isVisible) in visibility.enumerated() {
+ let graph = graphControllers[index]
+ for graphIndex in graph.chartLines.indices {
+ graph.mainLinesRenderer.setLineVisible(isVisible, at: graphIndex, animated: animated)
+ graph.previewLinesRenderer.setLineVisible(isVisible, at: graphIndex, animated: animated)
+ graph.lineBulletsRenerer.setLineVisible(isVisible, at: graphIndex, animated: animated)
+ }
+ graph.verticalScalesRenderer.setVisible(isVisible, animated: animated)
+ if let firstIndex = firstIndex {
+ graph.verticalScalesRenderer.setHorizontalLinesVisible(index == firstIndex, animated: animated)
+ }
+ }
+
+ updateVerticalLimitsAndRange(horizontalRange: currentHorizontalRange, animated: true)
+
+ if isChartInteractionBegun {
+ chartInteractionDidBegin(point: lastChartInteractionPoint)
+ }
+ }
+
+ override func chartInteractionDidBegin(point: CGPoint) {
+ let horizontalRange = currentHorizontalRange
+ let chartFrame = self.chartFrame()
+ guard chartFrame.width > 0 else { return }
+
+ let dateToFind = Date(timeIntervalSince1970: TimeInterval(horizontalRange.distance * point.x + horizontalRange.lowerBound))
+ guard let (closestDate, minIndex) = findClosestDateTo(dateToFind: dateToFind) else { return }
+
+ let chartInteractionWasBegin = isChartInteractionBegun
+ super.chartInteractionDidBegin(point: point)
+
+ for graphController in graphControllers {
+ graphController.lineBulletsRenerer.bullets = graphController.chartLines.map { chart in
+ LineBulletsRenerer.Bullet(coordinate: chart.points[minIndex], color: chart.color)
+ }
+ graphController.lineBulletsRenerer.isEnabled = true
+ }
+
+ let chartValue: CGFloat = CGFloat(closestDate.timeIntervalSince1970)
+ let detailsViewPosition = (chartValue - horizontalRange.lowerBound) / horizontalRange.distance * chartFrame.width + chartFrame.minX
+ self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex), chartInteractionWasBegin)
+ self.setDetailsChartVisibleClosure?(true, true)
+ self.setDetailsViewPositionClosure?(detailsViewPosition)
+ self.verticalLineRenderer.values = [chartValue]
+ }
+
+ override var currentChartHorizontalRangeFraction: ClosedRange {
+ let lowerPercent = (currentHorizontalRange.lowerBound - totalHorizontalRange.lowerBound) / totalHorizontalRange.distance
+ let upperPercent = (currentHorizontalRange.upperBound - totalHorizontalRange.lowerBound) / totalHorizontalRange.distance
+ return lowerPercent...upperPercent
+ }
+
+ override var currentHorizontalRange: ClosedRange {
+ return graphControllers.first?.mainLinesRenderer.horizontalRange.end ?? Constants.defaultRange
+ }
+
+ override func cancelChartInteraction() {
+ super.cancelChartInteraction()
+ for graphController in graphControllers {
+ graphController.lineBulletsRenerer.isEnabled = false
+ }
+
+ self.setDetailsChartVisibleClosure?(false, true)
+ self.verticalLineRenderer.values = []
+ }
+
+ override func didTapZoomOut() {
+ cancelChartInteraction()
+ self.setupChartCollection(chartsCollection: initialChartCollection, animated: true, isZoomed: false)
+ }
+
+ override func updateChartRange(_ rangeFraction: ClosedRange) {
+ cancelChartInteraction()
+
+ let horizontalRange = ClosedRange(uncheckedBounds:
+ (lower: totalHorizontalRange.lowerBound + rangeFraction.lowerBound * totalHorizontalRange.distance,
+ upper: totalHorizontalRange.lowerBound + rangeFraction.upperBound * totalHorizontalRange.distance))
+
+ zoomedChartRange = horizontalRange
+ updateChartRangeTitle(animated: true)
+
+ updateMainChartHorizontalRange(range: horizontalRange, animated: false)
+ updateHorizontalLimists(horizontalRange: horizontalRange, animated: true)
+ updateVerticalLimitsAndRange(horizontalRange: horizontalRange, animated: true)
+ }
+
+ func updateMainChartHorizontalRange(range: ClosedRange, animated: Bool) {
+ for controller in graphControllers {
+ controller.mainLinesRenderer.setup(horizontalRange: range, animated: animated)
+ controller.verticalScalesRenderer.setup(horizontalRange: range, animated: animated)
+ controller.lineBulletsRenerer.setup(horizontalRange: range, animated: animated)
+ }
+ horizontalScalesRenderer.setup(horizontalRange: range, animated: animated)
+ verticalLineRenderer.setup(horizontalRange: range, animated: animated)
+ }
+
+ func updateHorizontalLimists(horizontalRange: ClosedRange, animated: Bool) {
+ if let (stride, labels) = horizontalLimitsLabels(horizontalRange: horizontalRange,
+ scaleType: isZoomed ? .hour : .day,
+ prevoiusHorizontalStrideInterval: prevoiusHorizontalStrideInterval) {
+ self.horizontalScalesRenderer.setup(labels: labels, animated: animated)
+ self.prevoiusHorizontalStrideInterval = stride
+ }
+ }
+
+ func updateVerticalLimitsAndRange(horizontalRange: ClosedRange, animated: Bool) {
+ let chartHeight = chartFrame().height
+ let approximateNumberOfChartValues = (chartHeight / BaseConstants.minimumAxisYLabelsDistance)
+
+ var dividorsAndMultiplers: [(startValue: CGFloat, base: CGFloat, count: Int, maximumNumberOfDecimals: Int)] = graphControllers.enumerated().map { arg in
+ let (index, controller) = arg
+ let verticalRange = LinesChartRenderer.LineData.verticalRange(lines: controller.chartLines,
+ calculatingRange: horizontalRange,
+ addBounds: true) ?? controller.totalVerticalRange
+
+ var numberOfOffsetsPerItem = verticalRange.distance / approximateNumberOfChartValues
+
+ var multiplier: CGFloat = 1.0
+ while numberOfOffsetsPerItem > 10 {
+ numberOfOffsetsPerItem /= 10
+ multiplier *= 10
+ }
+ var dividor: CGFloat = 1.0
+ var maximumNumberOfDecimals = 2
+ while numberOfOffsetsPerItem < 1 {
+ numberOfOffsetsPerItem *= 10
+ dividor *= 10
+ maximumNumberOfDecimals += 1
+ }
+
+ let generalBase = Constants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor
+ let base = generalBase * multiplier / dividor
+
+ var verticalValue = (verticalRange.lowerBound / base).rounded(.down) * base
+ let startValue = verticalValue
+ var count = 0
+ if chartVisibility[index] {
+ while verticalValue < verticalRange.upperBound {
+ count += 1
+ verticalValue += base
+ }
+ }
+ return (startValue: startValue, base: base, count: count, maximumNumberOfDecimals: maximumNumberOfDecimals)
+ }
+
+ let totalCount = dividorsAndMultiplers.map { $0.count }.max() ?? 0
+ guard totalCount > 0 else { return }
+
+ let numberFormatter = BaseConstants.chartNumberFormatter
+ for (index, controller) in graphControllers.enumerated() {
+
+ let (startValue, base, _, maximumNumberOfDecimals) = dividorsAndMultiplers[index]
+
+ let updatedRange = startValue...(startValue + base * CGFloat(totalCount))
+ if controller.verticalScalesRenderer.verticalRange.end != updatedRange {
+ numberFormatter.maximumFractionDigits = maximumNumberOfDecimals
+
+ var verticalLabels: [LinesChartLabel] = []
+ for multipler in 0...(totalCount - 1) {
+ let verticalValue = startValue + base * CGFloat(multipler)
+ let text: String = numberFormatter.string(from: NSNumber(value: Double(verticalValue))) ?? ""
+ verticalLabels.append(LinesChartLabel(value: verticalValue, text: text))
+ }
+
+ controller.verticalScalesRenderer.setup(verticalLimitsLabels: verticalLabels, animated: animated)
+ controller.updateMainChartVerticalRange(range: updatedRange, animated: animated)
+ }
+ }
+ }
+
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
+
+ for controller in graphControllers {
+ controller.verticalScalesRenderer.horizontalLinesColor = colorMode.chartHelperLinesColor
+ controller.lineBulletsRenerer.setInnerColor(colorMode.chartBackgroundColor, animated: animated)
+ controller.verticalScalesRenderer.axisXColor = colorMode.chartStrongLinesColor
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PercentChartComponentController.swift b/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PercentChartComponentController.swift
new file mode 100644
index 0000000000..d75ba09d91
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PercentChartComponentController.swift
@@ -0,0 +1,195 @@
+//
+// PercentChartComponentController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/14/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class PercentChartComponentController: GeneralChartComponentController {
+ let mainPecentChartRenderer: PecentChartRenderer
+ let horizontalScalesRenderer: HorizontalScalesRenderer
+ let verticalScalesRenderer: VerticalScalesRenderer
+ let verticalLineRenderer: VerticalLinesRenderer
+ let previewPercentChartRenderer: PecentChartRenderer
+ var percentageData: PecentChartRenderer.PercentageData = .blank
+
+ init(isZoomed: Bool,
+ mainPecentChartRenderer: PecentChartRenderer,
+ horizontalScalesRenderer: HorizontalScalesRenderer,
+ verticalScalesRenderer: VerticalScalesRenderer,
+ verticalLineRenderer: VerticalLinesRenderer,
+ previewPercentChartRenderer: PecentChartRenderer) {
+ self.mainPecentChartRenderer = mainPecentChartRenderer
+ self.horizontalScalesRenderer = horizontalScalesRenderer
+ self.verticalScalesRenderer = verticalScalesRenderer
+ self.verticalLineRenderer = verticalLineRenderer
+ self.previewPercentChartRenderer = previewPercentChartRenderer
+
+ super.init(isZoomed: isZoomed)
+ }
+
+ override func initialize(chartsCollection: ChartsCollection, initialDate: Date, totalHorizontalRange _: ClosedRange, totalVerticalRange _: ClosedRange) {
+ let components = chartsCollection.chartValues.map { PecentChartRenderer.PercentageData.Component(color: $0.color,
+ values: $0.values.map { CGFloat($0) }) }
+ self.percentageData = PecentChartRenderer.PercentageData(locations: chartsCollection.axisValues.map { CGFloat($0.timeIntervalSince1970) },
+ components: components)
+ let totalHorizontalRange = PecentChartRenderer.PercentageData.horizontalRange(data: self.percentageData) ?? BaseConstants.defaultRange
+ let totalVerticalRange = BaseConstants.defaultRange
+
+ super.initialize(chartsCollection: chartsCollection,
+ initialDate: initialDate,
+ totalHorizontalRange: totalHorizontalRange,
+ totalVerticalRange: totalVerticalRange)
+
+ mainPecentChartRenderer.percentageData = self.percentageData
+ previewPercentChartRenderer.percentageData = self.percentageData
+
+ let axisValues: [CGFloat] = [0, 25, 50, 75, 100]
+ let labels: [LinesChartLabel] = axisValues.map { value in
+ return LinesChartLabel(value: value / 100, text: BaseConstants.detailsNumberFormatter.string(from: NSNumber(value: Double(value))) ?? "")
+ }
+ verticalScalesRenderer.setup(verticalLimitsLabels: labels, animated: false)
+
+ setupMainChart(horizontalRange: initialHorizontalRange, animated: false)
+ setupMainChart(verticalRange: initialVerticalRange, animated: false)
+ previewPercentChartRenderer.setup(verticalRange: totalVerticalRange, animated: false)
+ previewPercentChartRenderer.setup(horizontalRange: totalHorizontalRange, animated: false)
+ updateHorizontalLimitLabels(animated: false)
+ }
+
+ override func willAppear(animated: Bool) {
+ previewPercentChartRenderer.setup(verticalRange: totalVerticalRange, animated: animated)
+ previewPercentChartRenderer.setup(horizontalRange: totalHorizontalRange, animated: animated)
+
+ setConponentsVisible(visible: true, animated: true)
+
+ setupMainChart(verticalRange: initialVerticalRange, animated: animated)
+ setupMainChart(horizontalRange: initialHorizontalRange, animated: animated)
+
+ updatePreviewRangeClosure?(currentChartHorizontalRangeFraction, animated)
+
+ super.willAppear(animated: animated)
+ }
+
+ override func chartRangeDidUpdated(_ updatedRange: ClosedRange) {
+ super.chartRangeDidUpdated(updatedRange)
+
+ initialHorizontalRange = updatedRange
+ setupMainChart(horizontalRange: updatedRange, animated: false)
+ updateHorizontalLimitLabels(animated: true)
+ }
+
+ func updateHorizontalLimitLabels(animated: Bool) {
+ updateHorizontalLimitLabels(horizontalScalesRenderer: horizontalScalesRenderer,
+ horizontalRange: initialHorizontalRange,
+ scaleType: isZoomed ? .hour : .day,
+ forceUpdate: false,
+ animated: animated)
+ }
+
+ func prepareAppearanceAnimation(horizontalRnage: ClosedRange) {
+ setupMainChart(horizontalRange: horizontalRnage, animated: false)
+ setConponentsVisible(visible: false, animated: false)
+ }
+
+ func setConponentsVisible(visible: Bool, animated: Bool) {
+ mainPecentChartRenderer.setVisible(visible, animated: animated)
+ horizontalScalesRenderer.setVisible(visible, animated: animated)
+ verticalScalesRenderer.setVisible(visible, animated: animated)
+ verticalLineRenderer.setVisible(visible, animated: animated)
+ previewPercentChartRenderer.setVisible(visible, animated: animated)
+ }
+
+ func setupMainChart(horizontalRange: ClosedRange, animated: Bool) {
+ mainPecentChartRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ horizontalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ verticalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ verticalLineRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ }
+
+ func setupMainChart(verticalRange: ClosedRange, animated: Bool) {
+ mainPecentChartRenderer.setup(verticalRange: verticalRange, animated: animated)
+ horizontalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
+ verticalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
+ verticalLineRenderer.setup(verticalRange: verticalRange, animated: animated)
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ super.updateChartsVisibility(visibility: visibility, animated: animated)
+ for (index, isVisible) in visibility.enumerated() {
+ mainPecentChartRenderer.setComponentVisible(isVisible, at: index, animated: animated)
+ previewPercentChartRenderer.setComponentVisible(isVisible, at: index, animated: animated)
+ }
+ verticalScalesRenderer.setVisible(visibility.contains(true), animated: animated)
+ }
+
+ override func chartDetailsViewModel(closestDate: Date, pointIndex: Int) -> ChartDetailsViewModel {
+ let visibleValues = visibleDetailsChartValues
+
+ let total = visibleValues.map { $0.values[pointIndex] }.reduce(0, +)
+
+ let values: [ChartDetailsViewModel.Value] = chartsCollection.chartValues.enumerated().map { arg in
+ let (index, component) = arg
+ return ChartDetailsViewModel.Value(prefix: PercentConstants.percentValueFormatter.string(from: component.values[pointIndex] / total * 100),
+ title: component.name,
+ value: BaseConstants.detailsNumberFormatter.string(from: component.values[pointIndex]),
+ color: component.color,
+ visible: chartVisibility[index])
+ }
+ let dateString: String
+ if isZoomed {
+ dateString = BaseConstants.timeDateFormatter.string(from: closestDate)
+ } else {
+ dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
+ }
+ let viewModel = ChartDetailsViewModel(title: dateString,
+ showArrow: !self.isZoomed,
+ showPrefixes: true,
+ values: values,
+ totalValue: nil,
+ tapAction: { [weak self] in
+ self?.hideDetailsView(animated: true)
+ self?.zoomInOnDateClosure?(closestDate) })
+ return viewModel
+ }
+
+ var currentlyVisiblePercentageData: PecentChartRenderer.PercentageData {
+ var currentPercentageData = percentageData
+ currentPercentageData.components = chartVisibility.enumerated().compactMap { $0.element ? currentPercentageData.components[$0.offset] : nil }
+ return currentPercentageData
+ }
+
+ override var currentMainRangeRenderer: BaseChartRenderer {
+ return mainPecentChartRenderer
+ }
+
+ override var currentPreviewRangeRenderer: BaseChartRenderer {
+ return previewPercentChartRenderer
+ }
+
+ override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) {
+ super.showDetailsView(at: chartPosition, detailsViewPosition: detailsViewPosition, dataIndex: dataIndex, date: date, animted: animted)
+ verticalLineRenderer.values = [chartPosition]
+ verticalLineRenderer.isEnabled = true
+ }
+
+ override func hideDetailsView(animated: Bool) {
+ super.hideDetailsView(animated: animated)
+
+ verticalLineRenderer.values = []
+ verticalLineRenderer.isEnabled = false
+ }
+
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ super.apply(colorMode: colorMode, animated: animated)
+
+ horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.axisXColor = colorMode.barChartStrongLinesColor
+ verticalScalesRenderer.horizontalLinesColor = colorMode.barChartStrongLinesColor
+ verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PercentPieChartController.swift b/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PercentPieChartController.swift
new file mode 100644
index 0000000000..484d8a2f11
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PercentPieChartController.swift
@@ -0,0 +1,281 @@
+//
+// PercentPieChartController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+enum PercentConstants {
+ static let percentValueFormatter: NumberFormatter = {
+ let formatter = NumberFormatter()
+ formatter.positiveSuffix = "%"
+ return formatter
+ }()
+}
+
+private enum Constants {
+ static let zoomedRange = 7
+}
+
+class PercentPieChartController: BaseChartController {
+ let percentController: PercentChartComponentController
+ let pieController: PieChartComponentController
+ let transitionRenderer: PercentPieAnimationRenderer
+
+ override init(chartsCollection: ChartsCollection) {
+ transitionRenderer = PercentPieAnimationRenderer()
+ percentController = PercentChartComponentController(isZoomed: false,
+ mainPecentChartRenderer: PecentChartRenderer(),
+ horizontalScalesRenderer: HorizontalScalesRenderer(),
+ verticalScalesRenderer: VerticalScalesRenderer(),
+ verticalLineRenderer: VerticalLinesRenderer(),
+ previewPercentChartRenderer: PecentChartRenderer())
+ pieController = PieChartComponentController(isZoomed: true,
+ pieChartRenderer: PieChartRenderer(),
+ previewBarChartRenderer: BarChartRenderer())
+
+ super.init(chartsCollection: chartsCollection)
+
+ [percentController, pieController].forEach { controller in
+ controller.chartFrame = { [unowned self] in self.chartFrame() }
+ controller.cartViewBounds = { [unowned self] in self.cartViewBounds() }
+ controller.zoomInOnDateClosure = { [unowned self] date in
+ self.didTapZoomIn(date: date)
+ }
+ controller.setChartTitleClosure = { [unowned self] (title, animated) in
+ self.setChartTitleClosure?(title, animated)
+ }
+ controller.setDetailsViewPositionClosure = { [unowned self] (position) in
+ self.setDetailsViewPositionClosure?(position)
+ }
+ controller.setDetailsChartVisibleClosure = { [unowned self] (visible, animated) in
+ self.setDetailsChartVisibleClosure?(visible, animated)
+ }
+ controller.setDetailsViewModel = { [unowned self] (viewModel, animated) in
+ self.setDetailsViewModel?(viewModel, animated)
+ }
+ controller.updatePreviewRangeClosure = { [unowned self] (fraction, animated) in
+ self.chartRangeUpdatedClosure?(fraction, animated)
+ }
+ controller.chartRangePagingClosure = { [unowned self] (isEnabled, pageSize) in
+ self.setChartRangePagingEnabled(isEnabled: isEnabled, minimumSelectionSize: pageSize)
+ }
+ }
+ transitionRenderer.isEnabled = false
+ }
+
+ override var mainChartRenderers: [ChartViewRenderer] {
+ return [percentController.mainPecentChartRenderer,
+ transitionRenderer,
+ percentController.horizontalScalesRenderer,
+ percentController.verticalScalesRenderer,
+ percentController.verticalLineRenderer,
+ pieController.pieChartRenderer,
+// performanceRenderer
+ ]
+ }
+
+ override var navigationRenderers: [ChartViewRenderer] {
+ return [percentController.previewPercentChartRenderer,
+ pieController.previewBarChartRenderer]
+ }
+
+ override func initializeChart() {
+ percentController.initialize(chartsCollection: initialChartsCollection,
+ initialDate: Date(),
+ totalHorizontalRange: BaseConstants.defaultRange,
+ totalVerticalRange: BaseConstants.defaultRange)
+ switchToChart(chartsCollection: percentController.chartsCollection, isZoomed: false, animated: false)
+ }
+
+ func switchToChart(chartsCollection: ChartsCollection, isZoomed: Bool, animated: Bool) {
+ if animated {
+ TimeInterval.setDefaultSuration(.expandAnimationDuration)
+ DispatchQueue.main.asyncAfter(deadline: .now() + .expandAnimationDuration) {
+ TimeInterval.setDefaultSuration(.osXDuration)
+ }
+ }
+
+ super.isZoomed = isZoomed
+ if isZoomed {
+ let toHorizontalRange = pieController.initialHorizontalRange
+
+ pieController.updateChartsVisibility(visibility: percentController.chartVisibility, animated: false)
+ pieController.pieChartRenderer.setup(horizontalRange: percentController.currentHorizontalMainChartRange, animated: false)
+ pieController.previewBarChartRenderer.setup(horizontalRange: percentController.currentPreviewHorizontalRange, animated: false)
+ pieController.pieChartRenderer.setVisible(false, animated: false)
+ pieController.previewBarChartRenderer.setVisible(true, animated: false)
+
+ pieController.willAppear(animated: animated)
+ percentController.willDisappear(animated: animated)
+
+ pieController.pieChartRenderer.drawPie = false
+ percentController.mainPecentChartRenderer.isEnabled = false
+
+ setupTransitionRenderer()
+
+ percentController.setupMainChart(horizontalRange: toHorizontalRange, animated: animated)
+ percentController.previewPercentChartRenderer.setup(horizontalRange: toHorizontalRange, animated: animated)
+ percentController.setConponentsVisible(visible: false, animated: animated)
+
+ transitionRenderer.animate(fromDataToPie: true, animated: animated) { [weak self] in
+ self?.pieController.pieChartRenderer.drawPie = true
+ self?.percentController.mainPecentChartRenderer.isEnabled = true
+ }
+ } else {
+ if !pieController.chartsCollection.isBlank {
+ let fromHorizontalRange = pieController.currentHorizontalMainChartRange
+ let toHorizontalRange = percentController.initialHorizontalRange
+
+ pieController.pieChartRenderer.setup(horizontalRange: toHorizontalRange, animated: animated)
+ pieController.previewBarChartRenderer.setup(horizontalRange: toHorizontalRange, animated: animated)
+ pieController.pieChartRenderer.setVisible(false, animated: animated)
+ pieController.previewBarChartRenderer.setVisible(false, animated: animated)
+
+ percentController.updateChartsVisibility(visibility: pieController.chartVisibility, animated: false)
+ percentController.setupMainChart(horizontalRange: fromHorizontalRange, animated: false)
+ percentController.previewPercentChartRenderer.setup(horizontalRange: fromHorizontalRange, animated: false)
+ percentController.setConponentsVisible(visible: false, animated: false)
+ }
+
+ percentController.willAppear(animated: animated)
+ pieController.willDisappear(animated: animated)
+
+ if animated {
+ pieController.pieChartRenderer.drawPie = false
+ percentController.mainPecentChartRenderer.isEnabled = false
+
+ setupTransitionRenderer()
+
+ transitionRenderer.animate(fromDataToPie: false, animated: true) {
+ self.pieController.pieChartRenderer.drawPie = true
+ self.percentController.mainPecentChartRenderer.isEnabled = true
+ }
+ }
+ }
+
+ self.setBackButtonVisibilityClosure?(isZoomed, animated)
+ }
+
+ func setupTransitionRenderer() {
+ transitionRenderer.setup(verticalRange: percentController.currentVerticalMainChartRange, animated: false)
+ transitionRenderer.setup(horizontalRange: percentController.currentHorizontalMainChartRange, animated: false)
+ transitionRenderer.visiblePieComponents = pieController.visiblePieDataWithCurrentPreviewRange
+ transitionRenderer.visiblePercentageData = percentController.currentlyVisiblePercentageData
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ if isZoomed {
+ pieController.updateChartsVisibility(visibility: visibility, animated: animated)
+ } else {
+ percentController.updateChartsVisibility(visibility: visibility, animated: animated)
+ }
+ }
+
+ var visibleChartValues: [ChartsCollection.Chart] {
+ let visibility = isZoomed ? pieController.chartVisibility : percentController.chartVisibility
+ let collection = isZoomed ? pieController.chartsCollection : percentController.chartsCollection
+ let visibleCharts: [ChartsCollection.Chart] = visibility.enumerated().compactMap { args in
+ args.element ? collection.chartValues[args.offset] : nil
+ }
+ return visibleCharts
+ }
+
+ override var actualChartVisibility: [Bool] {
+ return isZoomed ? pieController.chartVisibility : percentController.chartVisibility
+ }
+
+ override var actualChartsCollection: ChartsCollection {
+ return isZoomed ? pieController.chartsCollection : percentController.chartsCollection
+ }
+
+ override func chartInteractionDidBegin(point: CGPoint) {
+ if isZoomed {
+ pieController.chartInteractionDidBegin(point: point)
+ } else {
+ percentController.chartInteractionDidBegin(point: point)
+ }
+ }
+
+ override func chartInteractionDidEnd() {
+ if isZoomed {
+ pieController.chartInteractionDidEnd()
+ } else {
+ percentController.chartInteractionDidEnd()
+ }
+ }
+
+ override var drawChartVisibity: Bool {
+ return true
+ }
+
+ override var currentChartHorizontalRangeFraction: ClosedRange {
+ if isZoomed {
+ return pieController.currentChartHorizontalRangeFraction
+ } else {
+ return percentController.currentChartHorizontalRangeFraction
+ }
+ }
+
+ override func cancelChartInteraction() {
+ if isZoomed {
+ return pieController.hideDetailsView(animated: true)
+ } else {
+ return percentController.hideDetailsView(animated: true)
+ }
+ }
+
+ override func didTapZoomIn(date: Date) {
+ guard isZoomed == false else { return }
+ cancelChartInteraction()
+ let currentCollection = percentController.chartsCollection
+ let range: Int = Constants.zoomedRange
+ guard let (foundDate, index) = percentController.findClosestDateTo(dateToFind: date) else { return }
+ var lowIndex = max(0, index - range / 2)
+ var highIndex = min(currentCollection.axisValues.count - 1, index + range / 2)
+ if lowIndex == 0 {
+ highIndex = lowIndex + (range - 1)
+ } else if highIndex == currentCollection.axisValues.count - 1 {
+ lowIndex = highIndex - (range - 1)
+ }
+
+ let newValues = currentCollection.chartValues.map { chart in
+ return ChartsCollection.Chart(color: chart.color,
+ name: chart.name,
+ values: Array(chart.values[(lowIndex...highIndex)]))
+ }
+ let newCollection = ChartsCollection(axisValues: Array(currentCollection.axisValues[(lowIndex...highIndex)]),
+ chartValues: newValues)
+ let selectedRange = CGFloat(foundDate.timeIntervalSince1970 - .day)...CGFloat(foundDate.timeIntervalSince1970)
+ pieController.initialize(chartsCollection: newCollection, initialDate: date, totalHorizontalRange: 0...1, totalVerticalRange: 0...1)
+ pieController.initialHorizontalRange = selectedRange
+
+ switchToChart(chartsCollection: newCollection, isZoomed: true, animated: true)
+ }
+
+ override func didTapZoomOut() {
+ self.pieController.deselectSegment(completion: { [weak self] in
+ guard let self = self else { return }
+ self.switchToChart(chartsCollection: self.percentController.chartsCollection, isZoomed: false, animated: true)
+ })
+ }
+
+ override func updateChartRange(_ rangeFraction: ClosedRange) {
+ if isZoomed {
+ return pieController.chartRangeFractionDidUpdated(rangeFraction)
+ } else {
+ return percentController.chartRangeFractionDidUpdated(rangeFraction)
+ }
+ }
+
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ super.apply(colorMode: colorMode, animated: animated)
+
+ pieController.apply(colorMode: colorMode, animated: animated)
+ percentController.apply(colorMode: colorMode, animated: animated)
+ transitionRenderer.backgroundColor = colorMode.chartBackgroundColor
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PieChartComponentController.swift b/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PieChartComponentController.swift
new file mode 100644
index 0000000000..68c3541912
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Percent And Pie/PieChartComponentController.swift
@@ -0,0 +1,198 @@
+//
+// PieChartComponentController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/14/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class PieChartComponentController: GeneralChartComponentController {
+ let pieChartRenderer: PieChartRenderer
+ let previewBarChartRenderer: BarChartRenderer
+ var barWidth: CGFloat = 1
+
+ var chartBars: BarChartRenderer.BarsData = .blank
+
+ init(isZoomed: Bool,
+ pieChartRenderer: PieChartRenderer,
+ previewBarChartRenderer: BarChartRenderer) {
+ self.pieChartRenderer = pieChartRenderer
+ self.previewBarChartRenderer = previewBarChartRenderer
+ super.init(isZoomed: isZoomed)
+ }
+
+ override func initialize(chartsCollection: ChartsCollection, initialDate: Date, totalHorizontalRange _: ClosedRange, totalVerticalRange _: ClosedRange) {
+ let (width, chartBars, totalHorizontalRange, _) = BarChartRenderer.BarsData.initialComponents(chartsCollection: chartsCollection)
+ self.barWidth = width
+ self.chartBars = chartBars
+ super.initialize(chartsCollection: chartsCollection,
+ initialDate: initialDate,
+ totalHorizontalRange: totalHorizontalRange,
+ totalVerticalRange: BaseConstants.defaultRange)
+
+ self.previewBarChartRenderer.bars = chartBars
+ self.previewBarChartRenderer.fillToTop = true
+
+ pieChartRenderer.valuesFormatter = PercentConstants.percentValueFormatter
+ pieChartRenderer.setup(horizontalRange: initialHorizontalRange, animated: false)
+ previewBarChartRenderer.setup(verticalRange: initialVerticalRange, animated: false)
+ previewBarChartRenderer.setup(horizontalRange: initialHorizontalRange, animated: false)
+
+ pieChartRenderer.updatePercentageData(pieDataWithCurrentPreviewRange, animated: false)
+ pieChartRenderer.selectSegmentAt(at: nil, animated: false)
+ }
+
+ private var pieDataWithCurrentPreviewRange: [PieChartRenderer.PieComponent] {
+ let range = currentHorizontalMainChartRange
+ var pieComponents = chartsCollection.chartValues.map { PieChartRenderer.PieComponent(color: $0.color,
+ value: 0) }
+ guard var valueIndex = chartsCollection.axisValues.firstIndex(where: { CGFloat($0.timeIntervalSince1970) > (range.lowerBound + 1)}) else {
+ return pieComponents
+ }
+ var count = 0
+ while valueIndex < chartsCollection.axisValues.count, CGFloat(chartsCollection.axisValues[valueIndex].timeIntervalSince1970) <= range.upperBound {
+ count += 1
+ for pieIndex in pieComponents.indices {
+ pieComponents[pieIndex].value += CGFloat(chartsCollection.chartValues[pieIndex].values[valueIndex])
+ }
+ valueIndex += 1
+ }
+ return pieComponents
+ }
+
+ var visiblePieDataWithCurrentPreviewRange: [PieChartRenderer.PieComponent] {
+ let currentData = pieDataWithCurrentPreviewRange
+ return chartVisibility.enumerated().compactMap { $0.element ? currentData[$0.offset] : nil }
+ }
+
+ override func willAppear(animated: Bool) {
+ pieChartRenderer.setup(horizontalRange: initialHorizontalRange, animated: animated)
+ pieChartRenderer.setVisible(true, animated: animated)
+
+ previewBarChartRenderer.setup(verticalRange: totalVerticalRange, animated: animated)
+ previewBarChartRenderer.setup(horizontalRange: totalHorizontalRange, animated: animated)
+ previewBarChartRenderer.setVisible(true, animated: animated)
+
+ updatePreviewRangeClosure?(currentChartHorizontalRangeFraction, animated)
+ pieChartRenderer.updatePercentageData(pieDataWithCurrentPreviewRange, animated: false)
+
+ super.willAppear(animated: animated)
+ }
+
+ override func setupChartRangePaging() {
+ let valuesCount = chartsCollection.axisValues.count
+ guard valuesCount > 0 else { return }
+ chartRangePagingClosure?(true, 1.0 / CGFloat(valuesCount))
+ }
+
+ override func chartRangeDidUpdated(_ updatedRange: ClosedRange) {
+ if isChartInteractionBegun {
+ chartInteractionDidBegin(point: lastChartInteractionPoint)
+ }
+ initialHorizontalRange = updatedRange
+
+ setupMainChart(horizontalRange: updatedRange, animated: true)
+ updateSelectedDataLabelIfNeeded()
+ }
+
+ func setupMainChart(horizontalRange: ClosedRange, animated: Bool) {
+ pieChartRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ pieChartRenderer.updatePercentageData(pieDataWithCurrentPreviewRange, animated: animated)
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ super.updateChartsVisibility(visibility: visibility, animated: animated)
+ for (index, isVisible) in visibility.enumerated() {
+ pieChartRenderer.setComponentVisible(isVisible, at: index, animated: animated)
+ previewBarChartRenderer.setComponentVisible(isVisible, at: index, animated: animated)
+ }
+ if let segment = pieChartRenderer.selectedSegment {
+ if !visibility[segment] {
+ pieChartRenderer.selectSegmentAt(at: nil, animated: true)
+ }
+ }
+ updateSelectedDataLabelIfNeeded()
+ }
+
+ func deselectSegment(completion: @escaping () -> Void) {
+ if pieChartRenderer.hasSelectedSegments {
+ hideDetailsView(animated: true)
+ pieChartRenderer.selectSegmentAt(at: nil, animated: true)
+ DispatchQueue.main.asyncAfter(deadline: .now() + .defaultDuration / 2) {
+ completion()
+ }
+ } else {
+ completion()
+ }
+ }
+
+ func updateSelectedDataLabelIfNeeded() {
+ if let segment = pieChartRenderer.selectedSegment {
+ self.setDetailsChartVisibleClosure?(true, true)
+ self.setDetailsViewModel?(chartDetailsViewModel(segmentInde: segment), false)
+ self.setDetailsViewPositionClosure?(chartFrame().width / 4)
+ } else {
+ self.setDetailsChartVisibleClosure?(false, true)
+ }
+ }
+
+ func chartDetailsViewModel(segmentInde: Int) -> ChartDetailsViewModel {
+ let pieItem = pieDataWithCurrentPreviewRange[segmentInde]
+ let title = chartsCollection.chartValues[segmentInde].name
+ let valueString = BaseConstants.detailsNumberFormatter.string(from: pieItem.value)
+ let viewModel = ChartDetailsViewModel(title: "",
+ showArrow: false,
+ showPrefixes: false,
+ values: [ChartDetailsViewModel.Value(prefix: nil,
+ title: title,
+ value: valueString,
+ color: pieItem.color,
+ visible: true)],
+ totalValue: nil,
+ tapAction: nil)
+ return viewModel
+ }
+
+ override var currentMainRangeRenderer: BaseChartRenderer {
+ return pieChartRenderer
+ }
+
+ override var currentPreviewRangeRenderer: BaseChartRenderer {
+ return previewBarChartRenderer
+ }
+
+ var lastInteractionPoint: CGPoint = .zero
+ override func chartInteractionDidBegin(point: CGPoint) {
+ lastInteractionPoint = point
+ }
+
+ override func chartInteractionDidEnd() {
+ if let segment = pieChartRenderer.selectedItemIndex(at: lastInteractionPoint) {
+ if pieChartRenderer.selectedSegment == segment {
+ pieChartRenderer.selectSegmentAt(at: nil, animated: true)
+ } else {
+ pieChartRenderer.selectSegmentAt(at: segment, animated: true)
+ }
+ updateSelectedDataLabelIfNeeded()
+ }
+ }
+
+ override func hideDetailsView(animated: Bool) {
+ pieChartRenderer.selectSegmentAt(at: nil, animated: animated)
+ updateSelectedDataLabelIfNeeded()
+ }
+
+ override func updateChartRangeTitle(animated: Bool) {
+ let fromDate = Date(timeIntervalSince1970: TimeInterval(currentHorizontalMainChartRange.lowerBound) + .day + 1)
+ let toDate = Date(timeIntervalSince1970: TimeInterval(currentHorizontalMainChartRange.upperBound))
+ if Calendar.utc.startOfDay(for: fromDate) == Calendar.utc.startOfDay(for: toDate) {
+ let stirng = BaseConstants.headerFullZoomedFormatter.string(from: fromDate)
+ self.setChartTitleClosure?(stirng, animated)
+ } else {
+ let stirng = "\(BaseConstants.headerMediumRangeFormatter.string(from: fromDate)) - \(BaseConstants.headerMediumRangeFormatter.string(from: toDate))"
+ self.setChartTitleClosure?(stirng, animated)
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift
new file mode 100644
index 0000000000..2e1894465b
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift
@@ -0,0 +1,226 @@
+//
+// BarsComponentController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/14/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class BarsComponentController: GeneralChartComponentController {
+ let mainBarsRenderer: BarChartRenderer
+ let horizontalScalesRenderer: HorizontalScalesRenderer
+ let verticalScalesRenderer: VerticalScalesRenderer
+
+ let previewBarsChartRenderer: BarChartRenderer
+ private(set) var barsWidth: CGFloat = 1
+
+ private (set) var chartBars: BarChartRenderer.BarsData = .blank
+
+ init(isZoomed: Bool,
+ mainBarsRenderer: BarChartRenderer,
+ horizontalScalesRenderer: HorizontalScalesRenderer,
+ verticalScalesRenderer: VerticalScalesRenderer,
+ previewBarsChartRenderer: BarChartRenderer) {
+ self.mainBarsRenderer = mainBarsRenderer
+ self.horizontalScalesRenderer = horizontalScalesRenderer
+ self.verticalScalesRenderer = verticalScalesRenderer
+ self.previewBarsChartRenderer = previewBarsChartRenderer
+
+ self.mainBarsRenderer.optimizationLevel = BaseConstants.barsChartOptimizationLevel
+ self.previewBarsChartRenderer.optimizationLevel = BaseConstants.barsChartOptimizationLevel
+
+ super.init(isZoomed: isZoomed)
+ }
+
+ override func initialize(chartsCollection: ChartsCollection, initialDate: Date, totalHorizontalRange _: ClosedRange, totalVerticalRange _: ClosedRange) {
+ let (width, chartBars, totalHorizontalRange, totalVerticalRange) = BarChartRenderer.BarsData.initialComponents(chartsCollection: chartsCollection)
+ self.chartBars = chartBars
+ self.barsWidth = width
+
+ super.initialize(chartsCollection: chartsCollection,
+ initialDate: initialDate,
+ totalHorizontalRange: totalHorizontalRange,
+ totalVerticalRange: totalVerticalRange)
+ }
+
+ override func setupInitialChartRange(initialDate: Date) {
+ guard let first = chartsCollection.axisValues.first?.timeIntervalSince1970,
+ let last = chartsCollection.axisValues.last?.timeIntervalSince1970 else { return }
+
+ let rangeStart = CGFloat(first)
+ let rangeEnd = CGFloat(last)
+
+ if isZoomed {
+ let initalDate = CGFloat(initialDate.timeIntervalSince1970)
+
+ initialHorizontalRange = max(initalDate - barsWidth, rangeStart)...min(initalDate + GeneralChartComponentConstants.defaultZoomedRangeLength - barsWidth, rangeEnd)
+ initialVerticalRange = totalVerticalRange
+ } else {
+ super.setupInitialChartRange(initialDate: initialDate)
+ }
+ }
+
+
+ override func willAppear(animated: Bool) {
+ mainBarsRenderer.bars = self.chartBars
+ previewBarsChartRenderer.bars = self.chartBars
+
+ previewBarsChartRenderer.setup(verticalRange: totalVerticalRange, animated: animated)
+ previewBarsChartRenderer.setup(horizontalRange: totalHorizontalRange, animated: animated)
+
+ setupMainChart(verticalRange: initialVerticalRange, animated: animated)
+ setupMainChart(horizontalRange: initialHorizontalRange, animated: animated)
+
+ updateChartVerticalRanges(horizontalRange: initialHorizontalRange, animated: animated)
+
+ super.willAppear(animated: animated)
+
+ updatePreviewRangeClosure?(currentChartHorizontalRangeFraction, animated)
+ setConponentsVisible(visible: true, animated: animated)
+ updateHorizontalLimitLabels(animated: animated, forceUpdate: true)
+ }
+
+ override func chartRangeDidUpdated(_ updatedRange: ClosedRange) {
+ super.chartRangeDidUpdated(updatedRange)
+ if !isZoomed {
+ initialHorizontalRange = updatedRange
+ }
+ setupMainChart(horizontalRange: updatedRange, animated: false)
+ updateHorizontalLimitLabels(animated: true, forceUpdate: false)
+ updateChartVerticalRanges(horizontalRange: updatedRange, animated: true)
+ }
+
+ func updateHorizontalLimitLabels(animated: Bool, forceUpdate: Bool) {
+ updateHorizontalLimitLabels(horizontalScalesRenderer: horizontalScalesRenderer,
+ horizontalRange: currentHorizontalMainChartRange,
+ scaleType: isZoomed ? .hour : .day,
+ forceUpdate: forceUpdate,
+ animated: animated)
+ }
+
+ func prepareAppearanceAnimation(horizontalRnage: ClosedRange) {
+ setupMainChart(horizontalRange: horizontalRnage, animated: false)
+ setConponentsVisible(visible: false, animated: false)
+ }
+
+ func setConponentsVisible(visible: Bool, animated: Bool) {
+ mainBarsRenderer.setVisible(visible, animated: animated)
+ horizontalScalesRenderer.setVisible(visible, animated: animated)
+ verticalScalesRenderer.setVisible(visible, animated: animated)
+ previewBarsChartRenderer.setVisible(visible, animated: animated)
+ }
+
+ func setupMainChart(horizontalRange: ClosedRange, animated: Bool) {
+ mainBarsRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ horizontalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ verticalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ }
+
+ var visibleBars: BarChartRenderer.BarsData {
+ let visibleComponents: [BarChartRenderer.BarsData.Component] = chartVisibility.enumerated().compactMap { args in
+ args.element ? chartBars.components[args.offset] : nil
+ }
+ return BarChartRenderer.BarsData(barWidth: chartBars.barWidth,
+ locations: chartBars.locations,
+ components: visibleComponents)
+ }
+
+ func updateChartVerticalRanges(horizontalRange: ClosedRange, animated: Bool) {
+ if let range = BarChartRenderer.BarsData.verticalRange(bars: visibleBars,
+ calculatingRange: horizontalRange,
+ addBounds: true) {
+ let (range, labels) = verticalLimitsLabels(verticalRange: range)
+ if verticalScalesRenderer.verticalRange.end != range {
+ verticalScalesRenderer.setup(verticalLimitsLabels: labels, animated: animated)
+ }
+ verticalScalesRenderer.setVisible(true, animated: animated)
+
+ setupMainChart(verticalRange: range, animated: animated)
+ } else {
+ verticalScalesRenderer.setVisible(false, animated: animated)
+ }
+
+ if let range = BarChartRenderer.BarsData.verticalRange(bars: visibleBars) {
+ previewBarsChartRenderer.setup(verticalRange: range, animated: animated)
+ }
+ }
+
+ func setupMainChart(verticalRange: ClosedRange, animated: Bool) {
+ mainBarsRenderer.setup(verticalRange: verticalRange, animated: animated)
+ horizontalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
+ verticalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ super.updateChartsVisibility(visibility: visibility, animated: animated)
+ for (index, isVisible) in visibility.enumerated() {
+ mainBarsRenderer.setComponentVisible(isVisible, at: index, animated: animated)
+ previewBarsChartRenderer.setComponentVisible(isVisible, at: index, animated: animated)
+ }
+ updateChartVerticalRanges(horizontalRange: currentHorizontalMainChartRange, animated: true)
+ }
+
+ var visibleChartValues: [ChartsCollection.Chart] {
+ let visibleCharts: [ChartsCollection.Chart] = chartVisibility.enumerated().compactMap { args in
+ args.element ? chartsCollection.chartValues[args.offset] : nil
+ }
+ return visibleCharts
+ }
+
+ override func chartDetailsViewModel(closestDate: Date, pointIndex: Int) -> ChartDetailsViewModel {
+ var viewModel = super.chartDetailsViewModel(closestDate: closestDate, pointIndex: pointIndex)
+ let visibleChartValues = self.visibleChartValues
+ let totalSumm: CGFloat = visibleChartValues.map { CGFloat($0.values[pointIndex]) }.reduce(0, +)
+
+ viewModel.totalValue = ChartDetailsViewModel.Value(prefix: nil,
+ title: "Total",
+ value: BaseConstants.detailsNumberFormatter.string(from: totalSumm),
+ color: .white,
+ visible: visibleChartValues.count > 1)
+ return viewModel
+ }
+
+ override var currentMainRangeRenderer: BaseChartRenderer {
+ return mainBarsRenderer
+ }
+
+ override var currentPreviewRangeRenderer: BaseChartRenderer {
+ return previewBarsChartRenderer
+ }
+
+ override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) {
+ let rangeWithOffset = detailsViewPosition - barsWidth / currentHorizontalMainChartRange.distance * chartFrame().width / 2
+ super.showDetailsView(at: chartPosition, detailsViewPosition: rangeWithOffset, dataIndex: dataIndex, date: date, animted: animted)
+ mainBarsRenderer.setSelectedIndex(dataIndex, animated: true)
+ }
+
+ override func hideDetailsView(animated: Bool) {
+ super.hideDetailsView(animated: animated)
+
+ mainBarsRenderer.setSelectedIndex(nil, animated: animated)
+ }
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ super.apply(colorMode: colorMode, animated: animated)
+
+ horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.axisXColor = colorMode.barChartStrongLinesColor
+ verticalScalesRenderer.horizontalLinesColor = colorMode.barChartStrongLinesColor
+ mainBarsRenderer.update(backgroundColor: colorMode.chartBackgroundColor, animated: false)
+ previewBarsChartRenderer.update(backgroundColor: colorMode.chartBackgroundColor, animated: false)
+ }
+
+ override func updateChartRangeTitle(animated: Bool) {
+ let fromDate = Date(timeIntervalSince1970: TimeInterval(currentHorizontalMainChartRange.lowerBound + barsWidth))
+ let toDate = Date(timeIntervalSince1970: TimeInterval(currentHorizontalMainChartRange.upperBound))
+ if Calendar.utc.startOfDay(for: fromDate) == Calendar.utc.startOfDay(for: toDate) {
+ let stirng = BaseConstants.headerFullZoomedFormatter.string(from: fromDate)
+ self.setChartTitleClosure?(stirng, animated)
+ } else {
+ let stirng = "\(BaseConstants.headerMediumRangeFormatter.string(from: fromDate)) - \(BaseConstants.headerMediumRangeFormatter.string(from: toDate))"
+ self.setChartTitleClosure?(stirng, animated)
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/DailyBarsChartController.swift b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/DailyBarsChartController.swift
new file mode 100644
index 0000000000..ae83803bb1
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/DailyBarsChartController.swift
@@ -0,0 +1,249 @@
+//
+// DailyBarsChartController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class DailyBarsChartController: BaseChartController {
+ let barsController: BarsComponentController
+ let linesController: LinesComponentController
+
+ override init(chartsCollection: ChartsCollection) {
+ let horizontalScalesRenderer = HorizontalScalesRenderer()
+ let verticalScalesRenderer = VerticalScalesRenderer()
+ barsController = BarsComponentController(isZoomed: false,
+ mainBarsRenderer: BarChartRenderer(),
+ horizontalScalesRenderer: horizontalScalesRenderer,
+ verticalScalesRenderer: verticalScalesRenderer,
+ previewBarsChartRenderer: BarChartRenderer())
+ linesController = LinesComponentController(isZoomed: true,
+ userLinesTransitionAnimation: false,
+ mainLinesRenderer: LinesChartRenderer(),
+ horizontalScalesRenderer: horizontalScalesRenderer,
+ verticalScalesRenderer: verticalScalesRenderer,
+ verticalLineRenderer: VerticalLinesRenderer(),
+ lineBulletsRenerer: LineBulletsRenerer(),
+ previewLinesChartRenderer: LinesChartRenderer())
+
+ super.init(chartsCollection: chartsCollection)
+
+ [barsController, linesController].forEach { controller in
+ controller.chartFrame = { [unowned self] in self.chartFrame() }
+ controller.cartViewBounds = { [unowned self] in self.cartViewBounds() }
+ controller.zoomInOnDateClosure = { [unowned self] date in
+ self.didTapZoomIn(date: date)
+ }
+ controller.setChartTitleClosure = { [unowned self] (title, animated) in
+ self.setChartTitleClosure?(title, animated)
+ }
+ controller.setDetailsViewPositionClosure = { [unowned self] (position) in
+ self.setDetailsViewPositionClosure?(position)
+ }
+ controller.setDetailsChartVisibleClosure = { [unowned self] (visible, animated) in
+ self.setDetailsChartVisibleClosure?(visible, animated)
+ }
+ controller.setDetailsViewModel = { [unowned self] (viewModel, animated) in
+ self.setDetailsViewModel?(viewModel, animated)
+ }
+ controller.updatePreviewRangeClosure = { [unowned self] (fraction, animated) in
+ self.chartRangeUpdatedClosure?(fraction, animated)
+ }
+ controller.chartRangePagingClosure = { [unowned self] (isEnabled, pageSize) in
+ self.setChartRangePagingEnabled(isEnabled: isEnabled, minimumSelectionSize: pageSize)
+ }
+ }
+ }
+
+ override var mainChartRenderers: [ChartViewRenderer] {
+ return [barsController.mainBarsRenderer,
+ linesController.mainLinesRenderer,
+ barsController.horizontalScalesRenderer,
+ barsController.verticalScalesRenderer,
+ linesController.verticalLineRenderer,
+ linesController.lineBulletsRenerer,
+// performanceRenderer
+ ]
+ }
+
+ override var navigationRenderers: [ChartViewRenderer] {
+ return [barsController.previewBarsChartRenderer,
+ linesController.previewLinesChartRenderer]
+ }
+
+ override func initializeChart() {
+ barsController.initialize(chartsCollection: initialChartsCollection,
+ initialDate: Date(),
+ totalHorizontalRange: BaseConstants.defaultRange,
+ totalVerticalRange: BaseConstants.defaultRange)
+ switchToChart(chartsCollection: barsController.chartsCollection, isZoomed: false, animated: false)
+ }
+
+ func switchToChart(chartsCollection: ChartsCollection, isZoomed: Bool, animated: Bool) {
+ if animated {
+ TimeInterval.setDefaultSuration(.expandAnimationDuration)
+ DispatchQueue.main.asyncAfter(deadline: .now() + .expandAnimationDuration) {
+ TimeInterval.setDefaultSuration(.osXDuration)
+ }
+ }
+
+ super.isZoomed = isZoomed
+ if isZoomed {
+ let toHorizontalRange = linesController.initialHorizontalRange
+ let destinationHorizontalRange = (toHorizontalRange.lowerBound - barsController.barsWidth)...(toHorizontalRange.upperBound - barsController.barsWidth)
+ let initialChartVerticalRange = lineProportionAnimationRange()
+
+ linesController.mainLinesRenderer.setup(horizontalRange: barsController.currentHorizontalMainChartRange, animated: false)
+ linesController.previewLinesChartRenderer.setup(horizontalRange: barsController.currentPreviewHorizontalRange, animated: false)
+ linesController.mainLinesRenderer.setup(verticalRange: initialChartVerticalRange, animated: false)
+ linesController.previewLinesChartRenderer.setup(verticalRange: initialChartVerticalRange, animated: false)
+ linesController.mainLinesRenderer.setVisible(false, animated: false)
+ linesController.previewLinesChartRenderer.setVisible(false, animated: false)
+
+ barsController.setupMainChart(horizontalRange: destinationHorizontalRange, animated: animated)
+ barsController.previewBarsChartRenderer.setup(horizontalRange: linesController.totalHorizontalRange, animated: animated)
+ barsController.mainBarsRenderer.setVisible(false, animated: animated)
+ barsController.previewBarsChartRenderer.setVisible(false, animated: animated)
+
+ linesController.willAppear(animated: animated)
+ barsController.willDisappear(animated: animated)
+
+ linesController.updateChartsVisibility(visibility: linesController.chartLines.map { _ in true }, animated: false)
+ } else {
+ if !linesController.chartsCollection.isBlank {
+ barsController.hideDetailsView(animated: false)
+ let visibleVerticalRange = BarChartRenderer.BarsData.verticalRange(bars: barsController.visibleBars,
+ calculatingRange: barsController.initialHorizontalRange) ?? BaseConstants.defaultRange
+ barsController.mainBarsRenderer.setup(verticalRange: visibleVerticalRange, animated: false)
+
+ let toHorizontalRange = barsController.initialHorizontalRange
+ let destinationChartVerticalRange = lineProportionAnimationRange()
+
+ linesController.setupMainChart(horizontalRange: toHorizontalRange, animated: animated)
+ linesController.mainLinesRenderer.setup(verticalRange: destinationChartVerticalRange, animated: animated)
+ linesController.previewLinesChartRenderer.setup(verticalRange: destinationChartVerticalRange, animated: animated)
+ linesController.previewLinesChartRenderer.setup(horizontalRange: barsController.totalHorizontalRange, animated: animated)
+ linesController.mainLinesRenderer.setVisible(false, animated: animated)
+ linesController.previewLinesChartRenderer.setVisible(false, animated: animated)
+ }
+
+ barsController.willAppear(animated: animated)
+ linesController.willDisappear(animated: animated)
+ }
+
+ self.setBackButtonVisibilityClosure?(isZoomed, animated)
+ self.refreshChartToolsClosure?(animated)
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ if isZoomed {
+ linesController.updateChartsVisibility(visibility: visibility, animated: animated)
+ } else {
+ barsController.updateChartsVisibility(visibility: visibility, animated: animated)
+ }
+ }
+
+ var visibleChartValues: [ChartsCollection.Chart] {
+ let visibility = isZoomed ? linesController.chartVisibility : barsController.chartVisibility
+ let collection = isZoomed ? linesController.chartsCollection : barsController.chartsCollection
+ let visibleCharts: [ChartsCollection.Chart] = visibility.enumerated().compactMap { args in
+ args.element ? collection.chartValues[args.offset] : nil
+ }
+ return visibleCharts
+ }
+
+ override var actualChartVisibility: [Bool] {
+ return isZoomed ? linesController.chartVisibility : barsController.chartVisibility
+ }
+
+ override var actualChartsCollection: ChartsCollection {
+ return isZoomed ? linesController.chartsCollection : barsController.chartsCollection
+ }
+
+ override func chartInteractionDidBegin(point: CGPoint) {
+ if isZoomed {
+ linesController.chartInteractionDidBegin(point: point)
+ } else {
+ barsController.chartInteractionDidBegin(point: point)
+ }
+ }
+
+ override func chartInteractionDidEnd() {
+ if isZoomed {
+ linesController.chartInteractionDidEnd()
+ } else {
+ barsController.chartInteractionDidEnd()
+ }
+ }
+
+ override var currentChartHorizontalRangeFraction: ClosedRange {
+ if isZoomed {
+ return linesController.currentChartHorizontalRangeFraction
+ } else {
+ return barsController.currentChartHorizontalRangeFraction
+ }
+ }
+
+ override func cancelChartInteraction() {
+ if isZoomed {
+ return linesController.hideDetailsView(animated: true)
+ } else {
+ return barsController.hideDetailsView(animated: true)
+ }
+ }
+
+ override func didTapZoomIn(date: Date) {
+ guard isZoomed == false else { return }
+ if isZoomed {
+ return linesController.hideDetailsView(animated: true)
+ }
+ self.getDetailsData?(date, { updatedCollection in
+ if let updatedCollection = updatedCollection {
+ self.linesController.initialize(chartsCollection: updatedCollection,
+ initialDate: date,
+ totalHorizontalRange: 0...1,
+ totalVerticalRange: 0...1)
+ self.switchToChart(chartsCollection: updatedCollection, isZoomed: true, animated: true)
+ }
+ })
+ }
+
+ func lineProportionAnimationRange() -> ClosedRange {
+ let visibleLines = self.barsController.chartVisibility.enumerated().compactMap { $0.element ? self.linesController.chartLines[$0.offset] : nil }
+ let linesRange = LinesChartRenderer.LineData.verticalRange(lines: visibleLines) ?? BaseConstants.defaultRange
+ let barsRange = BarChartRenderer.BarsData.verticalRange(bars: self.barsController.visibleBars,
+ calculatingRange: self.linesController.totalHorizontalRange) ?? BaseConstants.defaultRange
+ let range = 0...(linesRange.upperBound / barsRange.distance * self.barsController.currentVerticalMainChartRange.distance)
+ return range
+ }
+
+ override func didTapZoomOut() {
+ cancelChartInteraction()
+ switchToChart(chartsCollection: barsController.chartsCollection, isZoomed: false, animated: true)
+ }
+
+ override func updateChartRange(_ rangeFraction: ClosedRange) {
+ if isZoomed {
+ return linesController.chartRangeFractionDidUpdated(rangeFraction)
+ } else {
+ return barsController.chartRangeFractionDidUpdated(rangeFraction)
+ }
+ }
+
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ super.apply(colorMode: colorMode, animated: animated)
+
+ linesController.apply(colorMode: colorMode, animated: animated)
+ barsController.apply(colorMode: colorMode, animated: animated)
+ }
+
+ override var drawChartVisibity: Bool {
+ return isZoomed
+ }
+}
+
+//TODO: Убрать Performance полоски сверзу чартов (Не забыть)
+//TODO: Добавить ховеры на кнопки
diff --git a/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift
new file mode 100644
index 0000000000..fc39a5f4c6
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift
@@ -0,0 +1,210 @@
+//
+// LinesComponentController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/14/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class LinesComponentController: GeneralChartComponentController {
+ let mainLinesRenderer: LinesChartRenderer
+ let horizontalScalesRenderer: HorizontalScalesRenderer
+ let verticalScalesRenderer: VerticalScalesRenderer
+ let verticalLineRenderer: VerticalLinesRenderer
+ let lineBulletsRenerer: LineBulletsRenerer
+
+ let previewLinesChartRenderer: LinesChartRenderer
+
+ private let zoomedLinesRenderer = LinesChartRenderer()
+ private let zoomedPreviewLinesRenderer = LinesChartRenderer()
+
+ private let userLinesTransitionAnimation: Bool
+
+ private(set) var chartLines: [LinesChartRenderer.LineData] = []
+
+ init(isZoomed: Bool,
+ userLinesTransitionAnimation: Bool,
+ mainLinesRenderer: LinesChartRenderer,
+ horizontalScalesRenderer: HorizontalScalesRenderer,
+ verticalScalesRenderer: VerticalScalesRenderer,
+ verticalLineRenderer: VerticalLinesRenderer,
+ lineBulletsRenerer: LineBulletsRenerer,
+ previewLinesChartRenderer: LinesChartRenderer) {
+ self.mainLinesRenderer = mainLinesRenderer
+ self.horizontalScalesRenderer = horizontalScalesRenderer
+ self.verticalScalesRenderer = verticalScalesRenderer
+ self.verticalLineRenderer = verticalLineRenderer
+ self.lineBulletsRenerer = lineBulletsRenerer
+ self.previewLinesChartRenderer = previewLinesChartRenderer
+ self.userLinesTransitionAnimation = userLinesTransitionAnimation
+
+ super.init(isZoomed: isZoomed)
+
+ self.mainLinesRenderer.lineWidth = BaseConstants.mainChartLineWidth
+ self.mainLinesRenderer.optimizationLevel = BaseConstants.linesChartOptimizationLevel
+ self.previewLinesChartRenderer.lineWidth = BaseConstants.previewChartLineWidth
+ self.previewLinesChartRenderer.optimizationLevel = BaseConstants.previewLinesChartOptimizationLevel
+
+ self.lineBulletsRenerer.isEnabled = false
+ }
+
+ override func initialize(chartsCollection: ChartsCollection,
+ initialDate: Date,
+ totalHorizontalRange _: ClosedRange,
+ totalVerticalRange _: ClosedRange) {
+ let (chartLines, totalHorizontalRange, totalVerticalRange) = LinesChartRenderer.LineData.initialComponents(chartsCollection: chartsCollection)
+ self.chartLines = chartLines
+
+ self.lineBulletsRenerer.bullets = self.chartLines.map { LineBulletsRenerer.Bullet(coordinate: $0.points.first ?? .zero,
+ color: $0.color)}
+
+ super.initialize(chartsCollection: chartsCollection,
+ initialDate: initialDate,
+ totalHorizontalRange: totalHorizontalRange,
+ totalVerticalRange: totalVerticalRange)
+
+ self.mainLinesRenderer.setup(verticalRange: totalVerticalRange, animated: true)
+ }
+
+ override func willAppear(animated: Bool) {
+ mainLinesRenderer.setLines(lines: self.chartLines, animated: animated && userLinesTransitionAnimation)
+ previewLinesChartRenderer.setLines(lines: self.chartLines, animated: animated && userLinesTransitionAnimation)
+
+ previewLinesChartRenderer.setup(verticalRange: totalVerticalRange, animated: animated)
+ previewLinesChartRenderer.setup(horizontalRange: totalHorizontalRange, animated: animated)
+
+ setupMainChart(verticalRange: initialVerticalRange, animated: animated)
+ setupMainChart(horizontalRange: initialHorizontalRange, animated: animated)
+
+ updateChartVerticalRanges(horizontalRange: initialHorizontalRange, animated: animated)
+
+ super.willAppear(animated: animated)
+
+ updatePreviewRangeClosure?(currentChartHorizontalRangeFraction, animated)
+ setConponentsVisible(visible: true, animated: animated)
+ updateHorizontalLimitLabels(animated: animated, forceUpdate: true)
+ }
+
+ override func chartRangeDidUpdated(_ updatedRange: ClosedRange) {
+ super.chartRangeDidUpdated(updatedRange)
+ if !isZoomed {
+ initialHorizontalRange = updatedRange
+ }
+ setupMainChart(horizontalRange: updatedRange, animated: false)
+ updateHorizontalLimitLabels(animated: true, forceUpdate: false)
+ updateChartVerticalRanges(horizontalRange: updatedRange, animated: true)
+ }
+
+ func updateHorizontalLimitLabels(animated: Bool, forceUpdate: Bool) {
+ updateHorizontalLimitLabels(horizontalScalesRenderer: horizontalScalesRenderer,
+ horizontalRange: currentHorizontalMainChartRange,
+ scaleType: isZoomed ? .hour : .day,
+ forceUpdate: forceUpdate,
+ animated: animated)
+ }
+
+ func prepareAppearanceAnimation(horizontalRnage: ClosedRange) {
+ setupMainChart(horizontalRange: horizontalRnage, animated: false)
+ setConponentsVisible(visible: false, animated: false)
+ }
+
+ func setConponentsVisible(visible: Bool, animated: Bool) {
+ mainLinesRenderer.setVisible(visible, animated: animated)
+ horizontalScalesRenderer.setVisible(visible, animated: animated)
+ verticalScalesRenderer.setVisible(visible, animated: animated)
+ verticalLineRenderer.setVisible(visible, animated: animated)
+ previewLinesChartRenderer.setVisible(visible, animated: animated)
+ lineBulletsRenerer.setVisible(visible, animated: animated)
+ }
+
+ func setupMainChart(horizontalRange: ClosedRange, animated: Bool) {
+ mainLinesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ horizontalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ verticalScalesRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ verticalLineRenderer.setup(horizontalRange: horizontalRange, animated: animated)
+ lineBulletsRenerer.setup(horizontalRange: horizontalRange, animated: animated)
+ }
+
+ var visibleLines: [LinesChartRenderer.LineData] {
+ return chartVisibility.enumerated().compactMap { $0.element ? chartLines[$0.offset] : nil }
+ }
+
+ func updateChartVerticalRanges(horizontalRange: ClosedRange, animated: Bool) {
+ if let range = LinesChartRenderer.LineData.verticalRange(lines: visibleLines,
+ calculatingRange: horizontalRange,
+ addBounds: true) {
+ let (range, labels) = verticalLimitsLabels(verticalRange: range)
+ if verticalScalesRenderer.verticalRange.end != range {
+ verticalScalesRenderer.setup(verticalLimitsLabels: labels, animated: animated)
+ }
+
+ setupMainChart(verticalRange: range, animated: animated)
+ verticalScalesRenderer.setVisible(true, animated: animated)
+ } else {
+ verticalScalesRenderer.setVisible(false, animated: animated)
+ }
+
+ if let range = LinesChartRenderer.LineData.verticalRange(lines: visibleLines) {
+ previewLinesChartRenderer.setup(verticalRange: range, animated: animated)
+ }
+ }
+
+ func setupMainChart(verticalRange: ClosedRange, animated: Bool) {
+ mainLinesRenderer.setup(verticalRange: verticalRange, animated: animated)
+ horizontalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
+ verticalScalesRenderer.setup(verticalRange: verticalRange, animated: animated)
+ verticalLineRenderer.setup(verticalRange: verticalRange, animated: animated)
+ lineBulletsRenerer.setup(verticalRange: verticalRange, animated: animated)
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ super.updateChartsVisibility(visibility: visibility, animated: animated)
+ for (index, isVisible) in visibility.enumerated() {
+ mainLinesRenderer.setLineVisible(isVisible, at: index, animated: animated)
+ previewLinesChartRenderer.setLineVisible(isVisible, at: index, animated: animated)
+ lineBulletsRenerer.setLineVisible(isVisible, at: index, animated: animated)
+ }
+ updateChartVerticalRanges(horizontalRange: currentHorizontalMainChartRange, animated: true)
+ }
+
+ override var currentMainRangeRenderer: BaseChartRenderer {
+ return mainLinesRenderer
+ }
+
+ override var currentPreviewRangeRenderer: BaseChartRenderer {
+ return previewLinesChartRenderer
+ }
+
+ override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) {
+ super.showDetailsView(at: chartPosition, detailsViewPosition: detailsViewPosition, dataIndex: dataIndex, date: date, animted: animted)
+ verticalLineRenderer.values = [chartPosition]
+ verticalLineRenderer.isEnabled = true
+
+ lineBulletsRenerer.isEnabled = true
+ lineBulletsRenerer.setVisible(true, animated: animted)
+ lineBulletsRenerer.bullets = chartLines.compactMap { chart in
+ return LineBulletsRenerer.Bullet(coordinate: chart.points[dataIndex], color: chart.color)
+ }
+ }
+
+ override func hideDetailsView(animated: Bool) {
+ super.hideDetailsView(animated: animated)
+
+ verticalLineRenderer.values = []
+ verticalLineRenderer.isEnabled = false
+ lineBulletsRenerer.isEnabled = false
+ }
+
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ super.apply(colorMode: colorMode, animated: animated)
+
+ horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
+ verticalScalesRenderer.axisXColor = colorMode.chartStrongLinesColor
+ verticalScalesRenderer.horizontalLinesColor = colorMode.chartHelperLinesColor
+ lineBulletsRenerer.setInnerColor(colorMode.chartBackgroundColor, animated: animated)
+ verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/StackedBarsChartController.swift b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/StackedBarsChartController.swift
new file mode 100644
index 0000000000..ab836d00d2
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Controllers/Stacked Bars/StackedBarsChartController.swift
@@ -0,0 +1,243 @@
+//
+// StackedBarsChartController.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class StackedBarsChartController: BaseChartController {
+ let barsController: BarsComponentController
+ let zoomedBarsController: BarsComponentController
+
+ override init(chartsCollection: ChartsCollection) {
+ let horizontalScalesRenderer = HorizontalScalesRenderer()
+ let verticalScalesRenderer = VerticalScalesRenderer()
+ barsController = BarsComponentController(isZoomed: false,
+ mainBarsRenderer: BarChartRenderer(),
+ horizontalScalesRenderer: horizontalScalesRenderer,
+ verticalScalesRenderer: verticalScalesRenderer,
+ previewBarsChartRenderer: BarChartRenderer())
+ zoomedBarsController = BarsComponentController(isZoomed: true,
+ mainBarsRenderer: BarChartRenderer(),
+ horizontalScalesRenderer: horizontalScalesRenderer,
+ verticalScalesRenderer: verticalScalesRenderer,
+ previewBarsChartRenderer: BarChartRenderer())
+
+ super.init(chartsCollection: chartsCollection)
+
+ [barsController, zoomedBarsController].forEach { controller in
+ controller.chartFrame = { [unowned self] in self.chartFrame() }
+ controller.cartViewBounds = { [unowned self] in self.cartViewBounds() }
+ controller.zoomInOnDateClosure = { [unowned self] date in
+ self.didTapZoomIn(date: date)
+ }
+ controller.setChartTitleClosure = { [unowned self] (title, animated) in
+ self.setChartTitleClosure?(title, animated)
+ }
+ controller.setDetailsViewPositionClosure = { [unowned self] (position) in
+ self.setDetailsViewPositionClosure?(position)
+ }
+ controller.setDetailsChartVisibleClosure = { [unowned self] (visible, animated) in
+ self.setDetailsChartVisibleClosure?(visible, animated)
+ }
+ controller.setDetailsViewModel = { [unowned self] (viewModel, animated) in
+ self.setDetailsViewModel?(viewModel, animated)
+ }
+ controller.updatePreviewRangeClosure = { [unowned self] (fraction, animated) in
+ self.chartRangeUpdatedClosure?(fraction, animated)
+ }
+ controller.chartRangePagingClosure = { [unowned self] (isEnabled, pageSize) in
+ self.setChartRangePagingEnabled(isEnabled: isEnabled, minimumSelectionSize: pageSize)
+ }
+ }
+ }
+
+ override var mainChartRenderers: [ChartViewRenderer] {
+ return [barsController.mainBarsRenderer,
+ zoomedBarsController.mainBarsRenderer,
+ barsController.horizontalScalesRenderer,
+ barsController.verticalScalesRenderer,
+// performanceRenderer
+ ]
+ }
+
+ override var navigationRenderers: [ChartViewRenderer] {
+ return [barsController.previewBarsChartRenderer,
+ zoomedBarsController.previewBarsChartRenderer]
+ }
+
+ override func initializeChart() {
+ barsController.initialize(chartsCollection: initialChartsCollection,
+ initialDate: Date(),
+ totalHorizontalRange: BaseConstants.defaultRange,
+ totalVerticalRange: BaseConstants.defaultRange)
+ switchToChart(chartsCollection: barsController.chartsCollection, isZoomed: false, animated: false)
+ }
+
+ func switchToChart(chartsCollection: ChartsCollection, isZoomed: Bool, animated: Bool) {
+ if animated {
+ TimeInterval.setDefaultSuration(.expandAnimationDuration)
+ DispatchQueue.main.asyncAfter(deadline: .now() + .expandAnimationDuration) {
+ TimeInterval.setDefaultSuration(.osXDuration)
+ }
+ }
+
+ super.isZoomed = isZoomed
+ if isZoomed {
+ let toHorizontalRange = zoomedBarsController.initialHorizontalRange
+ let destinationHorizontalRange = (toHorizontalRange.lowerBound - barsController.barsWidth)...(toHorizontalRange.upperBound - barsController.barsWidth)
+ let verticalVisibleRange = barsController.currentVerticalMainChartRange
+ let initialVerticalRange = verticalVisibleRange.lowerBound...(verticalVisibleRange.upperBound + verticalVisibleRange.distance * 10)
+
+ zoomedBarsController.mainBarsRenderer.setup(horizontalRange: barsController.currentHorizontalMainChartRange, animated: false)
+ zoomedBarsController.previewBarsChartRenderer.setup(horizontalRange: barsController.currentPreviewHorizontalRange, animated: false)
+ zoomedBarsController.mainBarsRenderer.setup(verticalRange: initialVerticalRange, animated: false)
+ zoomedBarsController.previewBarsChartRenderer.setup(verticalRange: initialVerticalRange, animated: false)
+ zoomedBarsController.mainBarsRenderer.setVisible(true, animated: false)
+ zoomedBarsController.previewBarsChartRenderer.setVisible(true, animated: false)
+
+ barsController.setupMainChart(horizontalRange: destinationHorizontalRange, animated: animated)
+ barsController.previewBarsChartRenderer.setup(horizontalRange: zoomedBarsController.totalHorizontalRange, animated: animated)
+ barsController.mainBarsRenderer.setVisible(false, animated: animated)
+ barsController.previewBarsChartRenderer.setVisible(false, animated: animated)
+
+ zoomedBarsController.willAppear(animated: animated)
+ barsController.willDisappear(animated: animated)
+
+ zoomedBarsController.updateChartsVisibility(visibility: barsController.chartVisibility, animated: false)
+ zoomedBarsController.mainBarsRenderer.setup(verticalRange: zoomedBarsController.currentVerticalMainChartRange, animated: animated, timeFunction: .easeOut)
+ zoomedBarsController.previewBarsChartRenderer.setup(verticalRange: zoomedBarsController.currentPreviewVerticalRange, animated: animated, timeFunction: .easeOut)
+ } else {
+ if !zoomedBarsController.chartsCollection.isBlank {
+ barsController.hideDetailsView(animated: false)
+ barsController.chartVisibility = zoomedBarsController.chartVisibility
+ let visibleVerticalRange = BarChartRenderer.BarsData.verticalRange(bars: barsController.visibleBars,
+ calculatingRange: barsController.initialHorizontalRange) ?? BaseConstants.defaultRange
+ barsController.mainBarsRenderer.setup(verticalRange: visibleVerticalRange, animated: false)
+
+ let toHorizontalRange = barsController.initialHorizontalRange
+
+ let verticalVisibleRange = barsController.initialVerticalRange
+ let targetVerticalRange = verticalVisibleRange.lowerBound...(verticalVisibleRange.upperBound + verticalVisibleRange.distance * 10)
+
+ zoomedBarsController.setupMainChart(horizontalRange: toHorizontalRange, animated: animated)
+ zoomedBarsController.mainBarsRenderer.setup(verticalRange: targetVerticalRange, animated: animated, timeFunction: .easeIn)
+ zoomedBarsController.previewBarsChartRenderer.setup(verticalRange: targetVerticalRange, animated: animated, timeFunction: .easeIn)
+ zoomedBarsController.previewBarsChartRenderer.setup(horizontalRange: barsController.totalHorizontalRange, animated: animated)
+ DispatchQueue.main.asyncAfter(deadline: .now() + .defaultDuration) { [weak self] in
+ self?.zoomedBarsController.mainBarsRenderer.setVisible(false, animated: false)
+ self?.zoomedBarsController.previewBarsChartRenderer.setVisible(false, animated: false)
+ }
+ }
+
+ barsController.willAppear(animated: animated)
+ zoomedBarsController.willDisappear(animated: animated)
+
+ if !zoomedBarsController.chartsCollection.isBlank {
+ barsController.updateChartsVisibility(visibility: zoomedBarsController.chartVisibility, animated: false)
+ }
+ }
+
+ self.setBackButtonVisibilityClosure?(isZoomed, animated)
+ }
+
+ override func updateChartsVisibility(visibility: [Bool], animated: Bool) {
+ if isZoomed {
+ zoomedBarsController.updateChartsVisibility(visibility: visibility, animated: animated)
+ } else {
+ barsController.updateChartsVisibility(visibility: visibility, animated: animated)
+ }
+ }
+
+ var visibleChartValues: [ChartsCollection.Chart] {
+ let visibility = isZoomed ? zoomedBarsController.chartVisibility : barsController.chartVisibility
+ let collection = isZoomed ? zoomedBarsController.chartsCollection : barsController.chartsCollection
+ let visibleCharts: [ChartsCollection.Chart] = visibility.enumerated().compactMap { args in
+ args.element ? collection.chartValues[args.offset] : nil
+ }
+ return visibleCharts
+ }
+
+ override var actualChartVisibility: [Bool] {
+ return isZoomed ? zoomedBarsController.chartVisibility : barsController.chartVisibility
+ }
+
+ override var actualChartsCollection: ChartsCollection {
+ return isZoomed ? zoomedBarsController.chartsCollection : barsController.chartsCollection
+ }
+
+ override func chartInteractionDidBegin(point: CGPoint) {
+ if isZoomed {
+ zoomedBarsController.chartInteractionDidBegin(point: point)
+ } else {
+ barsController.chartInteractionDidBegin(point: point)
+ }
+ }
+
+ override func chartInteractionDidEnd() {
+ if isZoomed {
+ zoomedBarsController.chartInteractionDidEnd()
+ } else {
+ barsController.chartInteractionDidEnd()
+ }
+ }
+
+ override var drawChartVisibity: Bool {
+ return true
+ }
+
+ override var currentChartHorizontalRangeFraction: ClosedRange {
+ if isZoomed {
+ return zoomedBarsController.currentChartHorizontalRangeFraction
+ } else {
+ return barsController.currentChartHorizontalRangeFraction
+ }
+ }
+
+ override func cancelChartInteraction() {
+ if isZoomed {
+ return zoomedBarsController.hideDetailsView(animated: true)
+ } else {
+ return barsController.hideDetailsView(animated: true)
+ }
+ }
+
+ override func didTapZoomIn(date: Date) {
+ guard isZoomed == false else { return }
+ if isZoomed {
+ return zoomedBarsController.hideDetailsView(animated: true)
+ }
+ self.getDetailsData?(date, { updatedCollection in
+ if let updatedCollection = updatedCollection {
+ self.zoomedBarsController.initialize(chartsCollection: updatedCollection,
+ initialDate: date,
+ totalHorizontalRange: 0...1,
+ totalVerticalRange: 0...1)
+ self.switchToChart(chartsCollection: updatedCollection, isZoomed: true, animated: true)
+ }
+ })
+ }
+
+ override func didTapZoomOut() {
+ cancelChartInteraction()
+ switchToChart(chartsCollection: barsController.chartsCollection, isZoomed: false, animated: true)
+ }
+
+ override func updateChartRange(_ rangeFraction: ClosedRange) {
+ if isZoomed {
+ return zoomedBarsController.chartRangeFractionDidUpdated(rangeFraction)
+ } else {
+ return barsController.chartRangeFractionDidUpdated(rangeFraction)
+ }
+ }
+
+ override func apply(colorMode: ColorMode, animated: Bool) {
+ super.apply(colorMode: colorMode, animated: animated)
+
+ zoomedBarsController.apply(colorMode: colorMode, animated: animated)
+ barsController.apply(colorMode: colorMode, animated: animated)
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/BarChartRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/BarChartRenderer.swift
new file mode 100644
index 0000000000..73a6b52f42
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/BarChartRenderer.swift
@@ -0,0 +1,293 @@
+//
+// BarChartRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class BarChartRenderer: BaseChartRenderer {
+ struct BarsData {
+ static let blank = BarsData(barWidth: 1, locations: [], components: [])
+ var barWidth: CGFloat
+ var locations: [CGFloat]
+ var components: [Component]
+
+ struct Component {
+ var color: UIColor
+ var values: [CGFloat]
+ }
+ }
+
+ var fillToTop: Bool = false
+ private(set) lazy var selectedIndexAnimator: AnimationController = {
+ return AnimationController(current: 0, refreshClosure: self.refreshClosure)
+ }()
+ func setSelectedIndex(_ index: Int?, animated: Bool) {
+ let destinationValue: CGFloat = (index == nil) ? 0 : 1
+ if animated {
+ if index != nil {
+ selectedBarIndex = index
+ }
+ self.selectedIndexAnimator.completionClosure = {
+ self.selectedBarIndex = index
+ }
+ guard self.selectedIndexAnimator.end != destinationValue else { return }
+ self.selectedIndexAnimator.animate(to: destinationValue, duration: .defaultDuration)
+ } else {
+ self.selectedIndexAnimator.set(current: destinationValue)
+ self.selectedBarIndex = index
+ }
+ }
+
+ private var selectedBarIndex: Int? {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+ var generalUnselectedAlpha: CGFloat = 0.5
+
+ private var componentsAnimators: [AnimationController] = []
+ var bars: BarsData = BarsData(barWidth: 1, locations: [], components: []) {
+ willSet {
+ if bars.components.count != newValue.components.count {
+ componentsAnimators = newValue.components.map { _ in AnimationController(current: 1, refreshClosure: self.refreshClosure) }
+ }
+ }
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+
+ func setComponentVisible(_ isVisible: Bool, at index: Int, animated: Bool) {
+ componentsAnimators[index].animate(to: isVisible ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+
+ private lazy var backgroundColorAnimator = AnimationController(current: UIColorContainer(color: .white), refreshClosure: refreshClosure)
+ func update(backgroundColor: UIColor, animated: Bool) {
+ if animated {
+ backgroundColorAnimator.animate(to: UIColorContainer(color: backgroundColor), duration: .defaultDuration)
+ } else {
+ backgroundColorAnimator.set(current: UIColorContainer(color: backgroundColor))
+ }
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ let chartsAlpha = chartAlphaAnimator.current
+ if chartsAlpha == 0 { return }
+
+ let range = renderRange(bounds: bounds, chartFrame: chartFrame)
+
+ var selectedPaths: [[CGRect]] = bars.components.map { _ in [] }
+ var unselectedPaths: [[CGRect]] = bars.components.map { _ in [] }
+
+ if var barIndex = bars.locations.firstIndex(where: { $0 >= range.lowerBound }) {
+ if fillToTop {
+ barIndex = max(0, barIndex - 1)
+
+ while barIndex < bars.locations.count {
+ let currentLocation = bars.locations[barIndex]
+ let right = transform(toChartCoordinateHorizontal: currentLocation, chartFrame: chartFrame).roundedUpToPixelGrid()
+ let left = transform(toChartCoordinateHorizontal: currentLocation - bars.barWidth, chartFrame: chartFrame).roundedUpToPixelGrid()
+
+ var summ: CGFloat = 0
+ for (index, component) in bars.components.enumerated() {
+ summ += componentsAnimators[index].current * component.values[barIndex]
+ }
+ guard summ > 0 else {
+ barIndex += 1
+ continue
+ }
+
+ var stackedValue: CGFloat = 0
+ for (index, component) in bars.components.enumerated() {
+ let visibilityPercent = componentsAnimators[index].current
+ if visibilityPercent == 0 { continue }
+
+ let bottomFraction = stackedValue
+ let topFraction = stackedValue + ((component.values[barIndex] * visibilityPercent) / summ)
+
+ let rect = CGRect(x: left,
+ y: chartFrame.maxY - chartFrame.height * topFraction,
+ width: right - left,
+ height: chartFrame.height * (topFraction - bottomFraction))
+ if selectedBarIndex == barIndex {
+ selectedPaths[index].append(rect)
+ } else {
+ unselectedPaths[index].append(rect)
+ }
+ stackedValue = topFraction
+ }
+ if currentLocation > range.upperBound {
+ break
+ }
+ barIndex += 1
+ }
+
+ for (index, component) in bars.components.enumerated() {
+ context.saveGState()
+ context.setFillColor(component.color.withAlphaComponent(chartsAlpha * component.color.alphaValue).cgColor)
+ context.fill(selectedPaths[index])
+ let resultAlpha: CGFloat = 1.0 - (1.0 - generalUnselectedAlpha) * selectedIndexAnimator.current
+ context.setFillColor(component.color.withAlphaComponent(chartsAlpha * component.color.alphaValue * resultAlpha).cgColor)
+ context.fill(unselectedPaths[index])
+ context.restoreGState()
+ }
+ } else {
+ var selectedPaths: [[CGRect]] = bars.components.map { _ in [] }
+ barIndex = max(0, barIndex - 1)
+
+ var currentLocation = bars.locations[barIndex]
+ var leftX = transform(toChartCoordinateHorizontal: currentLocation - bars.barWidth, chartFrame: chartFrame)
+ var rightX: CGFloat = 0
+
+ let startPoint = CGPoint(x: leftX,
+ y: transform(toChartCoordinateVertical: verticalRange.current.lowerBound, chartFrame: chartFrame))
+
+ var backgourndPaths: [[CGPoint]] = bars.components.map { _ in Array() }
+ let itemsCount = ((bars.locations.count - barIndex) * 2) + 4
+ for path in backgourndPaths.indices {
+ backgourndPaths[path].reserveCapacity(itemsCount)
+ backgourndPaths[path].append(startPoint)
+ }
+ var maxValues: [CGFloat] = bars.components.map { _ in 0 }
+ while barIndex < bars.locations.count {
+ currentLocation = bars.locations[barIndex]
+ rightX = transform(toChartCoordinateHorizontal: currentLocation, chartFrame: chartFrame)
+
+ var stackedValue: CGFloat = 0
+ var bottomY: CGFloat = transform(toChartCoordinateVertical: stackedValue, chartFrame: chartFrame)
+ for (index, component) in bars.components.enumerated() {
+ let visibilityPercent = componentsAnimators[index].current
+ if visibilityPercent == 0 { continue }
+
+ let height = component.values[barIndex] * visibilityPercent
+ stackedValue += height
+ let topY = transform(toChartCoordinateVertical: stackedValue, chartFrame: chartFrame)
+ let componentHeight = (bottomY - topY)
+ maxValues[index] = max(maxValues[index], componentHeight)
+ if selectedBarIndex == barIndex {
+ let rect = CGRect(x: leftX,
+ y: topY,
+ width: rightX - leftX,
+ height: componentHeight)
+ selectedPaths[index].append(rect)
+ }
+ backgourndPaths[index].append(CGPoint(x: leftX, y: topY))
+ backgourndPaths[index].append(CGPoint(x: rightX, y: topY))
+ bottomY = topY
+ }
+ if currentLocation > range.upperBound {
+ break
+ }
+ leftX = rightX
+ barIndex += 1
+ }
+
+ let endPoint = CGPoint(x: transform(toChartCoordinateHorizontal: currentLocation, chartFrame: chartFrame).roundedUpToPixelGrid(),
+ y: transform(toChartCoordinateVertical: verticalRange.current.lowerBound, chartFrame: chartFrame))
+ let colorOffset = Double((1.0 - (1.0 - generalUnselectedAlpha) * selectedIndexAnimator.current) * chartsAlpha)
+
+ for (index, component) in bars.components.enumerated().reversed() {
+ if maxValues[index] < optimizationLevel {
+ continue
+ }
+ context.saveGState()
+ backgourndPaths[index].append(endPoint)
+
+ context.setFillColor(UIColor.valueBetween(start: backgroundColorAnimator.current.color,
+ end: component.color,
+ offset: colorOffset).cgColor)
+ context.beginPath()
+ context.addLines(between: backgourndPaths[index])
+ context.closePath()
+ context.fillPath()
+ context.restoreGState()
+ }
+
+ for (index, component) in bars.components.enumerated().reversed() {
+ context.setFillColor(component.color.withAlphaComponent(chartsAlpha * component.color.alphaValue).cgColor)
+ context.fill(selectedPaths[index])
+ }
+ }
+ }
+ }
+}
+
+extension BarChartRenderer.BarsData {
+ static func initialComponents(chartsCollection: ChartsCollection) ->
+ (width: CGFloat,
+ chartBars: BarChartRenderer.BarsData,
+ totalHorizontalRange: ClosedRange,
+ totalVerticalRange: ClosedRange) {
+ let width: CGFloat
+ if chartsCollection.axisValues.count > 1 {
+ width = CGFloat(abs(chartsCollection.axisValues[1].timeIntervalSince1970 - chartsCollection.axisValues[0].timeIntervalSince1970))
+ } else {
+ width = 1
+ }
+ let components = chartsCollection.chartValues.map { BarChartRenderer.BarsData.Component(color: $0.color,
+ values: $0.values.map { CGFloat($0) }) }
+ let chartBars = BarChartRenderer.BarsData(barWidth: width,
+ locations: chartsCollection.axisValues.map { CGFloat($0.timeIntervalSince1970) },
+ components: components)
+
+
+
+ let totalVerticalRange = BarChartRenderer.BarsData.verticalRange(bars: chartBars) ?? 0...1
+ let totalHorizontalRange = BarChartRenderer.BarsData.visibleHorizontalRange(bars: chartBars, width: width) ?? 0...1
+ return (width: width, chartBars: chartBars, totalHorizontalRange: totalHorizontalRange, totalVerticalRange: totalVerticalRange)
+ }
+
+ static func visibleHorizontalRange(bars: BarChartRenderer.BarsData, width: CGFloat) -> ClosedRange? {
+ guard let firstPoint = bars.locations.first,
+ let lastPoint = bars.locations.last,
+ firstPoint <= lastPoint else {
+ return nil
+ }
+
+ return (firstPoint - width)...lastPoint
+ }
+
+ static func verticalRange(bars: BarChartRenderer.BarsData, calculatingRange: ClosedRange? = nil, addBounds: Bool = false) -> ClosedRange? {
+ guard bars.components.count > 0 else {
+ return nil
+ }
+ if let calculatingRange = calculatingRange {
+ guard var index = bars.locations.firstIndex(where: { $0 >= calculatingRange.lowerBound && $0 <= calculatingRange.upperBound }) else {
+ return nil
+ }
+
+ var vMax: CGFloat = bars.components[0].values[index]
+ while index < bars.locations.count {
+ var summ: CGFloat = 0
+ for component in bars.components {
+ summ += component.values[index]
+ }
+ vMax = max(vMax, summ)
+
+ if bars.locations[index] > calculatingRange.upperBound {
+ break
+ }
+ index += 1
+ }
+ return 0...vMax
+ } else {
+ var index = 0
+
+ var vMax: CGFloat = bars.components[0].values[index]
+ while index < bars.locations.count {
+ var summ: CGFloat = 0
+ for component in bars.components {
+ summ += component.values[index]
+ }
+ vMax = max(vMax, summ)
+ index += 1
+ }
+ return 0...vMax
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/BaseChartRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/BaseChartRenderer.swift
new file mode 100644
index 0000000000..63627566e7
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/BaseChartRenderer.swift
@@ -0,0 +1,116 @@
+//
+// BaseChartRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private let exponentialAnimationTrashold: CGFloat = 100
+
+class BaseChartRenderer: ChartViewRenderer {
+ var containerViews: [UIView] = []
+
+ var optimizationLevel: CGFloat = 1 {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+ var isEnabled: Bool = true {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+
+ private(set) lazy var chartAlphaAnimator: AnimationController = {
+ return AnimationController(current: 1, refreshClosure: self.refreshClosure)
+ }()
+ func setVisible(_ visible: Bool, animated: Bool) {
+ let destinationValue: CGFloat = visible ? 1 : 0
+ guard self.chartAlphaAnimator.end != destinationValue else { return }
+ if animated {
+ self.chartAlphaAnimator.animate(to: destinationValue, duration: .defaultDuration)
+ } else {
+ self.chartAlphaAnimator.set(current: destinationValue)
+ }
+ }
+
+ lazy var horizontalRange = AnimationController>(current: 0...1, refreshClosure: refreshClosure)
+ lazy var verticalRange = AnimationController>(current: 0...1, refreshClosure: refreshClosure)
+
+ func setup(verticalRange: ClosedRange, animated: Bool, timeFunction: TimeFunction? = nil) {
+ guard self.verticalRange.end != verticalRange else {
+ self.verticalRange.timeFunction = timeFunction ?? .linear
+ return
+ }
+ if animated {
+ let function: TimeFunction
+ if let timeFunction = timeFunction {
+ function = timeFunction
+ } else if self.verticalRange.current.distance > 0 && verticalRange.distance > 0 {
+ if self.verticalRange.current.distance / verticalRange.distance > exponentialAnimationTrashold {
+ function = .easeIn
+ } else if verticalRange.distance / self.verticalRange.current.distance > exponentialAnimationTrashold {
+ function = .easeOut
+ } else {
+ function = .linear
+ }
+ } else {
+ function = .linear
+ }
+
+ self.verticalRange.animate(to: verticalRange, duration: .defaultDuration, timeFunction: function)
+ } else {
+ self.verticalRange.set(current: verticalRange)
+ }
+ }
+
+ func setup(horizontalRange: ClosedRange, animated: Bool) {
+ guard self.horizontalRange.end != horizontalRange else { return }
+ if animated {
+ let animationCurve: TimeFunction = self.horizontalRange.current.distance > horizontalRange.distance ? .easeOut : .easeIn
+ self.horizontalRange.animate(to: horizontalRange, duration: .defaultDuration, timeFunction: animationCurve)
+ } else {
+ self.horizontalRange.set(current: horizontalRange)
+ }
+ }
+
+ func transform(toChartCoordinateHorizontal x: CGFloat, chartFrame: CGRect) -> CGFloat {
+ return chartFrame.origin.x + (x - horizontalRange.current.lowerBound) / horizontalRange.current.distance * chartFrame.width
+ }
+
+ func transform(toChartCoordinateVertical y: CGFloat, chartFrame: CGRect) -> CGFloat {
+ return chartFrame.height + chartFrame.origin.y - (y - verticalRange.current.lowerBound) / verticalRange.current.distance * chartFrame.height
+ }
+
+ func transform(toChartCoordinate point: CGPoint, chartFrame: CGRect) -> CGPoint {
+ return CGPoint(x: transform(toChartCoordinateHorizontal: point.x, chartFrame: chartFrame),
+ y: transform(toChartCoordinateVertical: point.y, chartFrame: chartFrame))
+ }
+
+ func renderRange(bounds: CGRect, chartFrame: CGRect) -> ClosedRange {
+ let lowerBound = horizontalRange.current.lowerBound - chartFrame.origin.x / chartFrame.width * horizontalRange.current.distance
+ let upperBound = horizontalRange.current.upperBound + (bounds.width - chartFrame.width - chartFrame.origin.x) / chartFrame.width * horizontalRange.current.distance
+ guard lowerBound <= upperBound else {
+ print("Error: Unexpecated bounds range!")
+ return 0...1
+ }
+ return lowerBound...upperBound
+ }
+
+ func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ fatalError("abstract")
+ }
+
+ func setNeedsDisplay() {
+ containerViews.forEach { $0.setNeedsDisplay() }
+ }
+
+ var refreshClosure: () -> Void {
+ return { [weak self] in
+ self?.setNeedsDisplay()
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/ChartDetailsRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/ChartDetailsRenderer.swift
new file mode 100644
index 0000000000..ad61ff5dd9
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/ChartDetailsRenderer.swift
@@ -0,0 +1,147 @@
+//
+// ChartDetailsRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class ChartDetailsRenderer: BaseChartRenderer, ColorModeContainer {
+ private lazy var colorAnimator = AnimationController(current: 1, refreshClosure: refreshClosure)
+ private var fromColorMode: ColorMode = .day
+ private var currentColorMode: ColorMode = .day
+ func apply(colorMode: ColorMode, animated: Bool) {
+ if currentColorMode != colorMode {
+ fromColorMode = currentColorMode
+ currentColorMode = colorMode
+ if animated {
+ colorAnimator.set(current: 0)
+ colorAnimator.animate(to: 1, duration: .defaultDuration)
+ } else {
+ colorAnimator.set(current: 1)
+ }
+ }
+ }
+
+ private var valuesAnimators: [AnimationController] = []
+ func setValueVisible(_ isVisible: Bool, at index: Int, animated: Bool) {
+ valuesAnimators[index].animate(to: isVisible ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+ var detailsViewModel: ChartDetailsViewModel = .blank {
+ didSet {
+ if detailsViewModel.values.count != valuesAnimators.count {
+ valuesAnimators = detailsViewModel.values.map { _ in AnimationController(current: 1, refreshClosure: refreshClosure) }
+ }
+ setNeedsDisplay()
+ }
+ }
+
+ var detailsViewPosition: CGFloat = 0 {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+ var detailViewPositionOffset: CGFloat = 10
+ var detailViewTopOffset: CGFloat = 10
+ private var iconWidth: CGFloat = 10
+ private var margins: CGFloat = 10
+ private let cornerRadius: CGFloat = 5
+ private var rowHeight: CGFloat = 20
+ private let titleFont = UIFont.systemFont(ofSize: 14, weight: .bold)
+ private let prefixFont = UIFont.systemFont(ofSize: 14, weight: .bold)
+ private let labelsFont = UIFont.systemFont(ofSize: 14, weight: .medium)
+ private let valuesFont = UIFont.systemFont(ofSize: 14, weight: .bold)
+ private let labelsColor: UIColor = .black
+
+ private(set) var previousRenderBannerFrame: CGRect = .zero
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ previousRenderBannerFrame = .zero
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ let generalAlpha = chartAlphaAnimator.current
+ if generalAlpha == 0 { return }
+
+ let widths: [(prefix: CGFloat, label: CGFloat, value: CGFloat)] = detailsViewModel.values.map { value in
+ var prefixWidth: CGFloat = 0
+ if let prefixText = value.prefix {
+ prefixWidth = (prefixText as NSString).boundingRect(with: bounds.size,
+ options: .usesLineFragmentOrigin,
+ attributes: [.font: prefixFont],
+ context: nil).width.rounded(.up) + margins
+ }
+
+ let labelWidth = (value.title as NSString).boundingRect(with: bounds.size,
+ options: .usesLineFragmentOrigin,
+ attributes: [.font: labelsFont],
+ context: nil).width.rounded(.up) + margins
+
+ let valueWidth = (value.value as NSString).boundingRect(with: bounds.size,
+ options: .usesLineFragmentOrigin,
+ attributes: [.font: valuesFont],
+ context: nil).width.rounded(.up)
+ return (prefixWidth, labelWidth, valueWidth)
+ }
+
+ let titleWidth = (detailsViewModel.title as NSString).boundingRect(with: bounds.size,
+ options: .usesLineFragmentOrigin,
+ attributes: [.font: titleFont],
+ context: nil).width
+ let prefixesWidth = widths.map { $0.prefix }.max() ?? 0
+ let labelsWidth = widths.map { $0.label }.max() ?? 0
+ let valuesWidth = widths.map { $0.value }.max() ?? 0
+
+ let totalWidth: CGFloat = max(prefixesWidth + labelsWidth + valuesWidth, titleWidth + iconWidth) + margins * 2
+ let totalHeight: CGFloat = CGFloat(detailsViewModel.values.count + 1) * rowHeight + margins * 2
+ let backgroundColor = UIColor.valueBetween(start: fromColorMode.chartDetailsViewColor,
+ end: currentColorMode.chartDetailsViewColor,
+ offset: Double(colorAnimator.current))
+ let titleAndTextColor = UIColor.valueBetween(start: fromColorMode.chartDetailsTextColor,
+ end: currentColorMode.chartDetailsTextColor,
+ offset: Double(colorAnimator.current))
+ let detailsViewFrame: CGRect
+ if totalWidth + detailViewTopOffset > detailsViewPosition {
+ detailsViewFrame = CGRect(x: detailsViewPosition + detailViewTopOffset,
+ y: detailViewTopOffset + chartFrame.minY,
+ width: totalWidth,
+ height: totalHeight)
+ } else {
+ detailsViewFrame = CGRect(x: detailsViewPosition - totalWidth - detailViewTopOffset,
+ y: detailViewTopOffset + chartFrame.minY,
+ width: totalWidth,
+ height: totalHeight)
+ }
+ previousRenderBannerFrame = detailsViewFrame
+ context.saveGState()
+ context.setFillColor(backgroundColor.cgColor)
+ context.beginPath()
+ context.addPath(CGPath(roundedRect: detailsViewFrame, cornerWidth: 5, cornerHeight: 5, transform: nil))
+ context.fillPath()
+ context.endPage()
+ context.restoreGState()
+
+ var drawY = detailsViewFrame.minY + margins + (rowHeight - titleFont.pointSize) / 2
+ (detailsViewModel.title as NSString).draw(at: CGPoint(x: detailsViewFrame.minX + margins, y: drawY), withAttributes: [.font: titleFont,
+ .foregroundColor: titleAndTextColor])
+ drawY += rowHeight
+
+ for (index, row) in widths.enumerated() {
+ let value = detailsViewModel.values[index]
+ if let prefixText = value.prefix {
+ (prefixText as NSString).draw(at: CGPoint(x: detailsViewFrame.minX + prefixesWidth - row.prefix,
+ y: drawY),
+ withAttributes: [.font: prefixText, .foregroundColor: titleAndTextColor])
+ }
+
+ (value.title as NSString).draw(at: CGPoint(x: detailsViewFrame.minX + prefixesWidth + margins,
+ y: drawY),
+ withAttributes: [.font: labelsFont, .foregroundColor: titleAndTextColor])
+
+ (value.value as NSString).draw(at: CGPoint(x: detailsViewFrame.minX + prefixesWidth + labelsWidth + valuesWidth - row.value + margins,
+ y: drawY),
+ withAttributes: [.font: labelsFont, .foregroundColor: value.color])
+
+ drawY += rowHeight
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/HorizontalScalesRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/HorizontalScalesRenderer.swift
new file mode 100644
index 0000000000..3ab90ef546
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/HorizontalScalesRenderer.swift
@@ -0,0 +1,99 @@
+//
+// HorizontalScalesRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/8/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class HorizontalScalesRenderer: BaseChartRenderer {
+ private var horizontalLabels: [LinesChartLabel] = []
+ private var animatedHorizontalLabels: [AnimatedLinesChartLabels] = []
+
+ var labelsVerticalOffset: CGFloat = 8
+ var labelsFont: UIFont = .systemFont(ofSize: 11)
+ var labelsColor: UIColor = .gray
+
+ func setup(labels: [LinesChartLabel], animated: Bool) {
+ if animated {
+ var labelsToKeepVisible: [LinesChartLabel] = []
+ let labelsToHide: [LinesChartLabel]
+ var labelsToShow: [LinesChartLabel] = []
+
+ for label in labels {
+ if horizontalLabels.contains(label) {
+ labelsToKeepVisible.append(label)
+ } else {
+ labelsToShow.append(label)
+ }
+ }
+ labelsToHide = horizontalLabels.filter { !labels.contains($0) }
+ animatedHorizontalLabels.removeAll()
+ horizontalLabels = labelsToKeepVisible
+
+ let showAnimation = AnimatedLinesChartLabels(labels: labelsToShow, alphaAnimator: AnimationController(current: 1.0, refreshClosure: refreshClosure))
+ showAnimation.isAppearing = true
+ showAnimation.alphaAnimator.set(current: 0)
+ showAnimation.alphaAnimator.animate(to: 1, duration: .defaultDuration)
+ showAnimation.alphaAnimator.completionClosure = { [weak self, weak showAnimation] in
+ guard let self = self, let showAnimation = showAnimation else { return }
+ self.animatedHorizontalLabels.removeAll(where: { $0 === showAnimation })
+ self.horizontalLabels = labels
+ }
+
+ let hideAnimation = AnimatedLinesChartLabels(labels: labelsToHide, alphaAnimator: AnimationController(current: 1.0, refreshClosure: refreshClosure))
+ hideAnimation.isAppearing = false
+ hideAnimation.alphaAnimator.set(current: 1)
+ hideAnimation.alphaAnimator.animate(to: 0, duration: .defaultDuration)
+ hideAnimation.alphaAnimator.completionClosure = { [weak self, weak hideAnimation] in
+ guard let self = self, let hideAnimation = hideAnimation else { return }
+ self.animatedHorizontalLabels.removeAll(where: { $0 === hideAnimation })
+ }
+
+ animatedHorizontalLabels.append(showAnimation)
+ animatedHorizontalLabels.append(hideAnimation)
+ } else {
+ horizontalLabels = labels
+ animatedHorizontalLabels = []
+ }
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ let itemsAlpha = chartAlphaAnimator.current
+ guard itemsAlpha > 0 else { return }
+
+ let range = renderRange(bounds: bounds, chartFrame: chartFrame)
+
+ func drawHorizontalLabels(_ labels: [LinesChartLabel], color: UIColor) {
+ let attributes: [NSAttributedString.Key : Any] = [.foregroundColor: color,
+ .font: labelsFont]
+ let y = chartFrame.origin.y + chartFrame.height + labelsVerticalOffset
+
+ if let start = labels.firstIndex(where: { $0.value > range.lowerBound }) {
+ for index in start.. range.upperBound {
+ break
+ }
+ }
+ }
+ }
+ let labelColorAlpha = labelsColor.alphaValue * itemsAlpha
+ drawHorizontalLabels(horizontalLabels, color: labelsColor.withAlphaComponent(labelColorAlpha * itemsAlpha))
+ for animation in animatedHorizontalLabels {
+ let color = labelsColor.withAlphaComponent(animation.alphaAnimator.current * labelColorAlpha)
+ drawHorizontalLabels(animation.labels, color: color)
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/LineBulletsRenerer.swift b/submodules/Charts/Sources/Charts/Renderes/LineBulletsRenerer.swift
new file mode 100644
index 0000000000..e0417719d7
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/LineBulletsRenerer.swift
@@ -0,0 +1,67 @@
+//
+// LineBulletsRenerer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/8/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class LineBulletsRenerer: BaseChartRenderer {
+ struct Bullet {
+ var coordinate: CGPoint
+ var color: UIColor
+ }
+
+ var bullets: [Bullet] = [] {
+ willSet {
+ if alphaAnimators.count != newValue.count {
+ alphaAnimators = newValue.map { _ in AnimationController(current: 1.0, refreshClosure: refreshClosure) }
+ }
+ }
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+ private var alphaAnimators: [AnimationController] = []
+
+ private lazy var innerColorAnimator = AnimationController(current: UIColorContainer(color: .white), refreshClosure: refreshClosure)
+ public func setInnerColor(_ color: UIColor, animated: Bool) {
+ if animated {
+ innerColorAnimator.animate(to: UIColorContainer(color: color), duration: .defaultDuration)
+ } else {
+ innerColorAnimator.set(current: UIColorContainer(color: color))
+ }
+ }
+
+ var linesWidth: CGFloat = 2
+ var bulletRadius: CGFloat = 6
+
+ func setLineVisible(_ isVisible: Bool, at index: Int, animated: Bool) {
+ alphaAnimators[index].animate(to: isVisible ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ let generalAlpha = chartAlphaAnimator.current
+ if generalAlpha == 0 { return }
+
+ for (index, bullet) in bullets.enumerated() {
+ let alpha = alphaAnimators[index].current
+ if alpha == 0 { continue }
+
+ let centerX = transform(toChartCoordinateHorizontal: bullet.coordinate.x, chartFrame: chartFrame)
+ let centerY = transform(toChartCoordinateVertical: bullet.coordinate.y, chartFrame: chartFrame)
+ context.setFillColor(innerColorAnimator.current.color.withAlphaComponent(alpha).cgColor)
+ context.setStrokeColor(bullet.color.withAlphaComponent(alpha).cgColor)
+ context.setLineWidth(linesWidth)
+ let rect = CGRect(x: centerX - bulletRadius / 2,
+ y: centerY - bulletRadius / 2,
+ width: bulletRadius,
+ height: bulletRadius)
+ context.fillEllipse(in: rect)
+ context.strokeEllipse(in: rect)
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/LinesChartRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/LinesChartRenderer.swift
new file mode 100644
index 0000000000..fe3cdd47ab
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/LinesChartRenderer.swift
@@ -0,0 +1,538 @@
+//
+// LinesChartRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class LinesChartRenderer: BaseChartRenderer {
+ struct LineData {
+ var color: UIColor
+ var points: [CGPoint]
+ }
+
+ private var linesAlphaAnimators: [AnimationController] = []
+
+ var lineWidth: CGFloat = 1 {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+ private lazy var linesShapeAnimator = AnimationController(current: 1, refreshClosure: self.refreshClosure)
+ private var fromLines: [LineData] = []
+ private var toLines: [LineData] = []
+
+ func setLines(lines: [LineData], animated: Bool) {
+ if toLines.count != lines.count {
+ linesAlphaAnimators = lines.map { _ in AnimationController(current: 1, refreshClosure: self.refreshClosure) }
+ }
+ if animated {
+ self.fromLines = self.toLines
+ self.toLines = lines
+ linesShapeAnimator.set(current: 1.0 - linesShapeAnimator.current)
+ linesShapeAnimator.completionClosure = {
+ self.fromLines = []
+ }
+ linesShapeAnimator.animate(to: 1, duration: .defaultDuration)
+ } else {
+ self.fromLines = []
+ self.toLines = lines
+ linesShapeAnimator.set(current: 1)
+ }
+ }
+
+ func setLineVisible(_ isVisible: Bool, at index: Int, animated: Bool) {
+ linesAlphaAnimators[index].animate(to: isVisible ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ let chartsAlpha = chartAlphaAnimator.current
+ if chartsAlpha == 0 { return }
+ let range = renderRange(bounds: bounds, chartFrame: chartFrame)
+
+ for (index, toLine) in toLines.enumerated() {
+ let alpha = linesAlphaAnimators[index].current * chartsAlpha
+ if alpha == 0 { continue }
+ context.setStrokeColor(toLine.color.withAlphaComponent(alpha).cgColor)
+ context.setLineWidth(lineWidth)
+
+ if linesShapeAnimator.isAnimating {
+ let animationOffset = linesShapeAnimator.current
+
+ let path = CGMutablePath()
+ let fromPoints = fromLines.safeElement(at: index)?.points ?? []
+ let toPoints = toLines.safeElement(at: index)?.points ?? []
+
+ var fromIndex: Int? = fromPoints.firstIndex(where: { $0.x >= range.lowerBound })
+ var toIndex: Int? = toPoints.firstIndex(where: { $0.x >= range.lowerBound })
+
+ let fromRange = verticalRange.start
+ let currentRange = verticalRange.current
+ let toRange = verticalRange.end
+
+ func convertFromPoint(_ fromPoint: CGPoint) -> CGPoint {
+ return CGPoint(x: fromPoint.x,
+ y: (fromPoint.y - fromRange.lowerBound) / fromRange.distance * currentRange.distance + currentRange.lowerBound)
+ }
+
+ func convertToPoint(_ toPoint: CGPoint) -> CGPoint {
+ return CGPoint(x: toPoint.x,
+ y: (toPoint.y - toRange.lowerBound) / toRange.distance * currentRange.distance + currentRange.lowerBound)
+ }
+
+ var previousFromPoint: CGPoint
+ var previousToPoint: CGPoint
+ let startFromPoint: CGPoint?
+ let startToPoint: CGPoint?
+
+ if let validFrom = fromIndex {
+ previousFromPoint = convertFromPoint(fromPoints[max(0, validFrom - 1)])
+ startFromPoint = previousFromPoint
+ } else {
+ previousFromPoint = .zero
+ startFromPoint = nil
+ }
+ if let validTo = toIndex {
+ previousToPoint = convertToPoint(toPoints[max(0, validTo - 1)])
+ startToPoint = previousToPoint
+ } else {
+ previousToPoint = .zero
+ startToPoint = nil
+ }
+
+ var combinedPoints: [CGPoint] = []
+
+ func add(pointToDraw: CGPoint) {
+ if let startFromPoint = startFromPoint,
+ pointToDraw.x < startFromPoint.x {
+ let animatedPoint = CGPoint(x: pointToDraw.x,
+ y: CGFloat.valueBetween(start: startFromPoint.y, end: pointToDraw.y, offset: animationOffset))
+ combinedPoints.append(transform(toChartCoordinate: animatedPoint, chartFrame: chartFrame))
+ } else if let startToPoint = startToPoint,
+ pointToDraw.x < startToPoint.x {
+ let animatedPoint = CGPoint(x: pointToDraw.x,
+ y: CGFloat.valueBetween(start: startToPoint.y, end: pointToDraw.y, offset: 1 - animationOffset))
+ combinedPoints.append(transform(toChartCoordinate: animatedPoint, chartFrame: chartFrame))
+ } else {
+ combinedPoints.append(transform(toChartCoordinate: pointToDraw, chartFrame: chartFrame))
+ }
+ }
+
+ if previousToPoint != .zero && previousFromPoint != .zero {
+ add(pointToDraw: (previousToPoint.x < previousFromPoint.x ? previousToPoint : previousFromPoint))
+ } else if previousToPoint != .zero {
+ add(pointToDraw: previousToPoint)
+ } else if previousFromPoint != .zero {
+ add(pointToDraw: previousFromPoint)
+ }
+
+ while let validFromIndex = fromIndex,
+ let validToIndex = toIndex,
+ validFromIndex < fromPoints.count,
+ validToIndex < toPoints.count {
+ let currentFromPoint = convertFromPoint(fromPoints[validFromIndex])
+ let currentToPoint = convertToPoint(toPoints[validToIndex])
+ let pointToAdd: CGPoint
+ if currentFromPoint.x == currentToPoint.x {
+ pointToAdd = CGPoint.valueBetween(start: currentFromPoint, end: currentToPoint, offset: animationOffset)
+ previousFromPoint = currentFromPoint
+ previousToPoint = currentToPoint
+ fromIndex = validFromIndex + 1
+ toIndex = validToIndex + 1
+ } else if currentFromPoint.x < currentToPoint.x {
+ if previousToPoint.x < currentFromPoint.x {
+ let offset = Double((currentFromPoint.x - previousToPoint.x) / (currentToPoint.x - previousToPoint.x))
+ let intermidiateToPoint = CGPoint.valueBetween(start: previousToPoint, end: currentToPoint, offset: offset)
+ pointToAdd = CGPoint.valueBetween(start: currentFromPoint, end: intermidiateToPoint, offset: animationOffset)
+ } else {
+ pointToAdd = currentFromPoint
+ }
+ previousFromPoint = currentFromPoint
+ fromIndex = validFromIndex + 1
+ } else {
+ if previousFromPoint.x < currentToPoint.x {
+ let offset = Double((currentToPoint.x - previousFromPoint.x) / (currentFromPoint.x - previousFromPoint.x))
+ let intermidiateFromPoint = CGPoint.valueBetween(start: previousFromPoint, end: currentFromPoint, offset: offset)
+ pointToAdd = CGPoint.valueBetween(start: intermidiateFromPoint, end: currentToPoint, offset: animationOffset)
+ } else {
+ pointToAdd = currentToPoint
+ }
+ previousToPoint = currentToPoint
+ toIndex = validToIndex + 1
+ }
+ add(pointToDraw: pointToAdd)
+ if (pointToAdd.x > range.upperBound) {
+ break
+ }
+ }
+
+ while let validToIndex = toIndex, validToIndex < toPoints.count {
+ var pointToAdd = convertToPoint(toPoints[validToIndex])
+ pointToAdd.y = CGFloat.valueBetween(start: previousFromPoint.y,
+ end: pointToAdd.y,
+ offset: animationOffset)
+
+ add(pointToDraw: pointToAdd)
+ if (pointToAdd.x > range.upperBound) {
+ break
+ }
+
+ toIndex = validToIndex + 1
+ }
+
+ while let validFromIndex = fromIndex, validFromIndex < fromPoints.count {
+ var pointToAdd = convertFromPoint(fromPoints[validFromIndex])
+ pointToAdd.y = CGFloat.valueBetween(start: previousToPoint.y,
+ end: pointToAdd.y,
+ offset: 1 - animationOffset)
+
+ add(pointToDraw: pointToAdd)
+ if (pointToAdd.x > range.upperBound) {
+ break
+ }
+
+ fromIndex = validFromIndex + 1
+ }
+
+ var index = 0
+ var lines: [CGPoint] = []
+ var currentChartPoint = combinedPoints[index]
+ lines.append(currentChartPoint)
+
+ var chartPoints = [currentChartPoint]
+ var minIndex = 0
+ var maxIndex = 0
+ index += 1
+
+ while index < combinedPoints.count {
+ currentChartPoint = combinedPoints[index]
+
+ if currentChartPoint.x - chartPoints[0].x < lineWidth * optimizationLevel {
+ chartPoints.append(currentChartPoint)
+
+ if currentChartPoint.y > chartPoints[maxIndex].y {
+ maxIndex = chartPoints.count - 1
+ }
+ if currentChartPoint.y < chartPoints[minIndex].y {
+ minIndex = chartPoints.count - 1
+ }
+
+ index += 1
+ } else {
+ if chartPoints.count == 1 {
+ lines.append(currentChartPoint)
+ lines.append(currentChartPoint)
+ chartPoints[0] = currentChartPoint
+ index += 1
+ minIndex = 0
+ maxIndex = 0
+ } else {
+ if minIndex < maxIndex {
+ if minIndex != 0 {
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ }
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ if maxIndex != chartPoints.count - 1 {
+ chartPoints = [chartPoints[maxIndex], chartPoints.last!]
+ } else {
+ chartPoints = [chartPoints[maxIndex]]
+ }
+ } else {
+ if maxIndex != 0 {
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ }
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ if minIndex != chartPoints.count - 1 {
+ chartPoints = [chartPoints[minIndex], chartPoints.last!]
+ } else {
+ chartPoints = [chartPoints[minIndex]]
+ }
+ }
+ if chartPoints.count == 2 {
+ if chartPoints[0].y < chartPoints[1].y {
+ minIndex = 0
+ maxIndex = 1
+ } else {
+ minIndex = 1
+ maxIndex = 0
+ }
+ } else {
+ minIndex = 0
+ maxIndex = 0
+ }
+ }
+ }
+ }
+
+ if chartPoints.count == 1 {
+ lines.append(currentChartPoint)
+ lines.append(currentChartPoint)
+ } else {
+ if minIndex < maxIndex {
+ if minIndex != 0 {
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ }
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ if maxIndex != chartPoints.count - 1 {
+ lines.append(chartPoints.last!)
+ lines.append(chartPoints.last!)
+ }
+ } else {
+ if maxIndex != 0 {
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ }
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ if minIndex != chartPoints.count - 1 {
+ lines.append(chartPoints.last!)
+ lines.append(chartPoints.last!)
+ }
+ }
+ }
+
+ if (lines.count % 2) == 1 {
+ lines.removeLast()
+ }
+
+ context.setLineCap(.round)
+ context.strokeLineSegments(between: lines)
+
+ } else {
+ let alpha = linesAlphaAnimators[index].current * chartsAlpha
+ if alpha == 0 { continue }
+ context.setStrokeColor(toLine.color.withAlphaComponent(alpha).cgColor)
+ context.setLineWidth(lineWidth)
+
+ if var index = toLine.points.firstIndex(where: { $0.x >= range.lowerBound }) {
+ var lines: [CGPoint] = []
+ index = max(0, index - 1)
+ var currentPoint = toLine.points[index]
+ var currentChartPoint = transform(toChartCoordinate: currentPoint, chartFrame: chartFrame)
+ lines.append(currentChartPoint)
+ //context.move(to: currentChartPoint)
+
+ var chartPoints = [currentChartPoint]
+ var minIndex = 0
+ var maxIndex = 0
+ index += 1
+
+ while index < toLine.points.count {
+ currentPoint = toLine.points[index]
+ currentChartPoint = transform(toChartCoordinate: currentPoint, chartFrame: chartFrame)
+
+ if currentChartPoint.x - chartPoints[0].x < lineWidth * optimizationLevel {
+ chartPoints.append(currentChartPoint)
+
+ if currentChartPoint.y > chartPoints[maxIndex].y {
+ maxIndex = chartPoints.count - 1
+ }
+ if currentChartPoint.y < chartPoints[minIndex].y {
+ minIndex = chartPoints.count - 1
+ }
+
+ index += 1
+ } else {
+ if chartPoints.count == 1 {
+ lines.append(currentChartPoint)
+ lines.append(currentChartPoint)
+ chartPoints[0] = currentChartPoint
+ index += 1
+ minIndex = 0
+ maxIndex = 0
+ } else {
+ if minIndex < maxIndex {
+ if minIndex != 0 {
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ }
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ if maxIndex != chartPoints.count - 1 {
+ chartPoints = [chartPoints[maxIndex], chartPoints.last!]
+ } else {
+ chartPoints = [chartPoints[maxIndex]]
+ }
+ } else {
+ if maxIndex != 0 {
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ }
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ if minIndex != chartPoints.count - 1 {
+ chartPoints = [chartPoints[minIndex], chartPoints.last!]
+ } else {
+ chartPoints = [chartPoints[minIndex]]
+ }
+ }
+ if chartPoints.count == 2 {
+ if chartPoints[0].y < chartPoints[1].y {
+ minIndex = 0
+ maxIndex = 1
+ } else {
+ minIndex = 1
+ maxIndex = 0
+ }
+ } else {
+ minIndex = 0
+ maxIndex = 0
+ }
+ }
+ }
+ if currentPoint.x > range.upperBound {
+ break
+ }
+ }
+
+ if chartPoints.count == 1 {
+ lines.append(currentChartPoint)
+ lines.append(currentChartPoint)
+ } else {
+ if minIndex < maxIndex {
+ if minIndex != 0 {
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ }
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ if maxIndex != chartPoints.count - 1 {
+ lines.append(chartPoints.last!)
+ lines.append(chartPoints.last!)
+ }
+ } else {
+ if maxIndex != 0 {
+ lines.append(chartPoints[maxIndex])
+ lines.append(chartPoints[maxIndex])
+ }
+ lines.append(chartPoints[minIndex])
+ lines.append(chartPoints[minIndex])
+ if minIndex != chartPoints.count - 1 {
+ lines.append(chartPoints.last!)
+ lines.append(chartPoints.last!)
+ }
+ }
+ }
+
+ if (lines.count % 2) == 1 {
+ lines.removeLast()
+ }
+
+ context.setLineCap(.round)
+ context.strokeLineSegments(between: lines)
+ }
+
+// if var start = toLine.points.firstIndex(where: { $0.x > range.lowerBound }) {
+// let alpha = linesAlphaAnimators[index].current * chartsAlpha
+// if alpha == 0 { continue }
+// context.setStrokeColor(toLine.color.withAlphaComponent(alpha).cgColor)
+// context.setLineWidth(lineWidth)
+//
+// context.setLineCap(.round)
+// start = max(0, start - 1)
+// let startPoint = toLine.points[start]
+// var lines: [CGPoint] = []
+// var pointToDraw = CGPoint(x: transform(toChartCoordinateHorizontal: startPoint.x, chartFrame: chartFrame),
+// y: transform(toChartCoordinateVertical: startPoint.y, chartFrame: chartFrame))
+// for index in (start + 1).. range.upperBound {
+// break
+// }
+// }
+//
+// context.strokeLineSegments(between: lines)
+// }
+ }
+ }
+ }
+}
+
+extension LinesChartRenderer.LineData {
+ static func initialComponents(chartsCollection: ChartsCollection) -> (linesData: [LinesChartRenderer.LineData],
+ totalHorizontalRange: ClosedRange,
+ totalVerticalRange: ClosedRange) {
+ let lines: [LinesChartRenderer.LineData] = chartsCollection.chartValues.map { chart in
+ let points = chart.values.enumerated().map({ (arg) -> CGPoint in
+ return CGPoint(x: chartsCollection.axisValues[arg.offset].timeIntervalSince1970,
+ y: arg.element)
+ })
+ return LinesChartRenderer.LineData(color: chart.color, points: points)
+ }
+ let horizontalRange = LinesChartRenderer.LineData.horizontalRange(lines: lines) ?? BaseConstants.defaultRange
+ let verticalRange = LinesChartRenderer.LineData.verticalRange(lines: lines) ?? BaseConstants.defaultRange
+ return (linesData: lines, totalHorizontalRange: horizontalRange, totalVerticalRange: verticalRange)
+ }
+
+ static func horizontalRange(lines: [LinesChartRenderer.LineData]) -> ClosedRange? {
+ guard let firstPoint = lines.first?.points.first else { return nil }
+ var hMin: CGFloat = firstPoint.x
+ var hMax: CGFloat = firstPoint.x
+
+ for line in lines {
+ if let first = line.points.first,
+ let last = line.points.last {
+ hMin = min(hMin, first.x)
+ hMax = max(hMax, last.x)
+ }
+ }
+
+ return hMin...hMax
+ }
+
+ static func verticalRange(lines: [LinesChartRenderer.LineData], calculatingRange: ClosedRange? = nil, addBounds: Bool = false) -> ClosedRange? {
+ if let calculatingRange = calculatingRange {
+ guard let initalStart = lines.first?.points.first(where: { $0.x >= calculatingRange.lowerBound &&
+ $0.x <= calculatingRange.upperBound }) else { return nil }
+ var vMin: CGFloat = initalStart.y
+ var vMax: CGFloat = initalStart.y
+ for line in lines {
+ if var index = line.points.firstIndex(where: { $0.x > calculatingRange.lowerBound }) {
+ if addBounds {
+ index = max(0, index - 1)
+ }
+ while index < line.points.count {
+ let point = line.points[index]
+ if point.x < calculatingRange.upperBound {
+ vMin = min(vMin, point.y)
+ vMax = max(vMax, point.y)
+ } else if addBounds {
+ vMin = min(vMin, point.y)
+ vMax = max(vMax, point.y)
+ break
+ } else {
+ break
+ }
+ index += 1
+ }
+ }
+ }
+ return vMin...vMax
+ } else {
+ guard let firstPoint = lines.first?.points.first else { return nil }
+ var vMin: CGFloat = firstPoint.y
+ var vMax: CGFloat = firstPoint.y
+ for line in lines {
+ for point in line.points {
+ vMin = min(vMin, point.y)
+ vMax = max(vMax, point.y)
+ }
+ }
+ return vMin...vMax
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/PecentChartRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/PecentChartRenderer.swift
new file mode 100644
index 0000000000..07ff3daaaa
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/PecentChartRenderer.swift
@@ -0,0 +1,132 @@
+//
+// PecentChartRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class PecentChartRenderer: BaseChartRenderer {
+ struct PercentageData {
+ static let blank = PecentChartRenderer.PercentageData(locations: [], components: [])
+ var locations: [CGFloat]
+ var components: [Component]
+
+ struct Component {
+ var color: UIColor
+ var values: [CGFloat]
+ }
+ }
+
+ override func setup(verticalRange: ClosedRange, animated: Bool, timeFunction: TimeFunction? = nil) {
+ super.setup(verticalRange: 0...1, animated: animated, timeFunction: timeFunction)
+ }
+
+ private var componentsAnimators: [AnimationController] = []
+ var percentageData: PercentageData = PercentageData(locations: [], components: []) {
+ willSet {
+ if percentageData.components.count != newValue.components.count {
+ componentsAnimators = newValue.components.map { _ in AnimationController(current: 1, refreshClosure: self.refreshClosure) }
+ }
+ }
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+
+ func setComponentVisible(_ isVisible: Bool, at index: Int, animated: Bool) {
+ componentsAnimators[index].animate(to: isVisible ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ let alpha = chartAlphaAnimator.current
+ guard alpha > 0 else { return }
+
+ let range = renderRange(bounds: bounds, chartFrame: chartFrame)
+
+ var paths: [CGMutablePath] = percentageData.components.map { _ in CGMutablePath() }
+ var vertices: [CGFloat] = Array(repeating: 0, count: percentageData.components.count)
+
+ if var locationIndex = percentageData.locations.firstIndex(where: { $0 > range.lowerBound }) {
+ locationIndex = max(0, locationIndex - 1)
+
+ var currentLocation = transform(toChartCoordinateHorizontal: percentageData.locations[locationIndex], chartFrame: chartFrame)
+
+ let startPoint = CGPoint(x: currentLocation,
+ y: transform(toChartCoordinateVertical: verticalRange.current.lowerBound, chartFrame: chartFrame))
+
+ for path in paths {
+ path.move(to: startPoint)
+ }
+ paths.last?.addLine(to: CGPoint(x: currentLocation,
+ y: transform(toChartCoordinateVertical: verticalRange.current.upperBound, chartFrame: chartFrame)))
+
+ while locationIndex < percentageData.locations.count {
+ currentLocation = transform(toChartCoordinateHorizontal: percentageData.locations[locationIndex], chartFrame: chartFrame)
+ var summ: CGFloat = 0
+
+ for (index, component) in percentageData.components.enumerated() {
+ let visibilityPercent = componentsAnimators[index].current
+
+ let value = component.values[locationIndex] * visibilityPercent
+ if index == 0 {
+ vertices[index] = value
+ } else {
+ vertices[index] = value + vertices[index - 1]
+ }
+ summ += value
+ }
+
+ if summ > 0 {
+ for (index, value) in vertices.dropLast().enumerated() {
+ paths[index].addLine(to: CGPoint(x: currentLocation,
+ y: transform(toChartCoordinateVertical: value / summ, chartFrame: chartFrame)))
+ }
+ }
+
+ if currentLocation > range.upperBound {
+ break
+ }
+
+ locationIndex += 1
+ }
+
+ paths.last?.addLine(to: CGPoint(x: currentLocation,
+ y: transform(toChartCoordinateVertical: verticalRange.current.upperBound, chartFrame: chartFrame)))
+
+ let endPoint = CGPoint(x: currentLocation,
+ y: transform(toChartCoordinateVertical: verticalRange.current.lowerBound, chartFrame: chartFrame))
+
+ for (index, path) in paths.enumerated().reversed() {
+ let visibilityPercent = componentsAnimators[index].current
+ if visibilityPercent == 0 { continue }
+
+ path.addLine(to: endPoint)
+ path.closeSubpath()
+
+ context.saveGState()
+ context.beginPath()
+ context.addPath(path)
+
+ context.setFillColor(percentageData.components[index].color.cgColor)
+ context.fillPath()
+ context.restoreGState()
+ }
+ }
+ }
+}
+
+extension PecentChartRenderer.PercentageData {
+ static func horizontalRange(data: PecentChartRenderer.PercentageData) -> ClosedRange? {
+ guard let firstPoint = data.locations.first,
+ let lastPoint = data.locations.last,
+ firstPoint <= lastPoint else {
+ return nil
+ }
+
+ return firstPoint...lastPoint
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/PercentPieAnimationRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/PercentPieAnimationRenderer.swift
new file mode 100644
index 0000000000..e36fdaf913
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/PercentPieAnimationRenderer.swift
@@ -0,0 +1,202 @@
+//
+// PercentPieAnimationRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class PercentPieAnimationRenderer: BaseChartRenderer {
+ override func setup(verticalRange: ClosedRange, animated: Bool, timeFunction: TimeFunction? = nil) {
+ super.setup(verticalRange: 0...1, animated: animated, timeFunction: timeFunction)
+ }
+
+ private lazy var transitionAnimator = AnimationController(current: 0, refreshClosure: refreshClosure)
+ private var animationComponentsPoints: [[CGPoint]] = []
+ var visiblePercentageData: PecentChartRenderer.PercentageData = .blank {
+ didSet {
+ animationComponentsPoints = []
+ }
+ }
+ var visiblePieComponents: [PieChartRenderer.PieComponent] = []
+
+ func animate(fromDataToPie: Bool, animated: Bool, completion: @escaping () -> Void) {
+ assert(visiblePercentageData.components.count == visiblePieComponents.count)
+
+ isEnabled = true
+ transitionAnimator.completionClosure = { [weak self] in
+ self?.isEnabled = false
+ completion()
+ }
+ transitionAnimator.animate(to: fromDataToPie ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+
+ private func generateAnimationComponentPoints(bounds: CGRect, chartFrame: CGRect) {
+ let range = renderRange(bounds: bounds, chartFrame: chartFrame)
+
+ let componentsCount = visiblePercentageData.components.count
+ guard componentsCount > 0 else { return }
+ animationComponentsPoints = visiblePercentageData.components.map { _ in [] }
+ var vertices: [CGFloat] = Array(repeating: 0, count: visiblePercentageData.components.count)
+
+ if var locationIndex = visiblePercentageData.locations.firstIndex(where: { $0 > range.lowerBound }) {
+ locationIndex = max(0, locationIndex - 1)
+ var currentLocation = transform(toChartCoordinateHorizontal: visiblePercentageData.locations[locationIndex], chartFrame: chartFrame)
+ let startPoint = CGPoint(x: currentLocation, y: transform(toChartCoordinateVertical: verticalRange.current.lowerBound, chartFrame: chartFrame))
+ for index in 0.. range.upperBound {
+ break
+ }
+ locationIndex += 1
+ }
+
+ animationComponentsPoints[componentsCount - 1].append(CGPoint(x: currentLocation, y: transform(toChartCoordinateVertical: verticalRange.current.upperBound, chartFrame: chartFrame)))
+ let endPoint = CGPoint(x: currentLocation, y: transform(toChartCoordinateVertical: verticalRange.current.lowerBound, chartFrame: chartFrame))
+ for index in 0.. 0 && verticalRange.current.distance > 0 else { return }
+ self.optimizationLevel = 1
+
+ if animationComponentsPoints.isEmpty {
+ generateAnimationComponentPoints(bounds: bounds, chartFrame: chartFrame)
+ }
+
+ let numberOfComponents = animationComponentsPoints.count
+ guard numberOfComponents > 0 else { return }
+ let destinationRadius = max(chartFrame.width, chartFrame.height)
+
+ let animationFraction = transitionAnimator.current
+ let animationFractionD = Double(transitionAnimator.current)
+ let easeInAnimationFractionD = animationFractionD * animationFractionD * animationFractionD * animationFractionD
+ let center = CGPoint(x: chartFrame.midX, y: chartFrame.midY)
+ let totalPieSumm: CGFloat = visiblePieComponents.map { $0.value } .reduce(0, +)
+
+ let pathsToDraw: [CGMutablePath] = (0.. 4 else {
+ return
+ }
+
+ let percent = visiblePieComponents[componentIndex].value / totalPieSumm
+ let segmentSize = 2 * .pi * percent
+ let endAngle = startAngle + segmentSize
+ let centerAngle = (startAngle + endAngle) / 2
+
+ let lineCenterPoint = CGPoint.valueBetween(start: componentPoints[componentPoints.count / 2],
+ end: center,
+ offset: animationFractionD)
+
+ let startDestinationPoint = lineCenterPoint + CGPoint(x: destinationRadius, y: 0)
+ let centerDestinationPoint = lineCenterPoint + CGPoint(x: 0, y: destinationRadius)
+ let endDestinationPoint = lineCenterPoint + CGPoint(x: -destinationRadius, y: 0)
+ let initialStartDestinationAngle: CGFloat = 0
+ let initialCenterDestinationAngle: CGFloat = .pi / 2
+ let initialEndDestinationAngle: CGFloat = .pi
+
+ var previousAddedPoint = (componentPoints[0] * 2 - center)
+ .rotate(origin: lineCenterPoint, angle: CGFloat.valueBetween(start: 0, end: centerAngle - initialCenterDestinationAngle, offset: animationFractionD))
+
+ pathsToDraw[componentIndex].move(to: previousAddedPoint)
+
+ func addPointToPath(_ point: CGPoint) {
+ if (point - previousAddedPoint).lengthSquared() > optimizationLevel {
+ pathsToDraw[componentIndex].addLine(to: point)
+ previousAddedPoint = point
+ }
+ }
+
+ for endPointIndex in 1..<(componentPoints.count / 2) {
+ addPointToPath(CGPoint.valueBetween(start: componentPoints[endPointIndex], end: endDestinationPoint, offset: easeInAnimationFractionD)
+ .rotate(origin: lineCenterPoint, angle: CGFloat.valueBetween(start: 0, end: endAngle - initialEndDestinationAngle, offset: animationFractionD)))
+ }
+
+ addPointToPath(lineCenterPoint)
+
+ for startPointIndex in (componentPoints.count / 2 + 1)..<(componentPoints.count - 1) {
+ addPointToPath(CGPoint.valueBetween(start: componentPoints[startPointIndex], end: startDestinationPoint, offset: easeInAnimationFractionD)
+ .rotate(origin: lineCenterPoint, angle: CGFloat.valueBetween(start: 0, end: startAngle - initialStartDestinationAngle, offset: animationFractionD)))
+ }
+
+ if let lastPoint = componentPoints.last {
+ addPointToPath((lastPoint * 2 - center)
+ .rotate(origin: lineCenterPoint, angle: CGFloat.valueBetween(start: 0, end: centerAngle - initialCenterDestinationAngle, offset: animationFractionD)))
+ }
+
+ startAngle = endAngle
+ }
+
+ if let lastPath = animationComponentsPoints.last {
+ pathsToDraw.last?.addLines(between: lastPath)
+ }
+
+ for (index, path) in pathsToDraw.enumerated().reversed() {
+ path.closeSubpath()
+
+ context.saveGState()
+ context.beginPath()
+ context.addPath(path)
+
+ context.setFillColor(visiblePieComponents[index].color.cgColor)
+ context.fillPath()
+ context.restoreGState()
+ }
+
+ let diagramRadius = (min(chartFrame.width, chartFrame.height) / 2) * 0.925
+ let targetFrame = CGRect(origin: CGPoint(x: center.x - diagramRadius,
+ y: center.y - diagramRadius),
+ size: CGSize(width: diagramRadius * 2,
+ height: diagramRadius * 2))
+
+ let minX = animationComponentsPoints.last?.first?.x ?? 0
+ let maxX = animationComponentsPoints.last?.last?.x ?? 0
+ let startFrame = CGRect(x: minX,
+ y: chartFrame.minY,
+ width: maxX - minX,
+ height: chartFrame.height)
+ let cornerRadius = diagramRadius * animationFraction
+ let fadeOutFrame = CGRect.valueBetween(start: startFrame, end: targetFrame, offset: animationFractionD)
+ let fadeOutPath = CGMutablePath()
+ fadeOutPath.addRect(bounds)
+ fadeOutPath.addPath(CGPath(roundedRect: fadeOutFrame, cornerWidth: cornerRadius, cornerHeight: cornerRadius, transform: nil))
+
+ context.saveGState()
+ context.beginPath()
+ context.addPath(fadeOutPath)
+ context.setFillColor(backgroundColor.cgColor)
+ context.fillPath(using: .evenOdd)
+ context.restoreGState()
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/PerformanceRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/PerformanceRenderer.swift
new file mode 100644
index 0000000000..c17663ce5f
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/PerformanceRenderer.swift
@@ -0,0 +1,31 @@
+//
+// PerformanceRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/10/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class PerformanceRenderer: ChartViewRenderer {
+ var containerViews: [UIView] = []
+
+ private var previousTickTime: TimeInterval = CACurrentMediaTime()
+
+ func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ let currentTime = CACurrentMediaTime()
+ let delta = currentTime - previousTickTime
+ previousTickTime = currentTime
+
+ let normalDelta = 0.017
+ let redDelta = 0.05
+
+ if delta > normalDelta || delta < 0.75 {
+ let green = CGFloat( 1.0 - crop(0, (delta - normalDelta) / (redDelta - normalDelta), 1))
+ let color = UIColor(red: 1.0, green: green, blue: 0, alpha: 1)
+ context.setFillColor(color.cgColor)
+ context.fill(CGRect(x: 0, y: 0, width: bounds.width, height: 3))
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/PieChartRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/PieChartRenderer.swift
new file mode 100644
index 0000000000..ed4e6bdd49
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/PieChartRenderer.swift
@@ -0,0 +1,191 @@
+//
+// PieChartRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class PieChartRenderer: BaseChartRenderer {
+ struct PieComponent: Hashable {
+ var color: UIColor
+ var value: CGFloat
+ }
+
+ override func setup(verticalRange: ClosedRange, animated: Bool, timeFunction: TimeFunction? = nil) {
+ super.setup(verticalRange: 0...1, animated: animated, timeFunction: timeFunction)
+ }
+
+ var valuesFormatter: NumberFormatter = NumberFormatter()
+ var drawValues: Bool = true
+
+ private var componentsAnimators: [AnimationController] = []
+ private lazy var transitionAnimator: AnimationController = { AnimationController(current: 1, refreshClosure: self.refreshClosure) }()
+ private var oldPercentageData: [PieComponent] = []
+ private var percentageData: [PieComponent] = []
+ private var setlectedSegmentsAnimators: [AnimationController] = []
+
+ var drawPie: Bool = true
+ var initialAngle: CGFloat = .pi / 3
+ var hasSelectedSegments: Bool {
+ return selectedSegment != nil
+ }
+ private(set) var selectedSegment: Int?
+ func selectSegmentAt(at indexToSelect: Int?, animated: Bool) {
+ selectedSegment = indexToSelect
+ for (index, animator) in setlectedSegmentsAnimators.enumerated() {
+ let fraction: CGFloat = (index == indexToSelect) ? 1.0 : 0.0
+ if animated {
+ animator.animate(to: fraction, duration: .defaultDuration / 2)
+ } else {
+ animator.set(current: fraction)
+ }
+ }
+ }
+
+ func updatePercentageData(_ percentageData: [PieComponent], animated: Bool) {
+ if self.percentageData.count != percentageData.count {
+ componentsAnimators = percentageData.map { _ in AnimationController(current: 1, refreshClosure: self.refreshClosure) }
+ setlectedSegmentsAnimators = percentageData.map { _ in AnimationController(current: 0, refreshClosure: self.refreshClosure) }
+ }
+ if animated {
+ self.oldPercentageData = self.currentTransitionAnimationData
+ self.percentageData = percentageData
+ transitionAnimator.completionClosure = { [weak self] in
+ self?.oldPercentageData = []
+ }
+ transitionAnimator.set(current: 0)
+ transitionAnimator.animate(to: 1, duration: .defaultDuration)
+ } else {
+ self.oldPercentageData = []
+ self.percentageData = percentageData
+ transitionAnimator.set(current: 0)
+ }
+ }
+
+ func setComponentVisible(_ isVisible: Bool, at index: Int, animated: Bool) {
+ componentsAnimators[index].animate(to: isVisible ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+
+ var lastRenderedBounds: CGRect = .zero
+ var lastRenderedChartFrame: CGRect = .zero
+ func selectedItemIndex(at point: CGPoint) -> Int? {
+ let touchPosition = lastRenderedChartFrame.origin + point * lastRenderedChartFrame.size
+ let center = CGPoint(x: lastRenderedChartFrame.midX, y: lastRenderedChartFrame.midY)
+ let radius = min(lastRenderedChartFrame.width, lastRenderedChartFrame.height) / 2
+ if center.distanceTo(touchPosition) > radius { return nil }
+ let angle = (center - touchPosition).angle + .pi
+ let currentData = currentlyVisibleData
+ let total: CGFloat = currentData.map({ $0.value }).reduce(0, +)
+ var startAngle: CGFloat = initialAngle
+ for (index, piece) in currentData.enumerated() {
+ let percent = piece.value / total
+ let segmentSize = 2 * .pi * percent
+ let endAngle = startAngle + segmentSize
+ if angle >= startAngle && angle <= endAngle ||
+ angle + .pi * 2 >= startAngle && angle + .pi * 2 <= endAngle {
+ return index
+ }
+ startAngle = endAngle
+ }
+ return nil
+ }
+
+ private var currentTransitionAnimationData: [PieComponent] {
+ if transitionAnimator.isAnimating {
+ let animationFraction = transitionAnimator.current
+ return percentageData.enumerated().map { arg in
+ return PieComponent(color: arg.element.color,
+ value: oldPercentageData[arg.offset].value * (1 - animationFraction) + arg.element.value * animationFraction)
+ }
+ } else {
+ return percentageData
+ }
+ }
+
+ var currentlyVisibleData: [PieComponent] {
+ return currentTransitionAnimationData.enumerated().map { arg in
+ return PieComponent(color: arg.element.color,
+ value: arg.element.value * componentsAnimators[arg.offset].current)
+ }
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ lastRenderedBounds = bounds
+ lastRenderedChartFrame = chartFrame
+ let chartAlpha = chartAlphaAnimator.current
+ if chartAlpha == 0 { return }
+
+ let center = CGPoint(x: chartFrame.midX, y: chartFrame.midY)
+ let radius = min(chartFrame.width, chartFrame.height) / 2
+
+ let currentData = currentlyVisibleData
+
+ let total: CGFloat = currentData.map({ $0.value }).reduce(0, +)
+ guard total > 0 else {
+ return
+ }
+
+ let animationSelectionOffset: CGFloat = radius / 15
+ let maximumFontSize: CGFloat = radius / 7
+ let minimumFontSize: CGFloat = 4
+ let centerOffsetStartAngle = CGFloat.pi / 4
+ let minimumValueToDraw: CGFloat = 0.01
+ let diagramRadius = radius - animationSelectionOffset
+
+ let numberOfVisibleItems = currentlyVisibleData.filter { $0.value > 0 }.count
+ var startAngle: CGFloat = initialAngle
+ for (index, piece) in currentData.enumerated() {
+ let percent = piece.value / total
+ guard percent > 0 else { continue }
+ let segmentSize = 2 * .pi * percent * chartAlpha
+ let endAngle = startAngle + segmentSize
+ let centerAngle = (startAngle + endAngle) / 2
+ let labelVector = CGPoint(x: cos(centerAngle),
+ y: sin(centerAngle))
+
+ let selectionAnimationFraction = (numberOfVisibleItems > 1 ? setlectedSegmentsAnimators[index].current : 0)
+
+ let updatedCenter = CGPoint(x: center.x + labelVector.x * selectionAnimationFraction * animationSelectionOffset,
+ y: center.y + labelVector.y * selectionAnimationFraction * animationSelectionOffset)
+ if drawPie {
+ context.saveGState()
+ context.setFillColor(piece.color.withAlphaComponent(piece.color.alphaValue * chartAlpha).cgColor)
+ context.move(to: updatedCenter)
+ context.addArc(center: updatedCenter,
+ radius: radius - animationSelectionOffset,
+ startAngle: startAngle,
+ endAngle: endAngle,
+ clockwise: false)
+ context.fillPath()
+ context.restoreGState()
+ }
+
+ if drawValues && percent >= minimumValueToDraw {
+ context.saveGState()
+
+ let text = valuesFormatter.string(from: percent * 100)
+ let fraction = crop(0, segmentSize / centerOffsetStartAngle, 1)
+ let fontSize = (minimumFontSize + (maximumFontSize - minimumFontSize) * fraction).rounded(.up)
+ let labelPotisionOffset = diagramRadius / 2 + diagramRadius / 2 * (1 - fraction)
+ let font = UIFont.systemFont(ofSize: fontSize, weight: .bold)
+ let labelsEaseInColor = crop(0, chartAlpha * chartAlpha * 2 - 1, 1)
+ let attributes: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor.white.withAlphaComponent(labelsEaseInColor),
+ .font: font]
+ let rect = (text as NSString).boundingRect(with: bounds.size,
+ options: .usesLineFragmentOrigin,
+ attributes: attributes,
+ context: nil)
+ let labelPoint = CGPoint(x: labelVector.x * labelPotisionOffset + updatedCenter.x - rect.width / 2,
+ y: labelVector.y * labelPotisionOffset + updatedCenter.y - rect.height / 2)
+ (text as NSString).draw(at: labelPoint, withAttributes: attributes)
+ context.restoreGState()
+ }
+
+ startAngle = endAngle
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/VerticalLinesRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/VerticalLinesRenderer.swift
new file mode 100644
index 0000000000..39d1f26a46
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/VerticalLinesRenderer.swift
@@ -0,0 +1,42 @@
+//
+// VerticalLinesRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/8/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class VerticalLinesRenderer: BaseChartRenderer {
+ var values: [CGFloat] = [] {
+ didSet {
+ alphaAnimators = values.map { _ in AnimationController(current: 1.0, refreshClosure: refreshClosure) }
+ setNeedsDisplay()
+ }
+ }
+ private var alphaAnimators: [AnimationController] = []
+
+ var linesColor: UIColor = .black
+ var linesWidth: CGFloat = UIView.oneDevicePixel
+
+ func setLineVisible(_ isVisible: Bool, at index: Int, animated: Bool) {
+ alphaAnimators[index].animate(to: isVisible ? 1 : 0, duration: animated ? .defaultDuration : 0)
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+
+ context.setLineWidth(linesWidth)
+
+ for (index, value) in values.enumerated() {
+ let alpha = alphaAnimators[index].current
+ if alpha == 0 { continue }
+
+ context.setStrokeColor(linesColor.withAlphaComponent(linesColor.alphaValue * alpha).cgColor)
+ let pointX = transform(toChartCoordinateHorizontal: value, chartFrame: chartFrame)
+ context.strokeLineSegments(between: [CGPoint(x: pointX, y: chartFrame.minY),
+ CGPoint(x: pointX, y: chartFrame.maxY)])
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Charts/Renderes/VerticalScalesRenderer.swift b/submodules/Charts/Sources/Charts/Renderes/VerticalScalesRenderer.swift
new file mode 100644
index 0000000000..79d9dcec22
--- /dev/null
+++ b/submodules/Charts/Sources/Charts/Renderes/VerticalScalesRenderer.swift
@@ -0,0 +1,162 @@
+//
+// VerticalScalesRenderer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/8/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class VerticalScalesRenderer: BaseChartRenderer {
+ private var verticalLabelsAndLines: [LinesChartLabel] = []
+ private var animatedVerticalLabelsAndLines: [AnimatedLinesChartLabels] = []
+ private lazy var horizontalLinesAlphaAnimator: AnimationController = {
+ return AnimationController(current: 1, refreshClosure: self.refreshClosure)
+ }()
+
+ var drawAxisX: Bool = true
+ var axisXColor: UIColor = .black
+ var axisXWidth: CGFloat = UIView.oneDevicePixel
+
+ var isRightAligned: Bool = false
+
+ var horizontalLinesColor: UIColor = .black {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+ var horizontalLinesWidth: CGFloat = UIView.oneDevicePixel
+ var lavelsAsisOffset: CGFloat = 6
+ var labelsColor: UIColor = .black {
+ didSet {
+ setNeedsDisplay()
+ }
+ }
+ var labelsFont: UIFont = .systemFont(ofSize: 11)
+
+ func setHorizontalLinesVisible(_ visible: Bool, animated: Bool) {
+ let destinationValue: CGFloat = visible ? 1 : 0
+ guard self.horizontalLinesAlphaAnimator.end != destinationValue else { return }
+ if animated {
+ self.horizontalLinesAlphaAnimator.animate(to: destinationValue, duration: .defaultDuration)
+ } else {
+ self.horizontalLinesAlphaAnimator.set(current: destinationValue)
+ }
+ }
+
+ func setup(verticalLimitsLabels: [LinesChartLabel], animated: Bool) {
+ if animated {
+ var labelsToKeepVisible: [LinesChartLabel] = []
+ let labelsToHide: [LinesChartLabel]
+ var labelsToShow: [LinesChartLabel] = []
+
+ for label in verticalLimitsLabels {
+ if verticalLabelsAndLines.contains(label) {
+ labelsToKeepVisible.append(label)
+ } else {
+ labelsToShow.append(label)
+ }
+ }
+ labelsToHide = verticalLabelsAndLines.filter { !verticalLimitsLabels.contains($0) }
+ animatedVerticalLabelsAndLines.removeAll(where: { $0.isAppearing })
+ verticalLabelsAndLines = labelsToKeepVisible
+
+ let showAnimation = AnimatedLinesChartLabels(labels: labelsToShow, alphaAnimator: AnimationController(current: 1.0, refreshClosure: refreshClosure))
+ showAnimation.isAppearing = true
+ showAnimation.alphaAnimator.set(current: 0)
+ showAnimation.alphaAnimator.animate(to: 1, duration: .defaultDuration)
+ showAnimation.alphaAnimator.completionClosure = { [weak self, weak showAnimation] in
+ guard let self = self, let showAnimation = showAnimation else { return }
+ self.animatedVerticalLabelsAndLines.removeAll(where: { $0 === showAnimation })
+ self.verticalLabelsAndLines = verticalLimitsLabels
+ }
+
+ let hideAnimation = AnimatedLinesChartLabels(labels: labelsToHide, alphaAnimator: AnimationController(current: 1.0, refreshClosure: refreshClosure))
+ hideAnimation.isAppearing = false
+ hideAnimation.alphaAnimator.set(current: 1)
+ hideAnimation.alphaAnimator.animate(to: 0, duration: .defaultDuration)
+ hideAnimation.alphaAnimator.completionClosure = { [weak self, weak hideAnimation] in
+ guard let self = self, let hideAnimation = hideAnimation else { return }
+ self.animatedVerticalLabelsAndLines.removeAll(where: { $0 === hideAnimation })
+ }
+
+ animatedVerticalLabelsAndLines.append(showAnimation)
+ animatedVerticalLabelsAndLines.append(hideAnimation)
+ } else {
+ verticalLabelsAndLines = verticalLimitsLabels
+ animatedVerticalLabelsAndLines = []
+ }
+ }
+
+ override func render(context: CGContext, bounds: CGRect, chartFrame: CGRect) {
+ guard isEnabled && verticalRange.current.distance > 0 && verticalRange.current.distance > 0 else { return }
+ let generalAlpha = chartAlphaAnimator.current
+ if generalAlpha == 0 { return }
+ let labelColorAlpha = labelsColor.alphaValue
+
+ func drawLines(_ labels: [LinesChartLabel], alpha: CGFloat) {
+ var lineSegments: [CGPoint] = []
+ let x0 = chartFrame.minX
+ let x1 = chartFrame.maxX
+
+ context.setStrokeColor(horizontalLinesColor.withAlphaComponent(horizontalLinesColor.alphaValue * alpha).cgColor)
+
+ for lineInfo in labels {
+ let y = transform(toChartCoordinateVertical: lineInfo.value, chartFrame: chartFrame).roundedUpToPixelGrid()
+ lineSegments.append(CGPoint(x: x0, y: y))
+ lineSegments.append(CGPoint(x: x1, y: y))
+ }
+ context.strokeLineSegments(between: lineSegments)
+ }
+
+ func drawVerticalLabels(_ labels: [LinesChartLabel], attributes: [NSAttributedString.Key: Any]) {
+ if isRightAligned {
+ for label in labels {
+ let y = transform(toChartCoordinateVertical: label.value, chartFrame: chartFrame) - labelsFont.pointSize - lavelsAsisOffset
+
+ let rect = (label.text as NSString).boundingRect(with: bounds.size,
+ options: .usesLineFragmentOrigin,
+ attributes: attributes,
+ context: nil)
+
+ (label.text as NSString).draw(at: CGPoint(x:chartFrame.maxX - rect.width, y: y), withAttributes: attributes)
+ }
+ } else {
+ for label in labels {
+ let y = transform(toChartCoordinateVertical: label.value, chartFrame: chartFrame) - labelsFont.pointSize - lavelsAsisOffset
+
+ (label.text as NSString).draw(at: CGPoint(x:chartFrame.minX, y: y), withAttributes: attributes)
+ }
+ }
+ }
+
+ let horizontalLinesAlpha = horizontalLinesAlphaAnimator.current
+ if horizontalLinesAlpha > 0 {
+ context.setLineWidth(horizontalLinesWidth)
+
+ drawLines(verticalLabelsAndLines, alpha: generalAlpha)
+ for animatedLabesAndLines in animatedVerticalLabelsAndLines {
+ drawLines(animatedLabesAndLines.labels, alpha: animatedLabesAndLines.alphaAnimator.current * generalAlpha * horizontalLinesAlpha)
+ }
+
+ if drawAxisX {
+ context.setLineWidth(axisXWidth)
+ context.setStrokeColor(axisXColor.withAlphaComponent(axisXColor.alphaValue * horizontalLinesAlpha * generalAlpha).cgColor)
+
+ let lineSegments: [CGPoint] = [CGPoint(x: chartFrame.minX, y: chartFrame.maxY.roundedUpToPixelGrid()),
+ CGPoint(x: chartFrame.maxX, y: chartFrame.maxY.roundedUpToPixelGrid())]
+
+ context.strokeLineSegments(between: lineSegments)
+ }
+ }
+
+ drawVerticalLabels(verticalLabelsAndLines, attributes: [.foregroundColor: labelsColor.withAlphaComponent(labelColorAlpha * generalAlpha),
+ .font: labelsFont])
+ for animatedLabesAndLines in animatedVerticalLabelsAndLines {
+ drawVerticalLabels(animatedLabesAndLines.labels,
+ attributes: [.foregroundColor: labelsColor.withAlphaComponent(animatedLabesAndLines.alphaAnimator.current * labelColorAlpha * generalAlpha),
+ .font: labelsFont])
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/AnimationController.swift b/submodules/Charts/Sources/Helpers/AnimationController.swift
new file mode 100644
index 0000000000..6df8d17f76
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/AnimationController.swift
@@ -0,0 +1,178 @@
+//
+// RangeAnimatedContainer.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/12/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+protocol Animatable {
+ static func valueBetween(start: Self, end: Self, offset: Double) -> Self
+}
+
+enum TimeFunction {
+ case linear
+ case easeOut
+ case easeIn
+
+ func profress(time: TimeInterval, duration: TimeInterval) -> TimeInterval {
+ switch self {
+ case .linear:
+ return time / duration
+ case .easeIn:
+ return (pow(2, 10 * (time / duration - 1)) - 0.0009765625) * 1.0009775171065499
+
+ case .easeOut:
+ return (-pow(2, -10 * time / duration)) + 1 * 1.0009775171065499
+ }
+ }
+}
+
+class AnimationController {
+
+ private(set) var isAnimating: Bool = false
+ private(set) var animationDuration: TimeInterval = 0.0
+ private(set) var currentTime: TimeInterval = 0.0
+
+ private(set) var start: AnimatableObject
+ private(set) var end: AnimatableObject
+ private(set) var current: AnimatableObject
+
+ var timeFunction: TimeFunction = .linear
+
+ var refreshClosure: (() -> Void)?
+// var updateClosure: ((AnimatableObject) -> Void)?
+ var completionClosure: (() -> Void)?
+
+ init(current: AnimatableObject, refreshClosure: (() -> Void)?) {
+ self.current = current
+ self.start = current
+ self.end = current
+ self.refreshClosure = refreshClosure
+ }
+
+ func animate(to: AnimatableObject, duration: TimeInterval, timeFunction: TimeFunction = .linear) {
+ self.timeFunction = timeFunction
+ currentTime = 0
+ animationDuration = duration
+ if animationDuration > 0 {
+ start = current
+ end = to
+ isAnimating = true
+ DisplayLinkService.shared.add(listner: self)
+ } else {
+ start = to
+ end = to
+ current = to
+ isAnimating = false
+ DisplayLinkService.shared.remove(listner: self)
+ }
+ refreshClosure?()
+ }
+
+ func set(current: AnimatableObject) {
+ self.start = current
+ self.end = current
+ self.current = current
+
+ animationDuration = 0.0
+ currentTime = 0.0
+// updateClosure?(current)
+ refreshClosure?()
+ if isAnimating {
+ isAnimating = false
+ DisplayLinkService.shared.remove(listner: self)
+ }
+ }
+}
+
+extension AnimationController: DisplayLinkListner {
+ func update(delta: TimeInterval) {
+ guard isAnimating else {
+ DisplayLinkService.shared.remove(listner: self)
+ return
+ }
+
+ currentTime += delta
+ if currentTime > animationDuration || animationDuration <= 0 {
+ start = end
+ current = end
+ isAnimating = false
+ animationDuration = 0.0
+ currentTime = 0.0
+// updateClosure?(end)
+ completionClosure?()
+ refreshClosure?()
+ DisplayLinkService.shared.remove(listner: self)
+ } else {
+ let offset = timeFunction.profress(time: currentTime, duration: animationDuration)
+ current = AnimatableObject.valueBetween(start: start, end: end, offset: offset)
+// updateClosure?(current)
+ refreshClosure?()
+ }
+ }
+}
+
+extension ClosedRange: Animatable where Bound: BinaryFloatingPoint {
+ static func valueBetween(start: ClosedRange, end: ClosedRange, offset: Double) -> ClosedRange {
+ let castedOffset = Bound(offset)
+ return ClosedRange(uncheckedBounds: (lower: start.lowerBound + (end.lowerBound - start.lowerBound) * castedOffset,
+ upper: start.upperBound + (end.upperBound - start.upperBound) * castedOffset))
+ }
+}
+
+extension CGFloat: Animatable {
+ static func valueBetween(start: CGFloat, end: CGFloat, offset: Double) -> CGFloat {
+ return start + (end - start) * CGFloat(offset)
+ }
+}
+
+extension Double: Animatable {
+ static func valueBetween(start: Double, end: Double, offset: Double) -> Double {
+ return start + (end - start) * Double(offset)
+ }
+}
+
+extension Int: Animatable {
+ static func valueBetween(start: Int, end: Int, offset: Double) -> Int {
+ return start + Int(Double(end - start) * offset)
+ }
+}
+
+extension CGPoint: Animatable {
+ static func valueBetween(start: CGPoint, end: CGPoint, offset: Double) -> CGPoint {
+ return CGPoint(x: start.x + (end.x - start.x) * CGFloat(offset),
+ y: start.y + (end.y - start.y) * CGFloat(offset))
+ }
+}
+
+extension CGRect: Animatable {
+ static func valueBetween(start: CGRect, end: CGRect, offset: Double) -> CGRect {
+ return CGRect(x: start.origin.x + (end.origin.x - start.origin.x) * CGFloat(offset),
+ y: start.origin.y + (end.origin.y - start.origin.y) * CGFloat(offset),
+ width: start.width + (end.width - start.width) * CGFloat(offset),
+ height: start.height + (end.height - start.height) * CGFloat(offset))
+ }
+}
+
+struct UIColorContainer: Animatable {
+ var color: UIColor
+
+ static func valueBetween(start: UIColorContainer, end: UIColorContainer, offset: Double) -> UIColorContainer {
+ return UIColorContainer(color: UIColor.valueBetween(start: start.color, end: end.color, offset: offset))
+ }
+}
+
+extension UIColor {
+ static func valueBetween(start: UIColor, end: UIColor, offset: Double) -> UIColor {
+ let offsetF = CGFloat(offset)
+ let startCIColor = CIColor(color: start)
+ let endCIColor = CIColor(color: end)
+ return UIColor(red: startCIColor.red + (endCIColor.red - startCIColor.red) * offsetF,
+ green: startCIColor.green + (endCIColor.green - startCIColor.green) * offsetF,
+ blue: startCIColor.blue + (endCIColor.blue - startCIColor.blue) * offsetF,
+ alpha: startCIColor.alpha + (endCIColor.alpha - startCIColor.alpha) * offsetF)
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/Array+Utils.swift b/submodules/Charts/Sources/Helpers/Array+Utils.swift
new file mode 100644
index 0000000000..539a559756
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/Array+Utils.swift
@@ -0,0 +1,18 @@
+//
+// Array+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import Foundation
+
+extension Array {
+ func safeElement(at index: Int) -> Element? {
+ if index >= 0 && index < count {
+ return self[index]
+ }
+ return nil
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/CGFloat.swift b/submodules/Charts/Sources/Helpers/CGFloat.swift
new file mode 100644
index 0000000000..7bde39b84f
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/CGFloat.swift
@@ -0,0 +1,17 @@
+//
+// CGFloat.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private let screenScale: CGFloat = UIScreen.main.scale
+
+extension CGFloat {
+ func roundedUpToPixelGrid() -> CGFloat {
+ return (self * screenScale).rounded(.up) / screenScale
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/CGPoint+Extensions.swift b/submodules/Charts/Sources/Helpers/CGPoint+Extensions.swift
new file mode 100644
index 0000000000..b5bbd06da4
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/CGPoint+Extensions.swift
@@ -0,0 +1,219 @@
+//
+// CGPoint+Extensions.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+extension CGPoint {
+ public init(vector: CGVector) {
+ self.init(x: vector.dx, y: vector.dy)
+ }
+
+
+ public init(angle: CGFloat) {
+ self.init(x: cos(angle), y: sin(angle))
+ }
+
+
+ public mutating func offset(dx: CGFloat, dy: CGFloat) -> CGPoint {
+ x += dx
+ y += dy
+ return self
+ }
+
+ public func length() -> CGFloat {
+ return sqrt(x*x + y*y)
+ }
+
+ public func lengthSquared() -> CGFloat {
+ return x*x + y*y
+ }
+
+ func normalized() -> CGPoint {
+ let len = length()
+ return len>0 ? self / len : CGPoint.zero
+ }
+
+ public mutating func normalize() -> CGPoint {
+ self = normalized()
+ return self
+ }
+
+ public func distanceTo(_ point: CGPoint) -> CGFloat {
+ return (self - point).length()
+ }
+
+ public var angle: CGFloat {
+ return atan2(y, x)
+ }
+
+ public var cgSize: CGSize {
+ return CGSize(width: x, height: y)
+ }
+
+ func rotate(origin: CGPoint, angle: CGFloat) -> CGPoint {
+ let point = self - origin
+ let s = sin(angle)
+ let c = cos(angle)
+ return CGPoint(x: c * point.x - s * point.y,
+ y: s * point.x + c * point.y) + origin
+ }
+}
+
+extension CGSize {
+ public var cgPoint: CGPoint {
+ return CGPoint(x: width, y: height)
+ }
+
+ public init(point: CGPoint) {
+ self.init(width: point.x, height: point.y)
+ }
+}
+
+public func + (left: CGPoint, right: CGPoint) -> CGPoint {
+ return CGPoint(x: left.x + right.x, y: left.y + right.y)
+}
+
+public func += (left: inout CGPoint, right: CGPoint) {
+ left = left + right
+}
+
+public func + (left: CGPoint, right: CGVector) -> CGPoint {
+ return CGPoint(x: left.x + right.dx, y: left.y + right.dy)
+}
+
+public func += (left: inout CGPoint, right: CGVector) {
+ left = left + right
+}
+
+public func - (left: CGPoint, right: CGPoint) -> CGPoint { return CGPoint(x: left.x - right.x, y: left.y - right.y) }
+public func - (left: CGSize, right: CGSize) -> CGSize { return CGSize(width: left.width - right.width, height: left.height - right.height) }
+public func - (left: CGSize, right: CGPoint) -> CGSize { return CGSize(width: left.width - right.x, height: left.height - right.x) }
+public func - (left: CGPoint, right: CGSize) -> CGPoint { return CGPoint(x: left.x - right.width, y: left.y - right.height) }
+
+public func -= (left: inout CGPoint, right: CGPoint) {
+ left = left - right
+}
+
+public func - (left: CGPoint, right: CGVector) -> CGPoint {
+ return CGPoint(x: left.x - right.dx, y: left.y - right.dy)
+}
+
+public func -= (left: inout CGPoint, right: CGVector) {
+ left = left - right
+}
+
+public func *= (left: inout CGPoint, right: CGPoint) {
+ left = left * right
+}
+
+public func * (point: CGPoint, scalar: CGFloat) -> CGPoint { return CGPoint(x: point.x * scalar, y: point.y * scalar) }
+public func * (point: CGSize, scalar: CGFloat) -> CGSize { return CGSize(width: point.width * scalar, height: point.height * scalar) }
+
+public func *= (point: inout CGPoint, scalar: CGFloat) { point = point * scalar }
+
+public func * (left: CGPoint, right: CGVector) -> CGPoint {
+ return CGPoint(x: left.x * right.dx, y: left.y * right.dy)
+}
+
+public func *= (left: inout CGPoint, right: CGVector) {
+ left = left * right
+}
+
+public func / (left: CGPoint, right: CGPoint) -> CGPoint { return CGPoint(x: left.x / right.x, y: left.y / right.y) }
+public func / (left: CGSize, right: CGSize) -> CGSize { return CGSize(width: left.width / right.width, height: left.height / right.height) }
+public func / (left: CGPoint, right: CGSize) -> CGPoint { return CGPoint(x: left.x / right.width, y: left.y / right.height) }
+public func / (left: CGSize, right: CGPoint) -> CGSize { return CGSize(width: left.width / right.x, height: left.height / right.y) }
+public func /= (left: inout CGPoint, right: CGPoint) { left = left / right }
+public func /= (left: inout CGSize, right: CGSize) { left = left / right }
+public func /= (left: inout CGSize, right: CGPoint) { left = left / right }
+public func /= (left: inout CGPoint, right: CGSize) { left = left / right }
+
+
+public func / (point: CGPoint, scalar: CGFloat) -> CGPoint { return CGPoint(x: point.x / scalar, y: point.y / scalar) }
+public func / (point: CGSize, scalar: CGFloat) -> CGSize { return CGSize(width: point.width / scalar, height: point.height / scalar) }
+
+public func /= (point: inout CGPoint, scalar: CGFloat) {
+ point = point / scalar
+}
+
+public func / (left: CGPoint, right: CGVector) -> CGPoint {
+ return CGPoint(x: left.x / right.dx, y: left.y / right.dy)
+}
+
+public func / (left: CGSize, right: CGVector) -> CGSize {
+ return CGSize(width: left.width / right.dx, height: left.height / right.dy)
+}
+
+public func /= (left: inout CGPoint, right: CGVector) {
+ left = left / right
+}
+
+public func * (left: CGPoint, right: CGPoint) -> CGPoint { return CGPoint(x: left.x * right.x, y: left.y * right.y) }
+public func * (left: CGPoint, right: CGSize) -> CGPoint { return CGPoint(x: left.x * right.width, y: left.y * right.height) }
+public func *= (left: inout CGPoint, right: CGSize) { left = left * right }
+public func * (left: CGSize, right: CGSize) -> CGSize { return CGSize(width: left.width * right.width, height: left.height * right.height) }
+public func *= (left: inout CGSize, right: CGSize) { left = left * right }
+public func * (left: CGSize, right: CGPoint) -> CGSize { return CGSize(width: left.width * right.x, height: left.height * right.y) }
+public func *= (left: inout CGSize, right: CGPoint) { left = left * right }
+
+
+public func lerp(start: CGPoint, end: CGPoint, t: CGFloat) -> CGPoint {
+ return start + (end - start) * t
+}
+
+public func abs(_ point: CGPoint) -> CGPoint {
+ return CGPoint(x: abs(point.x), y: abs(point.y))
+}
+
+extension CGSize {
+ var isValid: Bool {
+ return width > 0 && height > 0 && width != .infinity && height != .infinity && width != .nan && height != .nan
+ }
+
+ var ratio: CGFloat {
+ return width / height
+ }
+}
+
+
+extension CGRect {
+ static var identity: CGRect {
+ return CGRect(x: 0, y: 0, width: 1, height: 1)
+ }
+
+ var center: CGPoint {
+ return origin + size.cgPoint / 2
+ }
+
+ var rounded: CGRect {
+ return CGRect(x: origin.x.rounded(),
+ y: origin.y.rounded(),
+ width: width.rounded(.up),
+ height: height.rounded(.up))
+ }
+
+ var mirroredVertically: CGRect {
+ return CGRect(x: origin.x,
+ y: 1.0 - (origin.y + height),
+ width: width,
+ height: height)
+ }
+}
+
+extension CGAffineTransform {
+ func inverted(with size: CGSize) -> CGAffineTransform {
+ var transform = self
+ let transformedSize = CGRect(origin: .zero, size: size).applying(transform).size
+ transform.tx /= transformedSize.width;
+ transform.ty /= transformedSize.height;
+ transform = transform.inverted()
+ transform.tx *= transformedSize.width;
+ transform.ty *= transformedSize.height;
+ return transform
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/ClosedRange+Utils.swift b/submodules/Charts/Sources/Helpers/ClosedRange+Utils.swift
new file mode 100644
index 0000000000..236d6c8a38
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/ClosedRange+Utils.swift
@@ -0,0 +1,15 @@
+//
+// ClosedRange+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import Foundation
+
+extension ClosedRange where Bound: Numeric {
+ var distance: Bound {
+ return upperBound - lowerBound
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/CustomNavigationController.swift b/submodules/Charts/Sources/Helpers/CustomNavigationController.swift
new file mode 100644
index 0000000000..977244dfcc
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/CustomNavigationController.swift
@@ -0,0 +1,19 @@
+//
+// CustomNavigationController.swift
+// GraphTest
+//
+// Created by Andrew Solovey on 15/03/2019.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+class CustomNavigationController: UINavigationController {
+ override var preferredStatusBarStyle: UIStatusBarStyle {
+ return topViewController?.preferredStatusBarStyle ?? .default
+ }
+
+ override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
+ return topViewController?.preferredStatusBarUpdateAnimation ?? .fade
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/DisplayLinkService.swift b/submodules/Charts/Sources/Helpers/DisplayLinkService.swift
new file mode 100644
index 0000000000..2c91471c39
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/DisplayLinkService.swift
@@ -0,0 +1,114 @@
+//
+// DisplayLinkService.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/7/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+import CoreGraphics
+
+public protocol DisplayLinkListner: class {
+ func update(delta: TimeInterval)
+}
+
+// DispatchSource mares refreshes more accurate
+class DisplayLinkService {
+ let listners = NSHashTable.weakObjects()
+ static let shared = DisplayLinkService()
+
+ public func add(listner: DisplayLinkListner) {
+ listners.add(listner)
+ startDisplayLink()
+ }
+
+ public func remove(listner: DisplayLinkListner) {
+ listners.remove(listner)
+
+ if listners.count == 0 {
+ stopDisplayLink()
+ }
+ }
+
+// private init() {
+// displayLink.add(to: .main, forMode: .common)
+// displayLink.preferredFramesPerSecond = 60
+// displayLink.isPaused = true
+// }
+//
+// // MARK: - Display Link
+// private lazy var displayLink: CADisplayLink! = { CADisplayLink(target: self, selector: #selector(displayLinkDidFire)) } ()
+// private var previousTickTime = 0.0
+//
+// private func startDisplayLink() {
+// guard displayLink.isPaused else {
+// return
+// }
+// previousTickTime = CACurrentMediaTime()
+// displayLink.isPaused = false
+// }
+//
+// @objc private func displayLinkDidFire(_ displayLink: CADisplayLink) {
+// let currentTime = CACurrentMediaTime()
+// let delta = currentTime - previousTickTime
+// previousTickTime = currentTime
+// let allListners = listners.allObjects
+// var hasListners = false
+// for listner in allListners {
+// (listner as! DisplayLinkListner).update(delta: delta)
+// hasListners = true
+// }
+//
+// if !hasListners {
+// stopDisplayLink()
+// }
+// }
+//
+// private func stopDisplayLink() {
+// displayLink.isPaused = true
+// }
+
+ private init() {
+ dispatchSourceTimer.schedule(deadline: .now() + 1.0 / 60, repeating: 1.0 / 60)
+ dispatchSourceTimer.setEventHandler {
+ DispatchQueue.main.sync {
+ self.fire()
+ }
+ }
+ }
+
+ private var dispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: .global(qos: .userInteractive))
+ private var dispatchSourceTimerStarted: Bool = false
+ private var previousTickTime = 0.0
+
+ private func startDisplayLink() {
+ guard !dispatchSourceTimerStarted else { return }
+ dispatchSourceTimerStarted = true
+ previousTickTime = CACurrentMediaTime()
+ dispatchSourceTimer.resume()
+ }
+
+ private func stopDisplayLink() {
+ guard dispatchSourceTimerStarted else { return }
+ dispatchSourceTimerStarted = false
+ dispatchSourceTimer.suspend()
+ }
+
+ public func fire() {
+ let currentTime = CACurrentMediaTime()
+
+ let delta = currentTime - previousTickTime
+ previousTickTime = currentTime
+ let allListners = listners.allObjects
+ var hasListners = false
+ for listner in allListners {
+ (listner as! DisplayLinkListner).update(delta: delta)
+ hasListners = true
+ }
+
+ if !hasListners {
+ stopDisplayLink()
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/GlobalHelpers.swift b/submodules/Charts/Sources/Helpers/GlobalHelpers.swift
new file mode 100644
index 0000000000..3f5c488ff9
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/GlobalHelpers.swift
@@ -0,0 +1,12 @@
+//
+// GlobalHelpers.swift
+// TrackingRecorder
+//
+// Created by Andrew Solovey on 07.09.2018.
+// Copyright © 2018 Andrew Solovey. All rights reserved.
+//
+
+public func crop(_ lower: Type, _ val: Type, _ upper: Type) -> Type where Type : Comparable {
+ assert(lower < upper, "Invalid lover and upper values")
+ return max(lower, min(upper, val))
+}
diff --git a/submodules/Charts/Sources/Helpers/NumberFormatter+Utils.swift b/submodules/Charts/Sources/Helpers/NumberFormatter+Utils.swift
new file mode 100644
index 0000000000..1254d44249
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/NumberFormatter+Utils.swift
@@ -0,0 +1,19 @@
+//
+// NumberFormatter+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/12/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+extension NumberFormatter {
+ func string(from value: CGFloat) -> String {
+ return string(from: Double(value))
+ }
+
+ func string(from value: Double) -> String {
+ return string(from: NSNumber(value: Double(value))) ?? ""
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/OnePixelConstraint.swift b/submodules/Charts/Sources/Helpers/OnePixelConstraint.swift
new file mode 100644
index 0000000000..03e33e6524
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/OnePixelConstraint.swift
@@ -0,0 +1,17 @@
+//
+// OnePixelConstraint.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+public class OnePixelConstrain: NSLayoutConstraint {
+ public override func awakeFromNib() {
+ super.awakeFromNib()
+
+ constant = UIView.oneDevicePixel
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/ScalesNumberFormatter.swift b/submodules/Charts/Sources/Helpers/ScalesNumberFormatter.swift
new file mode 100644
index 0000000000..db067f8a95
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/ScalesNumberFormatter.swift
@@ -0,0 +1,32 @@
+//
+// ScalesNumberFormatter.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+private let milionsScale = "M"
+private let thousandsScale = "K"
+
+class ScalesNumberFormatter: NumberFormatter {
+ override func string(from number: NSNumber) -> String? {
+ let value = number.doubleValue
+ let pow = log10(value)
+ if pow >= 6 {
+ guard let string = super.string(from: NSNumber(value: value / 1_000_000)) else {
+ return nil
+ }
+ return string + milionsScale
+ } else if pow >= 4 {
+ guard let string = super.string(from: NSNumber(value: value / 1_000)) else {
+ return nil
+ }
+ return string + thousandsScale
+ } else {
+ return super.string(from: number)
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/TimeInterval+Utils.swift b/submodules/Charts/Sources/Helpers/TimeInterval+Utils.swift
new file mode 100644
index 0000000000..204b1e861a
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/TimeInterval+Utils.swift
@@ -0,0 +1,27 @@
+//
+// TimeInterval+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import Foundation
+
+extension TimeInterval {
+ static let minute: TimeInterval = 60
+ static let hour: TimeInterval = 60 * 60
+ static let day: TimeInterval = 60 * 60 * 24
+ static let osXDuration: TimeInterval = 0.25
+ static let expandAnimationDuration: TimeInterval = 0.4
+ static var animationDurationMultipler: Double = 1.0
+
+ static var defaultDuration: TimeInterval {
+ return innerDefaultDuration * animationDurationMultipler
+ }
+ private static var innerDefaultDuration: TimeInterval = osXDuration
+
+ static func setDefaultSuration(_ duration: TimeInterval) {
+ innerDefaultDuration = duration
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/TimeZone.swift b/submodules/Charts/Sources/Helpers/TimeZone.swift
new file mode 100644
index 0000000000..40ba9ab8f5
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/TimeZone.swift
@@ -0,0 +1,36 @@
+//
+// TimeZone.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/9/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import Foundation
+
+extension TimeZone {
+ static let utc = TimeZone(secondsFromGMT: 0)!
+}
+
+extension Locale {
+ static let posix = Locale(identifier: "en_US_POSIX")
+}
+
+extension Calendar {
+ static let utc: Calendar = {
+ var calendar = Calendar.current
+ calendar.locale = Locale.posix
+ calendar.timeZone = TimeZone.utc
+ return calendar
+ }()
+}
+
+extension DateFormatter {
+ static func utc(format: String = "") -> DateFormatter {
+ let formatter = DateFormatter()
+ formatter.calendar = Calendar.utc
+ formatter.dateFormat = format
+ formatter.timeZone = TimeZone.utc
+ return formatter
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/UIColor+Utils.swift b/submodules/Charts/Sources/Helpers/UIColor+Utils.swift
new file mode 100644
index 0000000000..0a70421d5e
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/UIColor+Utils.swift
@@ -0,0 +1,64 @@
+//
+// UIColor+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/11/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+extension UIColor {
+ public convenience init?(hexString: String) {
+ let r, g, b, a: CGFloat
+
+ if hexString.hasPrefix("#") {
+ let start = hexString.index(hexString.startIndex, offsetBy: 1)
+ let hexColor = String(hexString[start...])
+
+ if hexColor.count == 8 {
+ let scanner = Scanner(string: hexColor)
+ var hexNumber: UInt64 = 0
+
+ if scanner.scanHexInt64(&hexNumber) {
+ r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
+ g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
+ b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
+ a = CGFloat(hexNumber & 0x000000ff) / 255
+
+ self.init(red: r, green: g, blue: b, alpha: a)
+ return
+ }
+ } else if hexColor.count == 6 {
+ let scanner = Scanner(string: hexColor)
+ var hexNumber: UInt64 = 0
+
+ if scanner.scanHexInt64(&hexNumber) {
+ r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
+ g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
+ b = CGFloat((hexNumber & 0x0000ff) >> 0) / 255
+
+ self.init(red: r, green: g, blue: b, alpha: 1.0)
+ return
+ }
+ }
+ }
+ return nil
+ }
+
+ func image(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
+ if #available(iOS 10.0, *) {
+ return UIGraphicsImageRenderer(size: size).image { rendererContext in
+ self.setFill()
+ rendererContext.fill(CGRect(origin: .zero, size: size))
+ }
+ } else {
+ return UIImage()
+ }
+ }
+
+ var redValue: CGFloat{ return CIColor(color: self).red }
+ var greenValue: CGFloat{ return CIColor(color: self).green }
+ var blueValue: CGFloat{ return CIColor(color: self).blue }
+ var alphaValue: CGFloat{ return CIColor(color: self).alpha }
+}
diff --git a/submodules/Charts/Sources/Helpers/UIImage+Utils.swift b/submodules/Charts/Sources/Helpers/UIImage+Utils.swift
new file mode 100644
index 0000000000..50964025c2
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/UIImage+Utils.swift
@@ -0,0 +1,28 @@
+//
+// UIImage+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/8/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+extension UIImage {
+ static let arrowRight = UIImage(bundleImageName: "Chart/arrow_right")
+ static let arrowLeft = UIImage(bundleImageName: "Chart/arrow_left")
+
+ public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
+ let rect = CGRect(origin: .zero, size: size)
+ UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
+ color.setFill()
+ UIRectFill(rect)
+ let image = UIGraphicsGetImageFromCurrentImageContext()
+ UIGraphicsEndImageContext()
+
+ guard let cgImage = image?.cgImage else { return nil }
+ self.init(cgImage: cgImage)
+ }
+
+
+}
diff --git a/submodules/Charts/Sources/Helpers/UIImageView+Utils.swift b/submodules/Charts/Sources/Helpers/UIImageView+Utils.swift
new file mode 100644
index 0000000000..608f25a114
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/UIImageView+Utils.swift
@@ -0,0 +1,24 @@
+//
+// UIImageView+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/9/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+extension UIImageView {
+ func setImage(_ image: UIImage?, animated: Bool) {
+ if self.image != image {
+ if animated {
+ let animation = CATransition()
+ animation.timingFunction = CAMediaTimingFunction.init(name: .linear)
+ animation.type = .fade
+ animation.duration = .defaultDuration
+ self.layer.add(animation, forKey: "kCATransitionImageFade")
+ }
+ self.image = image
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/UILabel+Utils.swift b/submodules/Charts/Sources/Helpers/UILabel+Utils.swift
new file mode 100644
index 0000000000..6c41c73fd9
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/UILabel+Utils.swift
@@ -0,0 +1,37 @@
+//
+// UILabel+Utils.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/9/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+extension UILabel {
+ func setTextColor(_ color: UIColor, animated: Bool) {
+ if self.textColor != color {
+ if animated {
+ let animation = CATransition()
+ animation.timingFunction = CAMediaTimingFunction.init(name: .linear)
+ animation.type = .fade
+ animation.duration = .defaultDuration
+ self.layer.add(animation, forKey: "kCATransitionColorFade")
+ }
+ self.textColor = color
+ }
+ }
+
+ func setText(_ title: String?, animated: Bool) {
+ if self.text != title {
+ if animated {
+ let animation = CATransition()
+ animation.timingFunction = CAMediaTimingFunction.init(name: .linear)
+ animation.type = .fade
+ animation.duration = .defaultDuration
+ self.layer.add(animation, forKey: "kCATransitionTextFade")
+ }
+ self.text = title
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Helpers/UIView+Extensions.swift b/submodules/Charts/Sources/Helpers/UIView+Extensions.swift
new file mode 100644
index 0000000000..bba2d1f886
--- /dev/null
+++ b/submodules/Charts/Sources/Helpers/UIView+Extensions.swift
@@ -0,0 +1,57 @@
+//
+// UIView+Extensions.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 4/10/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+extension UIView {
+ static let oneDevicePixel: CGFloat = (1.0 / max(2, min(1, UIScreen.main.scale)))
+}
+
+// MARK: UIView+Animation
+public extension UIView {
+ func bringToFront() {
+ superview?.bringSubviewToFront(self)
+ }
+
+ func layoutIfNeeded(animated: Bool) {
+ UIView.perform(animated: animated) {
+ self.layoutIfNeeded()
+ }
+ }
+
+ func setVisible(_ visible: Bool, animated: Bool) {
+ let updatedAlpha: CGFloat = visible ? 1 : 0
+ if self.alpha != updatedAlpha {
+ UIView.perform(animated: animated) {
+ self.alpha = updatedAlpha
+ }
+ }
+ }
+
+ static func perform(animated: Bool, animations: @escaping () -> Void) {
+ perform(animated: animated, animations: animations, completion: { _ in })
+ }
+
+ static func perform(animated: Bool, animations: @escaping () -> Void, completion: @escaping (Bool) -> Void) {
+ if animated {
+
+ UIView.animate(withDuration: .defaultDuration, delay: 0, animations: animations, completion: completion)
+ } else {
+ animations()
+ completion(true)
+ }
+ }
+
+ var isVisibleInWindow: Bool {
+ guard let windowBounds = window?.bounds else {
+ return false
+ }
+ let frame = convert(bounds, to: nil)
+ return frame.intersects(windowBounds)
+ }
+}
diff --git a/submodules/Charts/Sources/Models/ChartLineData.swift b/submodules/Charts/Sources/Models/ChartLineData.swift
new file mode 100644
index 0000000000..79813a2a35
--- /dev/null
+++ b/submodules/Charts/Sources/Models/ChartLineData.swift
@@ -0,0 +1,76 @@
+//
+// ChartLineData.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/13/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+struct ChartLineData {
+ var title: String
+ var color: UIColor
+ var width: CGFloat?
+ var points: [CGPoint]
+}
+
+extension ChartLineData {
+ static func horizontalRange(lines: [ChartLineData]) -> ClosedRange? {
+ guard let firstPoint = lines.first?.points.first else { return nil }
+ var hMin: CGFloat = firstPoint.x
+ var hMax: CGFloat = firstPoint.x
+
+ for line in lines {
+ if let first = line.points.first,
+ let last = line.points.last {
+ hMin = min(hMin, first.x)
+ hMax = max(hMax, last.x)
+ }
+ }
+
+ return hMin...hMax
+ }
+
+ static func verticalRange(lines: [ChartLineData], calculatingRange: ClosedRange? = nil, addBounds: Bool = false) -> ClosedRange? {
+ if let calculatingRange = calculatingRange {
+ guard let initalStart = lines.first?.points.first(where: { $0.x > calculatingRange.lowerBound &&
+ $0.x < calculatingRange.upperBound }) else { return nil }
+ var vMin: CGFloat = initalStart.y
+ var vMax: CGFloat = initalStart.y
+ for line in lines {
+ if var index = line.points.firstIndex(where: { $0.x > calculatingRange.lowerBound }) {
+ if addBounds {
+ index = max(0, index - 1)
+ }
+ while index < line.points.count {
+ let point = line.points[index]
+ if point.x < calculatingRange.upperBound {
+ vMin = min(vMin, point.y)
+ vMax = max(vMax, point.y)
+ } else if addBounds {
+ vMin = min(vMin, point.y)
+ vMax = max(vMax, point.y)
+ break
+ } else {
+ break
+ }
+ index += 1
+ }
+ }
+ }
+ return vMin...vMax
+ } else {
+ guard let firstPoint = lines.first?.points.first else { return nil }
+ var vMin: CGFloat = firstPoint.y
+ var vMax: CGFloat = firstPoint.y
+ for line in lines {
+ for point in line.points {
+ vMin = min(vMin, point.y)
+ vMax = max(vMax, point.y)
+ }
+ }
+ return vMin...vMax
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Models/ColorMode.swift b/submodules/Charts/Sources/Models/ColorMode.swift
new file mode 100644
index 0000000000..f0de7b52ae
--- /dev/null
+++ b/submodules/Charts/Sources/Models/ColorMode.swift
@@ -0,0 +1,175 @@
+//
+// ColorMode.swift
+// GraphTest
+//
+// Created by Andrew Solovey on 15/03/2019.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+import AppBundle
+
+protocol ColorModeContainer {
+ func apply(colorMode: ColorMode, animated: Bool)
+}
+
+enum ColorMode {
+ case day
+ case night
+}
+
+extension ColorMode {
+ var chartTitleColor: UIColor { // Текст с датой на чарте
+ switch self {
+ case .day: return .black
+ case .night: return .white
+ }
+ }
+
+ var actionButtonColor: UIColor { // Кнопка Zoom Out/ Смена режима день/ночь
+ switch self {
+ case .day: return UIColor(red: 53/255.0, green: 120/255.0, blue: 246/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 84/255.0, green: 164/255.0, blue: 247/255.0, alpha: 1.0)
+ }
+ }
+
+ var tableBackgroundColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 239/255.0, green: 239/255.0, blue: 244/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 24/255.0, green: 34/255.0, blue: 45/255.0, alpha: 1.0)
+ }
+ }
+
+ var chartBackgroundColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 34/255.0, green: 47/255.0, blue: 63/255.0, alpha: 1.0)
+ }
+ }
+
+ var sectionTitleColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 109/255.0, green: 109/255.0, blue: 114/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 133/255.0, green: 150/255.0, blue: 171/255.0, alpha: 1.0)
+ }
+ }
+
+ var tableSeparatorColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 200/255.0, green: 199/255.0, blue: 204/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 18/255.0, green: 26/255.0, blue: 35/255.0, alpha: 1.0)
+ }
+ }
+
+ var chartLabelsColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.5)
+ case .night: return UIColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.6)
+ }
+ }
+
+ var chartHelperLinesColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.1)
+ case .night: return UIColor(red: 133/255.0, green: 150/255.0, blue: 171/255.0, alpha: 0.20)
+ }
+ }
+
+ var chartStrongLinesColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.35)
+ case .night: return UIColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45)
+ }
+ }
+
+ var barChartStrongLinesColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.2)
+ case .night: return UIColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45)
+ }
+ }
+
+ var chartDetailsTextColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 109/255.0, green: 109/255.0, blue: 114/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
+ }
+ }
+
+ var chartDetailsArrowColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 197/255.0, green: 199/255.0, blue: 205/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 76/255.0, green: 84/255.0, blue: 96/255.0, alpha: 1.0)
+ }
+ }
+
+ var chartDetailsViewColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 245/255.0, green: 245/255.0, blue: 251/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 25/255.0, green: 35/255.0, blue: 47/255.0, alpha: 1.0)
+ }
+ }
+
+ var descriptionChatNameColor: UIColor {
+ switch self {
+ case .day: return .black
+ case .night: return UIColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
+ }
+ }
+
+ var descriptionActionColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 1/255.0, green: 125/255.0, blue: 229/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 24/255.0, green: 145/255.0, blue: 255/255.0, alpha: 1.0)
+ }
+ }
+
+ var rangeViewBackgroundColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 34/255.0, green: 47/255.0, blue: 63/255.0, alpha: 1.0)
+ }
+ }
+
+ var rangeViewFrameColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 202/255.0, green: 212/255.0, blue: 222/255.0, alpha: 1.0)
+ case .night: return UIColor(red: 53/255.0, green: 70/255.0, blue: 89/255.0, alpha: 1.0)
+ }
+ }
+
+ var rangeViewTintColor: UIColor {
+ switch self {
+ case .day: return UIColor(red: 239/255.0, green: 239/255.0, blue: 244/255.0, alpha: 0.5)
+ case .night: return UIColor(red: 24/255.0, green: 34/255.0, blue: 45/255.0, alpha: 0.5)
+ }
+ }
+
+ var rangeViewMarkerColor: UIColor {
+ switch self {
+ case .day: return UIColor.white
+ case .night: return UIColor.white
+ }
+ }
+
+ var statusBarStyle: UIStatusBarStyle {
+ switch self {
+ case .day: return .default
+ case .night: return .lightContent
+ }
+ }
+
+ var viewTintColor: UIColor {
+ switch self {
+ case .day: return .black
+ case .night: return UIColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
+ }
+ }
+
+ var rangeCropImage: UIImage? {
+ switch self {
+ case .day: return UIImage(bundleImageName: "Chart/selection_frame_light")
+ case .night: return UIImage(bundleImageName: "Chart/selection_frame_dark")
+ }
+ }
+}
diff --git a/submodules/Charts/Sources/Models/LinesChartLabel.swift b/submodules/Charts/Sources/Models/LinesChartLabel.swift
new file mode 100644
index 0000000000..6ace8c2c65
--- /dev/null
+++ b/submodules/Charts/Sources/Models/LinesChartLabel.swift
@@ -0,0 +1,25 @@
+//
+// LinesChartLabel.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/18/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+struct LinesChartLabel: Hashable {
+ let value: CGFloat
+ let text: String
+}
+
+class AnimatedLinesChartLabels {
+ var labels: [LinesChartLabel]
+ var isAppearing: Bool = false
+ let alphaAnimator: AnimationController
+
+ init(labels: [LinesChartLabel], alphaAnimator: AnimationController) {
+ self.labels = labels
+ self.alphaAnimator = alphaAnimator
+ }
+}
diff --git a/submodules/Charts/Sources/Models/LinesSelectionLabel.swift b/submodules/Charts/Sources/Models/LinesSelectionLabel.swift
new file mode 100644
index 0000000000..0fd7142eda
--- /dev/null
+++ b/submodules/Charts/Sources/Models/LinesSelectionLabel.swift
@@ -0,0 +1,15 @@
+//
+// LinesSelectionLabel.swift
+// GraphTest
+//
+// Created by Andrei Salavei on 3/18/19.
+// Copyright © 2019 Andrei Salavei. All rights reserved.
+//
+
+import UIKit
+
+struct LinesSelectionLabel {
+ let coordinate: CGPoint
+ let valueText: String
+ let color: UIColor
+}
diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift
index f2049711c5..4874490784 100644
--- a/submodules/ChatListUI/Sources/ChatListController.swift
+++ b/submodules/ChatListUI/Sources/ChatListController.swift
@@ -22,10 +22,6 @@ import AppBundle
import LocalizedPeerData
import TelegramIntents
-public func useSpecialTabBarIcons() -> Bool {
- return (Date(timeIntervalSince1970: 1545642000)...Date(timeIntervalSince1970: 1546387200)).contains(Date())
-}
-
private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool {
if searchNode.expansionProgress > 0.0 && searchNode.expansionProgress < 1.0 {
let scrollToItem: ListViewScrollToItem
@@ -178,8 +174,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
self.tabBarItem.title = self.presentationData.strings.DialogList_Title
let icon: UIImage?
- if (useSpecialTabBarIcons()) {
- icon = UIImage(bundleImageName: "Chat List/Tabs/NY/IconChats")
+ if useSpecialTabBarIcons() {
+ icon = UIImage(bundleImageName: "Chat List/Tabs/Holiday/IconChats")
} else {
icon = UIImage(bundleImageName: "Chat List/Tabs/IconChats")
}
diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift
index 22e250ef4a..af2a6d1b88 100644
--- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift
+++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift
@@ -715,7 +715,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
return (views, local)
}
}
- |> mapToSignal{ viewsAndPeers -> Signal<(peers: [RenderedPeer], unread: [PeerId: (Int32, Bool)]), NoError> in
+ |> mapToSignal { viewsAndPeers -> Signal<(peers: [RenderedPeer], unread: [PeerId: (Int32, Bool)]), NoError> in
return context.account.postbox.unreadMessageCountsView(items: viewsAndPeers.0.map {.peer($0.peerId)}) |> map { values in
var unread: [PeerId: (Int32, Bool)] = [:]
for peerView in viewsAndPeers.0 {
@@ -804,8 +804,18 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
)
}
- return combineLatest(accountPeer, foundLocalPeers, foundRemotePeers, foundRemoteMessages, presentationDataPromise.get(), searchStatePromise.get())
- |> map { accountPeer, foundLocalPeers, foundRemotePeers, foundRemoteMessages, presentationData, searchState -> ([ChatListSearchEntry], Bool)? in
+ let resolvedMessage = .single(nil)
+ |> then(context.sharedContext.resolveUrl(account: context.account, url: query)
+ |> mapToSignal { resolvedUrl -> Signal in
+ if case let .channelMessage(peerId, messageId) = resolvedUrl {
+ return downloadMessage(postbox: context.account.postbox, network: context.account.network, messageId: messageId)
+ } else {
+ return .single(nil)
+ }
+ })
+
+ return combineLatest(accountPeer, foundLocalPeers, foundRemotePeers, foundRemoteMessages, presentationDataPromise.get(), searchStatePromise.get(), resolvedMessage)
+ |> map { accountPeer, foundLocalPeers, foundRemotePeers, foundRemoteMessages, presentationData, searchState, resolvedMessage -> ([ChatListSearchEntry], Bool)? in
var entries: [ChatListSearchEntry] = []
let isSearching = foundRemotePeers.2 || foundRemoteMessages.1
var index = 0
@@ -938,6 +948,17 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
}
}
+ if let message = resolvedMessage {
+ var peer = RenderedPeer(message: message)
+ if let group = message.peers[message.id.peerId] as? TelegramGroup, let migrationReference = group.migrationReference {
+ if let channelPeer = message.peers[migrationReference.peerId] {
+ peer = RenderedPeer(peer: channelPeer)
+ }
+ }
+ entries.append(.message(message, peer, nil, presentationData))
+ index += 1
+ }
+
if !foundRemotePeers.2 {
index = 0
for message in foundRemoteMessages.0.0 {
diff --git a/submodules/ContactListUI/Sources/ContactsController.swift b/submodules/ContactListUI/Sources/ContactsController.swift
index 7dcfc4b716..b65dfabfec 100644
--- a/submodules/ContactListUI/Sources/ContactsController.swift
+++ b/submodules/ContactListUI/Sources/ContactsController.swift
@@ -105,7 +105,12 @@ public class ContactsController: ViewController {
self.title = self.presentationData.strings.Contacts_Title
self.tabBarItem.title = self.presentationData.strings.Contacts_Title
- let icon = UIImage(bundleImageName: "Chat List/Tabs/IconContacts")
+ let icon: UIImage?
+ if useSpecialTabBarIcons() {
+ icon = UIImage(bundleImageName: "Chat List/Tabs/Holiday/IconContacts")
+ } else {
+ icon = UIImage(bundleImageName: "Chat List/Tabs/IconContacts")
+ }
self.tabBarItem.image = icon
self.tabBarItem.selectedImage = icon
diff --git a/submodules/Display/Display/TabBarNode.swift b/submodules/Display/Display/TabBarNode.swift
index f83a6b1289..9301512ec1 100644
--- a/submodules/Display/Display/TabBarNode.swift
+++ b/submodules/Display/Display/TabBarNode.swift
@@ -442,7 +442,7 @@ class TabBarNode: ASDisplayNode {
if horizontal {
backgroundFrame = CGRect(origin: CGPoint(x: originX + 15.0, y: 3.0), size: backgroundSize)
} else {
- let contentWidth = node.contentWidth ?? node.frame.width
+ let contentWidth: CGFloat = 25.0 //node.contentWidth ?? node.frame.width
backgroundFrame = CGRect(origin: CGPoint(x: floor(originX + node.frame.width / 2.0) + contentWidth - backgroundSize.width - 5.0, y: self.centered ? 9.0 : 2.0), size: backgroundSize)
}
transition.updateFrame(node: container.badgeContainerNode, frame: backgroundFrame)
diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift
index 53b10ecb22..e0acc9d09c 100644
--- a/submodules/GalleryUI/Sources/GalleryController.swift
+++ b/submodules/GalleryUI/Sources/GalleryController.swift
@@ -332,7 +332,7 @@ public class GalleryController: ViewController, StandalonePresentableController
private let centralItemRightBarButtonItem = Promise()
private let centralItemRightBarButtonItems = Promise<[UIBarButtonItem]?>(nil)
private let centralItemNavigationStyle = Promise()
- private let centralItemFooterContentNode = Promise()
+ private let centralItemFooterContentNode = Promise<(GalleryFooterContentNode?, GalleryOverlayContentNode?)>()
private let centralItemAttributesDisposable = DisposableSet();
private let _hiddenMedia = Promise<(MessageId, Media)?>(nil)
@@ -531,9 +531,9 @@ public class GalleryController: ViewController, StandalonePresentableController
}
}))
- self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode in
+ self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode, overlayContentNode in
self?.galleryNode.updatePresentationState({
- $0.withUpdatedFooterContentNode(footerContentNode)
+ $0.withUpdatedFooterContentNode(footerContentNode).withUpdatedOverlayContentNode(overlayContentNode)
}, transition: .immediate)
}))
diff --git a/submodules/GalleryUI/Sources/GalleryControllerNode.swift b/submodules/GalleryUI/Sources/GalleryControllerNode.swift
index 0c82bd5bec..5409b07a5b 100644
--- a/submodules/GalleryUI/Sources/GalleryControllerNode.swift
+++ b/submodules/GalleryUI/Sources/GalleryControllerNode.swift
@@ -250,8 +250,8 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture
self.updateThumbnailContainerNodeAlpha(transition)
}
- self.footerNode.updateLayout(layout, footerContentNode: self.presentationState.footerContentNode, thumbnailPanelHeight: thumbnailPanelHeight, transition: transition)
-
+ self.footerNode.updateLayout(layout, footerContentNode: self.presentationState.footerContentNode, overlayContentNode: self.presentationState.overlayContentNode, thumbnailPanelHeight: thumbnailPanelHeight, transition: transition)
+
let previousContentHeight = self.scrollView.contentSize.height
let previousVerticalOffset = self.scrollView.contentOffset.y
@@ -276,14 +276,14 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture
let alpha: CGFloat = self.areControlsHidden ? 0.0 : 1.0
self.navigationBar?.alpha = alpha
self.statusBar?.updateAlpha(alpha, transition: .animated(duration: 0.3, curve: .easeInOut))
- self.footerNode.alpha = alpha
+ self.footerNode.setVisibilityAlpha(alpha)
self.updateThumbnailContainerNodeAlpha(.immediate)
})
} else {
let alpha: CGFloat = self.areControlsHidden ? 0.0 : 1.0
self.navigationBar?.alpha = alpha
self.statusBar?.updateAlpha(alpha, transition: .immediate)
- self.footerNode.alpha = alpha
+ self.footerNode.setVisibilityAlpha(alpha)
self.updateThumbnailContainerNodeAlpha(.immediate)
}
}
diff --git a/submodules/GalleryUI/Sources/GalleryControllerPresentationState.swift b/submodules/GalleryUI/Sources/GalleryControllerPresentationState.swift
index 7fd9620cb5..4881b7744e 100644
--- a/submodules/GalleryUI/Sources/GalleryControllerPresentationState.swift
+++ b/submodules/GalleryUI/Sources/GalleryControllerPresentationState.swift
@@ -2,16 +2,23 @@ import Foundation
public final class GalleryControllerPresentationState {
public let footerContentNode: GalleryFooterContentNode?
+ public let overlayContentNode: GalleryOverlayContentNode?
public init() {
self.footerContentNode = nil
+ self.overlayContentNode = nil
}
- public init(footerContentNode: GalleryFooterContentNode?) {
+ public init(footerContentNode: GalleryFooterContentNode?, overlayContentNode: GalleryOverlayContentNode?) {
self.footerContentNode = footerContentNode
+ self.overlayContentNode = overlayContentNode
}
public func withUpdatedFooterContentNode(_ footerContentNode: GalleryFooterContentNode?) -> GalleryControllerPresentationState {
- return GalleryControllerPresentationState(footerContentNode: footerContentNode)
+ return GalleryControllerPresentationState(footerContentNode: footerContentNode, overlayContentNode: self.overlayContentNode)
+ }
+
+ public func withUpdatedOverlayContentNode(_ overlayContentNode: GalleryOverlayContentNode?) -> GalleryControllerPresentationState {
+ return GalleryControllerPresentationState(footerContentNode: self.footerContentNode, overlayContentNode: overlayContentNode)
}
}
diff --git a/submodules/GalleryUI/Sources/GalleryFooterContentNode.swift b/submodules/GalleryUI/Sources/GalleryFooterContentNode.swift
index 9fe0dadf41..1d9126eec0 100644
--- a/submodules/GalleryUI/Sources/GalleryFooterContentNode.swift
+++ b/submodules/GalleryUI/Sources/GalleryFooterContentNode.swift
@@ -31,3 +31,20 @@ open class GalleryFooterContentNode: ASDisplayNode {
completion()
}
}
+
+open class GalleryOverlayContentNode: ASDisplayNode {
+ var visibilityAlpha: CGFloat = 1.0
+ open func setVisibilityAlpha(_ alpha: CGFloat) {
+ self.visibilityAlpha = alpha
+ }
+
+ open func updateLayout(size: CGSize, metrics: LayoutMetrics, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
+ }
+
+ open func animateIn(previousContentNode: GalleryOverlayContentNode?, transition: ContainedViewLayoutTransition) {
+ }
+
+ open func animateOut(nextContentNode: GalleryOverlayContentNode?, transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
+ completion()
+ }
+}
diff --git a/submodules/GalleryUI/Sources/GalleryFooterNode.swift b/submodules/GalleryUI/Sources/GalleryFooterNode.swift
index 7537360dce..155f2cc358 100644
--- a/submodules/GalleryUI/Sources/GalleryFooterNode.swift
+++ b/submodules/GalleryUI/Sources/GalleryFooterNode.swift
@@ -7,6 +7,7 @@ public final class GalleryFooterNode: ASDisplayNode {
private let backgroundNode: ASDisplayNode
private var currentFooterContentNode: GalleryFooterContentNode?
+ private var currentOverlayContentNode: GalleryOverlayContentNode?
private var currentLayout: (ContainerViewLayout, CGFloat)?
private let controllerInteraction: GalleryControllerInteraction
@@ -22,38 +23,59 @@ public final class GalleryFooterNode: ASDisplayNode {
self.addSubnode(self.backgroundNode)
}
- public func updateLayout(_ layout: ContainerViewLayout, footerContentNode: GalleryFooterContentNode?, thumbnailPanelHeight: CGFloat, transition: ContainedViewLayoutTransition) {
+ private var visibilityAlpha: CGFloat = 1.0
+ public func setVisibilityAlpha(_ alpha: CGFloat) {
+ self.visibilityAlpha = alpha
+ self.backgroundNode.alpha = alpha
+ self.currentFooterContentNode?.alpha = alpha
+ self.currentOverlayContentNode?.setVisibilityAlpha(alpha)
+ }
+
+ public func updateLayout(_ layout: ContainerViewLayout, footerContentNode: GalleryFooterContentNode?, overlayContentNode: GalleryOverlayContentNode?, thumbnailPanelHeight: CGFloat, transition: ContainedViewLayoutTransition) {
self.currentLayout = (layout, thumbnailPanelHeight)
let cleanInsets = layout.insets(options: [])
- var removeCurrentFooterContentNode: GalleryFooterContentNode?
+ var dismissedCurrentFooterContentNode: GalleryFooterContentNode?
if self.currentFooterContentNode !== footerContentNode {
if let currentFooterContentNode = self.currentFooterContentNode {
currentFooterContentNode.requestLayout = nil
- removeCurrentFooterContentNode = currentFooterContentNode
+ dismissedCurrentFooterContentNode = currentFooterContentNode
}
self.currentFooterContentNode = footerContentNode
if let footerContentNode = footerContentNode {
+ footerContentNode.alpha = self.visibilityAlpha
footerContentNode.controllerInteraction = self.controllerInteraction
footerContentNode.requestLayout = { [weak self] transition in
if let strongSelf = self, let (currentLayout, currentThumbnailPanelHeight) = strongSelf.currentLayout {
- strongSelf.updateLayout(currentLayout, footerContentNode: strongSelf.currentFooterContentNode, thumbnailPanelHeight: currentThumbnailPanelHeight, transition: transition)
+ strongSelf.updateLayout(currentLayout, footerContentNode: strongSelf.currentFooterContentNode, overlayContentNode: strongSelf.currentOverlayContentNode, thumbnailPanelHeight: currentThumbnailPanelHeight, transition: transition)
}
}
self.addSubnode(footerContentNode)
}
}
+ var dismissedCurrentOverlayContentNode: GalleryOverlayContentNode?
+ if self.currentOverlayContentNode !== overlayContentNode {
+ if let currentOverlayContentNode = self.currentOverlayContentNode {
+ dismissedCurrentOverlayContentNode = currentOverlayContentNode
+ }
+ self.currentOverlayContentNode = overlayContentNode
+ if let overlayContentNode = overlayContentNode {
+ overlayContentNode.setVisibilityAlpha(self.visibilityAlpha)
+ self.addSubnode(overlayContentNode)
+ }
+ }
+
var backgroundHeight: CGFloat = 0.0
if let footerContentNode = self.currentFooterContentNode {
backgroundHeight = footerContentNode.updateLayout(size: layout.size, metrics: layout.metrics, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, contentInset: thumbnailPanelHeight, transition: transition)
transition.updateFrame(node: footerContentNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - backgroundHeight), size: CGSize(width: layout.size.width, height: backgroundHeight)))
- if let removeCurrentFooterContentNode = removeCurrentFooterContentNode {
+ if let dismissedCurrentFooterContentNode = dismissedCurrentFooterContentNode {
let contentTransition = ContainedViewLayoutTransition.animated(duration: 0.4, curve: .spring)
- footerContentNode.animateIn(fromHeight: removeCurrentFooterContentNode.bounds.height, previousContentNode: removeCurrentFooterContentNode, transition: contentTransition)
- removeCurrentFooterContentNode.animateOut(toHeight: backgroundHeight, nextContentNode: footerContentNode, transition: contentTransition, completion: { [weak self, weak removeCurrentFooterContentNode] in
- if let strongSelf = self, let removeCurrentFooterContentNode = removeCurrentFooterContentNode, removeCurrentFooterContentNode !== strongSelf.currentFooterContentNode {
- removeCurrentFooterContentNode.removeFromSupernode()
+ footerContentNode.animateIn(fromHeight: dismissedCurrentFooterContentNode.bounds.height, previousContentNode: dismissedCurrentFooterContentNode, transition: contentTransition)
+ dismissedCurrentFooterContentNode.animateOut(toHeight: backgroundHeight, nextContentNode: footerContentNode, transition: contentTransition, completion: { [weak self, weak dismissedCurrentFooterContentNode] in
+ if let strongSelf = self, let dismissedCurrentFooterContentNode = dismissedCurrentFooterContentNode, dismissedCurrentFooterContentNode !== strongSelf.currentFooterContentNode {
+ dismissedCurrentFooterContentNode.removeFromSupernode()
}
})
contentTransition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - backgroundHeight), size: CGSize(width: layout.size.width, height: backgroundHeight)))
@@ -61,15 +83,41 @@ public final class GalleryFooterNode: ASDisplayNode {
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - backgroundHeight), size: CGSize(width: layout.size.width, height: backgroundHeight)))
}
} else {
- if let removeCurrentFooterContentNode = removeCurrentFooterContentNode {
- removeCurrentFooterContentNode.removeFromSupernode()
+ if let dismissedCurrentFooterContentNode = dismissedCurrentFooterContentNode {
+ dismissedCurrentFooterContentNode.removeFromSupernode()
}
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - backgroundHeight), size: CGSize(width: layout.size.width, height: backgroundHeight)))
}
+
+ let contentTransition = ContainedViewLayoutTransition.animated(duration: 0.4, curve: .spring)
+ if let overlayContentNode = self.currentOverlayContentNode {
+ overlayContentNode.updateLayout(size: layout.size, metrics: layout.metrics, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: backgroundHeight, transition: transition)
+ transition.updateFrame(node: overlayContentNode, frame: CGRect(origin: CGPoint(), size: layout.size))
+
+ overlayContentNode.animateIn(previousContentNode: dismissedCurrentOverlayContentNode, transition: contentTransition)
+ if let dismissedCurrentOverlayContentNode = dismissedCurrentOverlayContentNode {
+ dismissedCurrentOverlayContentNode.animateOut(nextContentNode: overlayContentNode, transition: contentTransition, completion: { [weak self, weak dismissedCurrentOverlayContentNode] in
+ if let strongSelf = self, let dismissedCurrentOverlayContentNode = dismissedCurrentOverlayContentNode, dismissedCurrentOverlayContentNode !== strongSelf.currentOverlayContentNode {
+ dismissedCurrentOverlayContentNode.removeFromSupernode()
+ }
+ })
+ }
+ } else {
+ if let dismissedCurrentOverlayContentNode = dismissedCurrentOverlayContentNode {
+ dismissedCurrentOverlayContentNode.animateOut(nextContentNode: overlayContentNode, transition: contentTransition, completion: { [weak self, weak dismissedCurrentOverlayContentNode] in
+ if let strongSelf = self, let dismissedCurrentOverlayContentNode = dismissedCurrentOverlayContentNode, dismissedCurrentOverlayContentNode !== strongSelf.currentOverlayContentNode {
+ dismissedCurrentOverlayContentNode.removeFromSupernode()
+ }
+ })
+ }
+ }
}
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
+ if let overlayResult = self.currentOverlayContentNode?.hitTest(point, with: event) {
+ return overlayResult
+ }
if !self.backgroundNode.frame.contains(point) {
return nil
}
diff --git a/submodules/GalleryUI/Sources/GalleryItemNode.swift b/submodules/GalleryUI/Sources/GalleryItemNode.swift
index ce3d8b3c59..615bdde364 100644
--- a/submodules/GalleryUI/Sources/GalleryItemNode.swift
+++ b/submodules/GalleryUI/Sources/GalleryItemNode.swift
@@ -21,6 +21,8 @@ open class GalleryItemNode: ASDisplayNode {
}
public var toggleControlsVisibility: () -> Void = { }
+ public var goToPreviousItem: () -> Void = { }
+ public var goToNextItem: () -> Void = { }
public var dismiss: () -> Void = { }
public var beginCustomDismiss: () -> Void = { }
public var completeCustomDismiss: () -> Void = { }
@@ -54,8 +56,8 @@ open class GalleryItemNode: ASDisplayNode {
return .single(nil)
}
- open func footerContent() -> Signal {
- return .single(nil)
+ open func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((nil, nil))
}
open func navigationStyle() -> Signal {
diff --git a/submodules/GalleryUI/Sources/GalleryPagerNode.swift b/submodules/GalleryUI/Sources/GalleryPagerNode.swift
index fea7e407af..125b432cdc 100644
--- a/submodules/GalleryUI/Sources/GalleryPagerNode.swift
+++ b/submodules/GalleryUI/Sources/GalleryPagerNode.swift
@@ -241,6 +241,20 @@ public final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate {
private func makeNodeForItem(at index: Int) -> GalleryItemNode {
let node = self.items[index].node()
node.toggleControlsVisibility = self.toggleControlsVisibility
+ node.goToPreviousItem = { [weak self] in
+ if let strongSelf = self {
+ if let index = strongSelf.centralItemIndex, index > 0 {
+ strongSelf.transaction(GalleryPagerTransaction(deleteItems: [], insertItems: [], updateItems: [], focusOnItem: index - 1))
+ }
+ }
+ }
+ node.goToNextItem = { [weak self] in
+ if let strongSelf = self {
+ if let index = strongSelf.centralItemIndex, index < strongSelf.items.count - 1 {
+ strongSelf.transaction(GalleryPagerTransaction(deleteItems: [], insertItems: [], updateItems: [], focusOnItem: index + 1))
+ }
+ }
+ }
node.dismiss = self.dismiss
node.beginCustomDismiss = self.beginCustomDismiss
node.completeCustomDismiss = self.completeCustomDismiss
@@ -314,7 +328,7 @@ public final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate {
}
}
- if centralItemIndex != items.count - 1 {
+ if centralItemIndex != self.items.count - 1 {
if self.shouldLoadItems(force: forceLoad) && self.visibleItemNode(at: centralItemIndex + 1) == nil {
let node = self.makeNodeForItem(at: centralItemIndex + 1)
node.frame = centralItemNode.frame.offsetBy(dx: centralItemNode.frame.size.width + self.pageGap, dy: 0.0)
diff --git a/submodules/GalleryUI/Sources/Items/ChatAnimationGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatAnimationGalleryItem.swift
index f4f24f1221..834d6758d1 100644
--- a/submodules/GalleryUI/Sources/Items/ChatAnimationGalleryItem.swift
+++ b/submodules/GalleryUI/Sources/Items/ChatAnimationGalleryItem.swift
@@ -325,8 +325,8 @@ final class ChatAnimationGalleryItemNode: ZoomableContentGalleryItemNode {
return self._rightBarButtonItems.get()
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
@objc func statusPressed() {
diff --git a/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift
index 1537d93a17..2be4d488cc 100644
--- a/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift
+++ b/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift
@@ -375,8 +375,8 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD
self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false)
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
@objc func statusPressed() {
diff --git a/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift
index c0714f5fd1..753b5cc904 100644
--- a/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift
+++ b/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift
@@ -310,8 +310,8 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode {
self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false)
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
@objc func statusPressed() {
diff --git a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift
index 083195070c..e07033342e 100644
--- a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift
+++ b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift
@@ -505,8 +505,8 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
return self._rightBarButtonItem.get()
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
@objc func statusPressed() {
diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift
index 183bce8efd..dc01efd988 100644
--- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift
+++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift
@@ -145,6 +145,87 @@ private final class UniversalVideoGalleryItemPictureInPictureNode: ASDisplayNode
}
}
+private let soundOnImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/SoundOn"), color: .white)
+private let soundOffImage = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/SoundOff"), color: .white)
+private var roundButtonBackgroundImage = {
+ return generateImage(CGSize(width: 42.0, height: 42), rotatedContext: { size, context in
+ let bounds = CGRect(origin: CGPoint(), size: size)
+ context.clear(bounds)
+ context.setFillColor(UIColor(white: 0.0, alpha: 0.5).cgColor)
+ context.fillEllipse(in: bounds)
+ })
+}()
+
+private final class UniversalVideoGalleryItemOverlayNode: GalleryOverlayContentNode {
+ private let soundButtonNode: HighlightableButtonNode
+ private var validLayout: (CGSize, LayoutMetrics, CGFloat, CGFloat, CGFloat)?
+
+ override init() {
+ self.soundButtonNode = HighlightableButtonNode()
+ self.soundButtonNode.alpha = 0.0
+ self.soundButtonNode.setBackgroundImage(roundButtonBackgroundImage, for: .normal)
+ self.soundButtonNode.setImage(soundOffImage, for: .normal)
+ self.soundButtonNode.setImage(soundOnImage, for: .selected)
+ self.soundButtonNode.setImage(soundOnImage, for: [.selected, .highlighted])
+
+ super.init()
+
+ self.soundButtonNode.addTarget(self, action: #selector(self.soundButtonPressed), forControlEvents: .touchUpInside)
+ self.addSubnode(self.soundButtonNode)
+ }
+
+ func hide() {
+ self.soundButtonNode.isHidden = true
+ }
+
+ override func updateLayout(size: CGSize, metrics: LayoutMetrics, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
+ self.validLayout = (size, metrics, leftInset, rightInset, bottomInset)
+
+ let soundButtonDiameter: CGFloat = 42.0
+ let inset: CGFloat = 12.0
+ let effectiveBottomInset = self.visibilityAlpha < 1.0 ? 0.0 : bottomInset
+ let soundButtonFrame = CGRect(origin: CGPoint(x: size.width - soundButtonDiameter - inset - rightInset, y: size.height - soundButtonDiameter - inset - effectiveBottomInset), size: CGSize(width: soundButtonDiameter, height: soundButtonDiameter))
+ transition.updateFrame(node: self.soundButtonNode, frame: soundButtonFrame)
+ }
+
+ override func animateIn(previousContentNode: GalleryOverlayContentNode?, transition: ContainedViewLayoutTransition) {
+ transition.updateAlpha(node: self.soundButtonNode, alpha: 1.0)
+ }
+
+ override func animateOut(nextContentNode: GalleryOverlayContentNode?, transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
+ transition.updateAlpha(node: self.soundButtonNode, alpha: 0.0)
+ }
+
+ override func setVisibilityAlpha(_ alpha: CGFloat) {
+ super.setVisibilityAlpha(alpha)
+ self.updateSoundButtonVisibility()
+ }
+
+ func updateSoundButtonVisibility() {
+ if self.soundButtonNode.isSelected {
+ self.soundButtonNode.alpha = self.visibilityAlpha
+ } else {
+ self.soundButtonNode.alpha = 1.0
+ }
+
+ if let validLayout = self.validLayout {
+ self.updateLayout(size: validLayout.0, metrics: validLayout.1, leftInset: validLayout.2, rightInset: validLayout.3, bottomInset: validLayout.4, transition: .animated(duration: 0.3, curve: .easeInOut))
+ }
+ }
+
+ @objc func soundButtonPressed() {
+ self.soundButtonNode.isSelected = !self.soundButtonNode.isSelected
+ self.updateSoundButtonVisibility()
+ }
+
+ override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
+ if !self.soundButtonNode.frame.contains(point) {
+ return nil
+ }
+ return super.hitTest(point, with: event)
+ }
+}
+
private struct FetchControls {
let fetch: () -> Void
let cancel: () -> Void
@@ -161,6 +242,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
private let scrubberView: ChatVideoGalleryItemScrubberView
private let footerContentNode: ChatItemGalleryFooterContentNode
+ private let overlayContentNode: UniversalVideoGalleryItemOverlayNode
private var videoNode: UniversalVideoNode?
private var videoFramePreview: MediaPlayerFramePreview?
@@ -206,6 +288,8 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
self.footerContentNode.performAction = performAction
self.footerContentNode.openActionOptions = openActionOptions
+ self.overlayContentNode = UniversalVideoGalleryItemOverlayNode()
+
self.statusButtonNode = HighlightableButtonNode()
self.statusNode = RadialStatusNode(backgroundNodeColor: UIColor(white: 0.0, alpha: 0.5))
self.statusNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 50.0, height: 50.0))
@@ -398,6 +482,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
videoNode.backgroundColor = videoNode.ownsContentNode ? UIColor.black : UIColor(rgb: 0x333335)
if item.fromPlayingVideo {
videoNode.canAttachContent = false
+ self.overlayContentNode.hide()
} else {
self.updateDisplayPlaceholder(!videoNode.ownsContentNode)
}
@@ -982,7 +1067,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
transformedSuperFrame = transformedSuperFrame.offsetBy(dx: videoNode.position.x - previousFrame.center.x, dy: videoNode.position.y - previousFrame.center.y)
}
- let initialScale: CGFloat = 1.0 //min(videoNode.layer.bounds.width / node.0.view.bounds.width, videoNode.layer.bounds.height / node.0.view.bounds.height)
+ let initialScale: CGFloat = 1.0
let targetScale = max(transformedFrame.size.width / videoNode.layer.bounds.size.width, transformedFrame.size.height / videoNode.layer.bounds.size.height)
videoNode.backgroundColor = .clear
@@ -1197,7 +1282,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, self.overlayContentNode))
}
}
diff --git a/submodules/GalleryUI/Sources/ZoomableContentGalleryItemNode.swift b/submodules/GalleryUI/Sources/ZoomableContentGalleryItemNode.swift
index 7c7851232a..a0abf7e711 100644
--- a/submodules/GalleryUI/Sources/ZoomableContentGalleryItemNode.swift
+++ b/submodules/GalleryUI/Sources/ZoomableContentGalleryItemNode.swift
@@ -3,8 +3,36 @@ import UIKit
import Display
import AsyncDisplayKit
+private let leftFadeImage = generateImage(CGSize(width: 64.0, height: 1.0), opaque: false, rotatedContext: { size, context in
+ let bounds = CGRect(origin: CGPoint(), size: size)
+ context.clear(bounds)
+
+ let gradientColors = [UIColor.black.withAlphaComponent(0.5).cgColor, UIColor.black.withAlphaComponent(0.0).cgColor] as CFArray
+
+ var locations: [CGFloat] = [0.0, 1.0]
+ let colorSpace = CGColorSpaceCreateDeviceRGB()
+ let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
+
+ context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 64.0, y: 0.0), options: CGGradientDrawingOptions())
+})
+
+private let rightFadeImage = generateImage(CGSize(width: 64.0, height: 1.0), opaque: false, rotatedContext: { size, context in
+ let bounds = CGRect(origin: CGPoint(), size: size)
+ context.clear(bounds)
+
+ let gradientColors = [UIColor.black.withAlphaComponent(0.0).cgColor, UIColor.black.withAlphaComponent(0.5).cgColor] as CFArray
+
+ var locations: [CGFloat] = [0.0, 1.0]
+ let colorSpace = CGColorSpaceCreateDeviceRGB()
+ let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
+
+ context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 64.0, y: 0.0), options: CGGradientDrawingOptions())
+})
+
open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate {
public let scrollNode: ASScrollNode
+ private let leftFadeNode: ASImageNode
+ private let rightFadeNode: ASImageNode
private var containerLayout: ContainerViewLayout?
@@ -32,6 +60,16 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
self.scrollNode.view.contentInsetAdjustmentBehavior = .never
}
+ self.leftFadeNode = ASImageNode()
+ self.leftFadeNode.contentMode = .scaleToFill
+ self.leftFadeNode.image = leftFadeImage
+ self.leftFadeNode.isHidden = true
+
+ self.rightFadeNode = ASImageNode()
+ self.rightFadeNode.contentMode = .scaleToFill
+ self.rightFadeNode.image = rightFadeImage
+ self.rightFadeNode.isHidden = true
+
super.init()
self.scrollNode.view.delegate = self
@@ -42,41 +80,69 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
self.scrollNode.view.delaysContentTouches = false
let tapRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.contentTap(_:)))
- tapRecognizer.tapActionAtPoint = { _ in
+ tapRecognizer.tapActionAtPoint = { [weak self] location in
+ if let strongSelf = self {
+ if location.x < 44.0 || location.x > strongSelf.frame.width - 44.0 {
+ return .waitForSingleTap
+ }
+ }
return .waitForDoubleTap
}
+ tapRecognizer.highlight = { [weak self] location in
+ if let strongSelf = self {
+ if let location = location, location.x < 44.0 {
+ strongSelf.leftFadeNode.isHidden = false
+ } else {
+ strongSelf.leftFadeNode.isHidden = true
+ }
+ if let location = location, location.x > strongSelf.frame.width - 44.0 {
+ strongSelf.rightFadeNode.isHidden = false
+ } else {
+ strongSelf.rightFadeNode.isHidden = true
+ }
+ }
+ }
self.scrollNode.view.addGestureRecognizer(tapRecognizer)
+
self.addSubnode(self.scrollNode)
+ self.addSubnode(self.leftFadeNode)
+ self.addSubnode(self.rightFadeNode)
}
@objc open func contentTap(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
if recognizer.state == .ended {
if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation {
- switch gesture {
- case .tap:
- self.toggleControlsVisibility()
- case .doubleTap:
- if let contentView = self.zoomableContent?.1.view, self.scrollNode.view.zoomScale.isLessThanOrEqualTo(self.scrollNode.view.minimumZoomScale) {
- let pointInView = self.scrollNode.view.convert(location, to: contentView)
-
- let newZoomScale = self.scrollNode.view.maximumZoomScale
- let scrollViewSize = self.scrollNode.view.bounds.size
-
- let w = scrollViewSize.width / newZoomScale
- let h = scrollViewSize.height / newZoomScale
- let x = pointInView.x - (w / 2.0)
- let y = pointInView.y - (h / 2.0)
-
- let rectToZoomTo = CGRect(x: x, y: y, width: w, height: h)
-
- self.scrollNode.view.zoom(to: rectToZoomTo, animated: true)
- } else {
- self.scrollNode.view.setZoomScale(self.scrollNode.view.minimumZoomScale, animated: true)
- }
- default:
- break
+ if location.x < 44.0 {
+ self.goToPreviousItem()
+ } else if location.x > self.frame.width - 44.0 {
+ self.goToNextItem()
+ } else {
+ switch gesture {
+ case .tap:
+ self.toggleControlsVisibility()
+ case .doubleTap:
+ if let contentView = self.zoomableContent?.1.view, self.scrollNode.view.zoomScale.isLessThanOrEqualTo(self.scrollNode.view.minimumZoomScale) {
+ let pointInView = self.scrollNode.view.convert(location, to: contentView)
+
+ let newZoomScale = self.scrollNode.view.maximumZoomScale
+ let scrollViewSize = self.scrollNode.view.bounds.size
+
+ let w = scrollViewSize.width / newZoomScale
+ let h = scrollViewSize.height / newZoomScale
+ let x = pointInView.x - (w / 2.0)
+ let y = pointInView.y - (h / 2.0)
+
+ let rectToZoomTo = CGRect(x: x, y: y, width: w, height: h)
+
+ self.scrollNode.view.zoom(to: rectToZoomTo, animated: true)
+ } else {
+ self.scrollNode.view.setZoomScale(self.scrollNode.view.minimumZoomScale, animated: true)
+ }
+ default:
+ break
+ }
}
}
}
@@ -93,6 +159,9 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
}
self.containerLayout = layout
+ self.leftFadeNode.frame = CGRect(x: 0.0, y: 0.0, width: layout.size.width * 0.2, height: layout.size.height)
+ self.rightFadeNode.frame = CGRect(x: layout.size.width - layout.size.width * 0.2, y: 0.0, width: layout.size.width * 0.2, height: layout.size.height)
+
if shouldResetContents {
var previousFrame: CGRect?
var previousScale: CGFloat?
diff --git a/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift b/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift
index 9254384396..1d0c082ae5 100644
--- a/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift
+++ b/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift
@@ -301,7 +301,7 @@ final class InstantImageGalleryItemNode: ZoomableContentGalleryItemNode {
return self._title.get()
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
}
diff --git a/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift b/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift
index 0e32aadb82..d50fc2b478 100644
--- a/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift
+++ b/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift
@@ -170,7 +170,7 @@ public class InstantPageGalleryController: ViewController, StandalonePresentable
private let centralItemTitleView = Promise()
private let centralItemRightBarButtonItem = Promise()
private let centralItemNavigationStyle = Promise()
- private let centralItemFooterContentNode = Promise()
+ private let centralItemFooterContentNode = Promise<(GalleryFooterContentNode?, GalleryOverlayContentNode?)>()
private let centralItemAttributesDisposable = DisposableSet();
private let _hiddenMedia = Promise(nil)
@@ -243,7 +243,7 @@ public class InstantPageGalleryController: ViewController, StandalonePresentable
self?.navigationItem.rightBarButtonItem = rightBarButtonItem
}))
- self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode in
+ self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode, _ in
self?.galleryNode.updatePresentationState({
$0.withUpdatedFooterContentNode(footerContentNode)
}, transition: .immediate)
diff --git a/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift b/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift
index 2b0988c6d8..b9da7f99eb 100644
--- a/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift
+++ b/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift
@@ -12,6 +12,11 @@ public enum ItemListPeerActionItemHeight {
case peerList
}
+public enum ItemListPeerActionItemColor {
+ case accent
+ case destructive
+}
+
public class ItemListPeerActionItem: ListViewItem, ItemListItem {
let presentationData: ItemListPresentationData
let icon: UIImage?
@@ -19,16 +24,18 @@ public class ItemListPeerActionItem: ListViewItem, ItemListItem {
public let alwaysPlain: Bool
let editing: Bool
let height: ItemListPeerActionItemHeight
+ let color: ItemListPeerActionItemColor
public let sectionId: ItemListSectionId
let action: (() -> Void)?
- public init(presentationData: ItemListPresentationData, icon: UIImage?, title: String, alwaysPlain: Bool = false, sectionId: ItemListSectionId, height: ItemListPeerActionItemHeight = .peerList, editing: Bool, action: (() -> Void)?) {
+ public init(presentationData: ItemListPresentationData, icon: UIImage?, title: String, alwaysPlain: Bool = false, sectionId: ItemListSectionId, height: ItemListPeerActionItemHeight = .peerList, color: ItemListPeerActionItemColor = .accent, editing: Bool, action: (() -> Void)?) {
self.presentationData = presentationData
self.icon = icon
self.title = title
self.alwaysPlain = alwaysPlain
self.editing = editing
self.height = height
+ self.color = color
self.sectionId = sectionId
self.action = action
}
@@ -167,7 +174,15 @@ class ItemListPeerActionItemNode: ListViewItemNode {
let editingOffset: CGFloat = (item.editing ? 38.0 : 0.0)
- let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: item.presentationData.theme.list.itemAccentColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - editingOffset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+ let textColor: UIColor
+ switch item.color {
+ case .accent:
+ textColor = item.presentationData.theme.list.itemAccentColor
+ case .destructive:
+ textColor = item.presentationData.theme.list.itemDestructiveColor
+ }
+
+ let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: textColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - editingOffset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let separatorHeight = UIScreenPixel
diff --git a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift
index 0eb1793f6c..f707e88839 100644
--- a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift
+++ b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift
@@ -31,6 +31,7 @@ public enum ItemListStickerPackItemControl: Equatable {
case none
case installation(installed: Bool)
case selection
+ case check(checked: Bool)
}
public final class ItemListStickerPackItem: ListViewItem, ItemListItem {
@@ -305,6 +306,8 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
case .selection:
rightInset += 16.0
checkImage = PresentationResourcesItemList.checkIconImage(item.presentationData.theme)
+ case .check:
+ rightInset += 16.0
}
var unreadImage: UIImage?
@@ -531,6 +534,10 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
strongSelf.selectionIconNode.image = image
strongSelf.selectionIconNode.frame = CGRect(origin: CGPoint(x: params.width - params.rightInset - image.size.width - floor((44.0 - image.size.width) / 2.0), y: floor((contentSize.height - image.size.height) / 2.0)), size: image.size)
}
+ case let .check(checked):
+ strongSelf.installationActionNode.isHidden = true
+ strongSelf.installationActionImageNode.isHidden = true
+ strongSelf.selectionIconNode.isHidden = true
}
if strongSelf.backgroundNode.supernode == nil {
diff --git a/submodules/PassportUI/Sources/SecureIdDocumentGalleryController.swift b/submodules/PassportUI/Sources/SecureIdDocumentGalleryController.swift
index d8a06b4494..b2604b8881 100644
--- a/submodules/PassportUI/Sources/SecureIdDocumentGalleryController.swift
+++ b/submodules/PassportUI/Sources/SecureIdDocumentGalleryController.swift
@@ -68,7 +68,7 @@ class SecureIdDocumentGalleryController: ViewController, StandalonePresentableCo
private let centralItemTitle = Promise()
private let centralItemTitleView = Promise()
private let centralItemNavigationStyle = Promise()
- private let centralItemFooterContentNode = Promise()
+ private let centralItemFooterContentNode = Promise<(GalleryFooterContentNode?, GalleryOverlayContentNode?)>()
private let centralItemAttributesDisposable = DisposableSet();
private let _hiddenMedia = Promise(nil)
@@ -123,7 +123,7 @@ class SecureIdDocumentGalleryController: ViewController, StandalonePresentableCo
self?.navigationItem.titleView = titleView
}))
- self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode in
+ self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode, _ in
self?.galleryNode.updatePresentationState({
$0.withUpdatedFooterContentNode(footerContentNode)
}, transition: .immediate)
diff --git a/submodules/PassportUI/Sources/SecureIdDocumentImageGalleryItem.swift b/submodules/PassportUI/Sources/SecureIdDocumentImageGalleryItem.swift
index b4f80aa4d5..857c233cc3 100644
--- a/submodules/PassportUI/Sources/SecureIdDocumentImageGalleryItem.swift
+++ b/submodules/PassportUI/Sources/SecureIdDocumentImageGalleryItem.swift
@@ -210,8 +210,8 @@ final class SecureIdDocumentGalleryItemNode: ZoomableContentGalleryItemNode {
return self._title.get()
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
}
diff --git a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift
index 30c25a1b5b..cb2f0a9d82 100644
--- a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift
+++ b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift
@@ -118,7 +118,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
private let centralItemTitle = Promise()
private let centralItemTitleView = Promise()
private let centralItemNavigationStyle = Promise()
- private let centralItemFooterContentNode = Promise()
+ private let centralItemFooterContentNode = Promise<(GalleryFooterContentNode?, GalleryOverlayContentNode?)>()
private let centralItemAttributesDisposable = DisposableSet();
private let _hiddenMedia = Promise(nil)
@@ -232,7 +232,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
self?.navigationItem.titleView = titleView
}))
- self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode in
+ self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode, _ in
self?.galleryNode.updatePresentationState({
$0.withUpdatedFooterContentNode(footerContentNode)
}, transition: .immediate)
diff --git a/submodules/PeerAvatarGalleryUI/Sources/PeerAvatarImageGalleryItem.swift b/submodules/PeerAvatarGalleryUI/Sources/PeerAvatarImageGalleryItem.swift
index 4789f0c18f..d2db820983 100644
--- a/submodules/PeerAvatarGalleryUI/Sources/PeerAvatarImageGalleryItem.swift
+++ b/submodules/PeerAvatarGalleryUI/Sources/PeerAvatarImageGalleryItem.swift
@@ -355,7 +355,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
}
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
}
diff --git a/submodules/PeerInfoUI/BUCK b/submodules/PeerInfoUI/BUCK
index 47da260275..16d723277d 100644
--- a/submodules/PeerInfoUI/BUCK
+++ b/submodules/PeerInfoUI/BUCK
@@ -64,6 +64,7 @@ static_library(
"//submodules/TelegramIntents:TelegramIntents",
"//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode",
"//submodules/ChatListSearchItemHeader:ChatListSearchItemHeader",
+ "//submodules/StatisticsUI:StatisticsUI",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
diff --git a/submodules/PeersNearbyUI/BUCK b/submodules/PeersNearbyUI/BUCK
index 5a6ca7965b..a6c565b2b6 100644
--- a/submodules/PeersNearbyUI/BUCK
+++ b/submodules/PeersNearbyUI/BUCK
@@ -26,6 +26,8 @@ static_library(
"//submodules/PeersNearbyIconNode:PeersNearbyIconNode",
"//submodules/Geocoding:Geocoding",
"//submodules/AppBundle:AppBundle",
+ "//submodules/AnimatedStickerNode:AnimatedStickerNode",
+ "//submodules/TelegramStringFormatting:TelegramStringFormatting",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
diff --git a/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift b/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift
index 5c6a28bdae..32b5157750 100644
--- a/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift
+++ b/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift
@@ -20,6 +20,9 @@ import TelegramPermissionsUI
import ItemListPeerActionItem
import Geocoding
import AppBundle
+import ContextUI
+import TelegramNotices
+import TelegramStringFormatting
private struct PeerNearbyEntry {
let peer: (Peer, CachedPeerData?)
@@ -49,13 +52,19 @@ private func arePeerNearbyArraysEqual(_ lhs: [PeerNearbyEntry], _ rhs: [PeerNear
private final class PeersNearbyControllerArguments {
let context: AccountContext
+ let toggleVisibility: (Bool) -> Void
+ let openProfile: (Peer) -> Void
let openChat: (Peer) -> Void
let openCreateGroup: (Double, Double, String?) -> Void
+ let contextAction: (Peer, ASDisplayNode, ContextGesture?) -> Void
- init(context: AccountContext, openChat: @escaping (Peer) -> Void, openCreateGroup: @escaping (Double, Double, String?) -> Void) {
+ init(context: AccountContext, toggleVisibility: @escaping (Bool) -> Void, openProfile: @escaping (Peer) -> Void, openChat: @escaping (Peer) -> Void, openCreateGroup: @escaping (Double, Double, String?) -> Void, contextAction: @escaping (Peer, ASDisplayNode, ContextGesture?) -> Void) {
self.context = context
+ self.toggleVisibility = toggleVisibility
+ self.openProfile = openProfile
self.openChat = openChat
self.openCreateGroup = openCreateGroup
+ self.contextAction = contextAction
}
}
@@ -71,6 +80,7 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
case usersHeader(PresentationTheme, String, Bool)
case empty(PresentationTheme, String)
+ case visibility(PresentationTheme, String, Bool)
case user(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, PeerNearbyEntry)
case groupsHeader(PresentationTheme, String, Bool)
@@ -84,7 +94,7 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
switch self {
case .header:
return PeersNearbySection.header.rawValue
- case .usersHeader, .empty, .user:
+ case .usersHeader, .empty, .visibility, .user:
return PeersNearbySection.users.rawValue
case .groupsHeader, .createGroup, .group:
return PeersNearbySection.groups.rawValue
@@ -101,8 +111,10 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
return 1
case .empty:
return 2
+ case .visibility:
+ return 3
case let .user(index, _, _, _, _, _):
- return 3 + index
+ return 4 + index
case .groupsHeader:
return 1000
case .createGroup:
@@ -136,6 +148,13 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
} else {
return false
}
+ case let .visibility(lhsTheme, lhsText, lhsStop):
+ if case let .visibility(rhsTheme, rhsText, rhsStop) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsStop == rhsStop {
+ return true
+ } else {
+ return false
+ }
+
case let .user(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsDisplayOrder, lhsPeer):
if case let .user(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsDisplayOrder, rhsPeer) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsDisplayOrder == rhsDisplayOrder, arePeersNearbyEqual(lhsPeer, rhsPeer) {
return true
@@ -199,10 +218,20 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, activityIndicator: loading ? .left : .none, sectionId: self.section)
case let .empty(theme, text):
return ItemListPlaceholderItem(theme: theme, text: text, sectionId: self.section, style: .blocks)
+ case let .visibility(theme, title, stop):
+ return ItemListPeerActionItem(presentationData: presentationData, icon: stop ? PresentationResourcesItemList.makeInvisibleIcon(theme) : PresentationResourcesItemList.makeVisibleIcon(theme), title: title, alwaysPlain: false, sectionId: self.section, color: stop ? .destructive : .accent, editing: false, action: {
+ arguments.toggleVisibility(!stop)
+ })
case let .user(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer):
+ var text = strings.Map_DistanceAway(stringForDistance(peer.distance)).0
+ if peer.peer.0.id == arguments.context.account.peerId {
+ text = strings.PeopleNearby_VisibleUntil(humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: peer.expires)).0
+ }
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer.peer.0, aliasHandling: .standard, nameColor: .primary, nameStyle: .distinctBold, presence: nil, text: .text(strings.Map_DistanceAway(stringForDistance(peer.distance)).0), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: {
- arguments.openChat(peer.peer.0)
- }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, hasTopGroupInset: false, tag: nil)
+ arguments.openProfile(peer.peer.0)
+ }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: { node, gesture in
+ arguments.contextAction(peer.peer.0, node, gesture)
+ }, hasTopGroupInset: false, tag: nil)
case let .groupsHeader(theme, text, loading):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, activityIndicator: loading ? .left : .none, sectionId: self.section)
case let .createGroup(theme, title, latitude, longitude, address):
@@ -220,7 +249,9 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
}
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer.peer.0, aliasHandling: .standard, nameColor: .primary, nameStyle: .distinctBold, presence: nil, text: text, label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: {
arguments.openChat(peer.peer.0)
- }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, hasTopGroupInset: false, tag: nil)
+ }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: { node, gesture in
+ arguments.contextAction(peer.peer.0, node, gesture)
+ }, hasTopGroupInset: false, tag: nil)
case let .channelsHeader(theme, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .channel(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer):
@@ -232,7 +263,9 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
}
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer.peer.0, aliasHandling: .standard, nameColor: .primary, nameStyle: .distinctBold, presence: nil, text: text, label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: {
arguments.openChat(peer.peer.0)
- }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, hasTopGroupInset: false, tag: nil)
+ }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: { node, gesture in
+ arguments.contextAction(peer.peer.0, node, gesture)
+ }, hasTopGroupInset: false, tag: nil)
}
}
}
@@ -241,37 +274,41 @@ private struct PeersNearbyData: Equatable {
let latitude: Double
let longitude: Double
let address: String?
+ let visible: Bool
let users: [PeerNearbyEntry]
let groups: [PeerNearbyEntry]
let channels: [PeerNearbyEntry]
- init(latitude: Double, longitude: Double, address: String?, users: [PeerNearbyEntry], groups: [PeerNearbyEntry], channels: [PeerNearbyEntry]) {
+ init(latitude: Double, longitude: Double, address: String?, visible: Bool, users: [PeerNearbyEntry], groups: [PeerNearbyEntry], channels: [PeerNearbyEntry]) {
self.latitude = latitude
self.longitude = longitude
self.address = address
+ self.visible = visible
self.users = users
self.groups = groups
self.channels = channels
}
static func ==(lhs: PeersNearbyData, rhs: PeersNearbyData) -> Bool {
- return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude && lhs.address == rhs.address && arePeerNearbyArraysEqual(lhs.users, rhs.users) && arePeerNearbyArraysEqual(lhs.groups, rhs.groups) && arePeerNearbyArraysEqual(lhs.channels, rhs.channels)
+ return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude && lhs.address == rhs.address && lhs.visible == rhs.visible && arePeerNearbyArraysEqual(lhs.users, rhs.users) && arePeerNearbyArraysEqual(lhs.groups, rhs.groups) && arePeerNearbyArraysEqual(lhs.channels, rhs.channels)
}
}
private func peersNearbyControllerEntries(data: PeersNearbyData?, presentationData: PresentationData, displayLoading: Bool) -> [PeersNearbyEntry] {
var entries: [PeersNearbyEntry] = []
- entries.append(.header(presentationData.theme, presentationData.strings.PeopleNearby_Description))
+ entries.append(.header(presentationData.theme, presentationData.strings.PeopleNearby_DiscoverDescription))
entries.append(.usersHeader(presentationData.theme, presentationData.strings.PeopleNearby_Users.uppercased(), displayLoading && data == nil))
+
+ let visible = data?.visible ?? false
+ entries.append(.visibility(presentationData.theme, visible ? presentationData.strings.PeopleNearby_MakeInvisible : presentationData.strings.PeopleNearby_MakeVisible, visible))
+
if let data = data, !data.users.isEmpty {
var i: Int32 = 0
for user in data.users {
entries.append(.user(i, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, user))
i += 1
}
- } else {
- entries.append(.empty(presentationData.theme, presentationData.strings.PeopleNearby_UsersEmpty))
}
entries.append(.groupsHeader(presentationData.theme, presentationData.strings.PeopleNearby_Groups.uppercased(), displayLoading && data == nil))
@@ -295,11 +332,94 @@ private func peersNearbyControllerEntries(data: PeersNearbyData?, presentationDa
return entries
}
+private final class ContextControllerContentSourceImpl: ContextControllerContentSource {
+ let controller: ViewController
+ weak var sourceNode: ASDisplayNode?
+
+ let navigationController: NavigationController? = nil
+
+ let passthroughTouches: Bool = true
+
+ init(controller: ViewController, sourceNode: ASDisplayNode?) {
+ self.controller = controller
+ self.sourceNode = sourceNode
+ }
+
+ func transitionInfo() -> ContextControllerTakeControllerInfo? {
+ let sourceNode = self.sourceNode
+ return ContextControllerTakeControllerInfo(contentAreaInScreenSpace: CGRect(origin: CGPoint(), size: CGSize(width: 10.0, height: 10.0)), sourceNode: { [weak sourceNode] in
+ if let sourceNode = sourceNode {
+ return (sourceNode, sourceNode.bounds)
+ } else {
+ return nil
+ }
+ })
+ }
+
+ func animatedIn() {
+ }
+}
+
+private func peerNearbyContextMenuItems(context: AccountContext, peerId: PeerId, present: @escaping (ViewController) -> Void) -> Signal<[ContextMenuItem], NoError> {
+ let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
+ return context.account.postbox.transaction { transaction -> [ContextMenuItem] in
+ var items: [ContextMenuItem] = []
+//
+// let peer = transaction.getPeer(peerId)
+//
+// if let peer = peer as? TelegramUser {
+// items.append(.action(ContextMenuActionItem(text: presentationData.strings.ChatList_Context_AddToContacts, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Add"), color: theme.contextMenu.primaryColor) }, action: { _, f in
+// f(.default)
+// })))
+// } else {
+// items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeopleNearby_Context_JoinGroup, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Add"), color: theme.contextMenu.primaryColor) }, action: { _, f in
+// let _ = (joinChannel(account: context.account, peerId: peerId) |> deliverOnMainQueue).start(next: { participant in
+// f(.default)
+// }, error: { error in
+//// if let strongSelf = self {
+//// if case .tooMuchJoined = error {
+//// if let parentNavigationController = strongSelf.parentNavigationController {
+//// let context = strongSelf.context
+//// let link = strongSelf.link
+//// let navigateToPeer = strongSelf.navigateToPeer
+//// let resolvedState = strongSelf.resolvedState
+//// parentNavigationController.pushViewController(oldChannelsController(context: strongSelf.context, intent: .join, completed: { [weak parentNavigationController] value in
+//// if value {
+//// (parentNavigationController?.viewControllers.last as? ViewController)?.present(JoinLinkPreviewController(context: context, link: link, navigateToPeer: navigateToPeer, parentNavigationController: parentNavigationController, resolvedState: resolvedState), in: .window(.root))
+//// }
+//// }))
+//// } else {
+//// strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.Join_ChannelsTooMuch, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
+//// }
+//// strongSelf.dismiss()
+//// }
+//// }
+// })
+// })))
+//
+// items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeopleNearby_Context_UnrelatedLocation, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Report"), color: theme.contextMenu.primaryColor) }, action: { _, f in
+// let _ = (TelegramCore.reportPeer(account: context.account, peerId: peerId, reason: .irrelevantLocation)
+// |> deliverOnMainQueue).start(completed: {
+// let _ = ApplicationSpecificNotice.setIrrelevantPeerGeoReport(postbox: context.account.postbox, peerId: peerId).start()
+//
+// present(textAlertController(context: context, title: nil, text: presentationData.strings.ReportPeer_AlertSuccess, actions: [TextAlertAction(type: TextAlertActionType.defaultAction, title: presentationData.strings.Common_OK, action: {})]))
+// })
+// f(.default)
+// })))
+// }
+
+ return items
+ }
+}
+
+
public func peersNearbyController(context: AccountContext) -> ViewController {
var pushControllerImpl: ((ViewController) -> Void)?
var replaceAllButRootControllerImpl: ((ViewController, Bool) -> Void)?
var replaceTopControllerImpl: ((ViewController) -> Void)?
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
+ var presentInGlobalOverlayImpl: ((ViewController) -> Void)?
+ var navigateToProfileImpl: ((Peer) -> Void)?
var navigateToChatImpl: ((Peer) -> Void)?
let actionsDisposable = DisposableSet()
@@ -309,7 +429,27 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
let dataPromise = Promise(nil)
let addressPromise = Promise(nil)
- let arguments = PeersNearbyControllerArguments(context: context, openChat: { peer in
+ let coordinatePromise = Promise(nil)
+ coordinatePromise.set(.single(nil) |> then(currentLocationManagerCoordinate(manager: context.sharedContext.locationManager!, timeout: 5.0)))
+
+ let arguments = PeersNearbyControllerArguments(context: context, toggleVisibility: { visible in
+ let presentationData = context.sharedContext.currentPresentationData.with { $0 }
+
+ if visible {
+ presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.PeopleNearby_MakeVisibleTitle, text: presentationData.strings.PeopleNearby_MakeVisibleDescription, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
+ let _ = (coordinatePromise.get()
+ |> deliverOnMainQueue).start(next: { coordinate in
+ if let coordinate = coordinate {
+ let _ = peersNearbyUpdateVisibility(network: context.account.network, stateManager: context.account.stateManager, update: .visible(latitude: coordinate.latitude, longitude: coordinate.longitude), background: false).start()
+ }
+ })
+ })]), nil)
+ } else {
+ let _ = peersNearbyUpdateVisibility(network: context.account.network, stateManager: context.account.stateManager, update: .invisible, background: false).start()
+ }
+ }, openProfile: { peer in
+ navigateToProfileImpl?(peer)
+ }, openChat: { peer in
navigateToChatImpl?(peer)
}, openCreateGroup: { latitude, longitude, address in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
@@ -350,16 +490,24 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.CreateGroup_ErrorLocatedGroupsTooMuch, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
}
}))
+ }, contextAction: { peer, node, gesture in
+ let presentationData = context.sharedContext.currentPresentationData.with { $0 }
+ let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
+ chatController.canReadHistory.set(false)
+ let contextController = ContextController(account: context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: peerNearbyContextMenuItems(context: context, peerId: peer.id, present: { c in
+ presentControllerImpl?(c, nil)
+ }), reactionItems: [], gesture: gesture)
+ presentInGlobalOverlayImpl?(contextController)
})
- let dataSignal: Signal = currentLocationManagerCoordinate(manager: context.sharedContext.locationManager!, timeout: 5.0)
+ let dataSignal: Signal = coordinatePromise.get()
|> mapToSignal { coordinate -> Signal in
guard let coordinate = coordinate else {
return .single(nil)
}
return Signal { subscriber in
- let peersNearbyContext = PeersNearbyContext(network: context.account.network, accountStateManager: context.account.stateManager, coordinate: (latitude: coordinate.latitude, longitude: coordinate.longitude))
+ let peersNearbyContext = PeersNearbyContext(network: context.account.network, stateManager: context.account.stateManager, coordinate: (latitude: coordinate.latitude, longitude: coordinate.longitude))
let peersNearby: Signal = combineLatest(peersNearbyContext.get(), addressPromise.get())
|> mapToSignal { peersNearby, address -> Signal<([PeerNearby]?, String?), NoError> in
@@ -379,17 +527,26 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
return context.account.postbox.transaction { transaction -> PeersNearbyData? in
var users: [PeerNearbyEntry] = []
var groups: [PeerNearbyEntry] = []
+ var visible = false
for peerNearby in peersNearby {
- if peerNearby.id != context.account.peerId, let peer = transaction.getPeer(peerNearby.id) {
- if peerNearby.id.namespace == Namespaces.Peer.CloudUser {
- users.append(PeerNearbyEntry(peer: (peer, nil), expires: peerNearby.expires, distance: peerNearby.distance))
- } else {
- let cachedData = transaction.getPeerCachedData(peerId: peerNearby.id) as? CachedChannelData
- groups.append(PeerNearbyEntry(peer: (peer, cachedData), expires: peerNearby.expires, distance: peerNearby.distance))
- }
+ switch peerNearby {
+ case let .peer(id, expires, distance):
+ if let peer = transaction.getPeer(id) {
+ if id.namespace == Namespaces.Peer.CloudUser {
+ users.append(PeerNearbyEntry(peer: (peer, nil), expires: expires, distance: distance))
+ } else {
+ let cachedData = transaction.getPeerCachedData(peerId: id) as? CachedChannelData
+ groups.append(PeerNearbyEntry(peer: (peer, cachedData), expires: expires, distance: distance))
+ }
+ }
+ case let .selfPeer(expires):
+ visible = true
+ if let peer = transaction.getPeer(context.account.peerId) {
+ users.append(PeerNearbyEntry(peer: (peer, nil), expires: expires, distance: 0))
+ }
}
}
- return PeersNearbyData(latitude: coordinate.latitude, longitude: coordinate.longitude, address: address, users: users, groups: groups, channels: [])
+ return PeersNearbyData(latitude: coordinate.latitude, longitude: coordinate.longitude, address: address, visible: visible, users: users, groups: groups, channels: [])
}
}
@@ -438,6 +595,11 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
controller.didDisappear = { [weak controller] _ in
controller?.clearItemNodesHighlight(animated: true)
}
+ navigateToProfileImpl = { [weak controller] peer in
+ if let navigationController = controller?.navigationController as? NavigationController, let controller = context.sharedContext.makePeerInfoController(context: context, peer: peer, mode: .generic) {
+ (navigationController as? NavigationController)?.pushViewController(controller)
+ }
+ }
navigateToChatImpl = { [weak controller] peer in
if let navigationController = controller?.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer.id), keepStack: .always, purposefulAction: { [weak navigationController] in
@@ -467,6 +629,10 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
controller.present(c, in: .window(.root), with: p)
}
}
-
+ presentInGlobalOverlayImpl = { [weak controller] c in
+ if let controller = controller {
+ controller.presentInGlobalOverlay(c)
+ }
+ }
return controller
}
diff --git a/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift b/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift
index 7bbb9e9428..ed5a84dc13 100644
--- a/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift
+++ b/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift
@@ -6,7 +6,8 @@ import SwiftSignalKit
import TelegramPresentationData
import ItemListUI
import PresentationDataUtils
-import PeersNearbyIconNode
+import AnimatedStickerNode
+import AppBundle
class PeersNearbyHeaderItem: ListViewItem, ItemListItem {
let theme: PresentationTheme
@@ -60,7 +61,7 @@ private let titleFont = Font.regular(13.0)
class PeersNearbyHeaderItemNode: ListViewItemNode {
private let titleNode: TextNode
- private var iconNode: PeersNearbyIconNode?
+ private var animationNode: AnimatedStickerNode
private var item: PeersNearbyHeaderItem?
@@ -70,24 +71,29 @@ class PeersNearbyHeaderItemNode: ListViewItemNode {
self.titleNode.contentMode = .left
self.titleNode.contentsScale = UIScreen.main.scale
+ self.animationNode = AnimatedStickerNode()
+ if let path = getAppBundle().path(forResource: "Compass", ofType: "tgs") {
+ self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .once, mode: .direct)
+ self.animationNode.visibility = true
+ }
+
super.init(layerBacked: false, dynamicBounce: false)
self.addSubnode(self.titleNode)
+ self.addSubnode(self.animationNode)
}
func asyncLayout() -> (_ item: PeersNearbyHeaderItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
return { item, params, neighbors in
- let leftInset: CGFloat = 48.0 + params.leftInset
+ let leftInset: CGFloat = 32.0 + params.leftInset
let topInset: CGFloat = 92.0
let attributedText = NSAttributedString(string: item.text, font: titleFont, textColor: item.theme.list.freeTextColor)
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
- let contentSize: CGSize
-
- contentSize = CGSize(width: params.width, height: topInset + titleLayout.size.height)
+ let contentSize = CGSize(width: params.width, height: topInset + titleLayout.size.height)
let insets = itemListNeighborsGroupedInsets(neighbors)
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
@@ -96,22 +102,13 @@ class PeersNearbyHeaderItemNode: ListViewItemNode {
if let strongSelf = self {
strongSelf.item = item
strongSelf.accessibilityLabel = attributedText.string
-
- let iconNode: PeersNearbyIconNode
- if let node = strongSelf.iconNode {
- iconNode = node
- iconNode.updateTheme(item.theme)
- } else {
- iconNode = PeersNearbyIconNode(theme: item.theme)
- strongSelf.iconNode = iconNode
- strongSelf.addSubnode(iconNode)
- }
-
- let iconSize = CGSize(width: 60.0, height: 60.0)
- iconNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: 5.0), size: iconSize)
+
+ let iconSize = CGSize(width: 96.0, height: 96.0)
+ strongSelf.animationNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: -10.0), size: iconSize)
+ strongSelf.animationNode.updateLayout(size: iconSize)
let _ = titleApply()
- strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleLayout.size.width) / 2.0), y: topInset), size: titleLayout.size)
+ strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleLayout.size.width) / 2.0), y: topInset + 8.0), size: titleLayout.size)
}
})
}
diff --git a/submodules/PresentationDataUtils/Sources/SpecialTabBarIcons.swift b/submodules/PresentationDataUtils/Sources/SpecialTabBarIcons.swift
new file mode 100644
index 0000000000..0fa053ebd0
--- /dev/null
+++ b/submodules/PresentationDataUtils/Sources/SpecialTabBarIcons.swift
@@ -0,0 +1,5 @@
+import Foundation
+
+public func useSpecialTabBarIcons() -> Bool {
+ return (Date(timeIntervalSince1970: 1581638400)...Date(timeIntervalSince1970: 1581724799)).contains(Date())
+}
diff --git a/submodules/SettingsUI/Sources/SettingsController.swift b/submodules/SettingsUI/Sources/SettingsController.swift
index 280b6055f8..e304b7390c 100644
--- a/submodules/SettingsUI/Sources/SettingsController.swift
+++ b/submodules/SettingsUI/Sources/SettingsController.swift
@@ -17,7 +17,6 @@ import AccountContext
import OverlayStatusController
import AvatarNode
import AlertUI
-import PresentationDataUtils
import TelegramNotices
import GalleryUI
import LegacyUI
@@ -1436,7 +1435,12 @@ public func settingsController(context: AccountContext, accountManager: AccountM
actionsDisposable.dispose()
}
- let icon = UIImage(bundleImageName: "Chat List/Tabs/IconSettings")
+ let icon: UIImage?
+ if useSpecialTabBarIcons() {
+ icon = UIImage(bundleImageName: "Chat List/Tabs/Holiday/IconSettings")
+ } else {
+ icon = UIImage(bundleImageName: "Chat List/Tabs/IconSettings")
+ }
let notificationsFromAllAccounts = accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.inAppNotificationSettings])
|> map { sharedData -> Bool in
diff --git a/submodules/StatisticsUI/BUCK b/submodules/StatisticsUI/BUCK
new file mode 100644
index 0000000000..911a9fff4a
--- /dev/null
+++ b/submodules/StatisticsUI/BUCK
@@ -0,0 +1,31 @@
+load("//Config:buck_rule_macros.bzl", "static_library")
+
+static_library(
+ name = "StatisticsUI",
+ srcs = glob([
+ "Sources/**/*.swift",
+ ]),
+ deps = [
+ "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared",
+ "//submodules/AsyncDisplayKit:AsyncDisplayKit#shared",
+ "//submodules/Display:Display#shared",
+ "//submodules/Postbox:Postbox#shared",
+ "//submodules/TelegramCore:TelegramCore#shared",
+ "//submodules/SyncCore:SyncCore#shared",
+ "//submodules/TelegramPresentationData:TelegramPresentationData",
+ "//submodules/TelegramUIPreferences:TelegramUIPreferences",
+ "//submodules/AccountContext:AccountContext",
+ "//submodules/ItemListUI:ItemListUI",
+ "//submodules/AvatarNode:AvatarNode",
+ "//submodules/TelegramStringFormatting:TelegramStringFormatting",
+ "//submodules/AlertUI:AlertUI",
+ "//submodules/PresentationDataUtils:PresentationDataUtils",
+ "//submodules/TelegramNotices:TelegramNotices",
+ "//submodules/MergeLists:MergeLists",
+ "//submodules/Charts:Charts",
+ ],
+ frameworks = [
+ "$SDKROOT/System/Library/Frameworks/Foundation.framework",
+ "$SDKROOT/System/Library/Frameworks/UIKit.framework",
+ ],
+)
diff --git a/submodules/StatisticsUI/Info.plist b/submodules/StatisticsUI/Info.plist
new file mode 100644
index 0000000000..e1fe4cfb7b
--- /dev/null
+++ b/submodules/StatisticsUI/Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+
+
diff --git a/submodules/StatisticsUI/Sources/StatisticsUI.h b/submodules/StatisticsUI/Sources/StatisticsUI.h
new file mode 100644
index 0000000000..89573b3f16
--- /dev/null
+++ b/submodules/StatisticsUI/Sources/StatisticsUI.h
@@ -0,0 +1,19 @@
+//
+// StatisticsUI.h
+// StatisticsUI
+//
+// Created by Peter on 8/13/19.
+// Copyright © 2019 Telegram Messenger LLP. All rights reserved.
+//
+
+#import
+
+//! Project version number for StatisticsUI.
+FOUNDATION_EXPORT double StatisticsUIVersionNumber;
+
+//! Project version string for StatisticsUI.
+FOUNDATION_EXPORT const unsigned char StatisticsUIVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import
+
+
diff --git a/submodules/StatisticsUI/Sources/StatsController.swift b/submodules/StatisticsUI/Sources/StatsController.swift
new file mode 100644
index 0000000000..440d29cf02
--- /dev/null
+++ b/submodules/StatisticsUI/Sources/StatsController.swift
@@ -0,0 +1,351 @@
+import Foundation
+import UIKit
+import Display
+import SwiftSignalKit
+import Postbox
+import TelegramCore
+import SyncCore
+import MapKit
+import TelegramPresentationData
+import TelegramUIPreferences
+import ItemListUI
+import PresentationDataUtils
+import AccountContext
+import PresentationDataUtils
+import AppBundle
+import ContextUI
+import TelegramNotices
+
+private final class StatsArguments {
+ init() {
+ }
+}
+
+private enum StatsSection: Int32 {
+ case overview
+ case growth
+ case followers
+ case notifications
+ case viewsByHour
+ case postInteractions
+ case viewsBySource
+ case followersBySource
+ case languages
+}
+
+private enum StatsEntry: ItemListNodeEntry {
+ case overviewHeader(PresentationTheme, String)
+ case overview(PresentationTheme, ChannelStats)
+
+ case growthTitle(PresentationTheme, String)
+ case growthGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ case followersTitle(PresentationTheme, String)
+ case followersGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ case notificationsTitle(PresentationTheme, String)
+ case notificationsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ case viewsByHourTitle(PresentationTheme, String)
+ case viewsByHourGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ case postInteractionsTitle(PresentationTheme, String)
+ case postInteractionsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ case viewsBySourceTitle(PresentationTheme, String)
+ case viewsBySourceGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ case followersBySourceTitle(PresentationTheme, String)
+ case followersBySourceGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ case languagesTitle(PresentationTheme, String)
+ case languagesGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, String, ChannelStatsGraph)
+
+ var section: ItemListSectionId {
+ switch self {
+ case .overviewHeader, .overview:
+ return StatsSection.overview.rawValue
+ case .growthTitle, .growthGraph:
+ return StatsSection.growth.rawValue
+ case .followersTitle, .followersGraph:
+ return StatsSection.followers.rawValue
+ case .notificationsTitle, .notificationsGraph:
+ return StatsSection.notifications.rawValue
+ case .viewsByHourTitle, .viewsByHourGraph:
+ return StatsSection.viewsByHour.rawValue
+ case .postInteractionsTitle, .postInteractionsGraph:
+ return StatsSection.postInteractions.rawValue
+ case .viewsBySourceTitle, .viewsBySourceGraph:
+ return StatsSection.viewsBySource.rawValue
+ case .followersBySourceTitle, .followersBySourceGraph:
+ return StatsSection.followersBySource.rawValue
+ case .languagesTitle, .languagesGraph:
+ return StatsSection.languages.rawValue
+ }
+ }
+
+ var stableId: Int32 {
+ switch self {
+ case .overviewHeader:
+ return 0
+ case .overview:
+ return 1
+ case .growthTitle:
+ return 2
+ case .growthGraph:
+ return 3
+ case .followersTitle:
+ return 4
+ case .followersGraph:
+ return 5
+ case .notificationsTitle:
+ return 6
+ case .notificationsGraph:
+ return 7
+ case .viewsByHourTitle:
+ return 8
+ case .viewsByHourGraph:
+ return 9
+ case .postInteractionsTitle:
+ return 10
+ case .postInteractionsGraph:
+ return 11
+ case .viewsBySourceTitle:
+ return 12
+ case .viewsBySourceGraph:
+ return 13
+ case .followersBySourceTitle:
+ return 14
+ case .followersBySourceGraph:
+ return 15
+ case .languagesTitle:
+ return 16
+ case .languagesGraph:
+ return 17
+ }
+ }
+
+ static func ==(lhs: StatsEntry, rhs: StatsEntry) -> Bool {
+ switch lhs {
+ case let .overviewHeader(lhsTheme, lhsText):
+ if case let .overviewHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .overview(lhsTheme, lhsStats):
+ if case let .overview(rhsTheme, rhsStats) = rhs, lhsTheme === rhsTheme, lhsStats == rhsStats {
+ return true
+ } else {
+ return false
+ }
+ case let .growthTitle(lhsTheme, lhsText):
+ if case let .growthTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .growthGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .growthGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ case let .followersTitle(lhsTheme, lhsText):
+ if case let .followersTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .followersGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .followersGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ case let .notificationsTitle(lhsTheme, lhsText):
+ if case let .notificationsTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .notificationsGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .notificationsGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ case let .viewsByHourTitle(lhsTheme, lhsText):
+ if case let .viewsByHourTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .viewsByHourGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .viewsByHourGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ case let .postInteractionsTitle(lhsTheme, lhsText):
+ if case let .postInteractionsTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .postInteractionsGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .postInteractionsGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ case let .viewsBySourceTitle(lhsTheme, lhsText):
+ if case let .viewsBySourceTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .viewsBySourceGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .viewsBySourceGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ case let .followersBySourceTitle(lhsTheme, lhsText):
+ if case let .followersBySourceTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .followersBySourceGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .followersBySourceGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ case let .languagesTitle(lhsTheme, lhsText):
+ if case let .languagesTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
+ return true
+ } else {
+ return false
+ }
+ case let .languagesGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsText, lhsGraph):
+ if case let .languagesGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsText, rhsGraph) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsText == rhsText, lhsGraph == rhsGraph {
+ return true
+ } else {
+ return false
+ }
+ }
+ }
+
+ static func <(lhs: StatsEntry, rhs: StatsEntry) -> Bool {
+ return lhs.stableId < rhs.stableId
+ }
+
+ func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
+ switch self {
+ case let .overviewHeader(theme, text),
+ let .growthTitle(theme, text),
+ let .followersTitle(theme, text),
+ let .notificationsTitle(theme, text),
+ let .viewsByHourTitle(theme, text),
+ let .postInteractionsTitle(theme, text),
+ let .viewsBySourceTitle(theme, text),
+ let .followersBySourceTitle(theme, text),
+ let .languagesTitle(theme, text):
+ return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
+ case let .overview(theme, stats):
+ return StatsOverviewItem(presentationData: presentationData, stats: stats, sectionId: self.section, style: .blocks)
+ case let .growthGraph(theme, strings, dateTimeFormat, title, graph),
+ let .followersGraph(theme, strings, dateTimeFormat, title, graph),
+ let .notificationsGraph(theme, strings, dateTimeFormat, title, graph),
+ let .viewsByHourGraph(theme, strings, dateTimeFormat, title, graph),
+ let .postInteractionsGraph(theme, strings, dateTimeFormat, title, graph),
+ let .viewsBySourceGraph(theme, strings, dateTimeFormat, title, graph),
+ let .followersBySourceGraph(theme, strings, dateTimeFormat, title, graph),
+ let .languagesGraph(theme, strings, dateTimeFormat, title, graph):
+ return StatsGraphItem(presentationData: presentationData, title: title, graph: graph, sectionId: self.section, style: .blocks)
+ }
+ }
+}
+
+private func statsControllerEntries(data: ChannelStats?, presentationData: PresentationData) -> [StatsEntry] {
+ var entries: [StatsEntry] = []
+
+ if let data = data {
+ entries.append(.overviewHeader(presentationData.theme, "OVERVIEW"))
+ entries.append(.overview(presentationData.theme, data))
+
+ entries.append(.growthTitle(presentationData.theme, "GROWTH"))
+ entries.append(.growthGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, "Growth", data.growthGraph))
+
+ entries.append(.followersTitle(presentationData.theme, "FOLLOWERS"))
+ entries.append(.followersGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, "Followers", data.followersGraph))
+
+ entries.append(.notificationsTitle(presentationData.theme, "NOTIFICATIONS"))
+ entries.append(.notificationsGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, "Notifications", data.muteGraph))
+ }
+
+ return entries
+}
+
+public func channelStatsController(context: AccountContext, peer: Peer, cachedPeerData: CachedPeerData) -> ViewController {
+ var pushControllerImpl: ((ViewController) -> Void)?
+ var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
+ var navigateToChatImpl: ((Peer) -> Void)?
+
+ let actionsDisposable = DisposableSet()
+ let checkCreationAvailabilityDisposable = MetaDisposable()
+ actionsDisposable.add(checkCreationAvailabilityDisposable)
+
+ let dataPromise = Promise(nil)
+
+ var datacenterId: Int32 = 0
+ if let cachedData = cachedPeerData as? CachedChannelData {
+ datacenterId = cachedData.statsDatacenterId
+ }
+
+ let statsContext = ChannelStatsContext(network: context.account.network, datacenterId: datacenterId, peer: peer)
+ let dataSignal: Signal = statsContext.state
+ |> map { state in
+ return state.stats
+ } |> afterNext({ [weak statsContext] a in
+ if let w = statsContext, let a = a {
+ if case .OnDemand = a.interactionsGraph {
+ w.loadInteractionsGraph()
+ }
+ }
+ })
+ dataPromise.set(.single(nil) |> then(dataSignal))
+
+ let arguments = StatsArguments()
+
+ let signal = combineLatest(context.sharedContext.presentationData, dataPromise.get())
+ |> deliverOnMainQueue
+ |> map { presentationData, data -> (ItemListControllerState, (ItemListNodeState, Any)) in
+ let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ChannelInfo_Stats), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
+ let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: statsControllerEntries(data: data, presentationData: presentationData), style: .blocks, emptyStateItem: nil, crossfadeState: false, animateChanges: false)
+
+ return (controllerState, (listState, arguments))
+ }
+ |> afterDisposed {
+ actionsDisposable.dispose()
+ let _ = statsContext.state
+ }
+
+ let controller = ItemListController(context: context, state: signal)
+ controller.didDisappear = { [weak controller] _ in
+ controller?.clearItemNodesHighlight(animated: true)
+ }
+ pushControllerImpl = { [weak controller] c in
+ if let controller = controller {
+ (controller.navigationController as? NavigationController)?.pushViewController(c, animated: true)
+ }
+ }
+ presentControllerImpl = { [weak controller] c, a in
+ if let controller = controller {
+ controller.present(c, in: .window(.root), with: a)
+ }
+ }
+ return controller
+}
diff --git a/submodules/StatisticsUI/Sources/StatsGraphItem.swift b/submodules/StatisticsUI/Sources/StatsGraphItem.swift
new file mode 100644
index 0000000000..a800baf8e9
--- /dev/null
+++ b/submodules/StatisticsUI/Sources/StatsGraphItem.swift
@@ -0,0 +1,205 @@
+import Foundation
+import UIKit
+import Display
+import AsyncDisplayKit
+import SwiftSignalKit
+import TelegramCore
+import SyncCore
+import TelegramPresentationData
+import ItemListUI
+import PresentationDataUtils
+import Charts
+
+class StatsGraphItem: ListViewItem, ItemListItem {
+ let presentationData: ItemListPresentationData
+ let title: String
+ let graph: ChannelStatsGraph
+ let sectionId: ItemListSectionId
+ let style: ItemListStyle
+
+ init(presentationData: ItemListPresentationData, title: String, graph: ChannelStatsGraph, sectionId: ItemListSectionId, style: ItemListStyle) {
+ self.presentationData = presentationData
+ self.title = title
+ self.graph = graph
+ self.sectionId = sectionId
+ self.style = style
+ }
+
+ func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) {
+ async {
+ let node = StatsGraphItemNode()
+ let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
+
+ node.contentSize = layout.contentSize
+ node.insets = layout.insets
+
+ Queue.mainQueue().async {
+ completion(node, {
+ return (nil, { _ in apply() })
+ })
+ }
+ }
+ }
+
+ func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
+ Queue.mainQueue().async {
+ if let nodeValue = node() as? StatsGraphItemNode {
+ let makeLayout = nodeValue.asyncLayout()
+
+ async {
+ let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
+ Queue.mainQueue().async {
+ completion(layout, { _ in
+ apply()
+ })
+ }
+ }
+ }
+ }
+ }
+
+ var selectable: Bool = false
+}
+
+class StatsGraphItemNode: ListViewItemNode {
+ private let backgroundNode: ASDisplayNode
+ private let topStripeNode: ASDisplayNode
+ private let bottomStripeNode: ASDisplayNode
+
+ let chartNode: ChartNode
+
+ private var item: StatsGraphItem?
+
+ init() {
+ self.backgroundNode = ASDisplayNode()
+ self.backgroundNode.isLayerBacked = true
+ self.backgroundNode.backgroundColor = .white
+
+ self.topStripeNode = ASDisplayNode()
+ self.topStripeNode.isLayerBacked = true
+
+ self.bottomStripeNode = ASDisplayNode()
+ self.bottomStripeNode.isLayerBacked = true
+
+ self.chartNode = ChartNode()
+
+ super.init(layerBacked: false, dynamicBounce: false)
+
+ self.clipsToBounds = true
+
+ self.addSubnode(self.chartNode)
+ }
+
+ func asyncLayout() -> (_ item: StatsGraphItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
+ let currentItem = self.item
+
+ return { item, params, neighbors in
+ let leftInset = params.leftInset
+ let rightInset: CGFloat = params.rightInset
+ var updatedTheme: PresentationTheme?
+ var updatedGraph: ChannelStatsGraph?
+
+ if currentItem?.presentationData.theme !== item.presentationData.theme {
+ updatedTheme = item.presentationData.theme
+ }
+
+ if currentItem?.graph != item.graph {
+ updatedGraph = item.graph
+ }
+
+ let contentSize: CGSize
+ let insets: UIEdgeInsets
+ let separatorHeight = UIScreenPixel
+ let itemBackgroundColor: UIColor
+ let itemSeparatorColor: UIColor
+
+ switch item.style {
+ case .plain:
+ itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
+ itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
+ contentSize = CGSize(width: params.width, height: 320.0)
+ insets = itemListNeighborsPlainInsets(neighbors)
+ case .blocks:
+ itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
+ itemSeparatorColor = item.presentationData.theme.list.itemBlocksSeparatorColor
+ contentSize = CGSize(width: params.width, height: 320.0)
+ insets = itemListNeighborsGroupedInsets(neighbors)
+ }
+
+ let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
+
+ return (ListViewItemNodeLayout(contentSize: contentSize, insets: insets), { [weak self] in
+ if let strongSelf = self {
+ strongSelf.item = item
+
+ if let _ = updatedTheme {
+ strongSelf.topStripeNode.backgroundColor = itemSeparatorColor
+ strongSelf.bottomStripeNode.backgroundColor = itemSeparatorColor
+ strongSelf.backgroundNode.backgroundColor = itemBackgroundColor
+ }
+
+ if let updatedGraph = updatedGraph, case let .Loaded(data) = updatedGraph {
+ strongSelf.chartNode.setup(data)
+ }
+
+ switch item.style {
+ case .plain:
+ if strongSelf.backgroundNode.supernode != nil {
+ strongSelf.backgroundNode.removeFromSupernode()
+ }
+ if strongSelf.topStripeNode.supernode != nil {
+ strongSelf.topStripeNode.removeFromSupernode()
+ }
+ if strongSelf.bottomStripeNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 0)
+ }
+
+ strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: leftInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - leftInset, height: separatorHeight))
+ case .blocks:
+ if strongSelf.backgroundNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
+ }
+ if strongSelf.topStripeNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.topStripeNode, at: 1)
+ }
+ if strongSelf.bottomStripeNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 2)
+ }
+ switch neighbors.top {
+ case .sameSection(false):
+ strongSelf.topStripeNode.isHidden = true
+ default:
+ strongSelf.topStripeNode.isHidden = false
+ }
+ let bottomStripeInset: CGFloat
+ switch neighbors.bottom {
+ case .sameSection(false):
+ bottomStripeInset = leftInset
+ default:
+ bottomStripeInset = 0.0
+ }
+
+ strongSelf.chartNode.frame = CGRect(origin: CGPoint(x: leftInset, y: -30.0), size: CGSize(width: layout.size.width - leftInset - rightInset, height: 350.0))
+
+ strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
+ strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: separatorHeight))
+ strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset, height: separatorHeight))
+ }
+ }
+ })
+ }
+ }
+
+ override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
+ self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
+ }
+
+ override func animateAdded(_ currentTimestamp: Double, duration: Double) {
+ self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
+ }
+
+ override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
+ self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
+ }
+}
+
diff --git a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift
new file mode 100644
index 0000000000..5e85186e30
--- /dev/null
+++ b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift
@@ -0,0 +1,292 @@
+import Foundation
+import UIKit
+import Display
+import AsyncDisplayKit
+import SwiftSignalKit
+import TelegramCore
+import SyncCore
+import TelegramPresentationData
+import ItemListUI
+import PresentationDataUtils
+import Charts
+
+class StatsOverviewItem: ListViewItem, ItemListItem {
+ let presentationData: ItemListPresentationData
+ let stats: ChannelStats
+ let sectionId: ItemListSectionId
+ let style: ItemListStyle
+
+ init(presentationData: ItemListPresentationData, stats: ChannelStats, sectionId: ItemListSectionId, style: ItemListStyle) {
+ self.presentationData = presentationData
+ self.stats = stats
+ self.sectionId = sectionId
+ self.style = style
+ }
+
+ func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) {
+ async {
+ let node = StatsOverviewItemNode()
+ let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
+
+ node.contentSize = layout.contentSize
+ node.insets = layout.insets
+
+ Queue.mainQueue().async {
+ completion(node, {
+ return (nil, { _ in apply() })
+ })
+ }
+ }
+ }
+
+ func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
+ Queue.mainQueue().async {
+ if let nodeValue = node() as? StatsOverviewItemNode {
+ let makeLayout = nodeValue.asyncLayout()
+
+ async {
+ let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
+ Queue.mainQueue().async {
+ completion(layout, { _ in
+ apply()
+ })
+ }
+ }
+ }
+ }
+ }
+
+ var selectable: Bool = false
+}
+
+class StatsOverviewItemNode: ListViewItemNode {
+ private let backgroundNode: ASDisplayNode
+ private let topStripeNode: ASDisplayNode
+ private let bottomStripeNode: ASDisplayNode
+
+ private let followersValueLabel: ImmediateTextNode
+ private let viewsPerPostValueLabel: ImmediateTextNode
+ private let sharesPerPostValueLabel: ImmediateTextNode
+ private let enabledNotificationsValueLabel: ImmediateTextNode
+
+ private let followersTitleLabel: ImmediateTextNode
+ private let viewsPerPostTitleLabel: ImmediateTextNode
+ private let sharesPerPostTitleLabel: ImmediateTextNode
+ private let enabledNotificationsTitleLabel: ImmediateTextNode
+
+ private let followersDeltaLabel: ImmediateTextNode
+ private let viewsPerPostDeltaLabel: ImmediateTextNode
+ private let sharesPerPostDeltaLabel: ImmediateTextNode
+
+ private var item: StatsOverviewItem?
+
+ init() {
+ self.backgroundNode = ASDisplayNode()
+ self.backgroundNode.isLayerBacked = true
+ self.backgroundNode.backgroundColor = .white
+
+ self.topStripeNode = ASDisplayNode()
+ self.topStripeNode.isLayerBacked = true
+
+ self.bottomStripeNode = ASDisplayNode()
+ self.bottomStripeNode.isLayerBacked = true
+
+ self.followersValueLabel = ImmediateTextNode()
+ self.viewsPerPostValueLabel = ImmediateTextNode()
+ self.sharesPerPostValueLabel = ImmediateTextNode()
+ self.enabledNotificationsValueLabel = ImmediateTextNode()
+
+ self.followersTitleLabel = ImmediateTextNode()
+ self.viewsPerPostTitleLabel = ImmediateTextNode()
+ self.sharesPerPostTitleLabel = ImmediateTextNode()
+ self.enabledNotificationsTitleLabel = ImmediateTextNode()
+
+ self.followersDeltaLabel = ImmediateTextNode()
+ self.viewsPerPostDeltaLabel = ImmediateTextNode()
+ self.sharesPerPostDeltaLabel = ImmediateTextNode()
+
+ super.init(layerBacked: false, dynamicBounce: false)
+
+ self.clipsToBounds = true
+
+ self.addSubnode(self.followersValueLabel)
+ self.addSubnode(self.viewsPerPostValueLabel)
+ self.addSubnode(self.sharesPerPostValueLabel)
+ self.addSubnode(self.enabledNotificationsValueLabel)
+
+ self.addSubnode(self.followersTitleLabel)
+ self.addSubnode(self.viewsPerPostTitleLabel)
+ self.addSubnode(self.sharesPerPostTitleLabel)
+ self.addSubnode(self.enabledNotificationsTitleLabel)
+
+ self.addSubnode(self.followersDeltaLabel)
+ self.addSubnode(self.viewsPerPostDeltaLabel)
+ self.addSubnode(self.sharesPerPostDeltaLabel)
+ }
+
+ func asyncLayout() -> (_ item: StatsOverviewItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
+ let makeFollowersValueLabelLayout = TextNode.asyncLayout(self.followersValueLabel)
+ let makeViewsPerPostValueLabelLayout = TextNode.asyncLayout(self.viewsPerPostValueLabel)
+ let makeSharesPerPostValueLabelLayout = TextNode.asyncLayout(self.sharesPerPostValueLabel)
+ let makeEnabledNotificationsValueLabelLayout = TextNode.asyncLayout(self.enabledNotificationsValueLabel)
+
+ let makeFollowersTitleLabelLayout = TextNode.asyncLayout(self.followersTitleLabel)
+ let makeViewsPerPostTitleLabelLayout = TextNode.asyncLayout(self.viewsPerPostTitleLabel)
+ let makeSharesPerPostTitleLabelLayout = TextNode.asyncLayout(self.sharesPerPostTitleLabel)
+ let makeEnabledNotificationsTitleLabelLayout = TextNode.asyncLayout(self.enabledNotificationsTitleLabel)
+
+ let makeFollowersDeltaLabelLayout = TextNode.asyncLayout(self.followersDeltaLabel)
+ let makeViewsPerPostDeltaLabelLayout = TextNode.asyncLayout(self.viewsPerPostDeltaLabel)
+ let makeSharesPerPostDeltaLabelLayout = TextNode.asyncLayout(self.sharesPerPostDeltaLabel)
+
+ let currentItem = self.item
+
+ return { item, params, neighbors in
+ let leftInset = params.leftInset
+ let rightInset: CGFloat = params.rightInset
+ var updatedTheme: PresentationTheme?
+ var updatedGraph: ChannelStatsGraph?
+
+ if currentItem?.presentationData.theme !== item.presentationData.theme {
+ updatedTheme = item.presentationData.theme
+ }
+
+ let valueFont = Font.regular(item.presentationData.fontSize.itemListBaseHeaderFontSize)
+ let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseHeaderFontSize)
+ let deltaFont = Font.regular(item.presentationData.fontSize.itemListBaseHeaderFontSize)
+
+ let (followersValueLabelLayout, followersValueLabelApply) = makeFollowersValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "221K", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (viewsPerPostValueLabelLayout, viewsPerPostValueLabelApply) = makeViewsPerPostValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "120K", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (sharesPerPostValueLabelLayout, sharesPerPostValueLabelApply) = makeSharesPerPostValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "350", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (enabledNotificationsValueLabelLayout, enabledNotificationsValueLabelApply) = makeEnabledNotificationsValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "22.77%", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+
+ let (followersTitleLabelLayout, followersTitleLabelApply) = makeFollowersTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Followers", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (viewsPerPostTitleLabelLayout, viewsPerPostTitleLabelApply) = makeViewsPerPostTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Views Per Post", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (sharesPerPostTitleLabelLayout, sharesPerPostTitleLabelApply) = makeSharesPerPostTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Shares Per Post", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (enabledNotificationsTitleLabelLayout, enabledNotificationsTitleLabelApply) = makeEnabledNotificationsTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Enabled Notifications", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (followersDeltaLabelLayout, followersDeltaLabelApply) = makeFollowersDeltaLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "+474 (0.21%)", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (viewsPerPostDeltaLabelLayout, viewsPerPostDeltaLabelApply) = makeViewsPerPostDeltaLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "-14K (10.68%)", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let (sharesPerPostDeltaLabelLayout, sharesPerPostDeltaLabelApply) = makeSharesPerPostDeltaLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "-134 (27.68%)", font: valueFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
+
+ let contentSize: CGSize
+ let insets: UIEdgeInsets
+ let separatorHeight = UIScreenPixel
+ let itemBackgroundColor: UIColor
+ let itemSeparatorColor: UIColor
+
+ switch item.style {
+ case .plain:
+ itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
+ itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
+ contentSize = CGSize(width: params.width, height: 120.0)
+ insets = itemListNeighborsPlainInsets(neighbors)
+ case .blocks:
+ itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
+ itemSeparatorColor = item.presentationData.theme.list.itemBlocksSeparatorColor
+ contentSize = CGSize(width: params.width, height: 120.0)
+ insets = itemListNeighborsGroupedInsets(neighbors)
+ }
+
+ let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
+
+ return (ListViewItemNodeLayout(contentSize: contentSize, insets: insets), { [weak self] in
+ if let strongSelf = self {
+ strongSelf.item = item
+
+ let _ = followersValueLabelApply()
+ let _ = viewsPerPostValueLabelApply()
+ let _ = sharesPerPostValueLabelApply()
+ let _ = enabledNotificationsValueLabelApply()
+
+ let _ = followersTitleLabelApply()
+ let _ = viewsPerPostTitleLabelApply()
+ let _ = sharesPerPostTitleLabelApply()
+ let _ = enabledNotificationsTitleLabelApply()
+
+ let _ = followersDeltaLabelApply()
+ let _ = viewsPerPostDeltaLabelApply()
+ let _ = sharesPerPostDeltaLabelApply()
+
+ if let _ = updatedTheme {
+ strongSelf.topStripeNode.backgroundColor = itemSeparatorColor
+ strongSelf.bottomStripeNode.backgroundColor = itemSeparatorColor
+ strongSelf.backgroundNode.backgroundColor = itemBackgroundColor
+ }
+
+ switch item.style {
+ case .plain:
+ if strongSelf.backgroundNode.supernode != nil {
+ strongSelf.backgroundNode.removeFromSupernode()
+ }
+ if strongSelf.topStripeNode.supernode != nil {
+ strongSelf.topStripeNode.removeFromSupernode()
+ }
+ if strongSelf.bottomStripeNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 0)
+ }
+
+ strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: leftInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - leftInset, height: separatorHeight))
+ case .blocks:
+ if strongSelf.backgroundNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
+ }
+ if strongSelf.topStripeNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.topStripeNode, at: 1)
+ }
+ if strongSelf.bottomStripeNode.supernode == nil {
+ strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 2)
+ }
+ switch neighbors.top {
+ case .sameSection(false):
+ strongSelf.topStripeNode.isHidden = true
+ default:
+ strongSelf.topStripeNode.isHidden = false
+ }
+ let bottomStripeInset: CGFloat
+ switch neighbors.bottom {
+ case .sameSection(false):
+ bottomStripeInset = leftInset
+ default:
+ bottomStripeInset = 0.0
+ }
+
+ strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
+ strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: separatorHeight))
+ strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset, height: separatorHeight))
+ }
+
+ strongSelf.followersValueLabel.frame = CGRect(origin: CGPoint(x: leftInset, y: 7.0), size: followersValueLabelLayout.size)
+
+ strongSelf.viewsPerPostValueLabel.frame = CGRect(origin: CGPoint(x: leftInset, y: 44.0), size: viewsPerPostValueLabelLayout.size)
+
+ strongSelf.sharesPerPostValueLabel.frame = CGRect(origin: CGPoint(x: layout.size.width / 2.0, y: 44.0), size: sharesPerPostValueLabelLayout.size)
+
+ strongSelf.enabledNotificationsValueLabel.frame = CGRect(origin: CGPoint(x: layout.size.width / 2.0, y: 7.0), size: enabledNotificationsValueLabelLayout.size)
+ }
+ })
+ }
+ }
+
+ override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
+ self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
+ }
+
+ override func animateAdded(_ currentTimestamp: Double, duration: Double) {
+ self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
+ }
+
+ override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
+ self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
+ }
+}
+
diff --git a/submodules/SyncCore/Sources/CachedChannelData.swift b/submodules/SyncCore/Sources/CachedChannelData.swift
index c00a913477..49bcb7c71c 100644
--- a/submodules/SyncCore/Sources/CachedChannelData.swift
+++ b/submodules/SyncCore/Sources/CachedChannelData.swift
@@ -166,6 +166,7 @@ public final class CachedChannelData: CachedPeerData {
public let slowModeTimeout: Int32?
public let slowModeValidUntilTimestamp: Int32?
public let hasScheduledMessages: Bool
+ public let statsDatacenterId: Int32
public let peerIds: Set
public let messageIds: Set
@@ -192,9 +193,10 @@ public final class CachedChannelData: CachedPeerData {
self.slowModeTimeout = nil
self.slowModeValidUntilTimestamp = nil
self.hasScheduledMessages = false
+ self.statsDatacenterId = 0
}
- public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: PeerId?, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool) {
+ public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: PeerId?, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool, statsDatacenterId: Int32) {
self.isNotAccessible = isNotAccessible
self.flags = flags
self.about = about
@@ -211,6 +213,7 @@ public final class CachedChannelData: CachedPeerData {
self.slowModeTimeout = slowModeTimeout
self.slowModeValidUntilTimestamp = slowModeValidUntilTimestamp
self.hasScheduledMessages = hasScheduledMessages
+ self.statsDatacenterId = statsDatacenterId
var peerIds = Set()
for botInfo in botInfos {
@@ -231,67 +234,71 @@ public final class CachedChannelData: CachedPeerData {
}
public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedAbout(_ about: String?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: PeerId?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
}
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData {
- return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages)
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId)
+ }
+
+ public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData {
+ return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId)
}
public init(decoder: PostboxDecoder) {
@@ -346,6 +353,7 @@ public final class CachedChannelData: CachedPeerData {
self.slowModeTimeout = decoder.decodeOptionalInt32ForKey("smt")
self.slowModeValidUntilTimestamp = decoder.decodeOptionalInt32ForKey("smv")
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
+ self.statsDatacenterId = decoder.decodeInt32ForKey("sdi", orElse: 0)
if let linkedDiscussionPeerId = self.linkedDiscussionPeerId {
peerIds.insert(linkedDiscussionPeerId)
@@ -430,6 +438,7 @@ public final class CachedChannelData: CachedPeerData {
encoder.encodeNil(forKey: "smv")
}
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
+ encoder.encodeInt32(self.statsDatacenterId, forKey: "sdi")
}
public func isEqual(to: CachedPeerData) -> Bool {
@@ -497,6 +506,14 @@ public final class CachedChannelData: CachedPeerData {
return false
}
+ if other.hasScheduledMessages != self.hasScheduledMessages {
+ return false
+ }
+
+ if other.statsDatacenterId != self.statsDatacenterId {
+ return false
+ }
+
return true
}
}
diff --git a/submodules/SyncCore/Sources/TextEntitiesMessageAttribute.swift b/submodules/SyncCore/Sources/TextEntitiesMessageAttribute.swift
index 79fe68a5ed..e0c3f565a9 100644
--- a/submodules/SyncCore/Sources/TextEntitiesMessageAttribute.swift
+++ b/submodules/SyncCore/Sources/TextEntitiesMessageAttribute.swift
@@ -19,6 +19,7 @@ public enum MessageTextEntityType: Equatable {
case Strikethrough
case BlockQuote
case Underline
+ case BankCard
case Custom(type: CustomEntityType)
}
@@ -65,6 +66,8 @@ public struct MessageTextEntity: PostboxCoding, Equatable {
self.type = .BlockQuote
case 15:
self.type = .Underline
+ case 16:
+ self.type = .BankCard
case Int32.max:
self.type = .Custom(type: decoder.decodeInt32ForKey("type", orElse: 0))
default:
@@ -110,6 +113,8 @@ public struct MessageTextEntity: PostboxCoding, Equatable {
encoder.encodeInt32(14, forKey: "_rawValue")
case .Underline:
encoder.encodeInt32(15, forKey: "_rawValue")
+ case .BankCard:
+ encoder.encodeInt32(16, forKey: "_rawValue")
case let .Custom(type):
encoder.encodeInt32(Int32.max, forKey: "_rawValue")
encoder.encodeInt32(type, forKey: "type")
diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift
index ab2f4a7b7b..be3e05a869 100644
--- a/submodules/TelegramApi/Sources/Api0.swift
+++ b/submodules/TelegramApi/Sources/Api0.swift
@@ -412,6 +412,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[2103482845] = { return Api.SecurePlainData.parse_securePlainPhone($0) }
dict[569137759] = { return Api.SecurePlainData.parse_securePlainEmail($0) }
dict[-1269012015] = { return Api.messages.AffectedHistory.parse_affectedHistory($0) }
+ dict[1244130093] = { return Api.StatsGraph.parse_statsGraphAsync($0) }
+ dict[-1092839390] = { return Api.StatsGraph.parse_statsGraphError($0) }
+ dict[-1057809608] = { return Api.StatsGraph.parse_statsGraph($0) }
dict[-1036572727] = { return Api.account.PasswordInputSettings.parse_passwordInputSettings($0) }
dict[878078826] = { return Api.PageTableCell.parse_pageTableCell($0) }
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
@@ -480,6 +483,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-668391402] = { return Api.InputUser.parse_inputUser($0) }
dict[-1366746132] = { return Api.Page.parse_page($0) }
dict[871426631] = { return Api.SecureCredentialsEncrypted.parse_secureCredentialsEncrypted($0) }
+ dict[-875679776] = { return Api.StatsPercentValue.parse_statsPercentValue($0) }
dict[157948117] = { return Api.upload.File.parse_file($0) }
dict[-242427324] = { return Api.upload.File.parse_fileCdnRedirect($0) }
dict[-1078612597] = { return Api.ChannelLocation.parse_channelLocationEmpty($0) }
@@ -506,6 +510,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1160215659] = { return Api.InputMessage.parse_inputMessageReplyTo($0) }
dict[-2037963464] = { return Api.InputMessage.parse_inputMessagePinned($0) }
dict[-1564789301] = { return Api.PhoneCallProtocol.parse_phoneCallProtocol($0) }
+ dict[-1237848657] = { return Api.StatsDateRangeDays.parse_statsDateRangeDays($0) }
dict[-1567175714] = { return Api.MessageFwdAuthor.parse_messageFwdAuthor($0) }
dict[-1539849235] = { return Api.WallPaper.parse_wallPaper($0) }
dict[-1963717851] = { return Api.WallPaper.parse_wallPaperNoFile($0) }
@@ -520,6 +525,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1837345356] = { return Api.InputChatPhoto.parse_inputChatUploadedPhoto($0) }
dict[-1991004873] = { return Api.InputChatPhoto.parse_inputChatPhoto($0) }
dict[-368917890] = { return Api.PaymentCharge.parse_paymentCharge($0) }
+ dict[205195937] = { return Api.stats.BroadcastStats.parse_broadcastStats($0) }
dict[-484987010] = { return Api.Updates.parse_updatesTooLong($0) }
dict[-1857044719] = { return Api.Updates.parse_updateShortMessage($0) }
dict[377562760] = { return Api.Updates.parse_updateShortChatMessage($0) }
@@ -527,6 +533,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1918567619] = { return Api.Updates.parse_updatesCombined($0) }
dict[1957577280] = { return Api.Updates.parse_updates($0) }
dict[301019932] = { return Api.Updates.parse_updateShortSentMessage($0) }
+ dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) }
dict[1038967584] = { return Api.MessageMedia.parse_messageMediaEmpty($0) }
dict[1457575028] = { return Api.MessageMedia.parse_messageMediaGeo($0) }
dict[-1618676578] = { return Api.MessageMedia.parse_messageMediaUnsupported($0) }
@@ -608,6 +615,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1421174295] = { return Api.WebPageAttribute.parse_webPageAttributeTheme($0) }
dict[82699215] = { return Api.messages.FeaturedStickers.parse_featuredStickersNotModified($0) }
dict[-123893531] = { return Api.messages.FeaturedStickers.parse_featuredStickers($0) }
+ dict[1375940666] = { return Api.auth.LoginTokenInfo.parse_loginTokenInfo($0) }
dict[-2048646399] = { return Api.PhoneCallDiscardReason.parse_phoneCallDiscardReasonMissed($0) }
dict[-527056480] = { return Api.PhoneCallDiscardReason.parse_phoneCallDiscardReasonDisconnect($0) }
dict[1471006352] = { return Api.PhoneCallDiscardReason.parse_phoneCallDiscardReasonHangup($0) }
@@ -678,8 +686,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-395967805] = { return Api.messages.AllStickers.parse_allStickersNotModified($0) }
dict[-302170017] = { return Api.messages.AllStickers.parse_allStickers($0) }
dict[-1655957568] = { return Api.PhoneConnection.parse_phoneConnection($0) }
- dict[-206688531] = { return Api.help.UserInfo.parse_userInfoEmpty($0) }
- dict[32192344] = { return Api.help.UserInfo.parse_userInfo($0) }
dict[-1194283041] = { return Api.AccountDaysTTL.parse_accountDaysTTL($0) }
dict[-1658158621] = { return Api.SecureValueType.parse_secureValueTypePersonalDetails($0) }
dict[1034709504] = { return Api.SecureValueType.parse_secureValueTypePassport($0) }
@@ -746,6 +752,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1363483106] = { return Api.DialogPeer.parse_dialogPeerFolder($0) }
dict[-104284986] = { return Api.WebDocument.parse_webDocumentNoProxy($0) }
dict[475467473] = { return Api.WebDocument.parse_webDocument($0) }
+ dict[1211967244] = { return Api.Theme.parse_themeDocumentNotModified($0) }
dict[42930452] = { return Api.Theme.parse_theme($0) }
dict[-1290580579] = { return Api.contacts.Found.parse_found($0) }
dict[-368018716] = { return Api.ChannelAdminLogEventsFilter.parse_channelAdminLogEventsFilter($0) }
@@ -761,6 +768,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1041346555] = { return Api.updates.ChannelDifference.parse_channelDifferenceEmpty($0) }
dict[543450958] = { return Api.updates.ChannelDifference.parse_channelDifference($0) }
dict[-1531132162] = { return Api.updates.ChannelDifference.parse_channelDifferenceTooLong($0) }
+ dict[-581804346] = { return Api.StatsRowAbsValueAndPrev.parse_statsRowAbsValueAndPrev($0) }
dict[-309659827] = { return Api.channels.AdminLogResults.parse_adminLogResults($0) }
dict[-264117680] = { return Api.ChatOnlines.parse_chatOnlines($0) }
dict[488313413] = { return Api.InputAppEvent.parse_inputAppEvent($0) }
@@ -782,6 +790,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1672577397] = { return Api.MessageEntity.parse_messageEntityUnderline($0) }
dict[-1090087980] = { return Api.MessageEntity.parse_messageEntityStrike($0) }
dict[34469328] = { return Api.MessageEntity.parse_messageEntityBlockquote($0) }
+ dict[1981704948] = { return Api.MessageEntity.parse_messageEntityBankCard($0) }
dict[483901197] = { return Api.InputPhoto.parse_inputPhotoEmpty($0) }
dict[1001634122] = { return Api.InputPhoto.parse_inputPhoto($0) }
dict[-567906571] = { return Api.contacts.TopPeers.parse_topPeersNotModified($0) }
@@ -799,11 +808,13 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-94974410] = { return Api.EncryptedChat.parse_encryptedChat($0) }
dict[332848423] = { return Api.EncryptedChat.parse_encryptedChatDiscarded($0) }
dict[-901375139] = { return Api.PeerLocated.parse_peerLocated($0) }
+ dict[-118740917] = { return Api.PeerLocated.parse_peerSelfLocated($0) }
dict[922273905] = { return Api.Document.parse_documentEmpty($0) }
dict[-1683841855] = { return Api.Document.parse_document($0) }
dict[-1707344487] = { return Api.messages.HighScores.parse_highScores($0) }
dict[-892779534] = { return Api.WebAuthorization.parse_webAuthorization($0) }
dict[-805141448] = { return Api.ImportedContact.parse_importedContact($0) }
+ dict[-419239361] = { return Api.payments.BankCardData.parse_bankCardData($0) }
return dict
}()
@@ -1081,6 +1092,8 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.messages.AffectedHistory:
_1.serialize(buffer, boxed)
+ case let _1 as Api.StatsGraph:
+ _1.serialize(buffer, boxed)
case let _1 as Api.account.PasswordInputSettings:
_1.serialize(buffer, boxed)
case let _1 as Api.PageTableCell:
@@ -1151,6 +1164,8 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.SecureCredentialsEncrypted:
_1.serialize(buffer, boxed)
+ case let _1 as Api.StatsPercentValue:
+ _1.serialize(buffer, boxed)
case let _1 as Api.upload.File:
_1.serialize(buffer, boxed)
case let _1 as Api.ChannelLocation:
@@ -1185,6 +1200,8 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.PhoneCallProtocol:
_1.serialize(buffer, boxed)
+ case let _1 as Api.StatsDateRangeDays:
+ _1.serialize(buffer, boxed)
case let _1 as Api.MessageFwdAuthor:
_1.serialize(buffer, boxed)
case let _1 as Api.WallPaper:
@@ -1201,8 +1218,12 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.PaymentCharge:
_1.serialize(buffer, boxed)
+ case let _1 as Api.stats.BroadcastStats:
+ _1.serialize(buffer, boxed)
case let _1 as Api.Updates:
_1.serialize(buffer, boxed)
+ case let _1 as Api.StatsAbsValueAndPrev:
+ _1.serialize(buffer, boxed)
case let _1 as Api.MessageMedia:
_1.serialize(buffer, boxed)
case let _1 as Api.PaymentSavedCredentials:
@@ -1273,6 +1294,8 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.messages.FeaturedStickers:
_1.serialize(buffer, boxed)
+ case let _1 as Api.auth.LoginTokenInfo:
+ _1.serialize(buffer, boxed)
case let _1 as Api.PhoneCallDiscardReason:
_1.serialize(buffer, boxed)
case let _1 as Api.NearestDc:
@@ -1331,8 +1354,6 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.PhoneConnection:
_1.serialize(buffer, boxed)
- case let _1 as Api.help.UserInfo:
- _1.serialize(buffer, boxed)
case let _1 as Api.AccountDaysTTL:
_1.serialize(buffer, boxed)
case let _1 as Api.SecureValueType:
@@ -1381,6 +1402,8 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.updates.ChannelDifference:
_1.serialize(buffer, boxed)
+ case let _1 as Api.StatsRowAbsValueAndPrev:
+ _1.serialize(buffer, boxed)
case let _1 as Api.channels.AdminLogResults:
_1.serialize(buffer, boxed)
case let _1 as Api.ChatOnlines:
@@ -1409,6 +1432,8 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.ImportedContact:
_1.serialize(buffer, boxed)
+ case let _1 as Api.payments.BankCardData:
+ _1.serialize(buffer, boxed)
default:
break
}
diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift
index 9e6d38f6d1..09dc6c09b6 100644
--- a/submodules/TelegramApi/Sources/Api1.swift
+++ b/submodules/TelegramApi/Sources/Api1.swift
@@ -11956,6 +11956,82 @@ public extension Api {
}
}
+ }
+ public enum StatsGraph: TypeConstructorDescription {
+ case statsGraphAsync(token: String)
+ case statsGraphError(error: String)
+ case statsGraph(json: Api.DataJSON)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .statsGraphAsync(let token):
+ if boxed {
+ buffer.appendInt32(1244130093)
+ }
+ serializeString(token, buffer: buffer, boxed: false)
+ break
+ case .statsGraphError(let error):
+ if boxed {
+ buffer.appendInt32(-1092839390)
+ }
+ serializeString(error, buffer: buffer, boxed: false)
+ break
+ case .statsGraph(let json):
+ if boxed {
+ buffer.appendInt32(-1057809608)
+ }
+ json.serialize(buffer, true)
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .statsGraphAsync(let token):
+ return ("statsGraphAsync", [("token", token)])
+ case .statsGraphError(let error):
+ return ("statsGraphError", [("error", error)])
+ case .statsGraph(let json):
+ return ("statsGraph", [("json", json)])
+ }
+ }
+
+ public static func parse_statsGraphAsync(_ reader: BufferReader) -> StatsGraph? {
+ var _1: String?
+ _1 = parseString(reader)
+ let _c1 = _1 != nil
+ if _c1 {
+ return Api.StatsGraph.statsGraphAsync(token: _1!)
+ }
+ else {
+ return nil
+ }
+ }
+ public static func parse_statsGraphError(_ reader: BufferReader) -> StatsGraph? {
+ var _1: String?
+ _1 = parseString(reader)
+ let _c1 = _1 != nil
+ if _c1 {
+ return Api.StatsGraph.statsGraphError(error: _1!)
+ }
+ else {
+ return nil
+ }
+ }
+ public static func parse_statsGraph(_ reader: BufferReader) -> StatsGraph? {
+ var _1: Api.DataJSON?
+ if let signature = reader.readInt32() {
+ _1 = Api.parse(reader, signature: signature) as? Api.DataJSON
+ }
+ let _c1 = _1 != nil
+ if _c1 {
+ return Api.StatsGraph.statsGraph(json: _1!)
+ }
+ else {
+ return nil
+ }
+ }
+
}
public enum PageTableCell: TypeConstructorDescription {
case pageTableCell(flags: Int32, text: Api.RichText?, colspan: Int32?, rowspan: Int32?)
@@ -13662,6 +13738,44 @@ public extension Api {
}
}
+ }
+ public enum StatsPercentValue: TypeConstructorDescription {
+ case statsPercentValue(part: Double, total: Double)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .statsPercentValue(let part, let total):
+ if boxed {
+ buffer.appendInt32(-875679776)
+ }
+ serializeDouble(part, buffer: buffer, boxed: false)
+ serializeDouble(total, buffer: buffer, boxed: false)
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .statsPercentValue(let part, let total):
+ return ("statsPercentValue", [("part", part), ("total", total)])
+ }
+ }
+
+ public static func parse_statsPercentValue(_ reader: BufferReader) -> StatsPercentValue? {
+ var _1: Double?
+ _1 = reader.readDouble()
+ var _2: Double?
+ _2 = reader.readDouble()
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ if _c1 && _c2 {
+ return Api.StatsPercentValue.statsPercentValue(part: _1!, total: _2!)
+ }
+ else {
+ return nil
+ }
+ }
+
}
public enum ChannelLocation: TypeConstructorDescription {
case channelLocationEmpty
@@ -14434,6 +14548,44 @@ public extension Api {
}
}
+ }
+ public enum StatsDateRangeDays: TypeConstructorDescription {
+ case statsDateRangeDays(minDate: Int32, maxDate: Int32)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .statsDateRangeDays(let minDate, let maxDate):
+ if boxed {
+ buffer.appendInt32(-1237848657)
+ }
+ serializeInt32(minDate, buffer: buffer, boxed: false)
+ serializeInt32(maxDate, buffer: buffer, boxed: false)
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .statsDateRangeDays(let minDate, let maxDate):
+ return ("statsDateRangeDays", [("minDate", minDate), ("maxDate", maxDate)])
+ }
+ }
+
+ public static func parse_statsDateRangeDays(_ reader: BufferReader) -> StatsDateRangeDays? {
+ var _1: Int32?
+ _1 = reader.readInt32()
+ var _2: Int32?
+ _2 = reader.readInt32()
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ if _c1 && _c2 {
+ return Api.StatsDateRangeDays.statsDateRangeDays(minDate: _1!, maxDate: _2!)
+ }
+ else {
+ return nil
+ }
+ }
+
}
public enum MessageFwdAuthor: TypeConstructorDescription {
case messageFwdAuthor(channelId: Int32)
@@ -15098,6 +15250,44 @@ public extension Api {
}
}
+ }
+ public enum StatsAbsValueAndPrev: TypeConstructorDescription {
+ case statsAbsValueAndPrev(current: Double, previous: Double)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .statsAbsValueAndPrev(let current, let previous):
+ if boxed {
+ buffer.appendInt32(-884757282)
+ }
+ serializeDouble(current, buffer: buffer, boxed: false)
+ serializeDouble(previous, buffer: buffer, boxed: false)
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .statsAbsValueAndPrev(let current, let previous):
+ return ("statsAbsValueAndPrev", [("current", current), ("previous", previous)])
+ }
+ }
+
+ public static func parse_statsAbsValueAndPrev(_ reader: BufferReader) -> StatsAbsValueAndPrev? {
+ var _1: Double?
+ _1 = reader.readDouble()
+ var _2: Double?
+ _2 = reader.readDouble()
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ if _c1 && _c2 {
+ return Api.StatsAbsValueAndPrev.statsAbsValueAndPrev(current: _1!, previous: _2!)
+ }
+ else {
+ return nil
+ }
+ }
+
}
public enum MessageMedia: TypeConstructorDescription {
case messageMediaEmpty
@@ -20448,10 +20638,17 @@ public extension Api {
}
public enum Theme: TypeConstructorDescription {
+ case themeDocumentNotModified
case theme(flags: Int32, id: Int64, accessHash: Int64, slug: String, title: String, document: Api.Document?, settings: Api.ThemeSettings?, installsCount: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
+ case .themeDocumentNotModified:
+ if boxed {
+ buffer.appendInt32(1211967244)
+ }
+
+ break
case .theme(let flags, let id, let accessHash, let slug, let title, let document, let settings, let installsCount):
if boxed {
buffer.appendInt32(42930452)
@@ -20470,11 +20667,16 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
+ case .themeDocumentNotModified:
+ return ("themeDocumentNotModified", [])
case .theme(let flags, let id, let accessHash, let slug, let title, let document, let settings, let installsCount):
return ("theme", [("flags", flags), ("id", id), ("accessHash", accessHash), ("slug", slug), ("title", title), ("document", document), ("settings", settings), ("installsCount", installsCount)])
}
}
+ public static func parse_themeDocumentNotModified(_ reader: BufferReader) -> Theme? {
+ return Api.Theme.themeDocumentNotModified
+ }
public static func parse_theme(_ reader: BufferReader) -> Theme? {
var _1: Int32?
_1 = reader.readInt32()
@@ -20880,6 +21082,54 @@ public extension Api {
}
}
+ }
+ public enum StatsRowAbsValueAndPrev: TypeConstructorDescription {
+ case statsRowAbsValueAndPrev(id: String, title: String, shortTitle: String, values: Api.StatsAbsValueAndPrev)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .statsRowAbsValueAndPrev(let id, let title, let shortTitle, let values):
+ if boxed {
+ buffer.appendInt32(-581804346)
+ }
+ serializeString(id, buffer: buffer, boxed: false)
+ serializeString(title, buffer: buffer, boxed: false)
+ serializeString(shortTitle, buffer: buffer, boxed: false)
+ values.serialize(buffer, true)
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .statsRowAbsValueAndPrev(let id, let title, let shortTitle, let values):
+ return ("statsRowAbsValueAndPrev", [("id", id), ("title", title), ("shortTitle", shortTitle), ("values", values)])
+ }
+ }
+
+ public static func parse_statsRowAbsValueAndPrev(_ reader: BufferReader) -> StatsRowAbsValueAndPrev? {
+ var _1: String?
+ _1 = parseString(reader)
+ var _2: String?
+ _2 = parseString(reader)
+ var _3: String?
+ _3 = parseString(reader)
+ var _4: Api.StatsAbsValueAndPrev?
+ if let signature = reader.readInt32() {
+ _4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
+ }
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ let _c3 = _3 != nil
+ let _c4 = _4 != nil
+ if _c1 && _c2 && _c3 && _c4 {
+ return Api.StatsRowAbsValueAndPrev.statsRowAbsValueAndPrev(id: _1!, title: _2!, shortTitle: _3!, values: _4!)
+ }
+ else {
+ return nil
+ }
+ }
+
}
public enum ChatOnlines: TypeConstructorDescription {
case chatOnlines(onlines: Int32)
@@ -20982,6 +21232,7 @@ public extension Api {
case messageEntityUnderline(offset: Int32, length: Int32)
case messageEntityStrike(offset: Int32, length: Int32)
case messageEntityBlockquote(offset: Int32, length: Int32)
+ case messageEntityBankCard(offset: Int32, length: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@@ -21115,6 +21366,13 @@ public extension Api {
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt32(length, buffer: buffer, boxed: false)
break
+ case .messageEntityBankCard(let offset, let length):
+ if boxed {
+ buffer.appendInt32(1981704948)
+ }
+ serializeInt32(offset, buffer: buffer, boxed: false)
+ serializeInt32(length, buffer: buffer, boxed: false)
+ break
}
}
@@ -21156,6 +21414,8 @@ public extension Api {
return ("messageEntityStrike", [("offset", offset), ("length", length)])
case .messageEntityBlockquote(let offset, let length):
return ("messageEntityBlockquote", [("offset", offset), ("length", length)])
+ case .messageEntityBankCard(let offset, let length):
+ return ("messageEntityBankCard", [("offset", offset), ("length", length)])
}
}
@@ -21425,6 +21685,20 @@ public extension Api {
return nil
}
}
+ public static func parse_messageEntityBankCard(_ reader: BufferReader) -> MessageEntity? {
+ var _1: Int32?
+ _1 = reader.readInt32()
+ var _2: Int32?
+ _2 = reader.readInt32()
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ if _c1 && _c2 {
+ return Api.MessageEntity.messageEntityBankCard(offset: _1!, length: _2!)
+ }
+ else {
+ return nil
+ }
+ }
}
public enum InputPhoto: TypeConstructorDescription {
@@ -21727,6 +22001,7 @@ public extension Api {
}
public enum PeerLocated: TypeConstructorDescription {
case peerLocated(peer: Api.Peer, expires: Int32, distance: Int32)
+ case peerSelfLocated(expires: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@@ -21738,6 +22013,12 @@ public extension Api {
serializeInt32(expires, buffer: buffer, boxed: false)
serializeInt32(distance, buffer: buffer, boxed: false)
break
+ case .peerSelfLocated(let expires):
+ if boxed {
+ buffer.appendInt32(-118740917)
+ }
+ serializeInt32(expires, buffer: buffer, boxed: false)
+ break
}
}
@@ -21745,6 +22026,8 @@ public extension Api {
switch self {
case .peerLocated(let peer, let expires, let distance):
return ("peerLocated", [("peer", peer), ("expires", expires), ("distance", distance)])
+ case .peerSelfLocated(let expires):
+ return ("peerSelfLocated", [("expires", expires)])
}
}
@@ -21767,6 +22050,17 @@ public extension Api {
return nil
}
}
+ public static func parse_peerSelfLocated(_ reader: BufferReader) -> PeerLocated? {
+ var _1: Int32?
+ _1 = reader.readInt32()
+ let _c1 = _1 != nil
+ if _c1 {
+ return Api.PeerLocated.peerSelfLocated(expires: _1!)
+ }
+ else {
+ return nil
+ }
+ }
}
public enum Document: TypeConstructorDescription {
diff --git a/submodules/TelegramApi/Sources/Api2.swift b/submodules/TelegramApi/Sources/Api2.swift
index f0cb6195e9..4f499c6615 100644
--- a/submodules/TelegramApi/Sources/Api2.swift
+++ b/submodules/TelegramApi/Sources/Api2.swift
@@ -490,6 +490,176 @@ public struct payments {
}
}
+ public enum BankCardData: TypeConstructorDescription {
+ case bankCardData(flags: Int32, title: String, url: String?, urlName: String?)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .bankCardData(let flags, let title, let url, let urlName):
+ if boxed {
+ buffer.appendInt32(-419239361)
+ }
+ serializeInt32(flags, buffer: buffer, boxed: false)
+ serializeString(title, buffer: buffer, boxed: false)
+ if Int(flags) & Int(1 << 0) != 0 {serializeString(url!, buffer: buffer, boxed: false)}
+ if Int(flags) & Int(1 << 0) != 0 {serializeString(urlName!, buffer: buffer, boxed: false)}
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .bankCardData(let flags, let title, let url, let urlName):
+ return ("bankCardData", [("flags", flags), ("title", title), ("url", url), ("urlName", urlName)])
+ }
+ }
+
+ public static func parse_bankCardData(_ reader: BufferReader) -> BankCardData? {
+ var _1: Int32?
+ _1 = reader.readInt32()
+ var _2: String?
+ _2 = parseString(reader)
+ var _3: String?
+ if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
+ var _4: String?
+ if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
+ let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
+ if _c1 && _c2 && _c3 && _c4 {
+ return Api.payments.BankCardData.bankCardData(flags: _1!, title: _2!, url: _3, urlName: _4)
+ }
+ else {
+ return nil
+ }
+ }
+
+ }
+}
+}
+public extension Api {
+public struct stats {
+ public enum BroadcastStats: TypeConstructorDescription {
+ case broadcastStats(period: Api.StatsDateRangeDays, followers: Api.StatsAbsValueAndPrev, viewsPerPost: Api.StatsAbsValueAndPrev, sharesPerPost: Api.StatsAbsValueAndPrev, enabledNotifications: Api.StatsPercentValue, viewsBySource: [Api.StatsRowAbsValueAndPrev], newFollowersBySource: [Api.StatsRowAbsValueAndPrev], languages: [Api.StatsRowAbsValueAndPrev], growthGraph: Api.StatsGraph, followersGraph: Api.StatsGraph, muteGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, interactionsGraph: Api.StatsGraph)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let enabledNotifications, let viewsBySource, let newFollowersBySource, let languages, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph):
+ if boxed {
+ buffer.appendInt32(205195937)
+ }
+ period.serialize(buffer, true)
+ followers.serialize(buffer, true)
+ viewsPerPost.serialize(buffer, true)
+ sharesPerPost.serialize(buffer, true)
+ enabledNotifications.serialize(buffer, true)
+ buffer.appendInt32(481674261)
+ buffer.appendInt32(Int32(viewsBySource.count))
+ for item in viewsBySource {
+ item.serialize(buffer, true)
+ }
+ buffer.appendInt32(481674261)
+ buffer.appendInt32(Int32(newFollowersBySource.count))
+ for item in newFollowersBySource {
+ item.serialize(buffer, true)
+ }
+ buffer.appendInt32(481674261)
+ buffer.appendInt32(Int32(languages.count))
+ for item in languages {
+ item.serialize(buffer, true)
+ }
+ growthGraph.serialize(buffer, true)
+ followersGraph.serialize(buffer, true)
+ muteGraph.serialize(buffer, true)
+ topHoursGraph.serialize(buffer, true)
+ interactionsGraph.serialize(buffer, true)
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let enabledNotifications, let viewsBySource, let newFollowersBySource, let languages, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph):
+ return ("broadcastStats", [("period", period), ("followers", followers), ("viewsPerPost", viewsPerPost), ("sharesPerPost", sharesPerPost), ("enabledNotifications", enabledNotifications), ("viewsBySource", viewsBySource), ("newFollowersBySource", newFollowersBySource), ("languages", languages), ("growthGraph", growthGraph), ("followersGraph", followersGraph), ("muteGraph", muteGraph), ("topHoursGraph", topHoursGraph), ("interactionsGraph", interactionsGraph)])
+ }
+ }
+
+ public static func parse_broadcastStats(_ reader: BufferReader) -> BroadcastStats? {
+ var _1: Api.StatsDateRangeDays?
+ if let signature = reader.readInt32() {
+ _1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays
+ }
+ var _2: Api.StatsAbsValueAndPrev?
+ if let signature = reader.readInt32() {
+ _2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
+ }
+ var _3: Api.StatsAbsValueAndPrev?
+ if let signature = reader.readInt32() {
+ _3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
+ }
+ var _4: Api.StatsAbsValueAndPrev?
+ if let signature = reader.readInt32() {
+ _4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
+ }
+ var _5: Api.StatsPercentValue?
+ if let signature = reader.readInt32() {
+ _5 = Api.parse(reader, signature: signature) as? Api.StatsPercentValue
+ }
+ var _6: [Api.StatsRowAbsValueAndPrev]?
+ if let _ = reader.readInt32() {
+ _6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsRowAbsValueAndPrev.self)
+ }
+ var _7: [Api.StatsRowAbsValueAndPrev]?
+ if let _ = reader.readInt32() {
+ _7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsRowAbsValueAndPrev.self)
+ }
+ var _8: [Api.StatsRowAbsValueAndPrev]?
+ if let _ = reader.readInt32() {
+ _8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsRowAbsValueAndPrev.self)
+ }
+ var _9: Api.StatsGraph?
+ if let signature = reader.readInt32() {
+ _9 = Api.parse(reader, signature: signature) as? Api.StatsGraph
+ }
+ var _10: Api.StatsGraph?
+ if let signature = reader.readInt32() {
+ _10 = Api.parse(reader, signature: signature) as? Api.StatsGraph
+ }
+ var _11: Api.StatsGraph?
+ if let signature = reader.readInt32() {
+ _11 = Api.parse(reader, signature: signature) as? Api.StatsGraph
+ }
+ var _12: Api.StatsGraph?
+ if let signature = reader.readInt32() {
+ _12 = Api.parse(reader, signature: signature) as? Api.StatsGraph
+ }
+ var _13: Api.StatsGraph?
+ if let signature = reader.readInt32() {
+ _13 = Api.parse(reader, signature: signature) as? Api.StatsGraph
+ }
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ let _c3 = _3 != nil
+ let _c4 = _4 != nil
+ let _c5 = _5 != nil
+ let _c6 = _6 != nil
+ let _c7 = _7 != nil
+ let _c8 = _8 != nil
+ let _c9 = _9 != nil
+ let _c10 = _10 != nil
+ let _c11 = _11 != nil
+ let _c12 = _12 != nil
+ let _c13 = _13 != nil
+ if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
+ return Api.stats.BroadcastStats.broadcastStats(period: _1!, followers: _2!, viewsPerPost: _3!, sharesPerPost: _4!, enabledNotifications: _5!, viewsBySource: _6!, newFollowersBySource: _7!, languages: _8!, growthGraph: _9!, followersGraph: _10!, muteGraph: _11!, topHoursGraph: _12!, interactionsGraph: _13!)
+ }
+ else {
+ return nil
+ }
+ }
+
+ }
}
}
public extension Api {
@@ -859,6 +1029,76 @@ public struct auth {
return Api.auth.CodeType.codeTypeFlashCall
}
+ }
+ public enum LoginTokenInfo: TypeConstructorDescription {
+ case loginTokenInfo(dcId: Int32, authKeyId: Int64, deviceModel: String, platform: String, systemVersion: String, apiId: Int32, appName: String, appVersion: String, ip: String, region: String)
+
+ public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
+ switch self {
+ case .loginTokenInfo(let dcId, let authKeyId, let deviceModel, let platform, let systemVersion, let apiId, let appName, let appVersion, let ip, let region):
+ if boxed {
+ buffer.appendInt32(1375940666)
+ }
+ serializeInt32(dcId, buffer: buffer, boxed: false)
+ serializeInt64(authKeyId, buffer: buffer, boxed: false)
+ serializeString(deviceModel, buffer: buffer, boxed: false)
+ serializeString(platform, buffer: buffer, boxed: false)
+ serializeString(systemVersion, buffer: buffer, boxed: false)
+ serializeInt32(apiId, buffer: buffer, boxed: false)
+ serializeString(appName, buffer: buffer, boxed: false)
+ serializeString(appVersion, buffer: buffer, boxed: false)
+ serializeString(ip, buffer: buffer, boxed: false)
+ serializeString(region, buffer: buffer, boxed: false)
+ break
+ }
+ }
+
+ public func descriptionFields() -> (String, [(String, Any)]) {
+ switch self {
+ case .loginTokenInfo(let dcId, let authKeyId, let deviceModel, let platform, let systemVersion, let apiId, let appName, let appVersion, let ip, let region):
+ return ("loginTokenInfo", [("dcId", dcId), ("authKeyId", authKeyId), ("deviceModel", deviceModel), ("platform", platform), ("systemVersion", systemVersion), ("apiId", apiId), ("appName", appName), ("appVersion", appVersion), ("ip", ip), ("region", region)])
+ }
+ }
+
+ public static func parse_loginTokenInfo(_ reader: BufferReader) -> LoginTokenInfo? {
+ var _1: Int32?
+ _1 = reader.readInt32()
+ var _2: Int64?
+ _2 = reader.readInt64()
+ var _3: String?
+ _3 = parseString(reader)
+ var _4: String?
+ _4 = parseString(reader)
+ var _5: String?
+ _5 = parseString(reader)
+ var _6: Int32?
+ _6 = reader.readInt32()
+ var _7: String?
+ _7 = parseString(reader)
+ var _8: String?
+ _8 = parseString(reader)
+ var _9: String?
+ _9 = parseString(reader)
+ var _10: String?
+ _10 = parseString(reader)
+ let _c1 = _1 != nil
+ let _c2 = _2 != nil
+ let _c3 = _3 != nil
+ let _c4 = _4 != nil
+ let _c5 = _5 != nil
+ let _c6 = _6 != nil
+ let _c7 = _7 != nil
+ let _c8 = _8 != nil
+ let _c9 = _9 != nil
+ let _c10 = _10 != nil
+ if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
+ return Api.auth.LoginTokenInfo.loginTokenInfo(dcId: _1!, authKeyId: _2!, deviceModel: _3!, platform: _4!, systemVersion: _5!, apiId: _6!, appName: _7!, appVersion: _8!, ip: _9!, region: _10!)
+ }
+ else {
+ return nil
+ }
+ }
+
}
public enum SentCodeType: TypeConstructorDescription {
case sentCodeTypeApp(length: Int32)
@@ -1859,70 +2099,6 @@ public struct help {
}
}
- }
- public enum UserInfo: TypeConstructorDescription {
- case userInfoEmpty
- case userInfo(message: String, entities: [Api.MessageEntity], author: String, date: Int32)
-
- public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
- switch self {
- case .userInfoEmpty:
- if boxed {
- buffer.appendInt32(-206688531)
- }
-
- break
- case .userInfo(let message, let entities, let author, let date):
- if boxed {
- buffer.appendInt32(32192344)
- }
- serializeString(message, buffer: buffer, boxed: false)
- buffer.appendInt32(481674261)
- buffer.appendInt32(Int32(entities.count))
- for item in entities {
- item.serialize(buffer, true)
- }
- serializeString(author, buffer: buffer, boxed: false)
- serializeInt32(date, buffer: buffer, boxed: false)
- break
- }
- }
-
- public func descriptionFields() -> (String, [(String, Any)]) {
- switch self {
- case .userInfoEmpty:
- return ("userInfoEmpty", [])
- case .userInfo(let message, let entities, let author, let date):
- return ("userInfo", [("message", message), ("entities", entities), ("author", author), ("date", date)])
- }
- }
-
- public static func parse_userInfoEmpty(_ reader: BufferReader) -> UserInfo? {
- return Api.help.UserInfo.userInfoEmpty
- }
- public static func parse_userInfo(_ reader: BufferReader) -> UserInfo? {
- var _1: String?
- _1 = parseString(reader)
- var _2: [Api.MessageEntity]?
- if let _ = reader.readInt32() {
- _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
- }
- var _3: String?
- _3 = parseString(reader)
- var _4: Int32?
- _4 = reader.readInt32()
- let _c1 = _1 != nil
- let _c2 = _2 != nil
- let _c3 = _3 != nil
- let _c4 = _4 != nil
- if _c1 && _c2 && _c3 && _c4 {
- return Api.help.UserInfo.userInfo(message: _1!, entities: _2!, author: _3!, date: _4!)
- }
- else {
- return nil
- }
- }
-
}
public enum TermsOfServiceUpdate: TypeConstructorDescription {
case termsOfServiceUpdateEmpty(expires: Int32)
diff --git a/submodules/TelegramApi/Sources/Api3.swift b/submodules/TelegramApi/Sources/Api3.swift
index 74e4884bf6..aee22f1e04 100644
--- a/submodules/TelegramApi/Sources/Api3.swift
+++ b/submodules/TelegramApi/Sources/Api3.swift
@@ -3196,6 +3196,25 @@ public extension Api {
})
}
+ public static func toggleStickerSets(flags: Int32, stickersets: [Api.InputStickerSet]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
+ let buffer = Buffer()
+ buffer.appendInt32(-1257951254)
+ serializeInt32(flags, buffer: buffer, boxed: false)
+ buffer.appendInt32(481674261)
+ buffer.appendInt32(Int32(stickersets.count))
+ for item in stickersets {
+ item.serialize(buffer, true)
+ }
+ return (FunctionDescription(name: "messages.toggleStickerSets", parameters: [("flags", flags), ("stickersets", stickersets)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
+ let reader = BufferReader(buffer)
+ var result: Api.Bool?
+ if let signature = reader.readInt32() {
+ result = Api.parse(reader, signature: signature) as? Api.Bool
+ }
+ return result
+ })
+ }
+
public static func getPollVotes(flags: Int32, peer: Api.InputPeer, id: Int32, option: Buffer?, offset: String?, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
let buffer = Buffer()
buffer.appendInt32(-1200736242)
@@ -3885,6 +3904,50 @@ public extension Api {
return result
})
}
+
+ public static func getBankCardData(number: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
+ let buffer = Buffer()
+ buffer.appendInt32(779736953)
+ serializeString(number, buffer: buffer, boxed: false)
+ return (FunctionDescription(name: "payments.getBankCardData", parameters: [("number", number)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.BankCardData? in
+ let reader = BufferReader(buffer)
+ var result: Api.payments.BankCardData?
+ if let signature = reader.readInt32() {
+ result = Api.parse(reader, signature: signature) as? Api.payments.BankCardData
+ }
+ return result
+ })
+ }
+ }
+ public struct stats {
+ public static func getBroadcastStats(flags: Int32, channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
+ let buffer = Buffer()
+ buffer.appendInt32(-1421720550)
+ serializeInt32(flags, buffer: buffer, boxed: false)
+ channel.serialize(buffer, true)
+ return (FunctionDescription(name: "stats.getBroadcastStats", parameters: [("flags", flags), ("channel", channel)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastStats? in
+ let reader = BufferReader(buffer)
+ var result: Api.stats.BroadcastStats?
+ if let signature = reader.readInt32() {
+ result = Api.parse(reader, signature: signature) as? Api.stats.BroadcastStats
+ }
+ return result
+ })
+ }
+
+ public static func loadAsyncGraph(token: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
+ let buffer = Buffer()
+ buffer.appendInt32(1749505346)
+ serializeString(token, buffer: buffer, boxed: false)
+ return (FunctionDescription(name: "stats.loadAsyncGraph", parameters: [("token", token)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.StatsGraph? in
+ let reader = BufferReader(buffer)
+ var result: Api.StatsGraph?
+ if let signature = reader.readInt32() {
+ result = Api.parse(reader, signature: signature) as? Api.StatsGraph
+ }
+ return result
+ })
+ }
}
public struct auth {
public static func checkPhone(phoneNumber: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
@@ -4558,11 +4621,13 @@ public extension Api {
})
}
- public static func getLocated(geoPoint: Api.InputGeoPoint) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
+ public static func getLocated(flags: Int32, geoPoint: Api.InputGeoPoint, selfExpires: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
let buffer = Buffer()
- buffer.appendInt32(171270230)
+ buffer.appendInt32(-750207932)
+ serializeInt32(flags, buffer: buffer, boxed: false)
geoPoint.serialize(buffer, true)
- return (FunctionDescription(name: "contacts.getLocated", parameters: [("geoPoint", geoPoint)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
+ if Int(flags) & Int(1 << 0) != 0 {serializeInt32(selfExpires!, buffer: buffer, boxed: false)}
+ return (FunctionDescription(name: "contacts.getLocated", parameters: [("flags", flags), ("geoPoint", geoPoint), ("selfExpires", selfExpires)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@@ -4815,40 +4880,6 @@ public extension Api {
return result
})
}
-
- public static func editUserInfo(userId: Api.InputUser, message: String, entities: [Api.MessageEntity]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
- let buffer = Buffer()
- buffer.appendInt32(1723407216)
- userId.serialize(buffer, true)
- serializeString(message, buffer: buffer, boxed: false)
- buffer.appendInt32(481674261)
- buffer.appendInt32(Int32(entities.count))
- for item in entities {
- item.serialize(buffer, true)
- }
- return (FunctionDescription(name: "help.editUserInfo", parameters: [("userId", userId), ("message", message), ("entities", entities)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.help.UserInfo? in
- let reader = BufferReader(buffer)
- var result: Api.help.UserInfo?
- if let signature = reader.readInt32() {
- result = Api.parse(reader, signature: signature) as? Api.help.UserInfo
- }
- return result
- })
- }
-
- public static func getUserInfo(userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
- let buffer = Buffer()
- buffer.appendInt32(59377875)
- userId.serialize(buffer, true)
- return (FunctionDescription(name: "help.getUserInfo", parameters: [("userId", userId)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.help.UserInfo? in
- let reader = BufferReader(buffer)
- var result: Api.help.UserInfo?
- if let signature = reader.readInt32() {
- result = Api.parse(reader, signature: signature) as? Api.help.UserInfo
- }
- return result
- })
- }
}
public struct updates {
public static func getState() -> (FunctionDescription, Buffer, DeserializeFunctionResponse) {
diff --git a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift
index ad168e7d01..4e870b88ce 100644
--- a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift
+++ b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift
@@ -1295,8 +1295,13 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
}
case let .updatePeerLocated(peers):
var peersNearby: [PeerNearby] = []
- for case let .peerLocated(peer, expires, distance) in peers {
- peersNearby.append(PeerNearby(id: peer.peerId, expires: expires, distance: distance))
+ for peer in peers {
+ switch peer {
+ case let .peerLocated(peer, expires, distance):
+ peersNearby.append(.peer(id: peer.peerId, expires: expires, distance: distance))
+ case let .peerSelfLocated(expires):
+ peersNearby.append(.selfPeer(expires: expires))
+ }
}
updatedState.updatePeersNearby(peersNearby)
case let .updateNewScheduledMessage(apiMessage):
diff --git a/submodules/TelegramCore/Sources/BankCards.swift b/submodules/TelegramCore/Sources/BankCards.swift
new file mode 100644
index 0000000000..f0db9d6304
--- /dev/null
+++ b/submodules/TelegramCore/Sources/BankCards.swift
@@ -0,0 +1,34 @@
+import Foundation
+import Postbox
+import TelegramApi
+import SyncCore
+import SwiftSignalKit
+
+public struct BankCardInfo {
+ public let title: String
+ public let url: String?
+ public let actionTitle: String?
+}
+
+public func getBankCardInfo(account: Account, cardNumber: String) -> Signal {
+ return account.network.request(Api.functions.payments.getBankCardData(number: cardNumber))
+ |> map { result -> BankCardInfo? in
+ return BankCardInfo(apiBankCardData: result)
+ }
+ |> `catch` { _ -> Signal in
+ return .single(nil)
+ }
+}
+
+extension BankCardInfo {
+ init(apiBankCardData: Api.payments.BankCardData) {
+ switch apiBankCardData {
+ case let .bankCardData(flags, title, url, urlName):
+ self.title = title
+ self.url = url
+ self.actionTitle = urlName
+ }
+ }
+}
+
+
diff --git a/submodules/TelegramCore/Sources/ChannelStatistics.swift b/submodules/TelegramCore/Sources/ChannelStatistics.swift
new file mode 100644
index 0000000000..1e501b535b
--- /dev/null
+++ b/submodules/TelegramCore/Sources/ChannelStatistics.swift
@@ -0,0 +1,424 @@
+import Foundation
+import SwiftSignalKit
+import Postbox
+import TelegramApi
+import MtProtoKit
+import SyncCore
+
+public struct ChannelStatsDateRange: Equatable {
+ public let minDate: Int32
+ public let maxDate: Int32
+}
+
+public struct ChannelStatsValue: Equatable {
+ public let current: Double
+ public let previous: Double
+}
+
+public struct ChannelStatsPercentValue: Equatable {
+ public let fraction: Double
+ public let total: Double
+}
+
+public struct ChannelStatsNamedValue: Equatable {
+ public let id: String
+ public let title: String
+ public let shortTitle: String
+ public let value: ChannelStatsValue
+}
+
+public enum ChannelStatsGraph: Equatable {
+ case OnDemand(token: String)
+ case Failed(error: String)
+ case Loaded(data: String)
+}
+
+public final class ChannelStats: Equatable {
+ public let period: ChannelStatsDateRange
+ public let followers: ChannelStatsValue
+ public let viewsPerPost: ChannelStatsValue
+ public let sharesPerPost: ChannelStatsValue
+ public let enabledNotifications: ChannelStatsPercentValue
+ public let viewsBySource: [ChannelStatsNamedValue]
+ public let newFollowersBySource: [ChannelStatsNamedValue]
+ public let languages: [ChannelStatsNamedValue]
+ public let growthGraph: ChannelStatsGraph
+ public let followersGraph: ChannelStatsGraph
+ public let muteGraph: ChannelStatsGraph
+ public let topHoursGraph: ChannelStatsGraph
+ public let interactionsGraph: ChannelStatsGraph
+
+ public init(period: ChannelStatsDateRange, followers: ChannelStatsValue, viewsPerPost: ChannelStatsValue, sharesPerPost: ChannelStatsValue, enabledNotifications: ChannelStatsPercentValue, viewsBySource: [ChannelStatsNamedValue], newFollowersBySource: [ChannelStatsNamedValue], languages: [ChannelStatsNamedValue], growthGraph: ChannelStatsGraph, followersGraph: ChannelStatsGraph, muteGraph: ChannelStatsGraph, topHoursGraph: ChannelStatsGraph, interactionsGraph: ChannelStatsGraph) {
+ self.period = period
+ self.followers = followers
+ self.viewsPerPost = viewsPerPost
+ self.sharesPerPost = sharesPerPost
+ self.enabledNotifications = enabledNotifications
+ self.viewsBySource = viewsBySource
+ self.newFollowersBySource = newFollowersBySource
+ self.languages = languages
+ self.growthGraph = growthGraph
+ self.followersGraph = followersGraph
+ self.muteGraph = muteGraph
+ self.topHoursGraph = topHoursGraph
+ self.interactionsGraph = interactionsGraph
+ }
+
+ public static func == (lhs: ChannelStats, rhs: ChannelStats) -> Bool {
+ if lhs.period != rhs.period {
+ return false
+ }
+ if lhs.followers != rhs.followers {
+ return false
+ }
+ if lhs.viewsPerPost != rhs.viewsPerPost {
+ return false
+ }
+ if lhs.sharesPerPost != rhs.sharesPerPost {
+ return false
+ }
+ if lhs.enabledNotifications != rhs.enabledNotifications {
+ return false
+ }
+ if lhs.viewsBySource != rhs.viewsBySource {
+ return false
+ }
+ if lhs.newFollowersBySource != rhs.newFollowersBySource {
+ return false
+ }
+ if lhs.languages != rhs.languages {
+ return false
+ }
+ if lhs.growthGraph != rhs.growthGraph {
+ return false
+ }
+ if lhs.followersGraph != rhs.followersGraph {
+ return false
+ }
+ if lhs.muteGraph != rhs.muteGraph {
+ return false
+ }
+ if lhs.topHoursGraph != rhs.topHoursGraph {
+ return false
+ }
+ if lhs.interactionsGraph != rhs.interactionsGraph {
+ return false
+ }
+ return true
+ }
+
+ public func withUpdatedGrowthGraph(_ growthGraph: ChannelStatsGraph) -> ChannelStats {
+ return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, viewsBySource: self.viewsBySource, newFollowersBySource: self.newFollowersBySource, languages: self.languages, growthGraph: growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph)
+ }
+
+ public func withUpdatedFollowersGraph(_ followersGraph: ChannelStatsGraph) -> ChannelStats {
+ return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, viewsBySource: self.viewsBySource, newFollowersBySource: self.newFollowersBySource, languages: self.languages, growthGraph: self.growthGraph, followersGraph: followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph)
+ }
+
+ public func withUpdatedMuteGraph(_ muteGraph: ChannelStatsGraph) -> ChannelStats {
+ return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, viewsBySource: self.viewsBySource, newFollowersBySource: self.newFollowersBySource, languages: self.languages, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph)
+ }
+
+ public func withUpdatedTopHoursGraph(_ viewsByHourGraph: ChannelStatsGraph) -> ChannelStats {
+ return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, viewsBySource: self.viewsBySource, newFollowersBySource: self.newFollowersBySource, languages: self.languages, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: viewsByHourGraph, interactionsGraph: self.interactionsGraph)
+ }
+
+ public func withUpdatedInteractionsGraph(_ interactionsGraph: ChannelStatsGraph) -> ChannelStats {
+ return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, viewsBySource: self.viewsBySource, newFollowersBySource: self.newFollowersBySource, languages: self.languages, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: interactionsGraph)
+ }
+}
+
+public struct ChannelStatsContextState: Equatable {
+ public var stats: ChannelStats?
+}
+
+private func requestStats(network: Network, datacenterId: Int32, peer: Peer, dark: Bool = false) -> Signal {
+ guard let inputChannel = apiInputChannel(peer) else {
+ return .never()
+ }
+
+ var flags: Int32 = 0
+ if dark {
+ flags |= (1 << 1)
+ }
+
+ let signal: Signal
+ if network.datacenterId != datacenterId {
+ signal = network.download(datacenterId: Int(datacenterId), isMedia: false, tag: nil)
+ |> castError(MTRpcError.self)
+ |> mapToSignal { worker in
+ return worker.request(Api.functions.stats.getBroadcastStats(flags: flags, channel: inputChannel))
+ }
+ } else {
+ signal = network.request(Api.functions.stats.getBroadcastStats(flags: flags, channel: inputChannel))
+ }
+
+ return signal
+ |> map { result -> ChannelStats? in
+ return ChannelStats(apiBroadcastStats: result)
+ }
+ |> `catch` { _ -> Signal in
+ return .single(nil)
+ }
+}
+
+private func requestGraph(network: Network, datacenterId: Int32, token: String) -> Signal {
+ let signal: Signal
+ if network.datacenterId != datacenterId {
+ signal = network.download(datacenterId: Int(datacenterId), isMedia: false, tag: nil)
+ |> castError(MTRpcError.self)
+ |> mapToSignal { worker in
+ return worker.request(Api.functions.stats.loadAsyncGraph(token: token))
+ }
+ } else {
+ signal = network.request(Api.functions.stats.loadAsyncGraph(token: token))
+ }
+
+ return signal
+ |> map { result -> ChannelStatsGraph? in
+ return ChannelStatsGraph(apiStatsGraph: result)
+ }
+ |> `catch` { _ -> Signal in
+ return .single(nil)
+ }
+}
+
+private final class ChannelStatsContextImpl {
+ private let network: Network
+ private let peer: Peer
+ private let datacenterId: Int32
+
+ private var _state: ChannelStatsContextState {
+ didSet {
+ if self._state != oldValue {
+ self._statePromise.set(.single(self._state))
+ }
+ }
+ }
+ private let _statePromise = Promise()
+ var state: Signal {
+ return self._statePromise.get()
+ }
+
+ private let disposable = MetaDisposable()
+ private let disposables = DisposableDict()
+
+ init(network: Network, datacenterId: Int32, peer: Peer) {
+ assert(Queue.mainQueue().isCurrent())
+
+ self.network = network
+ self.peer = peer
+ self.datacenterId = datacenterId
+ self._state = ChannelStatsContextState(stats: nil)
+ self._statePromise.set(.single(self._state))
+
+ self.load()
+ }
+
+ deinit {
+ assert(Queue.mainQueue().isCurrent())
+ self.disposable.dispose()
+ self.disposables.dispose()
+ }
+
+ private func load() {
+ assert(Queue.mainQueue().isCurrent())
+
+ self.disposable.set((requestStats(network: self.network, datacenterId: self.datacenterId, peer: self.peer)
+ |> deliverOnMainQueue).start(next: { [weak self] stats in
+ if let strongSelf = self {
+ strongSelf._state = ChannelStatsContextState(stats: stats)
+ strongSelf._statePromise.set(.single(strongSelf._state))
+ }
+ }))
+ }
+
+ func loadGrowthGraph() {
+ guard let stats = self._state.stats else {
+ return
+ }
+ if case let .OnDemand(token) = stats.growthGraph {
+ self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
+ |> deliverOnMainQueue).start(next: { [weak self] graph in
+ if let strongSelf = self, let graph = graph {
+ strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedGrowthGraph(graph))
+ strongSelf._statePromise.set(.single(strongSelf._state))
+ }
+ }), forKey: token)
+ }
+ }
+
+ func loadFollowersGraph() {
+ guard let stats = self._state.stats else {
+ return
+ }
+ if case let .OnDemand(token) = stats.followersGraph {
+ self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
+ |> deliverOnMainQueue).start(next: { [weak self] graph in
+ if let strongSelf = self, let graph = graph {
+ strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedFollowersGraph(graph))
+ strongSelf._statePromise.set(.single(strongSelf._state))
+ }
+ }), forKey: token)
+ }
+ }
+
+ func loadMuteGraph() {
+ guard let stats = self._state.stats else {
+ return
+ }
+ if case let .OnDemand(token) = stats.muteGraph {
+ self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
+ |> deliverOnMainQueue).start(next: { [weak self] graph in
+ if let strongSelf = self, let graph = graph {
+ strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedMuteGraph(graph))
+ strongSelf._statePromise.set(.single(strongSelf._state))
+ }
+ }), forKey: token)
+ }
+ }
+
+ func loadTopHoursGraph() {
+ guard let stats = self._state.stats else {
+ return
+ }
+ if case let .OnDemand(token) = stats.topHoursGraph {
+ self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
+ |> deliverOnMainQueue).start(next: { [weak self] graph in
+ if let strongSelf = self, let graph = graph {
+ strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedTopHoursGraph(graph))
+ strongSelf._statePromise.set(.single(strongSelf._state))
+ }
+ }), forKey: token)
+ }
+ }
+
+ func loadInteractionsGraph() {
+ guard let stats = self._state.stats else {
+ return
+ }
+ if case let .OnDemand(token) = stats.interactionsGraph {
+ self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
+ |> deliverOnMainQueue).start(next: { [weak self] graph in
+ if let strongSelf = self, let graph = graph {
+ strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedInteractionsGraph(graph))
+ strongSelf._statePromise.set(.single(strongSelf._state))
+ }
+ }), forKey: token)
+ }
+ }
+}
+
+public final class ChannelStatsContext {
+ private let impl: QueueLocalObject
+
+ public var state: Signal {
+ return Signal { subscriber in
+ let disposable = MetaDisposable()
+ self.impl.with { impl in
+ disposable.set(impl.state.start(next: { value in
+ subscriber.putNext(value)
+ }))
+ }
+ return disposable
+ }
+ }
+
+ public init(network: Network, datacenterId: Int32, peer: Peer) {
+ self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
+ return ChannelStatsContextImpl(network: network, datacenterId: datacenterId, peer: peer)
+ })
+ }
+
+ public func loadGrowthGraph() {
+ self.impl.with { impl in
+ impl.loadGrowthGraph()
+ }
+ }
+
+ public func loadFollowersGraph() {
+ self.impl.with { impl in
+ impl.loadFollowersGraph()
+ }
+ }
+
+ public func loadMuteGraph() {
+ self.impl.with { impl in
+ impl.loadMuteGraph()
+ }
+ }
+
+ public func loadTopHoursGraph() {
+ self.impl.with { impl in
+ impl.loadTopHoursGraph()
+ }
+ }
+
+ public func loadInteractionsGraph() {
+ self.impl.with { impl in
+ impl.loadInteractionsGraph()
+ }
+ }
+}
+
+extension ChannelStatsGraph {
+ init(apiStatsGraph: Api.StatsGraph) {
+ switch apiStatsGraph {
+ case let .statsGraph(json):
+ if case let .dataJSON(string) = json {
+ self = .Loaded(data: string)
+ } else {
+ self = .Failed(error: "")
+ }
+ case let .statsGraphError(error):
+ self = .Failed(error: error)
+ case let .statsGraphAsync(token):
+ self = .OnDemand(token: token)
+ }
+ }
+}
+
+extension ChannelStatsDateRange {
+ init(apiStatsDateRangeDays: Api.StatsDateRangeDays) {
+ switch apiStatsDateRangeDays {
+ case let .statsDateRangeDays(minDate, maxDate):
+ self = ChannelStatsDateRange(minDate: minDate, maxDate: maxDate)
+ }
+ }
+}
+
+extension ChannelStatsValue {
+ init(apiStatsAbsValueAndPrev: Api.StatsAbsValueAndPrev) {
+ switch apiStatsAbsValueAndPrev {
+ case let .statsAbsValueAndPrev(current, previous):
+ self = ChannelStatsValue(current: current, previous: previous)
+ }
+ }
+}
+
+extension ChannelStatsNamedValue {
+ init(apiStatsRowAbsValueAndPrev: Api.StatsRowAbsValueAndPrev) {
+ switch apiStatsRowAbsValueAndPrev {
+ case let .statsRowAbsValueAndPrev(id, title, shortTitle, values):
+ self = ChannelStatsNamedValue(id: id, title: title, shortTitle: shortTitle, value: ChannelStatsValue(apiStatsAbsValueAndPrev: values))
+ }
+ }
+}
+
+extension ChannelStatsPercentValue {
+ init(apiPercentValue: Api.StatsPercentValue) {
+ switch apiPercentValue {
+ case let .statsPercentValue(part, total):
+ self = ChannelStatsPercentValue(fraction: part, total: total)
+ }
+ }
+}
+
+extension ChannelStats {
+ convenience init(apiBroadcastStats: Api.stats.BroadcastStats) {
+ switch apiBroadcastStats {
+ case let .broadcastStats(period, followers, viewsPerPost, sharesPerPost, enabledNotifications, viewsBySource, newFollowersBySource, languages, growthGraph, followersGraph, muteGraph, topHoursGraph, interactionsGraph):
+ self.init(period: ChannelStatsDateRange(apiStatsDateRangeDays: period), followers: ChannelStatsValue(apiStatsAbsValueAndPrev: followers), viewsPerPost: ChannelStatsValue(apiStatsAbsValueAndPrev: viewsPerPost), sharesPerPost: ChannelStatsValue(apiStatsAbsValueAndPrev: sharesPerPost), enabledNotifications: ChannelStatsPercentValue(apiPercentValue: enabledNotifications), viewsBySource: viewsBySource.map { ChannelStatsNamedValue(apiStatsRowAbsValueAndPrev: $0) }, newFollowersBySource: newFollowersBySource.map { ChannelStatsNamedValue(apiStatsRowAbsValueAndPrev: $0) }, languages: languages.map { ChannelStatsNamedValue(apiStatsRowAbsValueAndPrev: $0) }, growthGraph: ChannelStatsGraph(apiStatsGraph: growthGraph), followersGraph: ChannelStatsGraph(apiStatsGraph: followersGraph), muteGraph: ChannelStatsGraph(apiStatsGraph: muteGraph), topHoursGraph: ChannelStatsGraph(apiStatsGraph: topHoursGraph), interactionsGraph: ChannelStatsGraph(apiStatsGraph: interactionsGraph))
+ }
+ }
+}
diff --git a/submodules/TelegramCore/Sources/JSON.swift b/submodules/TelegramCore/Sources/JSON.swift
index 556085328b..43dd62bebd 100644
--- a/submodules/TelegramCore/Sources/JSON.swift
+++ b/submodules/TelegramCore/Sources/JSON.swift
@@ -28,8 +28,7 @@ extension JSON {
}
}
self = .array(values)
- }
- else if let value = object as? String {
+ } else if let value = object as? String {
self = .string(value)
} else if let value = object as? Int {
self = .number(Double(value))
diff --git a/submodules/TelegramCore/Sources/ManagedSecretChatOutgoingOperations.swift b/submodules/TelegramCore/Sources/ManagedSecretChatOutgoingOperations.swift
index 7754b00b97..d490602165 100644
--- a/submodules/TelegramCore/Sources/ManagedSecretChatOutgoingOperations.swift
+++ b/submodules/TelegramCore/Sources/ManagedSecretChatOutgoingOperations.swift
@@ -676,6 +676,8 @@ private func decryptedEntities73(_ entities: [MessageTextEntity]?) -> [SecretApi
break
case .Underline:
break
+ case .BankCard:
+ break
case .Custom:
break
}
@@ -723,6 +725,8 @@ private func decryptedEntities101(_ entities: [MessageTextEntity]?) -> [SecretAp
result.append(.messageEntityBlockquote(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count)))
case .Underline:
result.append(.messageEntityUnderline(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count)))
+ case .BankCard:
+ break
case .Custom:
break
}
diff --git a/submodules/TelegramCore/Sources/PeersNearby.swift b/submodules/TelegramCore/Sources/PeersNearby.swift
index b872ec5837..4ea533867d 100644
--- a/submodules/TelegramCore/Sources/PeersNearby.swift
+++ b/submodules/TelegramCore/Sources/PeersNearby.swift
@@ -7,12 +7,57 @@ import SyncCore
private typealias SignalKitTimer = SwiftSignalKit.Timer
+public enum PeerNearby {
+ case selfPeer(expires: Int32)
+ case peer(id: PeerId, expires: Int32, distance: Int32)
+
+ var expires: Int32 {
+ switch self {
+ case let .selfPeer(expires), let .peer(_, expires, _):
+ return expires
+ }
+ }
+}
+public enum PeerNearbyVisibilityUpdate {
+ case visible(latitude: Double, longitude: Double)
+ case location(latitude: Double, longitude: Double)
+ case invisible
+}
-public struct PeerNearby {
- public let id: PeerId
- public let expires: Int32
- public let distance: Int32
+public func peersNearbyUpdateVisibility(network: Network, stateManager: AccountStateManager, update: PeerNearbyVisibilityUpdate, background: Bool) -> Signal {
+ var flags: Int32 = 0
+ var geoPoint: Api.InputGeoPoint
+ var selfExpires: Int32?
+
+ switch update {
+ case let .visible(latitude, longitude):
+ flags |= (1 << 0)
+ geoPoint = .inputGeoPoint(lat: latitude, long: longitude)
+ selfExpires = 86400
+ case let .location(latitude, longitude):
+ geoPoint = .inputGeoPoint(lat: latitude, long: longitude)
+ case .invisible:
+ flags |= (1 << 0)
+ geoPoint = .inputGeoPointEmpty
+ selfExpires = 0
+ }
+
+ if background {
+ flags |= (1 << 1)
+ }
+
+ return network.request(Api.functions.contacts.getLocated(flags: flags, geoPoint: geoPoint, selfExpires: selfExpires))
+ |> map(Optional.init)
+ |> `catch` { _ -> Signal in
+ return .single(nil)
+ }
+ |> mapToSignal { updates -> Signal in
+ if let updates = updates {
+ stateManager.addUpdates(updates)
+ }
+ return .complete()
+ }
}
public final class PeersNearbyContext {
@@ -23,10 +68,10 @@ public final class PeersNearbyContext {
private var entries: [PeerNearby]?
- public init(network: Network, accountStateManager: AccountStateManager, coordinate: (latitude: Double, longitude: Double)) {
+ public init(network: Network, stateManager: AccountStateManager, coordinate: (latitude: Double, longitude: Double)) {
let expiryExtension: Double = 10.0
- let poll = network.request(Api.functions.contacts.getLocated(geoPoint: .inputGeoPoint(lat: coordinate.latitude, long: coordinate.longitude)))
+ let poll = network.request(Api.functions.contacts.getLocated(flags: 0, geoPoint: .inputGeoPoint(lat: coordinate.latitude, long: coordinate.longitude), selfExpires: nil))
|> map(Optional.init)
|> `catch` { _ -> Signal in
return .single(nil)
@@ -39,23 +84,28 @@ public final class PeersNearbyContext {
case let .updates(updates, _, _, _, _):
for update in updates {
if case let .updatePeerLocated(peers) = update {
- for case let .peerLocated(peer, expires, distance) in peers {
- peersNearby.append(PeerNearby(id: peer.peerId, expires: expires, distance: distance))
+ for peer in peers {
+ switch peer {
+ case let .peerLocated(peer, expires, distance):
+ peersNearby.append(.peer(id: peer.peerId, expires: expires, distance: distance))
+ case let .peerSelfLocated(expires):
+ peersNearby.append(.selfPeer(expires: expires))
+ }
}
}
}
default:
break
}
- accountStateManager.addUpdates(updates)
+ stateManager.addUpdates(updates)
}
return .single(peersNearby)
|> then(
- accountStateManager.updatedPeersNearby()
+ stateManager.updatedPeersNearby()
|> castError(Void.self)
)
}
-
+
let error: Signal = .single(Void()) |> then(Signal.fail(Void()) |> suspendAwareDelay(25.0, queue: self.queue))
let combined = combineLatest(poll, error)
|> map { data, _ -> [PeerNearby] in
@@ -77,18 +127,37 @@ public final class PeersNearbyContext {
let updatedEntries = updatedEntries.filter { Double($0.expires) + expiryExtension > timestamp }
var existingPeerIds: [PeerId: Int] = [:]
+ var existingSelfPeer: Int?
for i in 0 ..< entries.count {
- existingPeerIds[entries[i].id] = i
+ if case let .peer(id, _, _) = entries[i] {
+ existingPeerIds[id] = i
+ } else if case .selfPeer = entries[i] {
+ existingSelfPeer = i
+ }
}
+ var selfPeer: PeerNearby?
for entry in updatedEntries {
- if let index = existingPeerIds[entry.id] {
- entries[index] = entry
- } else {
- entries.append(entry)
+ switch entry {
+ case let .selfPeer:
+ if let index = existingSelfPeer {
+ entries[index] = entry
+ } else {
+ selfPeer = entry
+ }
+ case let .peer(id, _, _):
+ if let index = existingPeerIds[id] {
+ entries[index] = entry
+ } else {
+ entries.append(entry)
+ }
}
}
+ if let peer = selfPeer {
+ entries.insert(peer, at: 0)
+ }
+
strongSelf.entries = entries
for subscriber in strongSelf.subscribers.copyItems() {
subscriber(strongSelf.entries)
diff --git a/submodules/TelegramCore/Sources/Serialization.swift b/submodules/TelegramCore/Sources/Serialization.swift
index 02470ccbac..15b20dd3d8 100644
--- a/submodules/TelegramCore/Sources/Serialization.swift
+++ b/submodules/TelegramCore/Sources/Serialization.swift
@@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
- return 109
+ return 110
}
public func parseMessage(_ data: Data!) -> Any! {
diff --git a/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift
index d5c0b31029..44751ce910 100644
--- a/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift
+++ b/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift
@@ -386,6 +386,8 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Strikethrough))
case let .messageEntityBlockquote(offset, length):
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .BlockQuote))
+ case let .messageEntityBankCard(offset, length):
+ result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .BankCard))
}
}
return result
diff --git a/submodules/TelegramCore/Sources/TextEntitiesMessageAttribute.swift b/submodules/TelegramCore/Sources/TextEntitiesMessageAttribute.swift
index c898bed30f..1702002184 100644
--- a/submodules/TelegramCore/Sources/TextEntitiesMessageAttribute.swift
+++ b/submodules/TelegramCore/Sources/TextEntitiesMessageAttribute.swift
@@ -45,6 +45,8 @@ func apiEntitiesFromMessageTextEntities(_ entities: [MessageTextEntity], associa
apiEntities.append(.messageEntityBlockquote(offset: offset, length: length))
case .Underline:
apiEntities.append(.messageEntityUnderline(offset: offset, length: length))
+ case .BankCard:
+ apiEntities.append(.messageEntityBankCard(offset: offset, length: length))
case .Custom:
break
}
diff --git a/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift
index 1050b92be7..d0f10bfb51 100644
--- a/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift
+++ b/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift
@@ -450,6 +450,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
.withUpdatedSlowModeTimeout(slowmodeSeconds)
.withUpdatedSlowModeValidUntilTimestamp(slowmodeNextSendDate)
.withUpdatedHasScheduledMessages(hasScheduledMessages)
+// .withUpdatedStatsDatacenterId(statsDc ?? 0)
})
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {
diff --git a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift
index f55acaf222..188fb8bab7 100644
--- a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift
+++ b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift
@@ -334,4899 +334,4909 @@ public final class PresentationStrings: Equatable {
public var SettingsSearch_Synonyms_EditProfile_Username: String { return self._s[136]! }
public var Group_Username_InvalidStartsWithNumber: String { return self._s[137]! }
public var UserInfo_NotificationsEnabled: String { return self._s[138]! }
- public var Map_Search: String { return self._s[139]! }
- public var ClearCache_StorageFree: String { return self._s[141]! }
- public var Login_TermsOfServiceHeader: String { return self._s[142]! }
+ public var PeopleNearby_MakeVisibleDescription: String { return self._s[139]! }
+ public var Map_Search: String { return self._s[140]! }
+ public var ClearCache_StorageFree: String { return self._s[142]! }
+ public var Login_TermsOfServiceHeader: String { return self._s[143]! }
public func Notification_PinnedVideoMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[143]!, self._r[143]!, [_0])
+ return formatWithArgumentRanges(self._s[144]!, self._r[144]!, [_0])
}
public func Channel_AdminLog_MessageToggleSignaturesOn(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[145]!, self._r[145]!, [_0])
+ return formatWithArgumentRanges(self._s[146]!, self._r[146]!, [_0])
}
- public var Wallet_Sent_Title: String { return self._s[146]! }
- public var TwoStepAuth_SetupPasswordConfirmPassword: String { return self._s[147]! }
- public var Weekday_Today: String { return self._s[148]! }
+ public var Wallet_Sent_Title: String { return self._s[147]! }
+ public var TwoStepAuth_SetupPasswordConfirmPassword: String { return self._s[148]! }
+ public var Weekday_Today: String { return self._s[149]! }
public func InstantPage_AuthorAndDateTitle(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[150]!, self._r[150]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[151]!, self._r[151]!, [_1, _2])
}
public func Conversation_MessageDialogRetryAll(_ _1: Int) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[151]!, self._r[151]!, ["\(_1)"])
+ return formatWithArgumentRanges(self._s[152]!, self._r[152]!, ["\(_1)"])
}
- public var Notification_PassportValuePersonalDetails: String { return self._s[153]! }
- public var Channel_AdminLog_MessagePreviousLink: String { return self._s[154]! }
- public var ChangePhoneNumberNumber_NewNumber: String { return self._s[155]! }
- public var ApplyLanguage_LanguageNotSupportedError: String { return self._s[156]! }
- public var TwoStepAuth_ChangePasswordDescription: String { return self._s[157]! }
- public var PhotoEditor_BlurToolLinear: String { return self._s[158]! }
- public var Contacts_PermissionsAllowInSettings: String { return self._s[159]! }
- public var Weekday_ShortMonday: String { return self._s[160]! }
- public var Cache_KeepMedia: String { return self._s[161]! }
- public var Passport_FieldIdentitySelfieHelp: String { return self._s[162]! }
+ public var Notification_PassportValuePersonalDetails: String { return self._s[154]! }
+ public var Channel_AdminLog_MessagePreviousLink: String { return self._s[155]! }
+ public var ChangePhoneNumberNumber_NewNumber: String { return self._s[156]! }
+ public var ApplyLanguage_LanguageNotSupportedError: String { return self._s[157]! }
+ public var TwoStepAuth_ChangePasswordDescription: String { return self._s[158]! }
+ public var PhotoEditor_BlurToolLinear: String { return self._s[159]! }
+ public var Contacts_PermissionsAllowInSettings: String { return self._s[160]! }
+ public var Weekday_ShortMonday: String { return self._s[161]! }
+ public var Cache_KeepMedia: String { return self._s[162]! }
+ public var Passport_FieldIdentitySelfieHelp: String { return self._s[163]! }
public func PUSH_PINNED_STICKER(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[163]!, self._r[163]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[164]!, self._r[164]!, [_1, _2])
}
public func Chat_SlowmodeTooltip(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[164]!, self._r[164]!, [_0])
+ return formatWithArgumentRanges(self._s[165]!, self._r[165]!, [_0])
}
- public var Wallet_Receive_ShareUrlInfo: String { return self._s[165]! }
- public var Conversation_ClousStorageInfo_Description4: String { return self._s[166]! }
- public var Wallet_RestoreFailed_Title: String { return self._s[167]! }
- public var Passport_Language_ru: String { return self._s[168]! }
+ public var Wallet_Receive_ShareUrlInfo: String { return self._s[166]! }
+ public var Conversation_ClousStorageInfo_Description4: String { return self._s[167]! }
+ public var Wallet_RestoreFailed_Title: String { return self._s[168]! }
+ public var Passport_Language_ru: String { return self._s[169]! }
public func Notification_CreatedChatWithTitle(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[169]!, self._r[169]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[170]!, self._r[170]!, [_0, _1])
}
- public var WallpaperPreview_PatternIntensity: String { return self._s[170]! }
- public var WebBrowser_InAppSafari: String { return self._s[173]! }
- public var TwoStepAuth_RecoveryUnavailable: String { return self._s[174]! }
- public var EnterPasscode_TouchId: String { return self._s[175]! }
- public var PhotoEditor_QualityVeryHigh: String { return self._s[178]! }
- public var Checkout_NewCard_SaveInfo: String { return self._s[180]! }
- public var Gif_NoGifsPlaceholder: String { return self._s[182]! }
+ public var WallpaperPreview_PatternIntensity: String { return self._s[171]! }
+ public var WebBrowser_InAppSafari: String { return self._s[174]! }
+ public var TwoStepAuth_RecoveryUnavailable: String { return self._s[175]! }
+ public var EnterPasscode_TouchId: String { return self._s[176]! }
+ public var PhotoEditor_QualityVeryHigh: String { return self._s[179]! }
+ public var Checkout_NewCard_SaveInfo: String { return self._s[181]! }
+ public var Gif_NoGifsPlaceholder: String { return self._s[183]! }
public func Notification_InvitedMultiple(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[184]!, self._r[184]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[185]!, self._r[185]!, [_0, _1])
}
- public var ChatSettings_AutoDownloadEnabled: String { return self._s[185]! }
- public var NetworkUsageSettings_BytesSent: String { return self._s[186]! }
- public var Checkout_PasswordEntry_Pay: String { return self._s[187]! }
- public var AuthSessions_TerminateSession: String { return self._s[188]! }
- public var Message_File: String { return self._s[189]! }
- public var MediaPicker_VideoMuteDescription: String { return self._s[190]! }
- public var SocksProxySetup_ProxyStatusConnected: String { return self._s[191]! }
- public var TwoStepAuth_RecoveryCode: String { return self._s[192]! }
- public var EnterPasscode_EnterCurrentPasscode: String { return self._s[193]! }
+ public var ChatSettings_AutoDownloadEnabled: String { return self._s[186]! }
+ public var NetworkUsageSettings_BytesSent: String { return self._s[187]! }
+ public var Checkout_PasswordEntry_Pay: String { return self._s[188]! }
+ public var AuthSessions_TerminateSession: String { return self._s[189]! }
+ public var Message_File: String { return self._s[190]! }
+ public var MediaPicker_VideoMuteDescription: String { return self._s[191]! }
+ public var SocksProxySetup_ProxyStatusConnected: String { return self._s[192]! }
+ public var TwoStepAuth_RecoveryCode: String { return self._s[193]! }
+ public var EnterPasscode_EnterCurrentPasscode: String { return self._s[194]! }
public func TwoStepAuth_EnterPasswordHint(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[194]!, self._r[194]!, [_0])
+ return formatWithArgumentRanges(self._s[195]!, self._r[195]!, [_0])
}
- public var Conversation_Moderate_Report: String { return self._s[196]! }
- public var TwoStepAuth_EmailInvalid: String { return self._s[197]! }
- public var Passport_Language_ms: String { return self._s[198]! }
- public var Channel_Edit_AboutItem: String { return self._s[200]! }
- public var DialogList_SearchSectionGlobal: String { return self._s[204]! }
- public var AttachmentMenu_WebSearch: String { return self._s[205]! }
- public var PasscodeSettings_TurnPasscodeOn: String { return self._s[206]! }
- public var Channel_BanUser_Title: String { return self._s[207]! }
- public var WallpaperPreview_SwipeTopText: String { return self._s[208]! }
- public var ChatList_DeleteSavedMessagesConfirmationText: String { return self._s[209]! }
- public var ArchivedChats_IntroText2: String { return self._s[210]! }
- public var Conversation_OpenBotLinkTitle: String { return self._s[211]! }
- public var ChatSearch_SearchPlaceholder: String { return self._s[213]! }
- public var Notification_Exceptions_DeleteAll: String { return self._s[214]! }
- public var Passport_FieldAddressTranslationHelp: String { return self._s[215]! }
- public var NotificationsSound_Aurora: String { return self._s[216]! }
+ public var Conversation_Moderate_Report: String { return self._s[197]! }
+ public var TwoStepAuth_EmailInvalid: String { return self._s[198]! }
+ public var Passport_Language_ms: String { return self._s[199]! }
+ public var Channel_Edit_AboutItem: String { return self._s[201]! }
+ public var DialogList_SearchSectionGlobal: String { return self._s[205]! }
+ public var AttachmentMenu_WebSearch: String { return self._s[206]! }
+ public var PasscodeSettings_TurnPasscodeOn: String { return self._s[207]! }
+ public var Channel_BanUser_Title: String { return self._s[208]! }
+ public var WallpaperPreview_SwipeTopText: String { return self._s[209]! }
+ public var ChatList_DeleteSavedMessagesConfirmationText: String { return self._s[210]! }
+ public var ArchivedChats_IntroText2: String { return self._s[211]! }
+ public var Conversation_OpenBotLinkTitle: String { return self._s[212]! }
+ public var ChatSearch_SearchPlaceholder: String { return self._s[214]! }
+ public var Notification_Exceptions_DeleteAll: String { return self._s[215]! }
+ public var Passport_FieldAddressTranslationHelp: String { return self._s[216]! }
+ public var NotificationsSound_Aurora: String { return self._s[217]! }
public func Channel_AdminLog_MessageTransferedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[217]!, self._r[217]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[218]!, self._r[218]!, [_1, _2])
}
public func FileSize_GB(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[218]!, self._r[218]!, [_0])
+ return formatWithArgumentRanges(self._s[219]!, self._r[219]!, [_0])
}
- public var AuthSessions_LoggedInWithTelegram: String { return self._s[221]! }
+ public var AuthSessions_LoggedInWithTelegram: String { return self._s[222]! }
public func Privacy_GroupsAndChannels_InviteToGroupError(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[222]!, self._r[222]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[223]!, self._r[223]!, [_0, _1])
}
- public var Passport_PasswordNext: String { return self._s[223]! }
- public var Bot_GroupStatusReadsHistory: String { return self._s[224]! }
- public var EmptyGroupInfo_Line2: String { return self._s[225]! }
- public var VoiceOver_Chat_SeenByRecipients: String { return self._s[226]! }
- public var Settings_FAQ_Intro: String { return self._s[229]! }
- public var PrivacySettings_PasscodeAndTouchId: String { return self._s[231]! }
- public var FeaturedStickerPacks_Title: String { return self._s[232]! }
- public var TwoStepAuth_PasswordRemoveConfirmation: String { return self._s[234]! }
- public var Username_Title: String { return self._s[235]! }
+ public var Passport_PasswordNext: String { return self._s[224]! }
+ public var Bot_GroupStatusReadsHistory: String { return self._s[225]! }
+ public var EmptyGroupInfo_Line2: String { return self._s[226]! }
+ public var VoiceOver_Chat_SeenByRecipients: String { return self._s[227]! }
+ public var Settings_FAQ_Intro: String { return self._s[230]! }
+ public var PrivacySettings_PasscodeAndTouchId: String { return self._s[232]! }
+ public var FeaturedStickerPacks_Title: String { return self._s[233]! }
+ public var TwoStepAuth_PasswordRemoveConfirmation: String { return self._s[235]! }
+ public var Username_Title: String { return self._s[236]! }
public func Message_StickerText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[236]!, self._r[236]!, [_0])
+ return formatWithArgumentRanges(self._s[237]!, self._r[237]!, [_0])
}
- public var PasscodeSettings_AlphanumericCode: String { return self._s[237]! }
- public var Localization_LanguageOther: String { return self._s[238]! }
- public var Stickers_SuggestStickers: String { return self._s[239]! }
+ public var PasscodeSettings_AlphanumericCode: String { return self._s[238]! }
+ public var Localization_LanguageOther: String { return self._s[239]! }
+ public var Stickers_SuggestStickers: String { return self._s[240]! }
public func Channel_AdminLog_MessageRemovedGroupUsername(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[240]!, self._r[240]!, [_0])
+ return formatWithArgumentRanges(self._s[241]!, self._r[241]!, [_0])
}
- public var NotificationSettings_ShowNotificationsFromAccountsSection: String { return self._s[241]! }
- public var Channel_AdminLogFilter_EventsAdmins: String { return self._s[242]! }
- public var Conversation_DefaultRestrictedStickers: String { return self._s[243]! }
+ public var NotificationSettings_ShowNotificationsFromAccountsSection: String { return self._s[242]! }
+ public var Channel_AdminLogFilter_EventsAdmins: String { return self._s[243]! }
+ public var Conversation_DefaultRestrictedStickers: String { return self._s[244]! }
public func Notification_PinnedDeletedMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[244]!, self._r[244]!, [_0])
+ return formatWithArgumentRanges(self._s[245]!, self._r[245]!, [_0])
}
- public var Wallet_TransactionInfo_CopyAddress: String { return self._s[246]! }
- public var Group_UpgradeConfirmation: String { return self._s[247]! }
- public var DialogList_Unpin: String { return self._s[248]! }
- public var Passport_Identity_DateOfBirth: String { return self._s[249]! }
- public var Month_ShortOctober: String { return self._s[250]! }
- public var SettingsSearch_Synonyms_Privacy_Data_ContactsSync: String { return self._s[251]! }
- public var TwoFactorSetup_Done_Text: String { return self._s[252]! }
- public var Notification_CallCanceledShort: String { return self._s[253]! }
- public var Conversation_StopQuiz: String { return self._s[254]! }
- public var Passport_Phone_Help: String { return self._s[255]! }
- public var Passport_Language_az: String { return self._s[257]! }
- public var CreatePoll_TextPlaceholder: String { return self._s[259]! }
- public var VoiceOver_Chat_AnonymousPoll: String { return self._s[260]! }
- public var Passport_Identity_DocumentNumber: String { return self._s[261]! }
- public var PhotoEditor_CurvesRed: String { return self._s[262]! }
- public var PhoneNumberHelp_Alert: String { return self._s[264]! }
- public var SocksProxySetup_Port: String { return self._s[265]! }
- public var Checkout_PayNone: String { return self._s[266]! }
- public var AutoDownloadSettings_WiFi: String { return self._s[267]! }
- public var GroupInfo_GroupType: String { return self._s[268]! }
- public var StickerSettings_ContextHide: String { return self._s[269]! }
- public var Passport_Address_OneOfTypeTemporaryRegistration: String { return self._s[270]! }
- public var Group_Setup_HistoryTitle: String { return self._s[272]! }
- public var Passport_Identity_FilesUploadNew: String { return self._s[273]! }
- public var PasscodeSettings_AutoLock: String { return self._s[274]! }
- public var Passport_Title: String { return self._s[275]! }
- public var VoiceOver_Chat_ContactPhoneNumber: String { return self._s[276]! }
- public var Channel_AdminLogFilter_EventsNewSubscribers: String { return self._s[277]! }
- public var GroupPermission_NoSendGifs: String { return self._s[278]! }
- public var PrivacySettings_PasscodeOn: String { return self._s[279]! }
+ public var Wallet_TransactionInfo_CopyAddress: String { return self._s[247]! }
+ public var Group_UpgradeConfirmation: String { return self._s[248]! }
+ public var DialogList_Unpin: String { return self._s[249]! }
+ public var Passport_Identity_DateOfBirth: String { return self._s[250]! }
+ public var Month_ShortOctober: String { return self._s[251]! }
+ public var SettingsSearch_Synonyms_Privacy_Data_ContactsSync: String { return self._s[252]! }
+ public var TwoFactorSetup_Done_Text: String { return self._s[253]! }
+ public var Notification_CallCanceledShort: String { return self._s[254]! }
+ public var Conversation_StopQuiz: String { return self._s[255]! }
+ public var Passport_Phone_Help: String { return self._s[256]! }
+ public var Passport_Language_az: String { return self._s[258]! }
+ public var CreatePoll_TextPlaceholder: String { return self._s[260]! }
+ public var VoiceOver_Chat_AnonymousPoll: String { return self._s[261]! }
+ public var Passport_Identity_DocumentNumber: String { return self._s[262]! }
+ public var PhotoEditor_CurvesRed: String { return self._s[263]! }
+ public var PhoneNumberHelp_Alert: String { return self._s[265]! }
+ public var SocksProxySetup_Port: String { return self._s[266]! }
+ public var Checkout_PayNone: String { return self._s[267]! }
+ public var AutoDownloadSettings_WiFi: String { return self._s[268]! }
+ public var GroupInfo_GroupType: String { return self._s[269]! }
+ public var StickerSettings_ContextHide: String { return self._s[270]! }
+ public var Passport_Address_OneOfTypeTemporaryRegistration: String { return self._s[271]! }
+ public var Group_Setup_HistoryTitle: String { return self._s[273]! }
+ public var Passport_Identity_FilesUploadNew: String { return self._s[274]! }
+ public var PasscodeSettings_AutoLock: String { return self._s[275]! }
+ public var Passport_Title: String { return self._s[276]! }
+ public var VoiceOver_Chat_ContactPhoneNumber: String { return self._s[277]! }
+ public var Channel_AdminLogFilter_EventsNewSubscribers: String { return self._s[278]! }
+ public var GroupPermission_NoSendGifs: String { return self._s[279]! }
+ public var PrivacySettings_PasscodeOn: String { return self._s[280]! }
public func Conversation_ScheduleMessage_SendTomorrow(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[280]!, self._r[280]!, [_0])
+ return formatWithArgumentRanges(self._s[281]!, self._r[281]!, [_0])
}
- public var State_WaitingForNetwork: String { return self._s[283]! }
+ public var State_WaitingForNetwork: String { return self._s[284]! }
public func Notification_Invited(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[284]!, self._r[284]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[285]!, self._r[285]!, [_0, _1])
}
- public var Calls_NotNow: String { return self._s[286]! }
+ public var Calls_NotNow: String { return self._s[287]! }
public func Channel_DiscussionGroup_HeaderSet(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[287]!, self._r[287]!, [_0])
+ return formatWithArgumentRanges(self._s[288]!, self._r[288]!, [_0])
}
- public var UserInfo_SendMessage: String { return self._s[288]! }
- public var TwoStepAuth_PasswordSet: String { return self._s[289]! }
- public var Passport_DeleteDocument: String { return self._s[290]! }
- public var SocksProxySetup_AddProxyTitle: String { return self._s[291]! }
+ public var UserInfo_SendMessage: String { return self._s[289]! }
+ public var TwoStepAuth_PasswordSet: String { return self._s[290]! }
+ public var Passport_DeleteDocument: String { return self._s[291]! }
+ public var SocksProxySetup_AddProxyTitle: String { return self._s[292]! }
public func PUSH_MESSAGE_VIDEO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[292]!, self._r[292]!, [_1])
+ return formatWithArgumentRanges(self._s[293]!, self._r[293]!, [_1])
}
- public var AuthSessions_AddedDeviceTitle: String { return self._s[293]! }
- public var GroupRemoved_Remove: String { return self._s[294]! }
- public var Passport_FieldIdentity: String { return self._s[295]! }
- public var Group_Setup_TypePrivateHelp: String { return self._s[296]! }
- public var Conversation_Processing: String { return self._s[299]! }
- public var Wallet_Settings_BackupWallet: String { return self._s[301]! }
- public var ChatSettings_AutoPlayAnimations: String { return self._s[302]! }
- public var AuthSessions_LogOutApplicationsHelp: String { return self._s[305]! }
- public var Forward_ErrorPublicQuizDisabledInChannels: String { return self._s[306]! }
- public var Month_GenFebruary: String { return self._s[307]! }
- public var Wallet_Send_NetworkErrorTitle: String { return self._s[308]! }
+ public var AuthSessions_AddedDeviceTitle: String { return self._s[294]! }
+ public var GroupRemoved_Remove: String { return self._s[295]! }
+ public var Passport_FieldIdentity: String { return self._s[296]! }
+ public var Group_Setup_TypePrivateHelp: String { return self._s[297]! }
+ public var Conversation_Processing: String { return self._s[300]! }
+ public var Wallet_Settings_BackupWallet: String { return self._s[302]! }
+ public var ChatSettings_AutoPlayAnimations: String { return self._s[303]! }
+ public var AuthSessions_LogOutApplicationsHelp: String { return self._s[306]! }
+ public var Forward_ErrorPublicQuizDisabledInChannels: String { return self._s[307]! }
+ public var Month_GenFebruary: String { return self._s[308]! }
+ public var Wallet_Send_NetworkErrorTitle: String { return self._s[309]! }
public func Login_InvalidPhoneEmailBody(_ _1: String, _ _2: String, _ _3: String, _ _4: String, _ _5: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[310]!, self._r[310]!, [_1, _2, _3, _4, _5])
+ return formatWithArgumentRanges(self._s[311]!, self._r[311]!, [_1, _2, _3, _4, _5])
}
- public var Passport_Identity_TypeIdentityCard: String { return self._s[311]! }
- public var Wallet_Month_ShortJune: String { return self._s[313]! }
- public var AutoDownloadSettings_DataUsageMedium: String { return self._s[314]! }
- public var GroupInfo_AddParticipant: String { return self._s[315]! }
- public var KeyCommand_SendMessage: String { return self._s[316]! }
- public var VoiceOver_Chat_YourContact: String { return self._s[318]! }
- public var Map_LiveLocationShowAll: String { return self._s[319]! }
- public var WallpaperSearch_ColorOrange: String { return self._s[321]! }
- public var Appearance_AppIconDefaultX: String { return self._s[322]! }
- public var Checkout_Receipt_Title: String { return self._s[323]! }
- public var Group_OwnershipTransfer_ErrorPrivacyRestricted: String { return self._s[324]! }
- public var WallpaperPreview_PreviewTopText: String { return self._s[325]! }
- public var Message_Contact: String { return self._s[326]! }
- public var Call_StatusIncoming: String { return self._s[327]! }
- public var Wallet_TransactionInfo_StorageFeeInfo: String { return self._s[328]! }
+ public var Passport_Identity_TypeIdentityCard: String { return self._s[312]! }
+ public var Wallet_Month_ShortJune: String { return self._s[314]! }
+ public var AutoDownloadSettings_DataUsageMedium: String { return self._s[315]! }
+ public var GroupInfo_AddParticipant: String { return self._s[316]! }
+ public var KeyCommand_SendMessage: String { return self._s[317]! }
+ public var VoiceOver_Chat_YourContact: String { return self._s[319]! }
+ public var Map_LiveLocationShowAll: String { return self._s[320]! }
+ public var WallpaperSearch_ColorOrange: String { return self._s[322]! }
+ public var Appearance_AppIconDefaultX: String { return self._s[323]! }
+ public var Checkout_Receipt_Title: String { return self._s[324]! }
+ public var Group_OwnershipTransfer_ErrorPrivacyRestricted: String { return self._s[325]! }
+ public var WallpaperPreview_PreviewTopText: String { return self._s[326]! }
+ public var Message_Contact: String { return self._s[327]! }
+ public var Call_StatusIncoming: String { return self._s[328]! }
+ public var Wallet_TransactionInfo_StorageFeeInfo: String { return self._s[329]! }
public func Channel_AdminLog_MessageKickedName(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[329]!, self._r[329]!, [_1])
+ return formatWithArgumentRanges(self._s[330]!, self._r[330]!, [_1])
}
public func PUSH_ENCRYPTED_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[331]!, self._r[331]!, [_1])
+ return formatWithArgumentRanges(self._s[332]!, self._r[332]!, [_1])
}
- public var VoiceOver_Media_PlaybackRate: String { return self._s[332]! }
- public var Passport_FieldIdentityDetailsHelp: String { return self._s[333]! }
- public var Conversation_ViewChannel: String { return self._s[334]! }
+ public var VoiceOver_Media_PlaybackRate: String { return self._s[333]! }
+ public var Passport_FieldIdentityDetailsHelp: String { return self._s[334]! }
+ public var Conversation_ViewChannel: String { return self._s[335]! }
public func Time_TodayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[335]!, self._r[335]!, [_0])
+ return formatWithArgumentRanges(self._s[336]!, self._r[336]!, [_0])
}
- public var Theme_Colors_Accent: String { return self._s[336]! }
- public var Passport_Language_nl: String { return self._s[338]! }
- public var Camera_Retake: String { return self._s[339]! }
+ public var Theme_Colors_Accent: String { return self._s[337]! }
+ public var Passport_Language_nl: String { return self._s[339]! }
+ public var Camera_Retake: String { return self._s[340]! }
public func UserInfo_BlockActionTitle(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[340]!, self._r[340]!, [_0])
+ return formatWithArgumentRanges(self._s[341]!, self._r[341]!, [_0])
}
- public var AuthSessions_LogOutApplications: String { return self._s[341]! }
- public var ApplyLanguage_ApplySuccess: String { return self._s[342]! }
- public var Tour_Title6: String { return self._s[343]! }
- public var Map_ChooseAPlace: String { return self._s[344]! }
- public var CallSettings_Never: String { return self._s[346]! }
+ public var AuthSessions_LogOutApplications: String { return self._s[342]! }
+ public var ApplyLanguage_ApplySuccess: String { return self._s[343]! }
+ public var Tour_Title6: String { return self._s[344]! }
+ public var Map_ChooseAPlace: String { return self._s[345]! }
+ public var CallSettings_Never: String { return self._s[347]! }
public func Notification_ChangedGroupPhoto(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[347]!, self._r[347]!, [_0])
+ return formatWithArgumentRanges(self._s[348]!, self._r[348]!, [_0])
}
- public var ChannelRemoved_RemoveInfo: String { return self._s[348]! }
+ public var ChannelRemoved_RemoveInfo: String { return self._s[349]! }
public func AutoDownloadSettings_PreloadVideoInfo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[349]!, self._r[349]!, [_0])
+ return formatWithArgumentRanges(self._s[350]!, self._r[350]!, [_0])
}
- public var SettingsSearch_Synonyms_Notifications_MessageNotificationsExceptions: String { return self._s[350]! }
+ public var SettingsSearch_Synonyms_Notifications_MessageNotificationsExceptions: String { return self._s[351]! }
public func Conversation_ClearChatConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[351]!, self._r[351]!, [_0])
+ return formatWithArgumentRanges(self._s[352]!, self._r[352]!, [_0])
}
- public var GroupInfo_InviteLink_Title: String { return self._s[352]! }
+ public var GroupInfo_InviteLink_Title: String { return self._s[353]! }
public func Channel_AdminLog_MessageUnkickedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[353]!, self._r[353]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[354]!, self._r[354]!, [_1, _2])
}
- public var KeyCommand_ScrollUp: String { return self._s[354]! }
- public var ContactInfo_URLLabelHomepage: String { return self._s[355]! }
- public var Channel_OwnershipTransfer_ChangeOwner: String { return self._s[356]! }
+ public var KeyCommand_ScrollUp: String { return self._s[355]! }
+ public var ContactInfo_URLLabelHomepage: String { return self._s[356]! }
+ public var Channel_OwnershipTransfer_ChangeOwner: String { return self._s[357]! }
public func Channel_AdminLog_DisabledSlowmode(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[357]!, self._r[357]!, [_0])
+ return formatWithArgumentRanges(self._s[358]!, self._r[358]!, [_0])
}
- public var TwoFactorSetup_Done_Title: String { return self._s[358]! }
+ public var TwoFactorSetup_Done_Title: String { return self._s[359]! }
public func Conversation_EncryptedPlaceholderTitleOutgoing(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[359]!, self._r[359]!, [_0])
+ return formatWithArgumentRanges(self._s[360]!, self._r[360]!, [_0])
}
- public var CallFeedback_ReasonDistortedSpeech: String { return self._s[360]! }
- public var Watch_LastSeen_WithinAWeek: String { return self._s[361]! }
- public var ContactList_Context_SendMessage: String { return self._s[363]! }
- public var Weekday_Tuesday: String { return self._s[364]! }
- public var Wallet_Created_Title: String { return self._s[366]! }
- public var ScheduledMessages_Delete: String { return self._s[367]! }
- public var UserInfo_StartSecretChat: String { return self._s[368]! }
- public var Passport_Identity_FilesTitle: String { return self._s[369]! }
- public var Permissions_NotificationsAllow_v0: String { return self._s[370]! }
- public var DialogList_DeleteConversationConfirmation: String { return self._s[372]! }
- public var ChatList_UndoArchiveRevealedTitle: String { return self._s[373]! }
+ public var CallFeedback_ReasonDistortedSpeech: String { return self._s[361]! }
+ public var Watch_LastSeen_WithinAWeek: String { return self._s[362]! }
+ public var ContactList_Context_SendMessage: String { return self._s[364]! }
+ public var Weekday_Tuesday: String { return self._s[365]! }
+ public var Wallet_Created_Title: String { return self._s[367]! }
+ public var ScheduledMessages_Delete: String { return self._s[368]! }
+ public var UserInfo_StartSecretChat: String { return self._s[369]! }
+ public var Passport_Identity_FilesTitle: String { return self._s[370]! }
+ public var Permissions_NotificationsAllow_v0: String { return self._s[371]! }
+ public var DialogList_DeleteConversationConfirmation: String { return self._s[373]! }
+ public var ChatList_UndoArchiveRevealedTitle: String { return self._s[374]! }
public func Wallet_Configuration_ApplyErrorTextURLUnreachable(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[374]!, self._r[374]!, [_0])
+ return formatWithArgumentRanges(self._s[375]!, self._r[375]!, [_0])
}
- public var AuthSessions_Sessions: String { return self._s[375]! }
+ public var AuthSessions_Sessions: String { return self._s[376]! }
public func Settings_KeepPhoneNumber(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[377]!, self._r[377]!, [_0])
+ return formatWithArgumentRanges(self._s[378]!, self._r[378]!, [_0])
}
- public var TwoStepAuth_RecoveryEmailChangeDescription: String { return self._s[378]! }
- public var Call_StatusWaiting: String { return self._s[379]! }
- public var CreateGroup_SoftUserLimitAlert: String { return self._s[380]! }
- public var FastTwoStepSetup_HintHelp: String { return self._s[381]! }
- public var WallpaperPreview_CustomColorBottomText: String { return self._s[382]! }
- public var EditTheme_Expand_Preview_OutgoingText: String { return self._s[383]! }
- public var LogoutOptions_AddAccountText: String { return self._s[384]! }
- public var PasscodeSettings_6DigitCode: String { return self._s[385]! }
- public var Settings_LogoutConfirmationText: String { return self._s[386]! }
- public var Passport_Identity_TypePassport: String { return self._s[388]! }
- public var Map_Work: String { return self._s[391]! }
+ public var TwoStepAuth_RecoveryEmailChangeDescription: String { return self._s[379]! }
+ public var Call_StatusWaiting: String { return self._s[380]! }
+ public var CreateGroup_SoftUserLimitAlert: String { return self._s[381]! }
+ public var FastTwoStepSetup_HintHelp: String { return self._s[382]! }
+ public var WallpaperPreview_CustomColorBottomText: String { return self._s[383]! }
+ public var EditTheme_Expand_Preview_OutgoingText: String { return self._s[384]! }
+ public var LogoutOptions_AddAccountText: String { return self._s[385]! }
+ public var PasscodeSettings_6DigitCode: String { return self._s[386]! }
+ public var Settings_LogoutConfirmationText: String { return self._s[387]! }
+ public var Passport_Identity_TypePassport: String { return self._s[389]! }
+ public var Map_Work: String { return self._s[392]! }
public func PUSH_MESSAGE_VIDEOS(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[392]!, self._r[392]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[393]!, self._r[393]!, [_1, _2])
}
- public var SocksProxySetup_SaveProxy: String { return self._s[393]! }
- public var AccessDenied_SaveMedia: String { return self._s[394]! }
- public var Checkout_ErrorInvoiceAlreadyPaid: String { return self._s[396]! }
- public var CreatePoll_MultipleChoice: String { return self._s[397]! }
- public var Settings_Title: String { return self._s[399]! }
- public var VoiceOver_Chat_RecordModeVideoMessageInfo: String { return self._s[400]! }
- public var Contacts_InviteSearchLabel: String { return self._s[402]! }
- public var PrivacySettings_WebSessions: String { return self._s[403]! }
- public var ConvertToSupergroup_Title: String { return self._s[404]! }
+ public var SocksProxySetup_SaveProxy: String { return self._s[394]! }
+ public var AccessDenied_SaveMedia: String { return self._s[395]! }
+ public var Checkout_ErrorInvoiceAlreadyPaid: String { return self._s[397]! }
+ public var CreatePoll_MultipleChoice: String { return self._s[398]! }
+ public var Settings_Title: String { return self._s[400]! }
+ public var VoiceOver_Chat_RecordModeVideoMessageInfo: String { return self._s[401]! }
+ public var Contacts_InviteSearchLabel: String { return self._s[403]! }
+ public var PrivacySettings_WebSessions: String { return self._s[404]! }
+ public var ConvertToSupergroup_Title: String { return self._s[405]! }
public func Channel_AdminLog_CaptionEdited(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[405]!, self._r[405]!, [_0])
+ return formatWithArgumentRanges(self._s[406]!, self._r[406]!, [_0])
}
- public var TwoFactorSetup_Hint_Text: String { return self._s[406]! }
- public var InfoPlist_NSSiriUsageDescription: String { return self._s[407]! }
+ public var TwoFactorSetup_Hint_Text: String { return self._s[407]! }
+ public var InfoPlist_NSSiriUsageDescription: String { return self._s[408]! }
public func PUSH_MESSAGE_CHANNEL_MESSAGE_GAME_SCORE(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[408]!, self._r[408]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[409]!, self._r[409]!, [_1, _2, _3])
}
- public var ChatSettings_AutomaticPhotoDownload: String { return self._s[409]! }
- public var UserInfo_BotHelp: String { return self._s[410]! }
- public var PrivacySettings_LastSeenEverybody: String { return self._s[411]! }
- public var Checkout_Name: String { return self._s[412]! }
- public var AutoDownloadSettings_DataUsage: String { return self._s[413]! }
- public var Channel_BanUser_BlockFor: String { return self._s[414]! }
- public var Checkout_ShippingAddress: String { return self._s[415]! }
- public var AutoDownloadSettings_MaxVideoSize: String { return self._s[416]! }
- public var Privacy_PaymentsClearInfoDoneHelp: String { return self._s[417]! }
- public var Privacy_Forwards: String { return self._s[418]! }
- public var Channel_BanUser_PermissionSendPolls: String { return self._s[419]! }
- public var Appearance_ThemeCarouselNewNight: String { return self._s[420]! }
+ public var ChatSettings_AutomaticPhotoDownload: String { return self._s[410]! }
+ public var UserInfo_BotHelp: String { return self._s[411]! }
+ public var PrivacySettings_LastSeenEverybody: String { return self._s[412]! }
+ public var Checkout_Name: String { return self._s[413]! }
+ public var AutoDownloadSettings_DataUsage: String { return self._s[414]! }
+ public var Channel_BanUser_BlockFor: String { return self._s[415]! }
+ public var Checkout_ShippingAddress: String { return self._s[416]! }
+ public var AutoDownloadSettings_MaxVideoSize: String { return self._s[417]! }
+ public var Privacy_PaymentsClearInfoDoneHelp: String { return self._s[418]! }
+ public var Privacy_Forwards: String { return self._s[419]! }
+ public var Channel_BanUser_PermissionSendPolls: String { return self._s[420]! }
+ public var Appearance_ThemeCarouselNewNight: String { return self._s[421]! }
public func SecretVideo_NotViewedYet(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[423]!, self._r[423]!, [_0])
+ return formatWithArgumentRanges(self._s[424]!, self._r[424]!, [_0])
}
- public var Contacts_SortedByName: String { return self._s[424]! }
- public var Group_OwnershipTransfer_Title: String { return self._s[425]! }
- public var VoiceOver_Chat_OpenHint: String { return self._s[427]! }
- public var Group_LeaveGroup: String { return self._s[428]! }
- public var Settings_UsernameEmpty: String { return self._s[429]! }
+ public var Contacts_SortedByName: String { return self._s[425]! }
+ public var Group_OwnershipTransfer_Title: String { return self._s[426]! }
+ public var VoiceOver_Chat_OpenHint: String { return self._s[428]! }
+ public var Group_LeaveGroup: String { return self._s[429]! }
+ public var Settings_UsernameEmpty: String { return self._s[430]! }
public func Notification_PinnedPollMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[430]!, self._r[430]!, [_0])
+ return formatWithArgumentRanges(self._s[431]!, self._r[431]!, [_0])
}
public func TwoStepAuth_ConfirmEmailDescription(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[431]!, self._r[431]!, [_1])
+ return formatWithArgumentRanges(self._s[432]!, self._r[432]!, [_1])
}
public func Channel_OwnershipTransfer_DescriptionInfo(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[432]!, self._r[432]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[433]!, self._r[433]!, [_1, _2])
}
- public var Message_ImageExpired: String { return self._s[433]! }
- public var TwoStepAuth_RecoveryFailed: String { return self._s[435]! }
- public var EditTheme_Edit_Preview_OutgoingText: String { return self._s[436]! }
- public var UserInfo_AddToExisting: String { return self._s[437]! }
- public var TwoStepAuth_EnabledSuccess: String { return self._s[438]! }
- public var Wallet_Send_SyncInProgress: String { return self._s[439]! }
- public var SettingsSearch_Synonyms_Appearance_ChatBackground_SetColor: String { return self._s[440]! }
+ public var Message_ImageExpired: String { return self._s[434]! }
+ public var TwoStepAuth_RecoveryFailed: String { return self._s[436]! }
+ public var EditTheme_Edit_Preview_OutgoingText: String { return self._s[437]! }
+ public var UserInfo_AddToExisting: String { return self._s[438]! }
+ public var TwoStepAuth_EnabledSuccess: String { return self._s[439]! }
+ public var Wallet_Send_SyncInProgress: String { return self._s[440]! }
+ public var SettingsSearch_Synonyms_Appearance_ChatBackground_SetColor: String { return self._s[441]! }
public func PUSH_CHANNEL_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[441]!, self._r[441]!, [_1])
+ return formatWithArgumentRanges(self._s[442]!, self._r[442]!, [_1])
}
- public var Notifications_GroupNotificationsAlert: String { return self._s[442]! }
- public var Passport_Language_km: String { return self._s[443]! }
- public var SocksProxySetup_AdNoticeHelp: String { return self._s[445]! }
- public var VoiceOver_Media_PlaybackPlay: String { return self._s[446]! }
- public var Notification_CallMissedShort: String { return self._s[447]! }
- public var Wallet_Info_YourBalance: String { return self._s[448]! }
- public var ReportPeer_ReasonOther_Send: String { return self._s[449]! }
- public var Watch_Compose_Send: String { return self._s[450]! }
- public var Passport_Identity_TypeInternalPassportUploadScan: String { return self._s[453]! }
- public var TwoFactorSetup_Email_Action: String { return self._s[454]! }
- public var Conversation_HoldForVideo: String { return self._s[455]! }
- public var Wallet_Configuration_ApplyErrorTextURLInvalidData: String { return self._s[456]! }
- public var AuthSessions_OtherDevices: String { return self._s[457]! }
- public var Wallet_TransactionInfo_CommentHeader: String { return self._s[458]! }
- public var CheckoutInfo_ErrorCityInvalid: String { return self._s[460]! }
- public var Appearance_AutoNightThemeDisabled: String { return self._s[462]! }
- public var Channel_LinkItem: String { return self._s[463]! }
+ public var Notifications_GroupNotificationsAlert: String { return self._s[443]! }
+ public var Passport_Language_km: String { return self._s[444]! }
+ public var SocksProxySetup_AdNoticeHelp: String { return self._s[446]! }
+ public var VoiceOver_Media_PlaybackPlay: String { return self._s[447]! }
+ public var Notification_CallMissedShort: String { return self._s[448]! }
+ public var Wallet_Info_YourBalance: String { return self._s[449]! }
+ public var ReportPeer_ReasonOther_Send: String { return self._s[451]! }
+ public var Watch_Compose_Send: String { return self._s[452]! }
+ public var Passport_Identity_TypeInternalPassportUploadScan: String { return self._s[455]! }
+ public var TwoFactorSetup_Email_Action: String { return self._s[456]! }
+ public var Conversation_HoldForVideo: String { return self._s[457]! }
+ public var Wallet_Configuration_ApplyErrorTextURLInvalidData: String { return self._s[458]! }
+ public var AuthSessions_OtherDevices: String { return self._s[459]! }
+ public var Wallet_TransactionInfo_CommentHeader: String { return self._s[460]! }
+ public var CheckoutInfo_ErrorCityInvalid: String { return self._s[462]! }
+ public var Appearance_AutoNightThemeDisabled: String { return self._s[464]! }
+ public var Channel_LinkItem: String { return self._s[465]! }
public func PrivacySettings_LastSeenContactsMinusPlus(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[464]!, self._r[464]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[466]!, self._r[466]!, [_0, _1])
}
public func Passport_Identity_NativeNameTitle(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[467]!, self._r[467]!, [_0])
+ return formatWithArgumentRanges(self._s[469]!, self._r[469]!, [_0])
}
- public var VoiceOver_Recording_StopAndPreview: String { return self._s[468]! }
- public var Passport_Language_dv: String { return self._s[469]! }
- public var Undo_LeftChannel: String { return self._s[470]! }
- public var Notifications_ExceptionsMuted: String { return self._s[471]! }
- public var ChatList_UnhideAction: String { return self._s[472]! }
- public var Conversation_ContextMenuShare: String { return self._s[473]! }
- public var Conversation_ContextMenuStickerPackInfo: String { return self._s[474]! }
- public var ShareFileTip_Title: String { return self._s[475]! }
- public var NotificationsSound_Chord: String { return self._s[476]! }
- public var Wallet_TransactionInfo_OtherFeeHeader: String { return self._s[477]! }
+ public var VoiceOver_Recording_StopAndPreview: String { return self._s[470]! }
+ public var Passport_Language_dv: String { return self._s[471]! }
+ public var Undo_LeftChannel: String { return self._s[472]! }
+ public var Notifications_ExceptionsMuted: String { return self._s[473]! }
+ public var ChatList_UnhideAction: String { return self._s[474]! }
+ public var Conversation_ContextMenuShare: String { return self._s[475]! }
+ public var Conversation_ContextMenuStickerPackInfo: String { return self._s[476]! }
+ public var ShareFileTip_Title: String { return self._s[477]! }
+ public var NotificationsSound_Chord: String { return self._s[478]! }
+ public var Wallet_TransactionInfo_OtherFeeHeader: String { return self._s[479]! }
public func PUSH_CHAT_RETURNED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[478]!, self._r[478]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[480]!, self._r[480]!, [_1, _2])
}
- public var Passport_Address_EditTemporaryRegistration: String { return self._s[479]! }
+ public var Passport_Address_EditTemporaryRegistration: String { return self._s[481]! }
public func Notification_Joined(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[480]!, self._r[480]!, [_0])
+ return formatWithArgumentRanges(self._s[482]!, self._r[482]!, [_0])
}
public func Wallet_Time_PreciseDate_m3(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[481]!, self._r[481]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[483]!, self._r[483]!, [_1, _2, _3])
}
- public var Wallet_Settings_ConfigurationInfo: String { return self._s[482]! }
- public var Wallpaper_ErrorNotFound: String { return self._s[483]! }
- public var Notification_CallOutgoingShort: String { return self._s[485]! }
- public var Wallet_WordImport_IncorrectText: String { return self._s[486]! }
+ public var Wallet_Settings_ConfigurationInfo: String { return self._s[484]! }
+ public var Wallpaper_ErrorNotFound: String { return self._s[485]! }
+ public var Notification_CallOutgoingShort: String { return self._s[487]! }
+ public var Wallet_WordImport_IncorrectText: String { return self._s[488]! }
public func Watch_Time_ShortFullAt(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[487]!, self._r[487]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[489]!, self._r[489]!, [_1, _2])
}
- public var Passport_Address_TypeUtilityBill: String { return self._s[488]! }
- public var Privacy_Forwards_LinkIfAllowed: String { return self._s[489]! }
- public var ReportPeer_Report: String { return self._s[490]! }
- public var SettingsSearch_Synonyms_Proxy_Title: String { return self._s[491]! }
- public var GroupInfo_DeactivatedStatus: String { return self._s[492]! }
+ public var Passport_Address_TypeUtilityBill: String { return self._s[490]! }
+ public var Privacy_Forwards_LinkIfAllowed: String { return self._s[491]! }
+ public var ReportPeer_Report: String { return self._s[492]! }
+ public var SettingsSearch_Synonyms_Proxy_Title: String { return self._s[493]! }
+ public var GroupInfo_DeactivatedStatus: String { return self._s[494]! }
public func VoiceOver_Chat_MusicTitle(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[493]!, self._r[493]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[495]!, self._r[495]!, [_1, _2])
}
- public var StickerPack_Send: String { return self._s[494]! }
- public var Login_CodeSentInternal: String { return self._s[495]! }
- public var Wallet_Month_GenJanuary: String { return self._s[496]! }
- public var GroupInfo_InviteLink_LinkSection: String { return self._s[497]! }
+ public var StickerPack_Send: String { return self._s[496]! }
+ public var Login_CodeSentInternal: String { return self._s[497]! }
+ public var Wallet_Month_GenJanuary: String { return self._s[498]! }
+ public var GroupInfo_InviteLink_LinkSection: String { return self._s[499]! }
public func Channel_AdminLog_MessageDeleted(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[498]!, self._r[498]!, [_0])
- }
- public func Conversation_EncryptionWaiting(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[500]!, self._r[500]!, [_0])
}
- public var Channel_BanUser_PermissionSendStickersAndGifs: String { return self._s[501]! }
- public func PUSH_PINNED_GAME(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[502]!, self._r[502]!, [_1])
+ public func Conversation_EncryptionWaiting(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[502]!, self._r[502]!, [_0])
}
- public var ReportPeer_ReasonViolence: String { return self._s[504]! }
- public var Appearance_ShareThemeColor: String { return self._s[505]! }
- public var Map_Locating: String { return self._s[506]! }
+ public var Channel_BanUser_PermissionSendStickersAndGifs: String { return self._s[503]! }
+ public func PUSH_PINNED_GAME(_ _1: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[504]!, self._r[504]!, [_1])
+ }
+ public var ReportPeer_ReasonViolence: String { return self._s[506]! }
+ public var Appearance_ShareThemeColor: String { return self._s[507]! }
+ public var Map_Locating: String { return self._s[508]! }
public func VoiceOver_Chat_VideoFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[507]!, self._r[507]!, [_0])
+ return formatWithArgumentRanges(self._s[509]!, self._r[509]!, [_0])
}
public func PUSH_ALBUM(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[508]!, self._r[508]!, [_1])
+ return formatWithArgumentRanges(self._s[510]!, self._r[510]!, [_1])
}
- public var AutoDownloadSettings_GroupChats: String { return self._s[510]! }
- public var CheckoutInfo_SaveInfo: String { return self._s[511]! }
- public var SharedMedia_EmptyLinksText: String { return self._s[513]! }
- public var Passport_Address_CityPlaceholder: String { return self._s[514]! }
- public var CheckoutInfo_ErrorStateInvalid: String { return self._s[515]! }
- public var Privacy_ProfilePhoto_CustomHelp: String { return self._s[516]! }
- public var Wallet_Send_OwnAddressAlertTitle: String { return self._s[518]! }
- public var Channel_AdminLog_CanAddAdmins: String { return self._s[519]! }
+ public var AutoDownloadSettings_GroupChats: String { return self._s[512]! }
+ public var CheckoutInfo_SaveInfo: String { return self._s[513]! }
+ public var SharedMedia_EmptyLinksText: String { return self._s[515]! }
+ public var Passport_Address_CityPlaceholder: String { return self._s[516]! }
+ public var CheckoutInfo_ErrorStateInvalid: String { return self._s[517]! }
+ public var Privacy_ProfilePhoto_CustomHelp: String { return self._s[518]! }
+ public var Wallet_Send_OwnAddressAlertTitle: String { return self._s[520]! }
+ public var Channel_AdminLog_CanAddAdmins: String { return self._s[521]! }
public func PUSH_CHANNEL_MESSAGE_FWD(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[520]!, self._r[520]!, [_1])
+ return formatWithArgumentRanges(self._s[522]!, self._r[522]!, [_1])
}
public func Time_MonthOfYear_m8(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[521]!, self._r[521]!, [_0])
+ return formatWithArgumentRanges(self._s[523]!, self._r[523]!, [_0])
}
- public var InfoPlist_NSLocationWhenInUseUsageDescription: String { return self._s[522]! }
- public var GroupInfo_InviteLink_RevokeAlert_Success: String { return self._s[523]! }
- public var ChangePhoneNumberCode_Code: String { return self._s[524]! }
- public var Appearance_CreateTheme: String { return self._s[525]! }
+ public var InfoPlist_NSLocationWhenInUseUsageDescription: String { return self._s[524]! }
+ public var GroupInfo_InviteLink_RevokeAlert_Success: String { return self._s[525]! }
+ public var ChangePhoneNumberCode_Code: String { return self._s[526]! }
+ public var Appearance_CreateTheme: String { return self._s[527]! }
public func UserInfo_NotificationsDefaultSound(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[526]!, self._r[526]!, [_0])
+ return formatWithArgumentRanges(self._s[528]!, self._r[528]!, [_0])
}
- public var TwoStepAuth_SetupEmail: String { return self._s[527]! }
- public var HashtagSearch_AllChats: String { return self._s[528]! }
- public var MediaPlayer_UnknownTrack: String { return self._s[529]! }
- public var SettingsSearch_Synonyms_Data_AutoDownloadUsingCellular: String { return self._s[531]! }
+ public var TwoStepAuth_SetupEmail: String { return self._s[529]! }
+ public var HashtagSearch_AllChats: String { return self._s[530]! }
+ public var MediaPlayer_UnknownTrack: String { return self._s[531]! }
+ public var SettingsSearch_Synonyms_Data_AutoDownloadUsingCellular: String { return self._s[533]! }
public func ChatList_DeleteForEveryone(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[532]!, self._r[532]!, [_0])
+ return formatWithArgumentRanges(self._s[534]!, self._r[534]!, [_0])
}
- public var PhotoEditor_QualityHigh: String { return self._s[534]! }
+ public var PhotoEditor_QualityHigh: String { return self._s[536]! }
public func Passport_Phone_UseTelegramNumber(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[535]!, self._r[535]!, [_0])
+ return formatWithArgumentRanges(self._s[537]!, self._r[537]!, [_0])
}
- public var ApplyLanguage_ApplyLanguageAction: String { return self._s[536]! }
- public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsPreview: String { return self._s[537]! }
- public var Message_LiveLocation: String { return self._s[538]! }
- public var Cache_LowDiskSpaceText: String { return self._s[539]! }
- public var Wallet_Receive_ShareAddress: String { return self._s[540]! }
- public var EditTheme_ErrorLinkTaken: String { return self._s[541]! }
- public var Conversation_SendMessage: String { return self._s[542]! }
- public var AuthSessions_EmptyTitle: String { return self._s[543]! }
- public var Privacy_PhoneNumber: String { return self._s[544]! }
- public var PeopleNearby_CreateGroup: String { return self._s[545]! }
- public var CallSettings_UseLessData: String { return self._s[546]! }
- public var NetworkUsageSettings_MediaDocumentDataSection: String { return self._s[547]! }
- public var Stickers_AddToFavorites: String { return self._s[548]! }
- public var Wallet_WordImport_Title: String { return self._s[549]! }
- public var PhotoEditor_QualityLow: String { return self._s[550]! }
- public var Watch_UserInfo_Unblock: String { return self._s[551]! }
- public var Settings_Logout: String { return self._s[552]! }
+ public var ApplyLanguage_ApplyLanguageAction: String { return self._s[538]! }
+ public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsPreview: String { return self._s[539]! }
+ public var Message_LiveLocation: String { return self._s[540]! }
+ public var Cache_LowDiskSpaceText: String { return self._s[541]! }
+ public var Wallet_Receive_ShareAddress: String { return self._s[542]! }
+ public var EditTheme_ErrorLinkTaken: String { return self._s[543]! }
+ public var Conversation_SendMessage: String { return self._s[544]! }
+ public var AuthSessions_EmptyTitle: String { return self._s[545]! }
+ public var Privacy_PhoneNumber: String { return self._s[546]! }
+ public var PeopleNearby_CreateGroup: String { return self._s[547]! }
+ public var CallSettings_UseLessData: String { return self._s[549]! }
+ public var NetworkUsageSettings_MediaDocumentDataSection: String { return self._s[550]! }
+ public var Stickers_AddToFavorites: String { return self._s[551]! }
+ public var Wallet_WordImport_Title: String { return self._s[552]! }
+ public var PhotoEditor_QualityLow: String { return self._s[553]! }
+ public var Watch_UserInfo_Unblock: String { return self._s[554]! }
+ public var Settings_Logout: String { return self._s[555]! }
public func PUSH_MESSAGE_ROUND(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[553]!, self._r[553]!, [_1])
+ return formatWithArgumentRanges(self._s[556]!, self._r[556]!, [_1])
}
- public var ContactInfo_PhoneLabelWork: String { return self._s[554]! }
- public var ChannelInfo_Stats: String { return self._s[555]! }
- public var TextFormat_Link: String { return self._s[556]! }
+ public var ContactInfo_PhoneLabelWork: String { return self._s[557]! }
+ public var ChannelInfo_Stats: String { return self._s[558]! }
+ public var TextFormat_Link: String { return self._s[559]! }
public func Date_ChatDateHeader(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[557]!, self._r[557]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[560]!, self._r[560]!, [_1, _2])
}
- public var Wallet_TransactionInfo_Title: String { return self._s[558]! }
+ public var Wallet_TransactionInfo_Title: String { return self._s[561]! }
public func Message_ForwardedMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[559]!, self._r[559]!, [_0])
+ return formatWithArgumentRanges(self._s[562]!, self._r[562]!, [_0])
}
- public var Watch_Notification_Joined: String { return self._s[560]! }
- public var Group_Setup_TypePublicHelp: String { return self._s[561]! }
- public var Passport_Scans_UploadNew: String { return self._s[562]! }
- public var Checkout_LiabilityAlertTitle: String { return self._s[563]! }
- public var DialogList_Title: String { return self._s[566]! }
- public var NotificationSettings_ContactJoined: String { return self._s[567]! }
- public var GroupInfo_LabelAdmin: String { return self._s[568]! }
- public var KeyCommand_ChatInfo: String { return self._s[569]! }
- public var Conversation_EditingCaptionPanelTitle: String { return self._s[570]! }
- public var Call_ReportIncludeLog: String { return self._s[571]! }
+ public var Watch_Notification_Joined: String { return self._s[563]! }
+ public var Group_Setup_TypePublicHelp: String { return self._s[564]! }
+ public var Passport_Scans_UploadNew: String { return self._s[565]! }
+ public var Checkout_LiabilityAlertTitle: String { return self._s[566]! }
+ public var DialogList_Title: String { return self._s[569]! }
+ public var NotificationSettings_ContactJoined: String { return self._s[570]! }
+ public var GroupInfo_LabelAdmin: String { return self._s[571]! }
+ public var KeyCommand_ChatInfo: String { return self._s[572]! }
+ public var Conversation_EditingCaptionPanelTitle: String { return self._s[573]! }
+ public var Call_ReportIncludeLog: String { return self._s[574]! }
public func Notifications_ExceptionsChangeSound(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[574]!, self._r[574]!, [_0])
+ return formatWithArgumentRanges(self._s[577]!, self._r[577]!, [_0])
}
- public var Channel_AdminLog_InfoPanelChannelAlertText: String { return self._s[575]! }
- public var ChatAdmins_AllMembersAreAdmins: String { return self._s[576]! }
- public var LocalGroup_IrrelevantWarning: String { return self._s[577]! }
- public var Conversation_DefaultRestrictedInline: String { return self._s[578]! }
- public var Message_Sticker: String { return self._s[579]! }
- public var LastSeen_JustNow: String { return self._s[581]! }
- public var Passport_Email_EmailPlaceholder: String { return self._s[583]! }
- public var SettingsSearch_Synonyms_AppLanguage: String { return self._s[584]! }
- public var Channel_AdminLogFilter_EventsEditedMessages: String { return self._s[585]! }
- public var Channel_EditAdmin_PermissionsHeader: String { return self._s[586]! }
- public var TwoStepAuth_Email: String { return self._s[587]! }
- public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsSound: String { return self._s[588]! }
- public var PhotoEditor_BlurToolOff: String { return self._s[589]! }
- public var Message_PinnedStickerMessage: String { return self._s[590]! }
- public var ContactInfo_PhoneLabelPager: String { return self._s[591]! }
- public var SettingsSearch_Synonyms_Appearance_TextSize: String { return self._s[592]! }
- public var Passport_DiscardMessageTitle: String { return self._s[593]! }
- public var Privacy_PaymentsTitle: String { return self._s[594]! }
- public var EditTheme_Edit_Preview_IncomingReplyName: String { return self._s[595]! }
- public var ClearCache_StorageCache: String { return self._s[596]! }
- public var Appearance_TextSizeSetting: String { return self._s[597]! }
- public var Channel_DiscussionGroup_Header: String { return self._s[599]! }
- public var VoiceOver_Chat_OptionSelected: String { return self._s[600]! }
- public var Appearance_ColorTheme: String { return self._s[601]! }
- public var UserInfo_ShareContact: String { return self._s[602]! }
- public var Passport_Address_TypePassportRegistration: String { return self._s[603]! }
- public var Common_More: String { return self._s[604]! }
- public var Watch_Message_Call: String { return self._s[605]! }
- public var Profile_EncryptionKey: String { return self._s[608]! }
- public var Privacy_TopPeers: String { return self._s[609]! }
- public var Conversation_StopPollConfirmation: String { return self._s[610]! }
- public var Wallet_Words_NotDoneText: String { return self._s[612]! }
- public var Privacy_TopPeersWarning: String { return self._s[614]! }
- public var SettingsSearch_Synonyms_Data_DownloadInBackground: String { return self._s[615]! }
- public var SettingsSearch_Synonyms_Data_Storage_KeepMedia: String { return self._s[616]! }
- public var Wallet_RestoreFailed_EnterWords: String { return self._s[619]! }
- public var DialogList_SearchSectionMessages: String { return self._s[620]! }
- public var Notifications_ChannelNotifications: String { return self._s[621]! }
- public var CheckoutInfo_ShippingInfoAddress1Placeholder: String { return self._s[622]! }
- public var Passport_Language_sk: String { return self._s[623]! }
- public var Notification_MessageLifetime1h: String { return self._s[624]! }
- public var Wallpaper_ResetWallpapersInfo: String { return self._s[625]! }
- public var Appearance_ThemePreview_Chat_5_Text: String { return self._s[626]! }
- public var Call_ReportSkip: String { return self._s[628]! }
- public var Cache_ServiceFiles: String { return self._s[629]! }
- public var Group_ErrorAddTooMuchAdmins: String { return self._s[630]! }
- public var VoiceOver_Chat_YourFile: String { return self._s[631]! }
- public var Map_Hybrid: String { return self._s[632]! }
- public var Contacts_SearchUsersAndGroupsLabel: String { return self._s[634]! }
- public var ChatSettings_AutoDownloadVideos: String { return self._s[636]! }
- public var Channel_BanUser_PermissionEmbedLinks: String { return self._s[637]! }
- public var InfoPlist_NSLocationAlwaysAndWhenInUseUsageDescription: String { return self._s[638]! }
- public var SocksProxySetup_ProxyTelegram: String { return self._s[641]! }
+ public var Channel_AdminLog_InfoPanelChannelAlertText: String { return self._s[578]! }
+ public var ChatAdmins_AllMembersAreAdmins: String { return self._s[579]! }
+ public var LocalGroup_IrrelevantWarning: String { return self._s[580]! }
+ public var Conversation_DefaultRestrictedInline: String { return self._s[581]! }
+ public var Message_Sticker: String { return self._s[582]! }
+ public var LastSeen_JustNow: String { return self._s[584]! }
+ public var Passport_Email_EmailPlaceholder: String { return self._s[586]! }
+ public var SettingsSearch_Synonyms_AppLanguage: String { return self._s[587]! }
+ public var Channel_AdminLogFilter_EventsEditedMessages: String { return self._s[588]! }
+ public var Channel_EditAdmin_PermissionsHeader: String { return self._s[589]! }
+ public var TwoStepAuth_Email: String { return self._s[590]! }
+ public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsSound: String { return self._s[591]! }
+ public var PhotoEditor_BlurToolOff: String { return self._s[592]! }
+ public var Message_PinnedStickerMessage: String { return self._s[593]! }
+ public var ContactInfo_PhoneLabelPager: String { return self._s[594]! }
+ public var SettingsSearch_Synonyms_Appearance_TextSize: String { return self._s[595]! }
+ public var Passport_DiscardMessageTitle: String { return self._s[596]! }
+ public var Privacy_PaymentsTitle: String { return self._s[597]! }
+ public var EditTheme_Edit_Preview_IncomingReplyName: String { return self._s[598]! }
+ public var ClearCache_StorageCache: String { return self._s[599]! }
+ public var Appearance_TextSizeSetting: String { return self._s[600]! }
+ public var Channel_DiscussionGroup_Header: String { return self._s[602]! }
+ public var VoiceOver_Chat_OptionSelected: String { return self._s[603]! }
+ public var Appearance_ColorTheme: String { return self._s[604]! }
+ public var UserInfo_ShareContact: String { return self._s[605]! }
+ public var Passport_Address_TypePassportRegistration: String { return self._s[606]! }
+ public var Common_More: String { return self._s[607]! }
+ public var Watch_Message_Call: String { return self._s[608]! }
+ public var Profile_EncryptionKey: String { return self._s[611]! }
+ public var Privacy_TopPeers: String { return self._s[612]! }
+ public var Conversation_StopPollConfirmation: String { return self._s[613]! }
+ public var Wallet_Words_NotDoneText: String { return self._s[615]! }
+ public var Privacy_TopPeersWarning: String { return self._s[617]! }
+ public var SettingsSearch_Synonyms_Data_DownloadInBackground: String { return self._s[618]! }
+ public var SettingsSearch_Synonyms_Data_Storage_KeepMedia: String { return self._s[619]! }
+ public var Wallet_RestoreFailed_EnterWords: String { return self._s[622]! }
+ public var DialogList_SearchSectionMessages: String { return self._s[623]! }
+ public var Notifications_ChannelNotifications: String { return self._s[624]! }
+ public var CheckoutInfo_ShippingInfoAddress1Placeholder: String { return self._s[625]! }
+ public var Passport_Language_sk: String { return self._s[626]! }
+ public var Notification_MessageLifetime1h: String { return self._s[627]! }
+ public var Wallpaper_ResetWallpapersInfo: String { return self._s[628]! }
+ public var Appearance_ThemePreview_Chat_5_Text: String { return self._s[629]! }
+ public var Call_ReportSkip: String { return self._s[631]! }
+ public var Cache_ServiceFiles: String { return self._s[632]! }
+ public var Group_ErrorAddTooMuchAdmins: String { return self._s[633]! }
+ public var VoiceOver_Chat_YourFile: String { return self._s[634]! }
+ public var Map_Hybrid: String { return self._s[635]! }
+ public var Contacts_SearchUsersAndGroupsLabel: String { return self._s[637]! }
+ public var ChatSettings_AutoDownloadVideos: String { return self._s[639]! }
+ public var Channel_BanUser_PermissionEmbedLinks: String { return self._s[640]! }
+ public var InfoPlist_NSLocationAlwaysAndWhenInUseUsageDescription: String { return self._s[641]! }
+ public var SocksProxySetup_ProxyTelegram: String { return self._s[644]! }
public func PUSH_MESSAGE_AUDIO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[642]!, self._r[642]!, [_1])
+ return formatWithArgumentRanges(self._s[645]!, self._r[645]!, [_1])
}
- public var Channel_Username_CreatePrivateLinkHelp: String { return self._s[644]! }
- public var ScheduledMessages_ScheduledToday: String { return self._s[645]! }
+ public var Channel_Username_CreatePrivateLinkHelp: String { return self._s[647]! }
+ public var ScheduledMessages_ScheduledToday: String { return self._s[648]! }
public func PUSH_CHAT_TITLE_EDITED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[646]!, self._r[646]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[649]!, self._r[649]!, [_1, _2])
}
- public var Conversation_LiveLocationYou: String { return self._s[647]! }
- public var SettingsSearch_Synonyms_Privacy_Calls: String { return self._s[648]! }
- public var SettingsSearch_Synonyms_Notifications_MessageNotificationsPreview: String { return self._s[649]! }
- public var UserInfo_ShareBot: String { return self._s[652]! }
+ public var Conversation_LiveLocationYou: String { return self._s[650]! }
+ public var SettingsSearch_Synonyms_Privacy_Calls: String { return self._s[651]! }
+ public var SettingsSearch_Synonyms_Notifications_MessageNotificationsPreview: String { return self._s[652]! }
+ public var UserInfo_ShareBot: String { return self._s[655]! }
public func PUSH_AUTH_REGION(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[653]!, self._r[653]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[656]!, self._r[656]!, [_1, _2])
}
- public var Conversation_ClearCache: String { return self._s[654]! }
- public var PhotoEditor_ShadowsTint: String { return self._s[655]! }
- public var Message_Audio: String { return self._s[656]! }
- public var Passport_Language_lt: String { return self._s[657]! }
+ public var Conversation_ClearCache: String { return self._s[657]! }
+ public var PhotoEditor_ShadowsTint: String { return self._s[658]! }
+ public var Message_Audio: String { return self._s[659]! }
+ public var Passport_Language_lt: String { return self._s[660]! }
public func Message_PinnedTextMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[658]!, self._r[658]!, [_0])
+ return formatWithArgumentRanges(self._s[661]!, self._r[661]!, [_0])
}
- public var Permissions_SiriText_v0: String { return self._s[659]! }
- public var Conversation_FileICloudDrive: String { return self._s[660]! }
- public var ChatList_DeleteForEveryoneConfirmationTitle: String { return self._s[661]! }
- public var Notifications_Badge_IncludeMutedChats: String { return self._s[662]! }
+ public var Permissions_SiriText_v0: String { return self._s[662]! }
+ public var Conversation_FileICloudDrive: String { return self._s[663]! }
+ public var ChatList_DeleteForEveryoneConfirmationTitle: String { return self._s[664]! }
+ public var Notifications_Badge_IncludeMutedChats: String { return self._s[665]! }
public func Notification_NewAuthDetected(_ _1: String, _ _2: String, _ _3: String, _ _4: String, _ _5: String, _ _6: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[663]!, self._r[663]!, [_1, _2, _3, _4, _5, _6])
+ return formatWithArgumentRanges(self._s[666]!, self._r[666]!, [_1, _2, _3, _4, _5, _6])
}
- public var DialogList_ProxyConnectionIssuesTooltip: String { return self._s[664]! }
+ public var DialogList_ProxyConnectionIssuesTooltip: String { return self._s[667]! }
public func Time_MonthOfYear_m5(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[665]!, self._r[665]!, [_0])
+ return formatWithArgumentRanges(self._s[668]!, self._r[668]!, [_0])
}
- public var Channel_SignMessages: String { return self._s[666]! }
+ public var Channel_SignMessages: String { return self._s[669]! }
public func PUSH_MESSAGE_NOTEXT(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[667]!, self._r[667]!, [_1])
+ return formatWithArgumentRanges(self._s[670]!, self._r[670]!, [_1])
}
- public var Compose_ChannelTokenListPlaceholder: String { return self._s[668]! }
- public var Passport_ScanPassport: String { return self._s[669]! }
- public var Watch_Suggestion_Thanks: String { return self._s[670]! }
- public var BlockedUsers_AddNew: String { return self._s[671]! }
+ public var Compose_ChannelTokenListPlaceholder: String { return self._s[671]! }
+ public var Passport_ScanPassport: String { return self._s[672]! }
+ public var Watch_Suggestion_Thanks: String { return self._s[673]! }
+ public var BlockedUsers_AddNew: String { return self._s[674]! }
public func PUSH_CHAT_MESSAGE(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[672]!, self._r[672]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[675]!, self._r[675]!, [_1, _2])
}
- public var Watch_Message_Invoice: String { return self._s[673]! }
- public var SettingsSearch_Synonyms_Privacy_LastSeen: String { return self._s[674]! }
- public var Month_GenJuly: String { return self._s[675]! }
- public var CreatePoll_QuizInfo: String { return self._s[676]! }
- public var UserInfo_StartSecretChatStart: String { return self._s[677]! }
- public var SocksProxySetup_ProxySocks5: String { return self._s[678]! }
- public var IntentsSettings_SuggestByShare: String { return self._s[680]! }
- public var Notification_Exceptions_DeleteAllConfirmation: String { return self._s[681]! }
- public var Notification_ChannelInviterSelf: String { return self._s[682]! }
- public var CheckoutInfo_ReceiverInfoEmail: String { return self._s[683]! }
+ public var Watch_Message_Invoice: String { return self._s[676]! }
+ public var SettingsSearch_Synonyms_Privacy_LastSeen: String { return self._s[677]! }
+ public var Month_GenJuly: String { return self._s[678]! }
+ public var CreatePoll_QuizInfo: String { return self._s[679]! }
+ public var UserInfo_StartSecretChatStart: String { return self._s[680]! }
+ public var SocksProxySetup_ProxySocks5: String { return self._s[681]! }
+ public var IntentsSettings_SuggestByShare: String { return self._s[683]! }
+ public var Notification_Exceptions_DeleteAllConfirmation: String { return self._s[684]! }
+ public var Notification_ChannelInviterSelf: String { return self._s[685]! }
+ public var CheckoutInfo_ReceiverInfoEmail: String { return self._s[686]! }
public func ApplyLanguage_ChangeLanguageUnofficialText(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[684]!, self._r[684]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[687]!, self._r[687]!, [_1, _2])
}
- public var CheckoutInfo_Title: String { return self._s[685]! }
- public var Watch_Stickers_RecentPlaceholder: String { return self._s[686]! }
+ public var CheckoutInfo_Title: String { return self._s[688]! }
+ public var Watch_Stickers_RecentPlaceholder: String { return self._s[689]! }
public func Map_DistanceAway(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[687]!, self._r[687]!, [_0])
+ return formatWithArgumentRanges(self._s[690]!, self._r[690]!, [_0])
}
- public var Passport_Identity_MainPage: String { return self._s[688]! }
- public var TwoStepAuth_ConfirmEmailResendCode: String { return self._s[689]! }
- public var Passport_Language_de: String { return self._s[690]! }
- public var Update_Title: String { return self._s[691]! }
- public var ContactInfo_PhoneLabelWorkFax: String { return self._s[692]! }
- public var Channel_AdminLog_BanEmbedLinks: String { return self._s[693]! }
- public var Passport_Email_UseTelegramEmailHelp: String { return self._s[694]! }
- public var Notifications_ChannelNotificationsPreview: String { return self._s[695]! }
- public var NotificationsSound_Telegraph: String { return self._s[696]! }
- public var Watch_LastSeen_ALongTimeAgo: String { return self._s[697]! }
- public var ChannelMembers_WhoCanAddMembers: String { return self._s[698]! }
+ public var Passport_Identity_MainPage: String { return self._s[691]! }
+ public var TwoStepAuth_ConfirmEmailResendCode: String { return self._s[692]! }
+ public var Passport_Language_de: String { return self._s[693]! }
+ public var Update_Title: String { return self._s[694]! }
+ public var ContactInfo_PhoneLabelWorkFax: String { return self._s[695]! }
+ public var Channel_AdminLog_BanEmbedLinks: String { return self._s[696]! }
+ public var Passport_Email_UseTelegramEmailHelp: String { return self._s[697]! }
+ public var Notifications_ChannelNotificationsPreview: String { return self._s[698]! }
+ public var NotificationsSound_Telegraph: String { return self._s[699]! }
+ public var Watch_LastSeen_ALongTimeAgo: String { return self._s[700]! }
+ public var ChannelMembers_WhoCanAddMembers: String { return self._s[701]! }
public func AutoDownloadSettings_UpTo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[699]!, self._r[699]!, [_0])
+ return formatWithArgumentRanges(self._s[702]!, self._r[702]!, [_0])
}
- public var ClearCache_Description: String { return self._s[700]! }
- public var Stickers_SuggestAll: String { return self._s[701]! }
- public var Conversation_ForwardTitle: String { return self._s[702]! }
- public var Appearance_ThemePreview_ChatList_7_Name: String { return self._s[703]! }
+ public var ClearCache_Description: String { return self._s[703]! }
+ public var Stickers_SuggestAll: String { return self._s[704]! }
+ public var Conversation_ForwardTitle: String { return self._s[705]! }
+ public var Appearance_ThemePreview_ChatList_7_Name: String { return self._s[706]! }
public func Notification_JoinedChannel(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[704]!, self._r[704]!, [_0])
+ return formatWithArgumentRanges(self._s[707]!, self._r[707]!, [_0])
}
- public var Calls_NewCall: String { return self._s[705]! }
- public var Call_StatusEnded: String { return self._s[706]! }
- public var AutoDownloadSettings_DataUsageLow: String { return self._s[707]! }
- public var Settings_ProxyConnected: String { return self._s[708]! }
- public var Channel_AdminLogFilter_EventsPinned: String { return self._s[709]! }
- public var PhotoEditor_QualityVeryLow: String { return self._s[710]! }
- public var Channel_AdminLogFilter_EventsDeletedMessages: String { return self._s[711]! }
- public var Passport_PasswordPlaceholder: String { return self._s[712]! }
- public var Message_PinnedInvoice: String { return self._s[713]! }
- public var Passport_Identity_IssueDate: String { return self._s[714]! }
- public var Passport_Language_pl: String { return self._s[715]! }
+ public var Calls_NewCall: String { return self._s[708]! }
+ public var Call_StatusEnded: String { return self._s[709]! }
+ public var AutoDownloadSettings_DataUsageLow: String { return self._s[710]! }
+ public var Settings_ProxyConnected: String { return self._s[711]! }
+ public var Channel_AdminLogFilter_EventsPinned: String { return self._s[712]! }
+ public var PhotoEditor_QualityVeryLow: String { return self._s[713]! }
+ public var Channel_AdminLogFilter_EventsDeletedMessages: String { return self._s[714]! }
+ public var Passport_PasswordPlaceholder: String { return self._s[715]! }
+ public var Message_PinnedInvoice: String { return self._s[716]! }
+ public var Passport_Identity_IssueDate: String { return self._s[717]! }
+ public var Passport_Language_pl: String { return self._s[718]! }
public func ChannelInfo_ChannelForbidden(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[716]!, self._r[716]!, [_0])
- }
- public var SocksProxySetup_PasteFromClipboard: String { return self._s[717]! }
- public var Call_StatusConnecting: String { return self._s[718]! }
- public func Username_UsernameIsAvailable(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[719]!, self._r[719]!, [_0])
}
- public var ChatSettings_ConnectionType_UseProxy: String { return self._s[721]! }
- public var Common_Edit: String { return self._s[722]! }
- public var PrivacySettings_LastSeenNobody: String { return self._s[723]! }
+ public var SocksProxySetup_PasteFromClipboard: String { return self._s[720]! }
+ public var Call_StatusConnecting: String { return self._s[721]! }
+ public func Username_UsernameIsAvailable(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[722]!, self._r[722]!, [_0])
+ }
+ public var ChatSettings_ConnectionType_UseProxy: String { return self._s[724]! }
+ public var Common_Edit: String { return self._s[725]! }
+ public var PrivacySettings_LastSeenNobody: String { return self._s[726]! }
public func Notification_LeftChat(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[724]!, self._r[724]!, [_0])
+ return formatWithArgumentRanges(self._s[727]!, self._r[727]!, [_0])
}
- public var GroupInfo_ChatAdmins: String { return self._s[725]! }
- public var PrivateDataSettings_Title: String { return self._s[726]! }
- public var Login_CancelPhoneVerificationStop: String { return self._s[727]! }
- public var ChatList_Read: String { return self._s[728]! }
- public var Wallet_WordImport_Text: String { return self._s[729]! }
- public var Undo_ChatClearedForBothSides: String { return self._s[730]! }
- public var GroupPermission_SectionTitle: String { return self._s[731]! }
- public var TwoFactorSetup_Intro_Title: String { return self._s[733]! }
+ public var GroupInfo_ChatAdmins: String { return self._s[728]! }
+ public var PrivateDataSettings_Title: String { return self._s[729]! }
+ public var Login_CancelPhoneVerificationStop: String { return self._s[730]! }
+ public var ChatList_Read: String { return self._s[731]! }
+ public var Wallet_WordImport_Text: String { return self._s[732]! }
+ public var Undo_ChatClearedForBothSides: String { return self._s[733]! }
+ public var GroupPermission_SectionTitle: String { return self._s[734]! }
+ public var TwoFactorSetup_Intro_Title: String { return self._s[736]! }
public func PUSH_CHAT_LEFT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[734]!, self._r[734]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[737]!, self._r[737]!, [_1, _2])
}
- public var Checkout_ErrorPaymentFailed: String { return self._s[735]! }
- public var Update_UpdateApp: String { return self._s[736]! }
- public var Group_Username_RevokeExistingUsernamesInfo: String { return self._s[737]! }
- public var Settings_Appearance: String { return self._s[738]! }
- public var SettingsSearch_Synonyms_Stickers_SuggestStickers: String { return self._s[742]! }
- public var Watch_Location_Access: String { return self._s[743]! }
- public var ShareMenu_CopyShareLink: String { return self._s[745]! }
- public var TwoStepAuth_SetupHintTitle: String { return self._s[746]! }
- public var Conversation_Theme: String { return self._s[748]! }
+ public var Checkout_ErrorPaymentFailed: String { return self._s[738]! }
+ public var Update_UpdateApp: String { return self._s[739]! }
+ public var Group_Username_RevokeExistingUsernamesInfo: String { return self._s[740]! }
+ public var Settings_Appearance: String { return self._s[741]! }
+ public var SettingsSearch_Synonyms_Stickers_SuggestStickers: String { return self._s[745]! }
+ public var Watch_Location_Access: String { return self._s[746]! }
+ public var ShareMenu_CopyShareLink: String { return self._s[748]! }
+ public var TwoStepAuth_SetupHintTitle: String { return self._s[749]! }
+ public var Conversation_Theme: String { return self._s[751]! }
public func DialogList_SingleRecordingVideoMessageSuffix(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[749]!, self._r[749]!, [_0])
+ return formatWithArgumentRanges(self._s[752]!, self._r[752]!, [_0])
}
- public var Notifications_ClassicTones: String { return self._s[750]! }
- public var Weekday_ShortWednesday: String { return self._s[751]! }
- public var WallpaperPreview_SwipeColorsBottomText: String { return self._s[752]! }
- public var Undo_LeftGroup: String { return self._s[755]! }
- public var Wallet_RestoreFailed_Text: String { return self._s[756]! }
- public var Conversation_LinkDialogCopy: String { return self._s[757]! }
- public var Wallet_TransactionInfo_NoAddress: String { return self._s[759]! }
- public var Wallet_Navigation_Back: String { return self._s[760]! }
- public var KeyCommand_FocusOnInputField: String { return self._s[761]! }
- public var Contacts_SelectAll: String { return self._s[762]! }
- public var Preview_SaveToCameraRoll: String { return self._s[763]! }
- public var PrivacySettings_PasscodeOff: String { return self._s[764]! }
- public var Appearance_ThemePreview_ChatList_6_Name: String { return self._s[765]! }
- public var Wallpaper_Title: String { return self._s[766]! }
- public var Conversation_FilePhotoOrVideo: String { return self._s[767]! }
- public var AccessDenied_Camera: String { return self._s[768]! }
- public var Watch_Compose_CurrentLocation: String { return self._s[769]! }
- public var Channel_DiscussionGroup_MakeHistoryPublicProceed: String { return self._s[771]! }
+ public var Notifications_ClassicTones: String { return self._s[753]! }
+ public var Weekday_ShortWednesday: String { return self._s[754]! }
+ public var WallpaperPreview_SwipeColorsBottomText: String { return self._s[755]! }
+ public var Undo_LeftGroup: String { return self._s[758]! }
+ public var Wallet_RestoreFailed_Text: String { return self._s[759]! }
+ public var Conversation_LinkDialogCopy: String { return self._s[760]! }
+ public var Wallet_TransactionInfo_NoAddress: String { return self._s[762]! }
+ public var Wallet_Navigation_Back: String { return self._s[763]! }
+ public var KeyCommand_FocusOnInputField: String { return self._s[764]! }
+ public var Contacts_SelectAll: String { return self._s[765]! }
+ public var Preview_SaveToCameraRoll: String { return self._s[766]! }
+ public var PrivacySettings_PasscodeOff: String { return self._s[767]! }
+ public var Appearance_ThemePreview_ChatList_6_Name: String { return self._s[768]! }
+ public var Wallpaper_Title: String { return self._s[769]! }
+ public var Conversation_FilePhotoOrVideo: String { return self._s[770]! }
+ public var AccessDenied_Camera: String { return self._s[771]! }
+ public var Watch_Compose_CurrentLocation: String { return self._s[772]! }
+ public var Channel_DiscussionGroup_MakeHistoryPublicProceed: String { return self._s[774]! }
public func SecretImage_NotViewedYet(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[772]!, self._r[772]!, [_0])
+ return formatWithArgumentRanges(self._s[775]!, self._r[775]!, [_0])
}
- public var GroupInfo_InvitationLinkDoesNotExist: String { return self._s[773]! }
- public var Passport_Language_ro: String { return self._s[774]! }
- public var EditTheme_UploadNewTheme: String { return self._s[775]! }
- public var CheckoutInfo_SaveInfoHelp: String { return self._s[776]! }
- public var Wallet_Intro_Terms: String { return self._s[777]! }
+ public var GroupInfo_InvitationLinkDoesNotExist: String { return self._s[776]! }
+ public var Passport_Language_ro: String { return self._s[777]! }
+ public var EditTheme_UploadNewTheme: String { return self._s[778]! }
+ public var CheckoutInfo_SaveInfoHelp: String { return self._s[779]! }
+ public var Wallet_Intro_Terms: String { return self._s[780]! }
public func Notification_SecretChatMessageScreenshot(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[778]!, self._r[778]!, [_0])
+ return formatWithArgumentRanges(self._s[781]!, self._r[781]!, [_0])
}
- public var Login_CancelPhoneVerification: String { return self._s[779]! }
- public var State_ConnectingToProxy: String { return self._s[780]! }
- public var Calls_RatingTitle: String { return self._s[781]! }
- public var Generic_ErrorMoreInfo: String { return self._s[782]! }
- public var ChatList_Search_ShowMore: String { return self._s[783]! }
- public var Appearance_PreviewReplyText: String { return self._s[784]! }
- public var CheckoutInfo_ShippingInfoPostcodePlaceholder: String { return self._s[785]! }
+ public var Login_CancelPhoneVerification: String { return self._s[782]! }
+ public var State_ConnectingToProxy: String { return self._s[783]! }
+ public var Calls_RatingTitle: String { return self._s[784]! }
+ public var Generic_ErrorMoreInfo: String { return self._s[785]! }
+ public var ChatList_Search_ShowMore: String { return self._s[786]! }
+ public var Appearance_PreviewReplyText: String { return self._s[787]! }
+ public var CheckoutInfo_ShippingInfoPostcodePlaceholder: String { return self._s[788]! }
public func Wallet_Send_Balance(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[786]!, self._r[786]!, [_0])
+ return formatWithArgumentRanges(self._s[789]!, self._r[789]!, [_0])
}
- public var IntentsSettings_SuggestedChatsContacts: String { return self._s[787]! }
- public var SharedMedia_CategoryLinks: String { return self._s[788]! }
- public var Calls_Missed: String { return self._s[789]! }
- public var Cache_Photos: String { return self._s[793]! }
- public var GroupPermission_NoAddMembers: String { return self._s[794]! }
- public var ScheduledMessages_Title: String { return self._s[795]! }
+ public var IntentsSettings_SuggestedChatsContacts: String { return self._s[790]! }
+ public var SharedMedia_CategoryLinks: String { return self._s[791]! }
+ public var Calls_Missed: String { return self._s[792]! }
+ public var Cache_Photos: String { return self._s[796]! }
+ public var GroupPermission_NoAddMembers: String { return self._s[797]! }
+ public var ScheduledMessages_Title: String { return self._s[798]! }
public func Channel_AdminLog_MessageUnpinned(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[796]!, self._r[796]!, [_0])
+ return formatWithArgumentRanges(self._s[799]!, self._r[799]!, [_0])
}
- public var Conversation_ShareBotLocationConfirmationTitle: String { return self._s[797]! }
- public var Settings_ProxyDisabled: String { return self._s[798]! }
+ public var Conversation_ShareBotLocationConfirmationTitle: String { return self._s[800]! }
+ public var Settings_ProxyDisabled: String { return self._s[801]! }
public func Settings_ApplyProxyAlertCredentials(_ _1: String, _ _2: String, _ _3: String, _ _4: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[799]!, self._r[799]!, [_1, _2, _3, _4])
+ return formatWithArgumentRanges(self._s[802]!, self._r[802]!, [_1, _2, _3, _4])
}
public func Conversation_RestrictedMediaTimed(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[800]!, self._r[800]!, [_0])
+ return formatWithArgumentRanges(self._s[803]!, self._r[803]!, [_0])
}
- public var ChatList_Context_RemoveFromRecents: String { return self._s[802]! }
- public var Appearance_Title: String { return self._s[803]! }
+ public var ChatList_Context_RemoveFromRecents: String { return self._s[805]! }
+ public var Appearance_Title: String { return self._s[806]! }
public func Time_MonthOfYear_m2(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[805]!, self._r[805]!, [_0])
+ return formatWithArgumentRanges(self._s[808]!, self._r[808]!, [_0])
}
- public var Conversation_WalletRequiredText: String { return self._s[806]! }
- public var StickerPacksSettings_ShowStickersButtonHelp: String { return self._s[807]! }
- public var OldChannels_NoticeCreateText: String { return self._s[808]! }
- public var Channel_EditMessageErrorGeneric: String { return self._s[809]! }
- public var Privacy_Calls_IntegrationHelp: String { return self._s[810]! }
- public var Preview_DeletePhoto: String { return self._s[811]! }
- public var Appearance_AppIconFilledX: String { return self._s[812]! }
- public var PrivacySettings_PrivacyTitle: String { return self._s[813]! }
+ public var Conversation_WalletRequiredText: String { return self._s[809]! }
+ public var StickerPacksSettings_ShowStickersButtonHelp: String { return self._s[810]! }
+ public var OldChannels_NoticeCreateText: String { return self._s[811]! }
+ public var Channel_EditMessageErrorGeneric: String { return self._s[812]! }
+ public var Privacy_Calls_IntegrationHelp: String { return self._s[813]! }
+ public var Preview_DeletePhoto: String { return self._s[814]! }
+ public var Appearance_AppIconFilledX: String { return self._s[815]! }
+ public var PrivacySettings_PrivacyTitle: String { return self._s[816]! }
public func Conversation_BotInteractiveUrlAlert(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[814]!, self._r[814]!, [_0])
+ return formatWithArgumentRanges(self._s[817]!, self._r[817]!, [_0])
}
- public var Coub_TapForSound: String { return self._s[817]! }
- public var Map_LocatingError: String { return self._s[818]! }
- public var TwoStepAuth_EmailChangeSuccess: String { return self._s[820]! }
- public var Conversation_SendMessage_SendSilently: String { return self._s[821]! }
- public var VoiceOver_MessageContextOpenMessageMenu: String { return self._s[822]! }
+ public var Coub_TapForSound: String { return self._s[820]! }
+ public var Map_LocatingError: String { return self._s[821]! }
+ public var TwoStepAuth_EmailChangeSuccess: String { return self._s[823]! }
+ public var Conversation_SendMessage_SendSilently: String { return self._s[824]! }
+ public var VoiceOver_MessageContextOpenMessageMenu: String { return self._s[825]! }
public func Wallet_Time_PreciseDate_m8(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[823]!, self._r[823]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[826]!, self._r[826]!, [_1, _2, _3])
}
- public var Passport_ForgottenPassword: String { return self._s[824]! }
- public var GroupInfo_InviteLink_RevokeLink: String { return self._s[825]! }
- public var StickerPacksSettings_ArchivedPacks: String { return self._s[826]! }
- public var Login_TermsOfServiceSignupDecline: String { return self._s[828]! }
- public var Channel_Moderator_AccessLevelRevoke: String { return self._s[829]! }
- public var Message_Location: String { return self._s[830]! }
- public var Passport_Identity_NamePlaceholder: String { return self._s[831]! }
- public var Channel_Management_Title: String { return self._s[832]! }
- public var DialogList_SearchSectionDialogs: String { return self._s[834]! }
- public var Compose_NewChannel_Members: String { return self._s[835]! }
+ public var Passport_ForgottenPassword: String { return self._s[827]! }
+ public var GroupInfo_InviteLink_RevokeLink: String { return self._s[828]! }
+ public var StickerPacksSettings_ArchivedPacks: String { return self._s[829]! }
+ public var Login_TermsOfServiceSignupDecline: String { return self._s[831]! }
+ public var Channel_Moderator_AccessLevelRevoke: String { return self._s[832]! }
+ public var Message_Location: String { return self._s[833]! }
+ public var Passport_Identity_NamePlaceholder: String { return self._s[834]! }
+ public var Channel_Management_Title: String { return self._s[835]! }
+ public var DialogList_SearchSectionDialogs: String { return self._s[837]! }
+ public var Compose_NewChannel_Members: String { return self._s[838]! }
public func DialogList_SingleUploadingFileSuffix(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[836]!, self._r[836]!, [_0])
+ return formatWithArgumentRanges(self._s[839]!, self._r[839]!, [_0])
}
- public var GroupInfo_Location: String { return self._s[837]! }
- public var Appearance_ThemePreview_ChatList_5_Name: String { return self._s[838]! }
- public var ClearCache_Clear: String { return self._s[839]! }
- public var AutoNightTheme_ScheduledFrom: String { return self._s[840]! }
- public var PhotoEditor_WarmthTool: String { return self._s[841]! }
- public var Passport_Language_tr: String { return self._s[842]! }
+ public var GroupInfo_Location: String { return self._s[840]! }
+ public var Appearance_ThemePreview_ChatList_5_Name: String { return self._s[841]! }
+ public var ClearCache_Clear: String { return self._s[842]! }
+ public var AutoNightTheme_ScheduledFrom: String { return self._s[843]! }
+ public var PhotoEditor_WarmthTool: String { return self._s[844]! }
+ public var Passport_Language_tr: String { return self._s[845]! }
public func PUSH_MESSAGE_GAME_SCORE(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[843]!, self._r[843]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[846]!, self._r[846]!, [_1, _2, _3])
}
- public var OldChannels_NoticeUpgradeText: String { return self._s[844]! }
- public var Login_ResetAccountProtected_Reset: String { return self._s[846]! }
- public var Watch_PhotoView_Title: String { return self._s[847]! }
- public var Passport_Phone_Delete: String { return self._s[848]! }
- public var Undo_ChatDeletedForBothSides: String { return self._s[849]! }
- public var Conversation_EditingMessageMediaEditCurrentPhoto: String { return self._s[850]! }
- public var GroupInfo_Permissions: String { return self._s[851]! }
- public var PasscodeSettings_TurnPasscodeOff: String { return self._s[852]! }
- public var Profile_ShareContactButton: String { return self._s[853]! }
- public var ChatSettings_Other: String { return self._s[854]! }
- public var UserInfo_NotificationsDisabled: String { return self._s[855]! }
- public var CheckoutInfo_ShippingInfoCity: String { return self._s[856]! }
- public var LastSeen_WithinAMonth: String { return self._s[857]! }
- public var VoiceOver_Chat_PlayHint: String { return self._s[858]! }
- public var Conversation_ReportGroupLocation: String { return self._s[859]! }
- public var Conversation_EncryptionCanceled: String { return self._s[860]! }
- public var MediaPicker_GroupDescription: String { return self._s[861]! }
- public var WebSearch_Images: String { return self._s[862]! }
+ public var OldChannels_NoticeUpgradeText: String { return self._s[847]! }
+ public var Login_ResetAccountProtected_Reset: String { return self._s[849]! }
+ public var Watch_PhotoView_Title: String { return self._s[850]! }
+ public var Passport_Phone_Delete: String { return self._s[851]! }
+ public var Undo_ChatDeletedForBothSides: String { return self._s[852]! }
+ public var Conversation_EditingMessageMediaEditCurrentPhoto: String { return self._s[853]! }
+ public var GroupInfo_Permissions: String { return self._s[854]! }
+ public var PasscodeSettings_TurnPasscodeOff: String { return self._s[855]! }
+ public var Profile_ShareContactButton: String { return self._s[856]! }
+ public var ChatSettings_Other: String { return self._s[857]! }
+ public var UserInfo_NotificationsDisabled: String { return self._s[858]! }
+ public var CheckoutInfo_ShippingInfoCity: String { return self._s[859]! }
+ public var LastSeen_WithinAMonth: String { return self._s[860]! }
+ public var VoiceOver_Chat_PlayHint: String { return self._s[861]! }
+ public var Conversation_ReportGroupLocation: String { return self._s[862]! }
+ public var Conversation_EncryptionCanceled: String { return self._s[863]! }
+ public var MediaPicker_GroupDescription: String { return self._s[864]! }
+ public var WebSearch_Images: String { return self._s[865]! }
public func Channel_Management_PromotedBy(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[863]!, self._r[863]!, [_0])
+ return formatWithArgumentRanges(self._s[866]!, self._r[866]!, [_0])
}
- public var Message_Photo: String { return self._s[864]! }
- public var PasscodeSettings_HelpBottom: String { return self._s[865]! }
- public var AutoDownloadSettings_VideosTitle: String { return self._s[866]! }
- public var VoiceOver_Media_PlaybackRateChange: String { return self._s[867]! }
- public var Passport_Identity_AddDriversLicense: String { return self._s[868]! }
- public var TwoStepAuth_EnterPasswordPassword: String { return self._s[869]! }
- public var NotificationsSound_Calypso: String { return self._s[870]! }
- public var Map_Map: String { return self._s[871]! }
+ public var Message_Photo: String { return self._s[867]! }
+ public var PasscodeSettings_HelpBottom: String { return self._s[868]! }
+ public var AutoDownloadSettings_VideosTitle: String { return self._s[869]! }
+ public var VoiceOver_Media_PlaybackRateChange: String { return self._s[870]! }
+ public var Passport_Identity_AddDriversLicense: String { return self._s[871]! }
+ public var TwoStepAuth_EnterPasswordPassword: String { return self._s[872]! }
+ public var NotificationsSound_Calypso: String { return self._s[873]! }
+ public var Map_Map: String { return self._s[874]! }
public func Conversation_LiveLocationYouAndOther(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[872]!, self._r[872]!, [_0])
+ return formatWithArgumentRanges(self._s[875]!, self._r[875]!, [_0])
}
- public var CheckoutInfo_ReceiverInfoTitle: String { return self._s[874]! }
- public var ChatSettings_TextSizeUnits: String { return self._s[875]! }
+ public var CheckoutInfo_ReceiverInfoTitle: String { return self._s[877]! }
+ public var ChatSettings_TextSizeUnits: String { return self._s[878]! }
public func VoiceOver_Chat_FileFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[876]!, self._r[876]!, [_0])
+ return formatWithArgumentRanges(self._s[879]!, self._r[879]!, [_0])
}
- public var Common_of: String { return self._s[877]! }
- public var Conversation_ForwardContacts: String { return self._s[880]! }
- public var IntentsSettings_SuggestByAll: String { return self._s[882]! }
+ public var Common_of: String { return self._s[880]! }
+ public var Conversation_ForwardContacts: String { return self._s[883]! }
+ public var IntentsSettings_SuggestByAll: String { return self._s[885]! }
public func Call_AnsweringWithAccount(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[883]!, self._r[883]!, [_0])
+ return formatWithArgumentRanges(self._s[886]!, self._r[886]!, [_0])
}
- public var Passport_Language_hy: String { return self._s[884]! }
- public var Notifications_MessageNotificationsHelp: String { return self._s[885]! }
- public var AutoDownloadSettings_Reset: String { return self._s[886]! }
- public var Wallet_TransactionInfo_AddressCopied: String { return self._s[887]! }
- public var Paint_ClearConfirm: String { return self._s[888]! }
- public var Camera_VideoMode: String { return self._s[889]! }
+ public var Passport_Language_hy: String { return self._s[887]! }
+ public var Notifications_MessageNotificationsHelp: String { return self._s[888]! }
+ public var AutoDownloadSettings_Reset: String { return self._s[889]! }
+ public var Wallet_TransactionInfo_AddressCopied: String { return self._s[890]! }
+ public var Paint_ClearConfirm: String { return self._s[891]! }
+ public var Camera_VideoMode: String { return self._s[892]! }
public func Conversation_RestrictedStickersTimed(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[890]!, self._r[890]!, [_0])
+ return formatWithArgumentRanges(self._s[893]!, self._r[893]!, [_0])
}
- public var Privacy_Calls_AlwaysAllow_Placeholder: String { return self._s[891]! }
- public var Conversation_ViewBackground: String { return self._s[892]! }
+ public var Privacy_Calls_AlwaysAllow_Placeholder: String { return self._s[894]! }
+ public var Conversation_ViewBackground: String { return self._s[895]! }
public func Wallet_Info_TransactionDateHeaderYear(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[893]!, self._r[893]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[896]!, self._r[896]!, [_1, _2, _3])
}
- public var Passport_Language_el: String { return self._s[894]! }
- public var PhotoEditor_Original: String { return self._s[895]! }
- public var Settings_FAQ_Button: String { return self._s[897]! }
- public var Channel_Setup_PublicNoLink: String { return self._s[899]! }
- public var Conversation_UnsupportedMedia: String { return self._s[900]! }
- public var Conversation_SlideToCancel: String { return self._s[901]! }
- public var Appearance_ThemePreview_ChatList_4_Name: String { return self._s[902]! }
- public var Passport_Identity_OneOfTypeInternalPassport: String { return self._s[903]! }
- public var CheckoutInfo_ShippingInfoPostcode: String { return self._s[904]! }
- public var Conversation_ReportSpamChannelConfirmation: String { return self._s[905]! }
- public var AutoNightTheme_NotAvailable: String { return self._s[906]! }
- public var Conversation_Owner: String { return self._s[907]! }
- public var Common_Create: String { return self._s[908]! }
- public var Settings_ApplyProxyAlertEnable: String { return self._s[909]! }
- public var ContactList_Context_Call: String { return self._s[910]! }
- public var Localization_ChooseLanguage: String { return self._s[912]! }
- public var ChatList_Context_AddToContacts: String { return self._s[914]! }
- public var OldChannels_NoticeTitle: String { return self._s[915]! }
- public var Settings_Proxy: String { return self._s[917]! }
- public var Privacy_TopPeersHelp: String { return self._s[918]! }
- public var CheckoutInfo_ShippingInfoCountryPlaceholder: String { return self._s[919]! }
- public var Chat_UnsendMyMessages: String { return self._s[920]! }
+ public var Passport_Language_el: String { return self._s[897]! }
+ public var PhotoEditor_Original: String { return self._s[898]! }
+ public var Settings_FAQ_Button: String { return self._s[900]! }
+ public var Channel_Setup_PublicNoLink: String { return self._s[902]! }
+ public var Conversation_UnsupportedMedia: String { return self._s[903]! }
+ public var Conversation_SlideToCancel: String { return self._s[904]! }
+ public var Appearance_ThemePreview_ChatList_4_Name: String { return self._s[905]! }
+ public var Passport_Identity_OneOfTypeInternalPassport: String { return self._s[906]! }
+ public var CheckoutInfo_ShippingInfoPostcode: String { return self._s[907]! }
+ public var Conversation_ReportSpamChannelConfirmation: String { return self._s[908]! }
+ public var AutoNightTheme_NotAvailable: String { return self._s[909]! }
+ public var Conversation_Owner: String { return self._s[910]! }
+ public var Common_Create: String { return self._s[911]! }
+ public var Settings_ApplyProxyAlertEnable: String { return self._s[912]! }
+ public var ContactList_Context_Call: String { return self._s[913]! }
+ public var Localization_ChooseLanguage: String { return self._s[915]! }
+ public var ChatList_Context_AddToContacts: String { return self._s[917]! }
+ public var OldChannels_NoticeTitle: String { return self._s[918]! }
+ public var Settings_Proxy: String { return self._s[920]! }
+ public var Privacy_TopPeersHelp: String { return self._s[921]! }
+ public var CheckoutInfo_ShippingInfoCountryPlaceholder: String { return self._s[922]! }
+ public var Chat_UnsendMyMessages: String { return self._s[923]! }
public func VoiceOver_Chat_Duration(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[921]!, self._r[921]!, [_0])
- }
- public var TwoStepAuth_ConfirmationAbort: String { return self._s[922]! }
- public func Contacts_AccessDeniedHelpPortrait(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[924]!, self._r[924]!, [_0])
}
- public var Contacts_SortedByPresence: String { return self._s[925]! }
- public var Passport_Identity_SurnamePlaceholder: String { return self._s[926]! }
- public var Cache_Title: String { return self._s[927]! }
+ public var TwoStepAuth_ConfirmationAbort: String { return self._s[925]! }
+ public func Contacts_AccessDeniedHelpPortrait(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[927]!, self._r[927]!, [_0])
+ }
+ public var Contacts_SortedByPresence: String { return self._s[928]! }
+ public var Passport_Identity_SurnamePlaceholder: String { return self._s[929]! }
+ public var Cache_Title: String { return self._s[930]! }
public func Login_PhoneBannedEmailSubject(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[928]!, self._r[928]!, [_0])
+ return formatWithArgumentRanges(self._s[931]!, self._r[931]!, [_0])
}
- public var TwoStepAuth_EmailCodeExpired: String { return self._s[929]! }
- public var Channel_Moderator_Title: String { return self._s[930]! }
- public var InstantPage_AutoNightTheme: String { return self._s[932]! }
+ public var TwoStepAuth_EmailCodeExpired: String { return self._s[932]! }
+ public var Channel_Moderator_Title: String { return self._s[933]! }
+ public var InstantPage_AutoNightTheme: String { return self._s[935]! }
public func PUSH_MESSAGE_POLL(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[935]!, self._r[935]!, [_1])
+ return formatWithArgumentRanges(self._s[938]!, self._r[938]!, [_1])
}
- public var Passport_Scans_Upload: String { return self._s[936]! }
- public var Undo_Undo: String { return self._s[938]! }
- public var Contacts_AccessDeniedHelpON: String { return self._s[939]! }
- public var TwoStepAuth_RemovePassword: String { return self._s[940]! }
- public var Common_Delete: String { return self._s[941]! }
- public var Contacts_AddPeopleNearby: String { return self._s[943]! }
- public var Conversation_ContextMenuDelete: String { return self._s[944]! }
- public var SocksProxySetup_Credentials: String { return self._s[945]! }
- public var Appearance_EditTheme: String { return self._s[947]! }
- public var ClearCache_StorageOtherApps: String { return self._s[948]! }
- public var PasscodeSettings_AutoLock_Disabled: String { return self._s[949]! }
- public var Wallet_Send_NetworkErrorText: String { return self._s[950]! }
- public var AuthSessions_DevicesTitle: String { return self._s[952]! }
- public var Passport_Address_OneOfTypeRentalAgreement: String { return self._s[954]! }
- public var Conversation_ShareBotContactConfirmationTitle: String { return self._s[955]! }
- public var Passport_Language_id: String { return self._s[957]! }
- public var WallpaperSearch_ColorTeal: String { return self._s[958]! }
- public var ChannelIntro_Title: String { return self._s[959]! }
+ public var Passport_Scans_Upload: String { return self._s[939]! }
+ public var Undo_Undo: String { return self._s[941]! }
+ public var Contacts_AccessDeniedHelpON: String { return self._s[942]! }
+ public var TwoStepAuth_RemovePassword: String { return self._s[943]! }
+ public var Common_Delete: String { return self._s[944]! }
+ public var Contacts_AddPeopleNearby: String { return self._s[946]! }
+ public var Conversation_ContextMenuDelete: String { return self._s[947]! }
+ public var SocksProxySetup_Credentials: String { return self._s[948]! }
+ public var Appearance_EditTheme: String { return self._s[950]! }
+ public var ClearCache_StorageOtherApps: String { return self._s[951]! }
+ public var PasscodeSettings_AutoLock_Disabled: String { return self._s[952]! }
+ public var Wallet_Send_NetworkErrorText: String { return self._s[953]! }
+ public var AuthSessions_DevicesTitle: String { return self._s[955]! }
+ public var Passport_Address_OneOfTypeRentalAgreement: String { return self._s[957]! }
+ public var Conversation_ShareBotContactConfirmationTitle: String { return self._s[958]! }
+ public var Passport_Language_id: String { return self._s[960]! }
+ public var WallpaperSearch_ColorTeal: String { return self._s[961]! }
+ public var ChannelIntro_Title: String { return self._s[962]! }
public func Channel_AdminLog_MessageToggleSignaturesOff(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[960]!, self._r[960]!, [_0])
+ return formatWithArgumentRanges(self._s[963]!, self._r[963]!, [_0])
}
- public var VoiceOver_Chat_OpenLinkHint: String { return self._s[962]! }
- public var VoiceOver_Chat_Reply: String { return self._s[963]! }
- public var ScheduledMessages_BotActionUnavailable: String { return self._s[964]! }
- public var Channel_Info_Description: String { return self._s[965]! }
- public var Stickers_FavoriteStickers: String { return self._s[966]! }
- public var Channel_BanUser_PermissionAddMembers: String { return self._s[967]! }
- public var Notifications_DisplayNamesOnLockScreen: String { return self._s[968]! }
- public var ChatSearch_ResultsTooltip: String { return self._s[969]! }
- public var Wallet_VoiceOver_Editing_ClearText: String { return self._s[970]! }
- public var Calls_NoMissedCallsPlacehoder: String { return self._s[971]! }
- public var Group_PublicLink_Placeholder: String { return self._s[972]! }
- public var Notifications_ExceptionsDefaultSound: String { return self._s[973]! }
+ public var VoiceOver_Chat_OpenLinkHint: String { return self._s[965]! }
+ public var VoiceOver_Chat_Reply: String { return self._s[966]! }
+ public var ScheduledMessages_BotActionUnavailable: String { return self._s[967]! }
+ public var Channel_Info_Description: String { return self._s[968]! }
+ public var Stickers_FavoriteStickers: String { return self._s[969]! }
+ public var Channel_BanUser_PermissionAddMembers: String { return self._s[970]! }
+ public var Notifications_DisplayNamesOnLockScreen: String { return self._s[971]! }
+ public var ChatSearch_ResultsTooltip: String { return self._s[972]! }
+ public var Wallet_VoiceOver_Editing_ClearText: String { return self._s[973]! }
+ public var Calls_NoMissedCallsPlacehoder: String { return self._s[974]! }
+ public var Group_PublicLink_Placeholder: String { return self._s[975]! }
+ public var Notifications_ExceptionsDefaultSound: String { return self._s[976]! }
public func PUSH_CHANNEL_MESSAGE_POLL(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[974]!, self._r[974]!, [_1])
+ return formatWithArgumentRanges(self._s[977]!, self._r[977]!, [_1])
}
- public var TextFormat_Underline: String { return self._s[975]! }
+ public var TextFormat_Underline: String { return self._s[978]! }
public func DialogList_SearchSubtitleFormat(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[977]!, self._r[977]!, [_1, _2])
- }
- public func Channel_AdminLog_MessageRemovedGroupStickerPack(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[978]!, self._r[978]!, [_0])
- }
- public var Appearance_ThemePreview_ChatList_3_Name: String { return self._s[979]! }
- public func Channel_OwnershipTransfer_TransferCompleted(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[980]!, self._r[980]!, [_1, _2])
}
- public var Wallet_Intro_ImportExisting: String { return self._s[981]! }
- public var GroupPermission_Delete: String { return self._s[982]! }
- public var Passport_Language_uk: String { return self._s[983]! }
- public var StickerPack_HideStickers: String { return self._s[985]! }
- public var ChangePhoneNumberNumber_NumberPlaceholder: String { return self._s[986]! }
+ public func Channel_AdminLog_MessageRemovedGroupStickerPack(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[981]!, self._r[981]!, [_0])
+ }
+ public var Appearance_ThemePreview_ChatList_3_Name: String { return self._s[982]! }
+ public func Channel_OwnershipTransfer_TransferCompleted(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[983]!, self._r[983]!, [_1, _2])
+ }
+ public var Wallet_Intro_ImportExisting: String { return self._s[984]! }
+ public var GroupPermission_Delete: String { return self._s[985]! }
+ public var Passport_Language_uk: String { return self._s[986]! }
+ public var StickerPack_HideStickers: String { return self._s[988]! }
+ public var ChangePhoneNumberNumber_NumberPlaceholder: String { return self._s[989]! }
public func PUSH_CHAT_MESSAGE_PHOTO(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[987]!, self._r[987]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[990]!, self._r[990]!, [_1, _2])
}
- public var Activity_UploadingVideoMessage: String { return self._s[988]! }
+ public var Activity_UploadingVideoMessage: String { return self._s[991]! }
public func GroupPermission_ApplyAlertText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[989]!, self._r[989]!, [_0])
+ return formatWithArgumentRanges(self._s[992]!, self._r[992]!, [_0])
}
- public var Channel_TitleInfo: String { return self._s[990]! }
- public var StickerPacksSettings_ArchivedPacks_Info: String { return self._s[991]! }
- public var Settings_CallSettings: String { return self._s[992]! }
- public var Camera_SquareMode: String { return self._s[993]! }
- public var Conversation_SendMessage_ScheduleMessage: String { return self._s[994]! }
- public var GroupInfo_SharedMediaNone: String { return self._s[995]! }
+ public var Channel_TitleInfo: String { return self._s[993]! }
+ public var StickerPacksSettings_ArchivedPacks_Info: String { return self._s[994]! }
+ public var Settings_CallSettings: String { return self._s[995]! }
+ public var Camera_SquareMode: String { return self._s[996]! }
+ public var Conversation_SendMessage_ScheduleMessage: String { return self._s[997]! }
+ public var GroupInfo_SharedMediaNone: String { return self._s[998]! }
public func PUSH_MESSAGE_VIDEO_SECRET(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[996]!, self._r[996]!, [_1])
+ return formatWithArgumentRanges(self._s[999]!, self._r[999]!, [_1])
}
- public var Bot_GenericBotStatus: String { return self._s[997]! }
- public var Application_Update: String { return self._s[999]! }
- public var Month_ShortJanuary: String { return self._s[1000]! }
- public var Contacts_PermissionsKeepDisabled: String { return self._s[1001]! }
- public var Channel_AdminLog_BanReadMessages: String { return self._s[1002]! }
- public var Settings_AppLanguage_Unofficial: String { return self._s[1003]! }
- public var Passport_Address_Street2Placeholder: String { return self._s[1004]! }
+ public var Bot_GenericBotStatus: String { return self._s[1000]! }
+ public var Application_Update: String { return self._s[1002]! }
+ public var Month_ShortJanuary: String { return self._s[1003]! }
+ public var Contacts_PermissionsKeepDisabled: String { return self._s[1004]! }
+ public var Channel_AdminLog_BanReadMessages: String { return self._s[1005]! }
+ public var Settings_AppLanguage_Unofficial: String { return self._s[1006]! }
+ public var Passport_Address_Street2Placeholder: String { return self._s[1007]! }
public func Map_LiveLocationShortHour(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1005]!, self._r[1005]!, [_0])
- }
- public var NetworkUsageSettings_Cellular: String { return self._s[1006]! }
- public var Appearance_PreviewOutgoingText: String { return self._s[1007]! }
- public func StickerPackActionInfo_RemovedText(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[1008]!, self._r[1008]!, [_0])
}
- public var Notifications_PermissionsAllowInSettings: String { return self._s[1009]! }
- public var AutoDownloadSettings_OnForAll: String { return self._s[1011]! }
- public var Map_Directions: String { return self._s[1012]! }
- public var Passport_FieldIdentityTranslationHelp: String { return self._s[1014]! }
- public var Appearance_ThemeDay: String { return self._s[1015]! }
- public var LogoutOptions_LogOut: String { return self._s[1016]! }
- public var Group_PublicLink_Title: String { return self._s[1018]! }
- public var Channel_AddBotErrorNoRights: String { return self._s[1019]! }
- public var ChatList_Search_ShowLess: String { return self._s[1020]! }
- public var Passport_Identity_AddPassport: String { return self._s[1021]! }
- public var LocalGroup_ButtonTitle: String { return self._s[1022]! }
- public var Call_Message: String { return self._s[1023]! }
- public var PhotoEditor_ExposureTool: String { return self._s[1024]! }
- public var Wallet_Receive_CommentInfo: String { return self._s[1026]! }
- public var Passport_FieldOneOf_Delimeter: String { return self._s[1027]! }
- public var Channel_AdminLog_CanBanUsers: String { return self._s[1029]! }
- public var Appearance_ThemePreview_ChatList_2_Name: String { return self._s[1030]! }
- public var Appearance_Preview: String { return self._s[1031]! }
- public var Compose_ChannelMembers: String { return self._s[1032]! }
- public var Conversation_DeleteManyMessages: String { return self._s[1033]! }
- public var ReportPeer_ReasonOther_Title: String { return self._s[1034]! }
- public var Checkout_ErrorProviderAccountTimeout: String { return self._s[1035]! }
- public var TwoStepAuth_ResetAccountConfirmation: String { return self._s[1036]! }
- public var Channel_Stickers_CreateYourOwn: String { return self._s[1039]! }
- public var Conversation_UpdateTelegram: String { return self._s[1040]! }
- public var EditTheme_Create_TopInfo: String { return self._s[1041]! }
+ public var NetworkUsageSettings_Cellular: String { return self._s[1009]! }
+ public var Appearance_PreviewOutgoingText: String { return self._s[1010]! }
+ public func StickerPackActionInfo_RemovedText(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[1011]!, self._r[1011]!, [_0])
+ }
+ public var Notifications_PermissionsAllowInSettings: String { return self._s[1012]! }
+ public var AutoDownloadSettings_OnForAll: String { return self._s[1014]! }
+ public var Map_Directions: String { return self._s[1015]! }
+ public var Passport_FieldIdentityTranslationHelp: String { return self._s[1017]! }
+ public var Appearance_ThemeDay: String { return self._s[1018]! }
+ public var LogoutOptions_LogOut: String { return self._s[1019]! }
+ public var Group_PublicLink_Title: String { return self._s[1021]! }
+ public var Channel_AddBotErrorNoRights: String { return self._s[1022]! }
+ public var ChatList_Search_ShowLess: String { return self._s[1023]! }
+ public var Passport_Identity_AddPassport: String { return self._s[1024]! }
+ public var LocalGroup_ButtonTitle: String { return self._s[1025]! }
+ public var Call_Message: String { return self._s[1026]! }
+ public var PhotoEditor_ExposureTool: String { return self._s[1027]! }
+ public var Wallet_Receive_CommentInfo: String { return self._s[1029]! }
+ public var Passport_FieldOneOf_Delimeter: String { return self._s[1030]! }
+ public var Channel_AdminLog_CanBanUsers: String { return self._s[1032]! }
+ public var Appearance_ThemePreview_ChatList_2_Name: String { return self._s[1033]! }
+ public var Appearance_Preview: String { return self._s[1034]! }
+ public var Compose_ChannelMembers: String { return self._s[1035]! }
+ public var Conversation_DeleteManyMessages: String { return self._s[1036]! }
+ public var ReportPeer_ReasonOther_Title: String { return self._s[1037]! }
+ public var Checkout_ErrorProviderAccountTimeout: String { return self._s[1038]! }
+ public var TwoStepAuth_ResetAccountConfirmation: String { return self._s[1039]! }
+ public var Channel_Stickers_CreateYourOwn: String { return self._s[1042]! }
+ public var Conversation_UpdateTelegram: String { return self._s[1043]! }
+ public var EditTheme_Create_TopInfo: String { return self._s[1044]! }
public func Notification_PinnedPhotoMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1042]!, self._r[1042]!, [_0])
+ return formatWithArgumentRanges(self._s[1045]!, self._r[1045]!, [_0])
}
- public var Wallet_WordCheck_Continue: String { return self._s[1043]! }
- public var TwoFactorSetup_Hint_Action: String { return self._s[1044]! }
- public var IntentsSettings_ResetAll: String { return self._s[1045]! }
+ public var Wallet_WordCheck_Continue: String { return self._s[1046]! }
+ public var TwoFactorSetup_Hint_Action: String { return self._s[1047]! }
+ public var IntentsSettings_ResetAll: String { return self._s[1048]! }
public func PUSH_PINNED_GIF(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1046]!, self._r[1046]!, [_1])
+ return formatWithArgumentRanges(self._s[1049]!, self._r[1049]!, [_1])
}
- public var GroupInfo_Administrators_Title: String { return self._s[1047]! }
- public var Privacy_Forwards_PreviewMessageText: String { return self._s[1048]! }
+ public var GroupInfo_Administrators_Title: String { return self._s[1050]! }
+ public var Privacy_Forwards_PreviewMessageText: String { return self._s[1051]! }
public func PrivacySettings_LastSeenNobodyPlus(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1049]!, self._r[1049]!, [_0])
+ return formatWithArgumentRanges(self._s[1052]!, self._r[1052]!, [_0])
}
- public var Tour_Title3: String { return self._s[1050]! }
- public var Channel_EditAdmin_PermissionInviteSubscribers: String { return self._s[1051]! }
- public var Clipboard_SendPhoto: String { return self._s[1055]! }
- public var MediaPicker_Videos: String { return self._s[1056]! }
- public var Passport_Email_Title: String { return self._s[1057]! }
+ public var Tour_Title3: String { return self._s[1053]! }
+ public var Channel_EditAdmin_PermissionInviteSubscribers: String { return self._s[1054]! }
+ public var Clipboard_SendPhoto: String { return self._s[1058]! }
+ public var MediaPicker_Videos: String { return self._s[1059]! }
+ public var Passport_Email_Title: String { return self._s[1060]! }
public func PrivacySettings_LastSeenEverybodyMinus(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1058]!, self._r[1058]!, [_0])
+ return formatWithArgumentRanges(self._s[1061]!, self._r[1061]!, [_0])
}
- public var StickerPacksSettings_Title: String { return self._s[1059]! }
- public var Conversation_MessageDialogDelete: String { return self._s[1060]! }
- public var Privacy_Calls_CustomHelp: String { return self._s[1062]! }
- public var Message_Wallpaper: String { return self._s[1063]! }
- public var MemberSearch_BotSection: String { return self._s[1064]! }
- public var GroupInfo_SetSound: String { return self._s[1065]! }
- public var Core_ServiceUserStatus: String { return self._s[1066]! }
- public var LiveLocationUpdated_JustNow: String { return self._s[1067]! }
- public var Call_StatusFailed: String { return self._s[1068]! }
- public var TwoFactorSetup_Email_Placeholder: String { return self._s[1069]! }
- public var TwoStepAuth_SetupPasswordDescription: String { return self._s[1070]! }
- public var TwoStepAuth_SetPassword: String { return self._s[1071]! }
- public var Permissions_PeopleNearbyText_v0: String { return self._s[1072]! }
+ public var StickerPacksSettings_Title: String { return self._s[1062]! }
+ public var Conversation_MessageDialogDelete: String { return self._s[1063]! }
+ public var Privacy_Calls_CustomHelp: String { return self._s[1065]! }
+ public var Message_Wallpaper: String { return self._s[1066]! }
+ public var MemberSearch_BotSection: String { return self._s[1067]! }
+ public var GroupInfo_SetSound: String { return self._s[1068]! }
+ public func Time_TomorrowAt(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[1069]!, self._r[1069]!, [_0])
+ }
+ public var Core_ServiceUserStatus: String { return self._s[1070]! }
+ public var LiveLocationUpdated_JustNow: String { return self._s[1071]! }
+ public var Call_StatusFailed: String { return self._s[1072]! }
+ public var TwoFactorSetup_Email_Placeholder: String { return self._s[1073]! }
+ public var TwoStepAuth_SetupPasswordDescription: String { return self._s[1074]! }
+ public var TwoStepAuth_SetPassword: String { return self._s[1075]! }
+ public var Permissions_PeopleNearbyText_v0: String { return self._s[1076]! }
public func SocksProxySetup_ProxyStatusPing(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1074]!, self._r[1074]!, [_0])
+ return formatWithArgumentRanges(self._s[1078]!, self._r[1078]!, [_0])
}
- public var Calls_SubmitRating: String { return self._s[1075]! }
- public var Map_NoPlacesNearby: String { return self._s[1076]! }
- public var Profile_Username: String { return self._s[1077]! }
- public var Bot_DescriptionTitle: String { return self._s[1078]! }
- public var MaskStickerSettings_Title: String { return self._s[1079]! }
- public var SharedMedia_CategoryOther: String { return self._s[1080]! }
- public var GroupInfo_SetGroupPhoto: String { return self._s[1081]! }
- public var Common_NotNow: String { return self._s[1082]! }
- public var CallFeedback_IncludeLogsInfo: String { return self._s[1083]! }
- public var Conversation_ShareMyPhoneNumber: String { return self._s[1084]! }
- public var Map_Location: String { return self._s[1085]! }
- public var Invitation_JoinGroup: String { return self._s[1086]! }
- public var AutoDownloadSettings_Title: String { return self._s[1088]! }
- public var Conversation_DiscardVoiceMessageDescription: String { return self._s[1089]! }
- public var Channel_ErrorAddBlocked: String { return self._s[1090]! }
- public var Conversation_UnblockUser: String { return self._s[1091]! }
- public var EditTheme_Edit_TopInfo: String { return self._s[1092]! }
- public var Watch_Bot_Restart: String { return self._s[1093]! }
- public var TwoStepAuth_Title: String { return self._s[1094]! }
- public var Channel_AdminLog_BanSendMessages: String { return self._s[1095]! }
- public var Checkout_ShippingMethod: String { return self._s[1096]! }
- public var Passport_Identity_OneOfTypeIdentityCard: String { return self._s[1097]! }
+ public var Calls_SubmitRating: String { return self._s[1079]! }
+ public var Map_NoPlacesNearby: String { return self._s[1080]! }
+ public var Profile_Username: String { return self._s[1081]! }
+ public var Bot_DescriptionTitle: String { return self._s[1082]! }
+ public var MaskStickerSettings_Title: String { return self._s[1083]! }
+ public var SharedMedia_CategoryOther: String { return self._s[1084]! }
+ public var GroupInfo_SetGroupPhoto: String { return self._s[1085]! }
+ public var Common_NotNow: String { return self._s[1086]! }
+ public var CallFeedback_IncludeLogsInfo: String { return self._s[1087]! }
+ public var Conversation_ShareMyPhoneNumber: String { return self._s[1088]! }
+ public var Map_Location: String { return self._s[1089]! }
+ public var Invitation_JoinGroup: String { return self._s[1090]! }
+ public var AutoDownloadSettings_Title: String { return self._s[1092]! }
+ public var Conversation_DiscardVoiceMessageDescription: String { return self._s[1093]! }
+ public var Channel_ErrorAddBlocked: String { return self._s[1094]! }
+ public var Conversation_UnblockUser: String { return self._s[1095]! }
+ public var EditTheme_Edit_TopInfo: String { return self._s[1096]! }
+ public var Watch_Bot_Restart: String { return self._s[1097]! }
+ public var TwoStepAuth_Title: String { return self._s[1098]! }
+ public var Channel_AdminLog_BanSendMessages: String { return self._s[1099]! }
+ public var Checkout_ShippingMethod: String { return self._s[1100]! }
+ public var Passport_Identity_OneOfTypeIdentityCard: String { return self._s[1101]! }
public func PUSH_CHAT_MESSAGE_STICKER(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1098]!, self._r[1098]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1102]!, self._r[1102]!, [_1, _2, _3])
}
- public var EditTheme_ChangeColors: String { return self._s[1100]! }
+ public var EditTheme_ChangeColors: String { return self._s[1104]! }
public func Chat_UnsendMyMessagesAlertTitle(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1101]!, self._r[1101]!, [_0])
+ return formatWithArgumentRanges(self._s[1105]!, self._r[1105]!, [_0])
}
public func Channel_Username_LinkHint(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1102]!, self._r[1102]!, [_0])
+ return formatWithArgumentRanges(self._s[1106]!, self._r[1106]!, [_0])
}
- public var Appearance_ThemePreview_ChatList_1_Name: String { return self._s[1103]! }
- public var SettingsSearch_Synonyms_Data_AutoplayGifs: String { return self._s[1104]! }
- public var AuthSessions_TerminateOtherSessions: String { return self._s[1105]! }
- public var Contacts_FailedToSendInvitesMessage: String { return self._s[1106]! }
- public var PrivacySettings_TwoStepAuth: String { return self._s[1107]! }
- public var Notification_Exceptions_PreviewAlwaysOn: String { return self._s[1108]! }
- public var SettingsSearch_Synonyms_Privacy_Passcode: String { return self._s[1109]! }
- public var Conversation_EditingMessagePanelMedia: String { return self._s[1110]! }
- public var Checkout_PaymentMethod_Title: String { return self._s[1111]! }
- public var SocksProxySetup_Connection: String { return self._s[1112]! }
- public var Group_MessagePhotoRemoved: String { return self._s[1113]! }
- public var Channel_Stickers_NotFound: String { return self._s[1116]! }
- public var Group_About_Help: String { return self._s[1117]! }
- public var Notification_PassportValueProofOfIdentity: String { return self._s[1118]! }
- public var PeopleNearby_Title: String { return self._s[1120]! }
+ public var Appearance_ThemePreview_ChatList_1_Name: String { return self._s[1107]! }
+ public var SettingsSearch_Synonyms_Data_AutoplayGifs: String { return self._s[1108]! }
+ public var AuthSessions_TerminateOtherSessions: String { return self._s[1109]! }
+ public var Contacts_FailedToSendInvitesMessage: String { return self._s[1110]! }
+ public var PrivacySettings_TwoStepAuth: String { return self._s[1111]! }
+ public var Notification_Exceptions_PreviewAlwaysOn: String { return self._s[1112]! }
+ public var SettingsSearch_Synonyms_Privacy_Passcode: String { return self._s[1113]! }
+ public var Conversation_EditingMessagePanelMedia: String { return self._s[1114]! }
+ public var Checkout_PaymentMethod_Title: String { return self._s[1115]! }
+ public var SocksProxySetup_Connection: String { return self._s[1116]! }
+ public var Group_MessagePhotoRemoved: String { return self._s[1117]! }
+ public var PeopleNearby_MakeInvisible: String { return self._s[1119]! }
+ public var Channel_Stickers_NotFound: String { return self._s[1121]! }
+ public var Group_About_Help: String { return self._s[1122]! }
+ public var Notification_PassportValueProofOfIdentity: String { return self._s[1123]! }
+ public var PeopleNearby_Title: String { return self._s[1125]! }
public func ApplyLanguage_ChangeLanguageOfficialText(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1121]!, self._r[1121]!, [_1])
+ return formatWithArgumentRanges(self._s[1126]!, self._r[1126]!, [_1])
}
- public var Map_Home: String { return self._s[1122]! }
- public var CheckoutInfo_ShippingInfoStatePlaceholder: String { return self._s[1124]! }
- public var Notifications_GroupNotificationsExceptionsHelp: String { return self._s[1125]! }
- public var SocksProxySetup_Password: String { return self._s[1126]! }
- public var Notifications_PermissionsEnable: String { return self._s[1127]! }
- public var TwoStepAuth_ChangeEmail: String { return self._s[1129]! }
+ public var Map_Home: String { return self._s[1127]! }
+ public var CheckoutInfo_ShippingInfoStatePlaceholder: String { return self._s[1129]! }
+ public var Notifications_GroupNotificationsExceptionsHelp: String { return self._s[1130]! }
+ public var SocksProxySetup_Password: String { return self._s[1131]! }
+ public var Notifications_PermissionsEnable: String { return self._s[1132]! }
+ public var TwoStepAuth_ChangeEmail: String { return self._s[1134]! }
public func Channel_AdminLog_MessageInvitedName(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1130]!, self._r[1130]!, [_1])
+ return formatWithArgumentRanges(self._s[1135]!, self._r[1135]!, [_1])
}
public func Time_MonthOfYear_m10(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1132]!, self._r[1132]!, [_0])
+ return formatWithArgumentRanges(self._s[1137]!, self._r[1137]!, [_0])
}
- public var Passport_Identity_TypeDriversLicense: String { return self._s[1133]! }
- public var ArchivedPacksAlert_Title: String { return self._s[1134]! }
- public var Wallet_Receive_InvoiceUrlCopied: String { return self._s[1135]! }
- public var Map_PlacesNearby: String { return self._s[1136]! }
+ public var Passport_Identity_TypeDriversLicense: String { return self._s[1138]! }
+ public var ArchivedPacksAlert_Title: String { return self._s[1139]! }
+ public var Wallet_Receive_InvoiceUrlCopied: String { return self._s[1140]! }
+ public var Map_PlacesNearby: String { return self._s[1141]! }
public func Time_PreciseDate_m7(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1137]!, self._r[1137]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1142]!, self._r[1142]!, [_1, _2, _3])
}
- public var PrivacyLastSeenSettings_GroupsAndChannelsHelp: String { return self._s[1138]! }
- public var Privacy_Calls_NeverAllow_Placeholder: String { return self._s[1140]! }
- public var Conversation_StatusTyping: String { return self._s[1141]! }
- public var Broadcast_AdminLog_EmptyText: String { return self._s[1142]! }
- public var Notification_PassportValueProofOfAddress: String { return self._s[1143]! }
- public var UserInfo_CreateNewContact: String { return self._s[1144]! }
- public var Passport_Identity_FrontSide: String { return self._s[1145]! }
- public var Login_PhoneNumberAlreadyAuthorizedSwitch: String { return self._s[1146]! }
- public var Calls_CallTabTitle: String { return self._s[1147]! }
- public var Channel_AdminLog_ChannelEmptyText: String { return self._s[1148]! }
+ public var PrivacyLastSeenSettings_GroupsAndChannelsHelp: String { return self._s[1143]! }
+ public var Privacy_Calls_NeverAllow_Placeholder: String { return self._s[1145]! }
+ public var Conversation_StatusTyping: String { return self._s[1146]! }
+ public var Broadcast_AdminLog_EmptyText: String { return self._s[1147]! }
+ public var Notification_PassportValueProofOfAddress: String { return self._s[1148]! }
+ public var UserInfo_CreateNewContact: String { return self._s[1149]! }
+ public var Passport_Identity_FrontSide: String { return self._s[1150]! }
+ public var Login_PhoneNumberAlreadyAuthorizedSwitch: String { return self._s[1151]! }
+ public var Calls_CallTabTitle: String { return self._s[1152]! }
+ public var Channel_AdminLog_ChannelEmptyText: String { return self._s[1153]! }
public func Login_BannedPhoneBody(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1150]!, self._r[1150]!, [_0])
+ return formatWithArgumentRanges(self._s[1155]!, self._r[1155]!, [_0])
}
- public var Watch_UserInfo_MuteTitle: String { return self._s[1151]! }
- public var Group_EditAdmin_RankAdminPlaceholder: String { return self._s[1152]! }
- public var SharedMedia_EmptyMusicText: String { return self._s[1153]! }
- public var Wallet_Completed_Text: String { return self._s[1154]! }
- public var PasscodeSettings_AutoLock_IfAwayFor_1minute: String { return self._s[1155]! }
- public var Paint_Stickers: String { return self._s[1156]! }
- public var Privacy_GroupsAndChannels: String { return self._s[1157]! }
- public var ChatList_Context_Delete: String { return self._s[1159]! }
- public var UserInfo_AddContact: String { return self._s[1160]! }
+ public var Watch_UserInfo_MuteTitle: String { return self._s[1156]! }
+ public var Group_EditAdmin_RankAdminPlaceholder: String { return self._s[1157]! }
+ public var SharedMedia_EmptyMusicText: String { return self._s[1158]! }
+ public var Wallet_Completed_Text: String { return self._s[1159]! }
+ public var PasscodeSettings_AutoLock_IfAwayFor_1minute: String { return self._s[1160]! }
+ public var Paint_Stickers: String { return self._s[1161]! }
+ public var Privacy_GroupsAndChannels: String { return self._s[1162]! }
+ public var ChatList_Context_Delete: String { return self._s[1164]! }
+ public var UserInfo_AddContact: String { return self._s[1165]! }
public func Conversation_MessageViaUser(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1161]!, self._r[1161]!, [_0])
+ return formatWithArgumentRanges(self._s[1166]!, self._r[1166]!, [_0])
}
- public var PhoneNumberHelp_ChangeNumber: String { return self._s[1163]! }
+ public var PhoneNumberHelp_ChangeNumber: String { return self._s[1168]! }
public func ChatList_ClearChatConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1165]!, self._r[1165]!, [_0])
+ return formatWithArgumentRanges(self._s[1170]!, self._r[1170]!, [_0])
}
- public var DialogList_NoMessagesTitle: String { return self._s[1166]! }
- public var EditProfile_NameAndPhotoHelp: String { return self._s[1167]! }
- public var BlockedUsers_BlockUser: String { return self._s[1168]! }
- public var Notifications_PermissionsOpenSettings: String { return self._s[1169]! }
- public var MediaPicker_UngroupDescription: String { return self._s[1171]! }
- public var Watch_NoConnection: String { return self._s[1172]! }
- public var Month_GenSeptember: String { return self._s[1173]! }
- public var Conversation_ViewGroup: String { return self._s[1175]! }
- public var Channel_AdminLogFilter_EventsLeavingSubscribers: String { return self._s[1178]! }
- public var Privacy_Forwards_AlwaysLink: String { return self._s[1179]! }
- public var Channel_OwnershipTransfer_ErrorAdminsTooMuch: String { return self._s[1180]! }
- public var Passport_FieldOneOf_FinalDelimeter: String { return self._s[1181]! }
- public var Wallet_WordCheck_IncorrectHeader: String { return self._s[1182]! }
- public var MediaPicker_CameraRoll: String { return self._s[1184]! }
- public var Month_GenAugust: String { return self._s[1185]! }
- public var Wallet_Configuration_SourceHeader: String { return self._s[1186]! }
- public var AccessDenied_VideoMessageMicrophone: String { return self._s[1187]! }
- public var SharedMedia_EmptyText: String { return self._s[1188]! }
- public var Map_ShareLiveLocation: String { return self._s[1189]! }
- public var Calls_All: String { return self._s[1190]! }
- public var Map_SendThisPlace: String { return self._s[1192]! }
- public var Appearance_ThemeNight: String { return self._s[1194]! }
- public var Conversation_HoldForAudio: String { return self._s[1195]! }
- public var SettingsSearch_Synonyms_Support: String { return self._s[1198]! }
- public var GroupInfo_GroupHistoryHidden: String { return self._s[1199]! }
- public var SocksProxySetup_Secret: String { return self._s[1200]! }
+ public var DialogList_NoMessagesTitle: String { return self._s[1171]! }
+ public var EditProfile_NameAndPhotoHelp: String { return self._s[1172]! }
+ public var BlockedUsers_BlockUser: String { return self._s[1173]! }
+ public var Notifications_PermissionsOpenSettings: String { return self._s[1174]! }
+ public var MediaPicker_UngroupDescription: String { return self._s[1176]! }
+ public var Watch_NoConnection: String { return self._s[1177]! }
+ public var Month_GenSeptember: String { return self._s[1178]! }
+ public var Conversation_ViewGroup: String { return self._s[1180]! }
+ public var Channel_AdminLogFilter_EventsLeavingSubscribers: String { return self._s[1183]! }
+ public var Privacy_Forwards_AlwaysLink: String { return self._s[1184]! }
+ public var Channel_OwnershipTransfer_ErrorAdminsTooMuch: String { return self._s[1185]! }
+ public var Passport_FieldOneOf_FinalDelimeter: String { return self._s[1186]! }
+ public var Wallet_WordCheck_IncorrectHeader: String { return self._s[1187]! }
+ public var MediaPicker_CameraRoll: String { return self._s[1189]! }
+ public var Month_GenAugust: String { return self._s[1190]! }
+ public var Wallet_Configuration_SourceHeader: String { return self._s[1191]! }
+ public var AccessDenied_VideoMessageMicrophone: String { return self._s[1192]! }
+ public var SharedMedia_EmptyText: String { return self._s[1193]! }
+ public var Map_ShareLiveLocation: String { return self._s[1194]! }
+ public var Calls_All: String { return self._s[1195]! }
+ public var Map_SendThisPlace: String { return self._s[1197]! }
+ public var Appearance_ThemeNight: String { return self._s[1199]! }
+ public var Conversation_HoldForAudio: String { return self._s[1200]! }
+ public var SettingsSearch_Synonyms_Support: String { return self._s[1203]! }
+ public var GroupInfo_GroupHistoryHidden: String { return self._s[1204]! }
+ public var SocksProxySetup_Secret: String { return self._s[1205]! }
public func Activity_RemindAboutChannel(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1201]!, self._r[1201]!, [_0])
+ return formatWithArgumentRanges(self._s[1206]!, self._r[1206]!, [_0])
}
- public var Channel_BanList_RestrictedTitle: String { return self._s[1203]! }
- public var Conversation_Location: String { return self._s[1204]! }
+ public var Channel_BanList_RestrictedTitle: String { return self._s[1208]! }
+ public var Conversation_Location: String { return self._s[1209]! }
public func AutoDownloadSettings_UpToFor(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1205]!, self._r[1205]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1210]!, self._r[1210]!, [_1, _2])
}
- public var ChatSettings_AutoDownloadPhotos: String { return self._s[1207]! }
- public var SettingsSearch_Synonyms_Privacy_Title: String { return self._s[1208]! }
- public var Notifications_PermissionsText: String { return self._s[1209]! }
- public var SettingsSearch_Synonyms_Data_SaveIncomingPhotos: String { return self._s[1210]! }
- public var Call_Flip: String { return self._s[1211]! }
- public var Channel_AdminLog_CanDeleteMessagesOfOthers: String { return self._s[1213]! }
- public var SocksProxySetup_ProxyStatusConnecting: String { return self._s[1214]! }
- public var Wallet_TransactionInfo_StorageFeeInfoUrl: String { return self._s[1215]! }
- public var PrivacyPhoneNumberSettings_DiscoveryHeader: String { return self._s[1216]! }
- public var Channel_EditAdmin_PermissionPinMessages: String { return self._s[1218]! }
- public var TwoStepAuth_ReEnterPasswordDescription: String { return self._s[1220]! }
- public var Channel_TooMuchBots: String { return self._s[1222]! }
- public var Passport_DeletePassportConfirmation: String { return self._s[1223]! }
- public var Login_InvalidCodeError: String { return self._s[1224]! }
- public var StickerPacksSettings_FeaturedPacks: String { return self._s[1225]! }
+ public var ChatSettings_AutoDownloadPhotos: String { return self._s[1212]! }
+ public var SettingsSearch_Synonyms_Privacy_Title: String { return self._s[1213]! }
+ public var Notifications_PermissionsText: String { return self._s[1214]! }
+ public var SettingsSearch_Synonyms_Data_SaveIncomingPhotos: String { return self._s[1215]! }
+ public var Call_Flip: String { return self._s[1216]! }
+ public var Channel_AdminLog_CanDeleteMessagesOfOthers: String { return self._s[1218]! }
+ public var SocksProxySetup_ProxyStatusConnecting: String { return self._s[1219]! }
+ public var Wallet_TransactionInfo_StorageFeeInfoUrl: String { return self._s[1220]! }
+ public var PrivacyPhoneNumberSettings_DiscoveryHeader: String { return self._s[1221]! }
+ public var Channel_EditAdmin_PermissionPinMessages: String { return self._s[1223]! }
+ public var TwoStepAuth_ReEnterPasswordDescription: String { return self._s[1225]! }
+ public var Channel_TooMuchBots: String { return self._s[1227]! }
+ public var Passport_DeletePassportConfirmation: String { return self._s[1228]! }
+ public var Login_InvalidCodeError: String { return self._s[1229]! }
+ public var StickerPacksSettings_FeaturedPacks: String { return self._s[1230]! }
public func ChatList_DeleteSecretChatConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1226]!, self._r[1226]!, [_0])
+ return formatWithArgumentRanges(self._s[1231]!, self._r[1231]!, [_0])
}
public func GroupInfo_InvitationLinkAcceptChannel(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1227]!, self._r[1227]!, [_0])
+ return formatWithArgumentRanges(self._s[1232]!, self._r[1232]!, [_0])
}
- public var VoiceOver_Navigation_ProxySettings: String { return self._s[1228]! }
- public var Call_CallInProgressTitle: String { return self._s[1229]! }
- public var Month_ShortSeptember: String { return self._s[1230]! }
- public var Watch_ChannelInfo_Title: String { return self._s[1231]! }
- public var ChatList_DeleteSavedMessagesConfirmation: String { return self._s[1234]! }
- public var DialogList_PasscodeLockHelp: String { return self._s[1235]! }
- public var Chat_MultipleTextMessagesDisabled: String { return self._s[1236]! }
- public var Wallet_Receive_Title: String { return self._s[1237]! }
- public var Notifications_Badge_IncludePublicGroups: String { return self._s[1238]! }
- public var Channel_AdminLogFilter_EventsTitle: String { return self._s[1239]! }
- public var PhotoEditor_CropReset: String { return self._s[1240]! }
- public var Group_Username_CreatePrivateLinkHelp: String { return self._s[1242]! }
- public var Channel_Management_LabelEditor: String { return self._s[1243]! }
- public var Passport_Identity_LatinNameHelp: String { return self._s[1245]! }
- public var PhotoEditor_HighlightsTool: String { return self._s[1246]! }
- public var Wallet_Info_WalletCreated: String { return self._s[1247]! }
- public var UserInfo_Title: String { return self._s[1248]! }
- public var ChatList_HideAction: String { return self._s[1249]! }
- public var AccessDenied_Title: String { return self._s[1250]! }
- public var DialogList_SearchLabel: String { return self._s[1251]! }
- public var Group_Setup_HistoryHidden: String { return self._s[1252]! }
- public var TwoStepAuth_PasswordChangeSuccess: String { return self._s[1253]! }
- public var State_Updating: String { return self._s[1255]! }
- public var Contacts_TabTitle: String { return self._s[1256]! }
- public var Notifications_Badge_CountUnreadMessages: String { return self._s[1258]! }
- public var GroupInfo_GroupHistory: String { return self._s[1259]! }
- public var Conversation_UnsupportedMediaPlaceholder: String { return self._s[1260]! }
- public var Wallpaper_SetColor: String { return self._s[1261]! }
- public var CheckoutInfo_ShippingInfoCountry: String { return self._s[1262]! }
- public var SettingsSearch_Synonyms_SavedMessages: String { return self._s[1263]! }
- public var Chat_AttachmentLimitReached: String { return self._s[1264]! }
- public var Passport_Identity_OneOfTypeDriversLicense: String { return self._s[1265]! }
- public var Contacts_NotRegisteredSection: String { return self._s[1266]! }
+ public var VoiceOver_Navigation_ProxySettings: String { return self._s[1233]! }
+ public var Call_CallInProgressTitle: String { return self._s[1234]! }
+ public var Month_ShortSeptember: String { return self._s[1235]! }
+ public var Watch_ChannelInfo_Title: String { return self._s[1236]! }
+ public var ChatList_DeleteSavedMessagesConfirmation: String { return self._s[1239]! }
+ public var DialogList_PasscodeLockHelp: String { return self._s[1240]! }
+ public var Chat_MultipleTextMessagesDisabled: String { return self._s[1241]! }
+ public var Wallet_Receive_Title: String { return self._s[1242]! }
+ public var Notifications_Badge_IncludePublicGroups: String { return self._s[1243]! }
+ public var Channel_AdminLogFilter_EventsTitle: String { return self._s[1244]! }
+ public var PhotoEditor_CropReset: String { return self._s[1245]! }
+ public var Group_Username_CreatePrivateLinkHelp: String { return self._s[1247]! }
+ public var Channel_Management_LabelEditor: String { return self._s[1248]! }
+ public var Passport_Identity_LatinNameHelp: String { return self._s[1250]! }
+ public var PhotoEditor_HighlightsTool: String { return self._s[1251]! }
+ public var Wallet_Info_WalletCreated: String { return self._s[1252]! }
+ public var UserInfo_Title: String { return self._s[1253]! }
+ public var ChatList_HideAction: String { return self._s[1254]! }
+ public var AccessDenied_Title: String { return self._s[1255]! }
+ public var DialogList_SearchLabel: String { return self._s[1256]! }
+ public var Group_Setup_HistoryHidden: String { return self._s[1257]! }
+ public var TwoStepAuth_PasswordChangeSuccess: String { return self._s[1258]! }
+ public var State_Updating: String { return self._s[1260]! }
+ public var Contacts_TabTitle: String { return self._s[1261]! }
+ public var Notifications_Badge_CountUnreadMessages: String { return self._s[1263]! }
+ public var GroupInfo_GroupHistory: String { return self._s[1264]! }
+ public var Conversation_UnsupportedMediaPlaceholder: String { return self._s[1265]! }
+ public var Wallpaper_SetColor: String { return self._s[1266]! }
+ public var CheckoutInfo_ShippingInfoCountry: String { return self._s[1267]! }
+ public var SettingsSearch_Synonyms_SavedMessages: String { return self._s[1268]! }
+ public var Chat_AttachmentLimitReached: String { return self._s[1269]! }
+ public var Passport_Identity_OneOfTypeDriversLicense: String { return self._s[1270]! }
+ public var Contacts_NotRegisteredSection: String { return self._s[1271]! }
public func Time_PreciseDate_m4(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1267]!, self._r[1267]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1272]!, self._r[1272]!, [_1, _2, _3])
}
- public var Paint_Clear: String { return self._s[1268]! }
- public var StickerPacksSettings_ArchivedMasks: String { return self._s[1269]! }
- public var SocksProxySetup_Connecting: String { return self._s[1270]! }
- public var ExplicitContent_AlertChannel: String { return self._s[1271]! }
- public var CreatePoll_AllOptionsAdded: String { return self._s[1272]! }
- public var Conversation_Contact: String { return self._s[1273]! }
- public var Login_CodeExpired: String { return self._s[1274]! }
- public var Passport_DiscardMessageAction: String { return self._s[1275]! }
- public var ChatList_Context_Unpin: String { return self._s[1276]! }
- public var Channel_AdminLog_MessagePreviousDescription: String { return self._s[1277]! }
+ public var Paint_Clear: String { return self._s[1273]! }
+ public var StickerPacksSettings_ArchivedMasks: String { return self._s[1274]! }
+ public var SocksProxySetup_Connecting: String { return self._s[1275]! }
+ public var ExplicitContent_AlertChannel: String { return self._s[1276]! }
+ public var CreatePoll_AllOptionsAdded: String { return self._s[1277]! }
+ public var Conversation_Contact: String { return self._s[1278]! }
+ public var Login_CodeExpired: String { return self._s[1279]! }
+ public var Passport_DiscardMessageAction: String { return self._s[1280]! }
+ public var ChatList_Context_Unpin: String { return self._s[1281]! }
+ public var Channel_AdminLog_MessagePreviousDescription: String { return self._s[1282]! }
public func VoiceOver_Chat_MusicFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1278]!, self._r[1278]!, [_0])
+ return formatWithArgumentRanges(self._s[1283]!, self._r[1283]!, [_0])
}
- public var Channel_AdminLog_EmptyMessageText: String { return self._s[1279]! }
- public var SettingsSearch_Synonyms_Data_NetworkUsage: String { return self._s[1280]! }
+ public var Channel_AdminLog_EmptyMessageText: String { return self._s[1284]! }
+ public var SettingsSearch_Synonyms_Data_NetworkUsage: String { return self._s[1285]! }
public func Group_EditAdmin_RankInfo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1281]!, self._r[1281]!, [_0])
+ return formatWithArgumentRanges(self._s[1286]!, self._r[1286]!, [_0])
}
- public var Month_ShortApril: String { return self._s[1282]! }
- public var AuthSessions_CurrentSession: String { return self._s[1283]! }
- public var Chat_AttachmentMultipleFilesDisabled: String { return self._s[1286]! }
- public var Wallet_Navigation_Cancel: String { return self._s[1288]! }
- public var WallpaperPreview_CropTopText: String { return self._s[1289]! }
- public var PrivacySettings_DeleteAccountIfAwayFor: String { return self._s[1290]! }
- public var CheckoutInfo_ShippingInfoTitle: String { return self._s[1291]! }
+ public var Month_ShortApril: String { return self._s[1287]! }
+ public var AuthSessions_CurrentSession: String { return self._s[1288]! }
+ public var Chat_AttachmentMultipleFilesDisabled: String { return self._s[1291]! }
+ public var Wallet_Navigation_Cancel: String { return self._s[1293]! }
+ public var WallpaperPreview_CropTopText: String { return self._s[1294]! }
+ public var PrivacySettings_DeleteAccountIfAwayFor: String { return self._s[1295]! }
+ public var CheckoutInfo_ShippingInfoTitle: String { return self._s[1296]! }
public func Conversation_ScheduleMessage_SendOn(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1292]!, self._r[1292]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[1297]!, self._r[1297]!, [_0, _1])
}
- public var Appearance_ThemePreview_Chat_2_Text: String { return self._s[1293]! }
- public var Channel_Setup_TypePrivate: String { return self._s[1295]! }
- public var Forward_ChannelReadOnly: String { return self._s[1298]! }
- public var PhotoEditor_CurvesBlue: String { return self._s[1299]! }
- public var AddContact_SharedContactException: String { return self._s[1300]! }
- public var UserInfo_BotPrivacy: String { return self._s[1302]! }
- public var Wallet_CreateInvoice_Title: String { return self._s[1303]! }
- public var Notification_PassportValueEmail: String { return self._s[1304]! }
- public var EmptyGroupInfo_Subtitle: String { return self._s[1305]! }
- public var GroupPermission_NewTitle: String { return self._s[1306]! }
- public var CallFeedback_ReasonDropped: String { return self._s[1307]! }
- public var GroupInfo_Permissions_AddException: String { return self._s[1308]! }
- public var Channel_SignMessages_Help: String { return self._s[1310]! }
- public var Undo_ChatDeleted: String { return self._s[1312]! }
- public var Conversation_ChatBackground: String { return self._s[1313]! }
+ public var Appearance_ThemePreview_Chat_2_Text: String { return self._s[1298]! }
+ public var Channel_Setup_TypePrivate: String { return self._s[1300]! }
+ public var Forward_ChannelReadOnly: String { return self._s[1303]! }
+ public var PhotoEditor_CurvesBlue: String { return self._s[1304]! }
+ public var AddContact_SharedContactException: String { return self._s[1305]! }
+ public var UserInfo_BotPrivacy: String { return self._s[1307]! }
+ public var Wallet_CreateInvoice_Title: String { return self._s[1308]! }
+ public var Notification_PassportValueEmail: String { return self._s[1309]! }
+ public var EmptyGroupInfo_Subtitle: String { return self._s[1310]! }
+ public var GroupPermission_NewTitle: String { return self._s[1311]! }
+ public var CallFeedback_ReasonDropped: String { return self._s[1312]! }
+ public var GroupInfo_Permissions_AddException: String { return self._s[1313]! }
+ public var Channel_SignMessages_Help: String { return self._s[1315]! }
+ public var Undo_ChatDeleted: String { return self._s[1317]! }
+ public var Conversation_ChatBackground: String { return self._s[1318]! }
public func Wallet_WordCheck_Text(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1314]!, self._r[1314]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1319]!, self._r[1319]!, [_1, _2, _3])
}
- public var ChannelMembers_WhoCanAddMembers_Admins: String { return self._s[1315]! }
- public var FastTwoStepSetup_EmailPlaceholder: String { return self._s[1316]! }
- public var Passport_Language_pt: String { return self._s[1317]! }
- public var VoiceOver_Chat_YourVoiceMessage: String { return self._s[1318]! }
- public var NotificationsSound_Popcorn: String { return self._s[1321]! }
- public var AutoNightTheme_Disabled: String { return self._s[1322]! }
- public var BlockedUsers_LeavePrefix: String { return self._s[1323]! }
- public var WallpaperPreview_CustomColorTopText: String { return self._s[1324]! }
- public var Contacts_PermissionsSuppressWarningText: String { return self._s[1325]! }
- public var WallpaperSearch_ColorBlue: String { return self._s[1326]! }
+ public var ChannelMembers_WhoCanAddMembers_Admins: String { return self._s[1320]! }
+ public var FastTwoStepSetup_EmailPlaceholder: String { return self._s[1321]! }
+ public var Passport_Language_pt: String { return self._s[1322]! }
+ public var VoiceOver_Chat_YourVoiceMessage: String { return self._s[1323]! }
+ public var NotificationsSound_Popcorn: String { return self._s[1326]! }
+ public var AutoNightTheme_Disabled: String { return self._s[1327]! }
+ public var BlockedUsers_LeavePrefix: String { return self._s[1328]! }
+ public var WallpaperPreview_CustomColorTopText: String { return self._s[1329]! }
+ public var Contacts_PermissionsSuppressWarningText: String { return self._s[1330]! }
+ public var WallpaperSearch_ColorBlue: String { return self._s[1331]! }
public func CancelResetAccount_TextSMS(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1327]!, self._r[1327]!, [_0])
+ return formatWithArgumentRanges(self._s[1332]!, self._r[1332]!, [_0])
}
- public var CheckoutInfo_ErrorNameInvalid: String { return self._s[1328]! }
- public var SocksProxySetup_UseForCalls: String { return self._s[1329]! }
- public var Passport_DeleteDocumentConfirmation: String { return self._s[1331]! }
+ public var CheckoutInfo_ErrorNameInvalid: String { return self._s[1333]! }
+ public var SocksProxySetup_UseForCalls: String { return self._s[1334]! }
+ public var Passport_DeleteDocumentConfirmation: String { return self._s[1336]! }
public func Conversation_Megabytes(_ _0: Float) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1332]!, self._r[1332]!, ["\(_0)"])
+ return formatWithArgumentRanges(self._s[1337]!, self._r[1337]!, ["\(_0)"])
}
- public var SocksProxySetup_Hostname: String { return self._s[1335]! }
- public var ChatSettings_AutoDownloadSettings_OffForAll: String { return self._s[1336]! }
- public var Compose_NewEncryptedChat: String { return self._s[1337]! }
- public var Login_CodeFloodError: String { return self._s[1338]! }
- public var Calls_TabTitle: String { return self._s[1339]! }
- public var Privacy_ProfilePhoto: String { return self._s[1340]! }
- public var Passport_Language_he: String { return self._s[1341]! }
+ public var SocksProxySetup_Hostname: String { return self._s[1340]! }
+ public var ChatSettings_AutoDownloadSettings_OffForAll: String { return self._s[1341]! }
+ public var Compose_NewEncryptedChat: String { return self._s[1342]! }
+ public var Login_CodeFloodError: String { return self._s[1343]! }
+ public var Calls_TabTitle: String { return self._s[1344]! }
+ public var Privacy_ProfilePhoto: String { return self._s[1345]! }
+ public var Passport_Language_he: String { return self._s[1346]! }
public func Conversation_SetReminder_RemindToday(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1342]!, self._r[1342]!, [_0])
+ return formatWithArgumentRanges(self._s[1347]!, self._r[1347]!, [_0])
}
- public var GroupPermission_Title: String { return self._s[1343]! }
+ public var GroupPermission_Title: String { return self._s[1348]! }
public func Channel_AdminLog_MessageGroupPreHistoryHidden(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1344]!, self._r[1344]!, [_0])
+ return formatWithArgumentRanges(self._s[1349]!, self._r[1349]!, [_0])
}
- public var Wallet_TransactionInfo_SenderHeader: String { return self._s[1345]! }
- public var GroupPermission_NoChangeInfo: String { return self._s[1346]! }
- public var ChatList_DeleteForCurrentUser: String { return self._s[1347]! }
- public var Tour_Text1: String { return self._s[1348]! }
- public var Channel_EditAdmin_TransferOwnership: String { return self._s[1349]! }
- public var Month_ShortFebruary: String { return self._s[1350]! }
- public var TwoStepAuth_EmailSkip: String { return self._s[1351]! }
+ public var Wallet_TransactionInfo_SenderHeader: String { return self._s[1350]! }
+ public var GroupPermission_NoChangeInfo: String { return self._s[1351]! }
+ public var ChatList_DeleteForCurrentUser: String { return self._s[1352]! }
+ public var Tour_Text1: String { return self._s[1353]! }
+ public var Channel_EditAdmin_TransferOwnership: String { return self._s[1354]! }
+ public var Month_ShortFebruary: String { return self._s[1355]! }
+ public var TwoStepAuth_EmailSkip: String { return self._s[1356]! }
public func Wallet_Time_PreciseDate_m4(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1352]!, self._r[1352]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1357]!, self._r[1357]!, [_1, _2, _3])
}
- public var NotificationsSound_Glass: String { return self._s[1353]! }
- public var Appearance_ThemeNightBlue: String { return self._s[1354]! }
- public var CheckoutInfo_Pay: String { return self._s[1355]! }
- public var Invite_LargeRecipientsCountWarning: String { return self._s[1357]! }
- public var Call_CallAgain: String { return self._s[1359]! }
- public var AttachmentMenu_SendAsFile: String { return self._s[1360]! }
- public var AccessDenied_MicrophoneRestricted: String { return self._s[1361]! }
- public var Passport_InvalidPasswordError: String { return self._s[1362]! }
- public var Watch_Message_Game: String { return self._s[1363]! }
- public var Stickers_Install: String { return self._s[1364]! }
- public var VoiceOver_Chat_Message: String { return self._s[1365]! }
- public var PrivacyLastSeenSettings_NeverShareWith: String { return self._s[1366]! }
- public var Passport_Identity_ResidenceCountry: String { return self._s[1368]! }
- public var Notifications_GroupNotificationsHelp: String { return self._s[1369]! }
- public var AuthSessions_OtherSessions: String { return self._s[1370]! }
- public var Channel_Username_Help: String { return self._s[1371]! }
- public var Camera_Title: String { return self._s[1372]! }
- public var IntentsSettings_Title: String { return self._s[1373]! }
- public var GroupInfo_SetGroupPhotoDelete: String { return self._s[1375]! }
- public var Privacy_ProfilePhoto_NeverShareWith_Title: String { return self._s[1376]! }
- public var Channel_AdminLog_SendPolls: String { return self._s[1377]! }
- public var Channel_AdminLog_TitleAllEvents: String { return self._s[1378]! }
- public var Channel_EditAdmin_PermissionInviteMembers: String { return self._s[1379]! }
- public var Contacts_MemberSearchSectionTitleGroup: String { return self._s[1380]! }
- public var ScheduledMessages_DeleteMany: String { return self._s[1381]! }
- public var Conversation_RestrictedStickers: String { return self._s[1382]! }
- public var Notifications_ExceptionsResetToDefaults: String { return self._s[1384]! }
- public var UserInfo_TelegramCall: String { return self._s[1386]! }
- public var TwoStepAuth_SetupResendEmailCode: String { return self._s[1387]! }
- public var CreatePoll_OptionsHeader: String { return self._s[1388]! }
- public var SettingsSearch_Synonyms_Data_CallsUseLessData: String { return self._s[1389]! }
- public var ArchivedChats_IntroTitle1: String { return self._s[1390]! }
- public var Privacy_GroupsAndChannels_AlwaysAllow_Title: String { return self._s[1391]! }
- public var Theme_Colors_Proceed: String { return self._s[1392]! }
- public var Passport_Identity_EditPersonalDetails: String { return self._s[1393]! }
+ public var NotificationsSound_Glass: String { return self._s[1358]! }
+ public var Appearance_ThemeNightBlue: String { return self._s[1359]! }
+ public var CheckoutInfo_Pay: String { return self._s[1360]! }
+ public var Invite_LargeRecipientsCountWarning: String { return self._s[1362]! }
+ public var Call_CallAgain: String { return self._s[1364]! }
+ public var AttachmentMenu_SendAsFile: String { return self._s[1365]! }
+ public var AccessDenied_MicrophoneRestricted: String { return self._s[1366]! }
+ public var Passport_InvalidPasswordError: String { return self._s[1367]! }
+ public var Watch_Message_Game: String { return self._s[1368]! }
+ public var Stickers_Install: String { return self._s[1369]! }
+ public var VoiceOver_Chat_Message: String { return self._s[1370]! }
+ public var PrivacyLastSeenSettings_NeverShareWith: String { return self._s[1371]! }
+ public var Passport_Identity_ResidenceCountry: String { return self._s[1373]! }
+ public var Notifications_GroupNotificationsHelp: String { return self._s[1374]! }
+ public var AuthSessions_OtherSessions: String { return self._s[1375]! }
+ public var Channel_Username_Help: String { return self._s[1376]! }
+ public var Camera_Title: String { return self._s[1377]! }
+ public var IntentsSettings_Title: String { return self._s[1378]! }
+ public var GroupInfo_SetGroupPhotoDelete: String { return self._s[1380]! }
+ public var Privacy_ProfilePhoto_NeverShareWith_Title: String { return self._s[1381]! }
+ public var Channel_AdminLog_SendPolls: String { return self._s[1382]! }
+ public var Channel_AdminLog_TitleAllEvents: String { return self._s[1383]! }
+ public var Channel_EditAdmin_PermissionInviteMembers: String { return self._s[1384]! }
+ public var Contacts_MemberSearchSectionTitleGroup: String { return self._s[1385]! }
+ public var ScheduledMessages_DeleteMany: String { return self._s[1386]! }
+ public var Conversation_RestrictedStickers: String { return self._s[1387]! }
+ public var Notifications_ExceptionsResetToDefaults: String { return self._s[1389]! }
+ public var UserInfo_TelegramCall: String { return self._s[1391]! }
+ public var TwoStepAuth_SetupResendEmailCode: String { return self._s[1392]! }
+ public var CreatePoll_OptionsHeader: String { return self._s[1393]! }
+ public var SettingsSearch_Synonyms_Data_CallsUseLessData: String { return self._s[1394]! }
+ public var ArchivedChats_IntroTitle1: String { return self._s[1395]! }
+ public var Privacy_GroupsAndChannels_AlwaysAllow_Title: String { return self._s[1396]! }
+ public var Theme_Colors_Proceed: String { return self._s[1397]! }
+ public var Passport_Identity_EditPersonalDetails: String { return self._s[1398]! }
public func Time_PreciseDate_m1(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1394]!, self._r[1394]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1399]!, self._r[1399]!, [_1, _2, _3])
}
- public var Wallet_Month_GenAugust: String { return self._s[1395]! }
- public var Settings_SaveEditedPhotos: String { return self._s[1396]! }
- public var TwoStepAuth_ConfirmationTitle: String { return self._s[1397]! }
- public var Privacy_GroupsAndChannels_NeverAllow_Title: String { return self._s[1398]! }
- public var Conversation_MessageDialogRetry: String { return self._s[1399]! }
- public var ChatList_Context_MarkAsUnread: String { return self._s[1400]! }
- public var MessagePoll_SubmitVote: String { return self._s[1401]! }
- public var Conversation_DiscardVoiceMessageAction: String { return self._s[1402]! }
- public var Permissions_PeopleNearbyTitle_v0: String { return self._s[1403]! }
- public var Group_Setup_TypeHeader: String { return self._s[1404]! }
- public var Paint_RecentStickers: String { return self._s[1405]! }
- public var PhotoEditor_GrainTool: String { return self._s[1406]! }
- public var CheckoutInfo_ShippingInfoState: String { return self._s[1407]! }
- public var EmptyGroupInfo_Line4: String { return self._s[1408]! }
- public var Watch_AuthRequired: String { return self._s[1410]! }
+ public var Wallet_Month_GenAugust: String { return self._s[1400]! }
+ public var Settings_SaveEditedPhotos: String { return self._s[1401]! }
+ public var TwoStepAuth_ConfirmationTitle: String { return self._s[1402]! }
+ public var Privacy_GroupsAndChannels_NeverAllow_Title: String { return self._s[1403]! }
+ public var Conversation_MessageDialogRetry: String { return self._s[1404]! }
+ public var ChatList_Context_MarkAsUnread: String { return self._s[1405]! }
+ public var MessagePoll_SubmitVote: String { return self._s[1406]! }
+ public var Conversation_DiscardVoiceMessageAction: String { return self._s[1407]! }
+ public var Permissions_PeopleNearbyTitle_v0: String { return self._s[1408]! }
+ public var Group_Setup_TypeHeader: String { return self._s[1409]! }
+ public var Paint_RecentStickers: String { return self._s[1410]! }
+ public var PhotoEditor_GrainTool: String { return self._s[1411]! }
+ public var CheckoutInfo_ShippingInfoState: String { return self._s[1412]! }
+ public var EmptyGroupInfo_Line4: String { return self._s[1413]! }
+ public var Watch_AuthRequired: String { return self._s[1415]! }
public func Passport_Email_UseTelegramEmail(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1411]!, self._r[1411]!, [_0])
+ return formatWithArgumentRanges(self._s[1416]!, self._r[1416]!, [_0])
}
- public var Conversation_EncryptedDescriptionTitle: String { return self._s[1412]! }
- public var ChannelIntro_Text: String { return self._s[1413]! }
- public var DialogList_DeleteBotConfirmation: String { return self._s[1414]! }
- public var GroupPermission_NoSendMedia: String { return self._s[1415]! }
- public var Calls_AddTab: String { return self._s[1416]! }
- public var Message_ReplyActionButtonShowReceipt: String { return self._s[1417]! }
- public var Channel_AdminLog_EmptyFilterText: String { return self._s[1418]! }
- public var Conversation_WalletRequiredSetup: String { return self._s[1419]! }
- public var Notification_MessageLifetime1d: String { return self._s[1420]! }
- public var Notifications_ChannelNotificationsExceptionsHelp: String { return self._s[1421]! }
- public var Channel_BanUser_PermissionsHeader: String { return self._s[1422]! }
- public var Passport_Identity_GenderFemale: String { return self._s[1423]! }
- public var BlockedUsers_BlockTitle: String { return self._s[1424]! }
+ public var Conversation_EncryptedDescriptionTitle: String { return self._s[1417]! }
+ public var ChannelIntro_Text: String { return self._s[1418]! }
+ public var DialogList_DeleteBotConfirmation: String { return self._s[1419]! }
+ public var GroupPermission_NoSendMedia: String { return self._s[1420]! }
+ public var Calls_AddTab: String { return self._s[1421]! }
+ public var Message_ReplyActionButtonShowReceipt: String { return self._s[1422]! }
+ public var Channel_AdminLog_EmptyFilterText: String { return self._s[1423]! }
+ public var Conversation_WalletRequiredSetup: String { return self._s[1424]! }
+ public var Notification_MessageLifetime1d: String { return self._s[1425]! }
+ public var Notifications_ChannelNotificationsExceptionsHelp: String { return self._s[1426]! }
+ public var Channel_BanUser_PermissionsHeader: String { return self._s[1427]! }
+ public var Passport_Identity_GenderFemale: String { return self._s[1428]! }
+ public var BlockedUsers_BlockTitle: String { return self._s[1429]! }
public func PUSH_CHANNEL_MESSAGE_GIF(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1425]!, self._r[1425]!, [_1])
+ return formatWithArgumentRanges(self._s[1430]!, self._r[1430]!, [_1])
}
- public var Weekday_Yesterday: String { return self._s[1426]! }
- public var WallpaperSearch_ColorBlack: String { return self._s[1427]! }
- public var Settings_Context_Logout: String { return self._s[1428]! }
- public var Wallet_Info_UnknownTransaction: String { return self._s[1429]! }
- public var ChatList_ArchiveAction: String { return self._s[1430]! }
- public var AutoNightTheme_Scheduled: String { return self._s[1431]! }
- public var TwoFactorSetup_Email_SkipAction: String { return self._s[1432]! }
- public var Settings_Devices: String { return self._s[1433]! }
- public var ContactInfo_Note: String { return self._s[1434]! }
+ public var Weekday_Yesterday: String { return self._s[1431]! }
+ public var WallpaperSearch_ColorBlack: String { return self._s[1432]! }
+ public var Settings_Context_Logout: String { return self._s[1433]! }
+ public var Wallet_Info_UnknownTransaction: String { return self._s[1434]! }
+ public var ChatList_ArchiveAction: String { return self._s[1435]! }
+ public var AutoNightTheme_Scheduled: String { return self._s[1436]! }
+ public var TwoFactorSetup_Email_SkipAction: String { return self._s[1437]! }
+ public var Settings_Devices: String { return self._s[1438]! }
+ public var ContactInfo_Note: String { return self._s[1439]! }
public func Login_PhoneGenericEmailBody(_ _1: String, _ _2: String, _ _3: String, _ _4: String, _ _5: String, _ _6: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1435]!, self._r[1435]!, [_1, _2, _3, _4, _5, _6])
+ return formatWithArgumentRanges(self._s[1440]!, self._r[1440]!, [_1, _2, _3, _4, _5, _6])
}
- public var EditTheme_ThemeTemplateAlertTitle: String { return self._s[1436]! }
- public var Wallet_Receive_CreateInvoice: String { return self._s[1437]! }
- public var PrivacyPolicy_DeclineDeleteNow: String { return self._s[1438]! }
- public var Theme_Colors_ColorWallpaperWarningProceed: String { return self._s[1439]! }
+ public var EditTheme_ThemeTemplateAlertTitle: String { return self._s[1441]! }
+ public var Wallet_Receive_CreateInvoice: String { return self._s[1442]! }
+ public var PrivacyPolicy_DeclineDeleteNow: String { return self._s[1443]! }
+ public var Theme_Colors_ColorWallpaperWarningProceed: String { return self._s[1444]! }
public func PUSH_CHAT_JOINED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1440]!, self._r[1440]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1445]!, self._r[1445]!, [_1, _2])
}
- public var CreatePoll_Create: String { return self._s[1441]! }
- public var Channel_Members_AddBannedErrorAdmin: String { return self._s[1442]! }
+ public var CreatePoll_Create: String { return self._s[1446]! }
+ public var Channel_Members_AddBannedErrorAdmin: String { return self._s[1447]! }
public func Notification_CallFormat(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1443]!, self._r[1443]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1448]!, self._r[1448]!, [_1, _2])
}
- public var ScheduledMessages_ClearAllConfirmation: String { return self._s[1444]! }
- public var Checkout_ErrorProviderAccountInvalid: String { return self._s[1445]! }
- public var Notifications_InAppNotificationsSounds: String { return self._s[1447]! }
+ public var ScheduledMessages_ClearAllConfirmation: String { return self._s[1449]! }
+ public var Checkout_ErrorProviderAccountInvalid: String { return self._s[1450]! }
+ public var Notifications_InAppNotificationsSounds: String { return self._s[1452]! }
public func PUSH_PINNED_GAME_SCORE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1448]!, self._r[1448]!, [_1])
+ return formatWithArgumentRanges(self._s[1453]!, self._r[1453]!, [_1])
}
- public var Preview_OpenInInstagram: String { return self._s[1449]! }
- public var Notification_MessageLifetimeRemovedOutgoing: String { return self._s[1450]! }
+ public var Preview_OpenInInstagram: String { return self._s[1454]! }
+ public var Notification_MessageLifetimeRemovedOutgoing: String { return self._s[1455]! }
public func PUSH_CHAT_ADD_MEMBER(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1451]!, self._r[1451]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1456]!, self._r[1456]!, [_1, _2, _3])
}
public func Passport_PrivacyPolicy(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1452]!, self._r[1452]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1457]!, self._r[1457]!, [_1, _2])
}
- public var Channel_AdminLog_InfoPanelAlertTitle: String { return self._s[1453]! }
- public var ArchivedChats_IntroText3: String { return self._s[1454]! }
- public var ChatList_UndoArchiveHiddenText: String { return self._s[1455]! }
- public var NetworkUsageSettings_TotalSection: String { return self._s[1456]! }
- public var Wallet_Month_GenSeptember: String { return self._s[1457]! }
- public var Channel_Setup_TypePrivateHelp: String { return self._s[1458]! }
+ public var Channel_AdminLog_InfoPanelAlertTitle: String { return self._s[1458]! }
+ public var ArchivedChats_IntroText3: String { return self._s[1459]! }
+ public var ChatList_UndoArchiveHiddenText: String { return self._s[1460]! }
+ public var NetworkUsageSettings_TotalSection: String { return self._s[1461]! }
+ public var Wallet_Month_GenSeptember: String { return self._s[1462]! }
+ public var Channel_Setup_TypePrivateHelp: String { return self._s[1463]! }
public func PUSH_CHAT_MESSAGE_POLL(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1459]!, self._r[1459]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1464]!, self._r[1464]!, [_1, _2, _3])
}
- public var Privacy_GroupsAndChannels_NeverAllow_Placeholder: String { return self._s[1461]! }
- public var FastTwoStepSetup_HintSection: String { return self._s[1462]! }
- public var Wallpaper_PhotoLibrary: String { return self._s[1463]! }
- public var TwoStepAuth_SetupResendEmailCodeAlert: String { return self._s[1464]! }
- public var Gif_NoGifsFound: String { return self._s[1465]! }
- public var Watch_LastSeen_WithinAMonth: String { return self._s[1466]! }
- public var VoiceOver_MessageContextDelete: String { return self._s[1467]! }
- public var EditTheme_Preview: String { return self._s[1468]! }
+ public var Privacy_GroupsAndChannels_NeverAllow_Placeholder: String { return self._s[1466]! }
+ public var FastTwoStepSetup_HintSection: String { return self._s[1467]! }
+ public var Wallpaper_PhotoLibrary: String { return self._s[1468]! }
+ public var TwoStepAuth_SetupResendEmailCodeAlert: String { return self._s[1469]! }
+ public var Gif_NoGifsFound: String { return self._s[1470]! }
+ public var Watch_LastSeen_WithinAMonth: String { return self._s[1471]! }
+ public var VoiceOver_MessageContextDelete: String { return self._s[1472]! }
+ public var EditTheme_Preview: String { return self._s[1473]! }
public func ClearCache_StorageTitle(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1469]!, self._r[1469]!, [_0])
+ return formatWithArgumentRanges(self._s[1474]!, self._r[1474]!, [_0])
}
- public var GroupInfo_ActionPromote: String { return self._s[1470]! }
- public var PasscodeSettings_SimplePasscode: String { return self._s[1471]! }
- public var GroupInfo_Permissions_Title: String { return self._s[1472]! }
- public var Permissions_ContactsText_v0: String { return self._s[1473]! }
- public var PrivacyPhoneNumberSettings_CustomDisabledHelp: String { return self._s[1474]! }
- public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedPublicGroups: String { return self._s[1475]! }
- public var PrivacySettings_DataSettingsHelp: String { return self._s[1478]! }
- public var Passport_FieldEmailHelp: String { return self._s[1479]! }
+ public var GroupInfo_ActionPromote: String { return self._s[1475]! }
+ public var PasscodeSettings_SimplePasscode: String { return self._s[1476]! }
+ public var GroupInfo_Permissions_Title: String { return self._s[1477]! }
+ public var Permissions_ContactsText_v0: String { return self._s[1478]! }
+ public var PrivacyPhoneNumberSettings_CustomDisabledHelp: String { return self._s[1479]! }
+ public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedPublicGroups: String { return self._s[1480]! }
+ public var PrivacySettings_DataSettingsHelp: String { return self._s[1483]! }
+ public var Passport_FieldEmailHelp: String { return self._s[1484]! }
public func Activity_RemindAboutUser(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1480]!, self._r[1480]!, [_0])
+ return formatWithArgumentRanges(self._s[1485]!, self._r[1485]!, [_0])
}
- public var Passport_Identity_GenderPlaceholder: String { return self._s[1481]! }
- public var Weekday_ShortSaturday: String { return self._s[1482]! }
- public var ContactInfo_PhoneLabelMain: String { return self._s[1483]! }
- public var Watch_Conversation_UserInfo: String { return self._s[1484]! }
- public var CheckoutInfo_ShippingInfoCityPlaceholder: String { return self._s[1485]! }
- public var GroupPermission_PermissionDisabledByDefault: String { return self._s[1486]! }
- public var PrivacyLastSeenSettings_Title: String { return self._s[1487]! }
- public var Conversation_ShareBotLocationConfirmation: String { return self._s[1488]! }
- public var PhotoEditor_VignetteTool: String { return self._s[1489]! }
- public var Passport_Address_Street1Placeholder: String { return self._s[1490]! }
- public var Passport_Language_et: String { return self._s[1491]! }
- public var AppUpgrade_Running: String { return self._s[1492]! }
- public var Channel_DiscussionGroup_Info: String { return self._s[1494]! }
- public var EditTheme_Create_Preview_IncomingReplyName: String { return self._s[1495]! }
- public var Passport_Language_bg: String { return self._s[1496]! }
- public var Stickers_NoStickersFound: String { return self._s[1498]! }
+ public var Passport_Identity_GenderPlaceholder: String { return self._s[1486]! }
+ public var Weekday_ShortSaturday: String { return self._s[1487]! }
+ public var ContactInfo_PhoneLabelMain: String { return self._s[1488]! }
+ public var Watch_Conversation_UserInfo: String { return self._s[1489]! }
+ public var CheckoutInfo_ShippingInfoCityPlaceholder: String { return self._s[1490]! }
+ public var GroupPermission_PermissionDisabledByDefault: String { return self._s[1491]! }
+ public var PrivacyLastSeenSettings_Title: String { return self._s[1492]! }
+ public var Conversation_ShareBotLocationConfirmation: String { return self._s[1493]! }
+ public var PhotoEditor_VignetteTool: String { return self._s[1494]! }
+ public var Passport_Address_Street1Placeholder: String { return self._s[1495]! }
+ public var Passport_Language_et: String { return self._s[1496]! }
+ public var AppUpgrade_Running: String { return self._s[1497]! }
+ public var Channel_DiscussionGroup_Info: String { return self._s[1499]! }
+ public var EditTheme_Create_Preview_IncomingReplyName: String { return self._s[1500]! }
+ public var Passport_Language_bg: String { return self._s[1501]! }
+ public var Stickers_NoStickersFound: String { return self._s[1503]! }
public func PUSH_CHANNEL_MESSAGE_TEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1500]!, self._r[1500]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1505]!, self._r[1505]!, [_1, _2])
}
public func VoiceOver_Chat_ContactFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1501]!, self._r[1501]!, [_0])
+ return formatWithArgumentRanges(self._s[1506]!, self._r[1506]!, [_0])
}
- public var Wallet_Month_GenJuly: String { return self._s[1502]! }
- public var Wallet_Receive_AddressHeader: String { return self._s[1503]! }
- public var Wallet_Send_AmountText: String { return self._s[1504]! }
- public var Settings_About: String { return self._s[1505]! }
+ public var Wallet_Month_GenJuly: String { return self._s[1507]! }
+ public var Wallet_Receive_AddressHeader: String { return self._s[1508]! }
+ public var Wallet_Send_AmountText: String { return self._s[1509]! }
+ public var Settings_About: String { return self._s[1510]! }
public func Channel_AdminLog_MessageRestricted(_ _0: String, _ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1506]!, self._r[1506]!, [_0, _1, _2])
+ return formatWithArgumentRanges(self._s[1511]!, self._r[1511]!, [_0, _1, _2])
}
- public var ChatList_Context_MarkAsRead: String { return self._s[1508]! }
- public var KeyCommand_NewMessage: String { return self._s[1509]! }
- public var Group_ErrorAddBlocked: String { return self._s[1510]! }
+ public var ChatList_Context_MarkAsRead: String { return self._s[1513]! }
+ public var KeyCommand_NewMessage: String { return self._s[1514]! }
+ public var Group_ErrorAddBlocked: String { return self._s[1515]! }
public func Message_PaymentSent(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1511]!, self._r[1511]!, [_0])
- }
- public var Map_LocationTitle: String { return self._s[1512]! }
- public var ReportGroupLocation_Title: String { return self._s[1513]! }
- public var CallSettings_UseLessDataLongDescription: String { return self._s[1514]! }
- public var Cache_ClearProgress: String { return self._s[1515]! }
- public func Channel_Management_ErrorNotMember(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[1516]!, self._r[1516]!, [_0])
}
- public var GroupRemoved_AddToGroup: String { return self._s[1517]! }
- public var Passport_UpdateRequiredError: String { return self._s[1518]! }
- public var Wallet_SecureStorageNotAvailable_Text: String { return self._s[1519]! }
+ public var Map_LocationTitle: String { return self._s[1517]! }
+ public var ReportGroupLocation_Title: String { return self._s[1518]! }
+ public var CallSettings_UseLessDataLongDescription: String { return self._s[1519]! }
+ public var Cache_ClearProgress: String { return self._s[1520]! }
+ public func Channel_Management_ErrorNotMember(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[1521]!, self._r[1521]!, [_0])
+ }
+ public var GroupRemoved_AddToGroup: String { return self._s[1522]! }
+ public var Passport_UpdateRequiredError: String { return self._s[1523]! }
+ public var Wallet_SecureStorageNotAvailable_Text: String { return self._s[1524]! }
public func PUSH_MESSAGE_DOC(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1520]!, self._r[1520]!, [_1])
+ return formatWithArgumentRanges(self._s[1525]!, self._r[1525]!, [_1])
}
- public var Notifications_PermissionsSuppressWarningText: String { return self._s[1522]! }
- public var Passport_Identity_MainPageHelp: String { return self._s[1523]! }
- public var Conversation_StatusKickedFromGroup: String { return self._s[1524]! }
- public var Passport_Language_ka: String { return self._s[1525]! }
+ public var Notifications_PermissionsSuppressWarningText: String { return self._s[1527]! }
+ public var Passport_Identity_MainPageHelp: String { return self._s[1528]! }
+ public var Conversation_StatusKickedFromGroup: String { return self._s[1529]! }
+ public var Passport_Language_ka: String { return self._s[1530]! }
public func Wallet_Time_PreciseDate_m12(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1526]!, self._r[1526]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1531]!, self._r[1531]!, [_1, _2, _3])
}
- public var Call_Decline: String { return self._s[1527]! }
- public var SocksProxySetup_ProxyEnabled: String { return self._s[1528]! }
- public var TwoFactorSetup_Email_SkipConfirmationText: String { return self._s[1531]! }
+ public var Call_Decline: String { return self._s[1532]! }
+ public var SocksProxySetup_ProxyEnabled: String { return self._s[1533]! }
+ public var TwoFactorSetup_Email_SkipConfirmationText: String { return self._s[1536]! }
public func AuthCode_Alert(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1532]!, self._r[1532]!, [_0])
+ return formatWithArgumentRanges(self._s[1537]!, self._r[1537]!, [_0])
}
- public var CallFeedback_Send: String { return self._s[1533]! }
- public var EditTheme_EditTitle: String { return self._s[1534]! }
+ public var CallFeedback_Send: String { return self._s[1538]! }
+ public var EditTheme_EditTitle: String { return self._s[1539]! }
public func Channel_AdminLog_MessagePromotedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1535]!, self._r[1535]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1540]!, self._r[1540]!, [_1, _2])
}
- public var Passport_Phone_UseTelegramNumberHelp: String { return self._s[1536]! }
+ public var Passport_Phone_UseTelegramNumberHelp: String { return self._s[1541]! }
public func Wallet_Updated_TodayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1538]!, self._r[1538]!, [_0])
+ return formatWithArgumentRanges(self._s[1543]!, self._r[1543]!, [_0])
}
- public var SettingsSearch_Synonyms_Data_Title: String { return self._s[1539]! }
- public var Passport_DeletePassport: String { return self._s[1540]! }
- public var Appearance_AppIconFilled: String { return self._s[1541]! }
- public var Privacy_Calls_P2PAlways: String { return self._s[1542]! }
- public var Month_ShortDecember: String { return self._s[1543]! }
- public var Channel_AdminLog_CanEditMessages: String { return self._s[1545]! }
+ public var SettingsSearch_Synonyms_Data_Title: String { return self._s[1544]! }
+ public var Passport_DeletePassport: String { return self._s[1545]! }
+ public var Appearance_AppIconFilled: String { return self._s[1546]! }
+ public var Privacy_Calls_P2PAlways: String { return self._s[1547]! }
+ public var Month_ShortDecember: String { return self._s[1548]! }
+ public var Channel_AdminLog_CanEditMessages: String { return self._s[1550]! }
public func Contacts_AccessDeniedHelpLandscape(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1546]!, self._r[1546]!, [_0])
+ return formatWithArgumentRanges(self._s[1551]!, self._r[1551]!, [_0])
}
- public var Channel_Stickers_Searching: String { return self._s[1547]! }
- public var Conversation_EncryptedDescription1: String { return self._s[1548]! }
- public var Conversation_EncryptedDescription2: String { return self._s[1549]! }
- public var PasscodeSettings_PasscodeOptions: String { return self._s[1550]! }
- public var Conversation_EncryptedDescription3: String { return self._s[1552]! }
- public var PhotoEditor_SharpenTool: String { return self._s[1553]! }
- public var Wallet_Configuration_Title: String { return self._s[1554]! }
+ public var Channel_Stickers_Searching: String { return self._s[1552]! }
+ public var Conversation_EncryptedDescription1: String { return self._s[1553]! }
+ public var Conversation_EncryptedDescription2: String { return self._s[1554]! }
+ public var PasscodeSettings_PasscodeOptions: String { return self._s[1555]! }
+ public var Conversation_EncryptedDescription3: String { return self._s[1557]! }
+ public var PhotoEditor_SharpenTool: String { return self._s[1558]! }
+ public var Wallet_Configuration_Title: String { return self._s[1559]! }
public func Conversation_AddNameToContacts(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1555]!, self._r[1555]!, [_0])
+ return formatWithArgumentRanges(self._s[1560]!, self._r[1560]!, [_0])
}
- public var Conversation_EncryptedDescription4: String { return self._s[1557]! }
- public var Channel_Members_AddMembers: String { return self._s[1558]! }
- public var Wallpaper_Search: String { return self._s[1559]! }
- public var Weekday_Friday: String { return self._s[1561]! }
- public var Privacy_ContactsSync: String { return self._s[1562]! }
- public var SettingsSearch_Synonyms_Privacy_Data_ContactsReset: String { return self._s[1563]! }
- public var ApplyLanguage_ChangeLanguageAction: String { return self._s[1564]! }
+ public var Conversation_EncryptedDescription4: String { return self._s[1562]! }
+ public var Channel_Members_AddMembers: String { return self._s[1563]! }
+ public var Wallpaper_Search: String { return self._s[1564]! }
+ public var Weekday_Friday: String { return self._s[1566]! }
+ public var Privacy_ContactsSync: String { return self._s[1567]! }
+ public var SettingsSearch_Synonyms_Privacy_Data_ContactsReset: String { return self._s[1568]! }
+ public var ApplyLanguage_ChangeLanguageAction: String { return self._s[1569]! }
public func Channel_Management_RestrictedBy(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1565]!, self._r[1565]!, [_0])
- }
- public var Wallet_Configuration_BlockchainIdHeader: String { return self._s[1566]! }
- public var GroupInfo_Permissions_Removed: String { return self._s[1567]! }
- public var ScheduledMessages_ScheduledOnline: String { return self._s[1568]! }
- public var Passport_Identity_GenderMale: String { return self._s[1569]! }
- public func Call_StatusBar(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[1570]!, self._r[1570]!, [_0])
}
- public var Notifications_PermissionsKeepDisabled: String { return self._s[1571]! }
- public var Conversation_JumpToDate: String { return self._s[1572]! }
- public var Contacts_GlobalSearch: String { return self._s[1573]! }
- public var AutoDownloadSettings_ResetHelp: String { return self._s[1574]! }
- public var SettingsSearch_Synonyms_FAQ: String { return self._s[1575]! }
- public var Profile_MessageLifetime1d: String { return self._s[1576]! }
+ public var Wallet_Configuration_BlockchainIdHeader: String { return self._s[1571]! }
+ public var GroupInfo_Permissions_Removed: String { return self._s[1572]! }
+ public var ScheduledMessages_ScheduledOnline: String { return self._s[1573]! }
+ public var Passport_Identity_GenderMale: String { return self._s[1574]! }
+ public func Call_StatusBar(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[1575]!, self._r[1575]!, [_0])
+ }
+ public var Notifications_PermissionsKeepDisabled: String { return self._s[1576]! }
+ public var Conversation_JumpToDate: String { return self._s[1577]! }
+ public var Contacts_GlobalSearch: String { return self._s[1578]! }
+ public var AutoDownloadSettings_ResetHelp: String { return self._s[1579]! }
+ public var SettingsSearch_Synonyms_FAQ: String { return self._s[1580]! }
+ public var Profile_MessageLifetime1d: String { return self._s[1581]! }
public func MESSAGE_INVOICE(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1577]!, self._r[1577]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1582]!, self._r[1582]!, [_1, _2])
}
- public var StickerPack_BuiltinPackName: String { return self._s[1580]! }
+ public var StickerPack_BuiltinPackName: String { return self._s[1585]! }
public func PUSH_CHAT_MESSAGE_AUDIO(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1581]!, self._r[1581]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1586]!, self._r[1586]!, [_1, _2])
}
- public var VoiceOver_Chat_RecordModeVoiceMessageInfo: String { return self._s[1582]! }
- public var Passport_InfoTitle: String { return self._s[1584]! }
- public var Notifications_PermissionsUnreachableText: String { return self._s[1585]! }
+ public var VoiceOver_Chat_RecordModeVoiceMessageInfo: String { return self._s[1587]! }
+ public var Passport_InfoTitle: String { return self._s[1589]! }
+ public var Notifications_PermissionsUnreachableText: String { return self._s[1590]! }
public func NetworkUsageSettings_CellularUsageSince(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1589]!, self._r[1589]!, [_0])
+ return formatWithArgumentRanges(self._s[1594]!, self._r[1594]!, [_0])
}
public func PUSH_CHAT_MESSAGE_GEO(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1590]!, self._r[1590]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1595]!, self._r[1595]!, [_1, _2])
}
- public var Passport_Address_TypePassportRegistrationUploadScan: String { return self._s[1591]! }
- public var Profile_BotInfo: String { return self._s[1592]! }
- public var Watch_Compose_CreateMessage: String { return self._s[1593]! }
- public var AutoDownloadSettings_VoiceMessagesInfo: String { return self._s[1594]! }
- public var Month_ShortNovember: String { return self._s[1595]! }
- public var Conversation_ScamWarning: String { return self._s[1596]! }
- public var Wallpaper_SetCustomBackground: String { return self._s[1597]! }
- public var Appearance_TextSize_Title: String { return self._s[1598]! }
- public var Passport_Identity_TranslationsHelp: String { return self._s[1599]! }
- public var NotificationsSound_Chime: String { return self._s[1600]! }
- public var Passport_Language_ko: String { return self._s[1602]! }
- public var InviteText_URL: String { return self._s[1603]! }
- public var TextFormat_Monospace: String { return self._s[1604]! }
+ public var Passport_Address_TypePassportRegistrationUploadScan: String { return self._s[1596]! }
+ public var Profile_BotInfo: String { return self._s[1597]! }
+ public var Watch_Compose_CreateMessage: String { return self._s[1598]! }
+ public var AutoDownloadSettings_VoiceMessagesInfo: String { return self._s[1599]! }
+ public var Month_ShortNovember: String { return self._s[1600]! }
+ public var Conversation_ScamWarning: String { return self._s[1601]! }
+ public var Wallpaper_SetCustomBackground: String { return self._s[1602]! }
+ public var Appearance_TextSize_Title: String { return self._s[1603]! }
+ public var Passport_Identity_TranslationsHelp: String { return self._s[1604]! }
+ public var NotificationsSound_Chime: String { return self._s[1605]! }
+ public var Passport_Language_ko: String { return self._s[1607]! }
+ public var InviteText_URL: String { return self._s[1608]! }
+ public var TextFormat_Monospace: String { return self._s[1609]! }
public func Time_PreciseDate_m11(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1605]!, self._r[1605]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1610]!, self._r[1610]!, [_1, _2, _3])
}
- public var EditTheme_Edit_BottomInfo: String { return self._s[1606]! }
+ public var EditTheme_Edit_BottomInfo: String { return self._s[1611]! }
public func Login_WillSendSms(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1607]!, self._r[1607]!, [_0])
+ return formatWithArgumentRanges(self._s[1612]!, self._r[1612]!, [_0])
}
public func Watch_Time_ShortWeekdayAt(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1608]!, self._r[1608]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1613]!, self._r[1613]!, [_1, _2])
}
- public var Wallet_Words_Title: String { return self._s[1609]! }
- public var Wallet_Month_ShortMay: String { return self._s[1610]! }
- public var EditTheme_CreateTitle: String { return self._s[1612]! }
- public var Passport_InfoLearnMore: String { return self._s[1613]! }
- public var TwoStepAuth_EmailPlaceholder: String { return self._s[1614]! }
- public var Passport_Identity_AddIdentityCard: String { return self._s[1615]! }
- public var Your_card_has_expired: String { return self._s[1616]! }
- public var StickerPacksSettings_StickerPacksSection: String { return self._s[1617]! }
- public var GroupInfo_InviteLink_Help: String { return self._s[1618]! }
- public var TwoFactorSetup_EmailVerification_ResendAction: String { return self._s[1622]! }
- public var Conversation_Report: String { return self._s[1624]! }
- public var Notifications_MessageNotificationsSound: String { return self._s[1625]! }
- public var Notification_MessageLifetime1m: String { return self._s[1626]! }
- public var Privacy_ContactsTitle: String { return self._s[1627]! }
- public var Conversation_ShareMyContactInfo: String { return self._s[1628]! }
- public var Wallet_WordCheck_Title: String { return self._s[1629]! }
- public var ChannelMembers_WhoCanAddMembersAdminsHelp: String { return self._s[1630]! }
- public var Channel_Members_Title: String { return self._s[1631]! }
- public var Map_OpenInWaze: String { return self._s[1632]! }
- public var Appearance_RemoveThemeColorConfirmation: String { return self._s[1633]! }
- public var Login_PhoneBannedError: String { return self._s[1634]! }
+ public var Wallet_Words_Title: String { return self._s[1614]! }
+ public var Wallet_Month_ShortMay: String { return self._s[1615]! }
+ public var EditTheme_CreateTitle: String { return self._s[1617]! }
+ public var Passport_InfoLearnMore: String { return self._s[1618]! }
+ public var TwoStepAuth_EmailPlaceholder: String { return self._s[1619]! }
+ public var Passport_Identity_AddIdentityCard: String { return self._s[1620]! }
+ public var Your_card_has_expired: String { return self._s[1621]! }
+ public var StickerPacksSettings_StickerPacksSection: String { return self._s[1622]! }
+ public var GroupInfo_InviteLink_Help: String { return self._s[1623]! }
+ public var TwoFactorSetup_EmailVerification_ResendAction: String { return self._s[1627]! }
+ public var Conversation_Report: String { return self._s[1629]! }
+ public var Notifications_MessageNotificationsSound: String { return self._s[1630]! }
+ public var Notification_MessageLifetime1m: String { return self._s[1631]! }
+ public var Privacy_ContactsTitle: String { return self._s[1632]! }
+ public var Conversation_ShareMyContactInfo: String { return self._s[1633]! }
+ public var Wallet_WordCheck_Title: String { return self._s[1634]! }
+ public var ChannelMembers_WhoCanAddMembersAdminsHelp: String { return self._s[1635]! }
+ public var Channel_Members_Title: String { return self._s[1636]! }
+ public var Map_OpenInWaze: String { return self._s[1637]! }
+ public var Appearance_RemoveThemeColorConfirmation: String { return self._s[1638]! }
+ public var Login_PhoneBannedError: String { return self._s[1639]! }
public func LiveLocationUpdated_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1635]!, self._r[1635]!, [_0])
+ return formatWithArgumentRanges(self._s[1640]!, self._r[1640]!, [_0])
}
- public var IntentsSettings_MainAccount: String { return self._s[1636]! }
- public var Group_Management_AddModeratorHelp: String { return self._s[1637]! }
- public var AutoDownloadSettings_WifiTitle: String { return self._s[1638]! }
- public var Common_OK: String { return self._s[1639]! }
- public var Passport_Address_TypeBankStatementUploadScan: String { return self._s[1640]! }
- public var Wallet_Words_NotDoneResponse: String { return self._s[1641]! }
- public var Cache_Music: String { return self._s[1642]! }
- public var Wallet_Configuration_SourceURL: String { return self._s[1643]! }
- public var SettingsSearch_Synonyms_EditProfile_PhoneNumber: String { return self._s[1644]! }
- public var PasscodeSettings_UnlockWithTouchId: String { return self._s[1646]! }
- public var TwoStepAuth_HintPlaceholder: String { return self._s[1647]! }
+ public var IntentsSettings_MainAccount: String { return self._s[1641]! }
+ public var Group_Management_AddModeratorHelp: String { return self._s[1642]! }
+ public var AutoDownloadSettings_WifiTitle: String { return self._s[1643]! }
+ public var Common_OK: String { return self._s[1644]! }
+ public var Passport_Address_TypeBankStatementUploadScan: String { return self._s[1645]! }
+ public var Wallet_Words_NotDoneResponse: String { return self._s[1646]! }
+ public var Cache_Music: String { return self._s[1647]! }
+ public var Wallet_Configuration_SourceURL: String { return self._s[1648]! }
+ public var SettingsSearch_Synonyms_EditProfile_PhoneNumber: String { return self._s[1649]! }
+ public var PasscodeSettings_UnlockWithTouchId: String { return self._s[1652]! }
+ public var TwoStepAuth_HintPlaceholder: String { return self._s[1653]! }
public func PUSH_PINNED_INVOICE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1648]!, self._r[1648]!, [_1])
+ return formatWithArgumentRanges(self._s[1654]!, self._r[1654]!, [_1])
}
public func Passport_RequestHeader(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1649]!, self._r[1649]!, [_0])
+ return formatWithArgumentRanges(self._s[1655]!, self._r[1655]!, [_0])
}
- public var TwoFactorSetup_Done_Action: String { return self._s[1650]! }
+ public var TwoFactorSetup_Done_Action: String { return self._s[1656]! }
public func VoiceOver_Chat_ContactOrganization(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1651]!, self._r[1651]!, [_0])
+ return formatWithArgumentRanges(self._s[1657]!, self._r[1657]!, [_0])
}
- public var Wallet_Send_ErrorNotEnoughFundsText: String { return self._s[1652]! }
- public var Watch_MessageView_ViewOnPhone: String { return self._s[1654]! }
- public var Privacy_Calls_CustomShareHelp: String { return self._s[1655]! }
- public var Wallet_Receive_CreateInvoiceInfo: String { return self._s[1657]! }
- public var ChangePhoneNumberNumber_Title: String { return self._s[1658]! }
- public var State_ConnectingToProxyInfo: String { return self._s[1659]! }
- public var Conversation_SwipeToReplyHintTitle: String { return self._s[1660]! }
- public var Message_VideoMessage: String { return self._s[1662]! }
- public var ChannelInfo_DeleteChannel: String { return self._s[1663]! }
- public var ContactInfo_PhoneLabelOther: String { return self._s[1664]! }
- public var Channel_EditAdmin_CannotEdit: String { return self._s[1665]! }
- public var Passport_DeleteAddressConfirmation: String { return self._s[1666]! }
+ public var Wallet_Send_ErrorNotEnoughFundsText: String { return self._s[1658]! }
+ public var Watch_MessageView_ViewOnPhone: String { return self._s[1660]! }
+ public var Privacy_Calls_CustomShareHelp: String { return self._s[1661]! }
+ public var Wallet_Receive_CreateInvoiceInfo: String { return self._s[1663]! }
+ public var ChangePhoneNumberNumber_Title: String { return self._s[1664]! }
+ public var State_ConnectingToProxyInfo: String { return self._s[1665]! }
+ public var Conversation_SwipeToReplyHintTitle: String { return self._s[1666]! }
+ public var Message_VideoMessage: String { return self._s[1668]! }
+ public var ChannelInfo_DeleteChannel: String { return self._s[1669]! }
+ public var ContactInfo_PhoneLabelOther: String { return self._s[1670]! }
+ public var Channel_EditAdmin_CannotEdit: String { return self._s[1671]! }
+ public var Passport_DeleteAddressConfirmation: String { return self._s[1672]! }
public func Wallet_Time_PreciseDate_m9(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1667]!, self._r[1667]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1673]!, self._r[1673]!, [_1, _2, _3])
}
- public var WallpaperPreview_SwipeBottomText: String { return self._s[1668]! }
- public var Activity_RecordingAudio: String { return self._s[1669]! }
- public var SettingsSearch_Synonyms_Watch: String { return self._s[1670]! }
- public var PasscodeSettings_TryAgainIn1Minute: String { return self._s[1671]! }
- public var Wallet_Info_Address: String { return self._s[1672]! }
+ public var WallpaperPreview_SwipeBottomText: String { return self._s[1674]! }
+ public var Activity_RecordingAudio: String { return self._s[1675]! }
+ public var SettingsSearch_Synonyms_Watch: String { return self._s[1676]! }
+ public var PasscodeSettings_TryAgainIn1Minute: String { return self._s[1677]! }
+ public var Wallet_Info_Address: String { return self._s[1678]! }
public func Notification_ChangedGroupName(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1674]!, self._r[1674]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[1680]!, self._r[1680]!, [_0, _1])
}
public func EmptyGroupInfo_Line1(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1678]!, self._r[1678]!, [_0])
+ return formatWithArgumentRanges(self._s[1684]!, self._r[1684]!, [_0])
}
- public var Conversation_ApplyLocalization: String { return self._s[1679]! }
- public var TwoFactorSetup_Intro_Action: String { return self._s[1680]! }
- public var UserInfo_AddPhone: String { return self._s[1681]! }
- public var Map_ShareLiveLocationHelp: String { return self._s[1682]! }
+ public var Conversation_ApplyLocalization: String { return self._s[1685]! }
+ public var TwoFactorSetup_Intro_Action: String { return self._s[1686]! }
+ public var UserInfo_AddPhone: String { return self._s[1687]! }
+ public var Map_ShareLiveLocationHelp: String { return self._s[1688]! }
public func Passport_Identity_NativeNameGenericHelp(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1683]!, self._r[1683]!, [_0])
+ return formatWithArgumentRanges(self._s[1689]!, self._r[1689]!, [_0])
}
- public var Passport_Scans: String { return self._s[1685]! }
- public var BlockedUsers_Unblock: String { return self._s[1686]! }
+ public var Passport_Scans: String { return self._s[1691]! }
+ public var BlockedUsers_Unblock: String { return self._s[1692]! }
public func PUSH_ENCRYPTION_REQUEST(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1687]!, self._r[1687]!, [_1])
+ return formatWithArgumentRanges(self._s[1693]!, self._r[1693]!, [_1])
}
- public var Channel_Management_LabelCreator: String { return self._s[1688]! }
- public var Conversation_ReportSpamAndLeave: String { return self._s[1689]! }
- public var SettingsSearch_Synonyms_EditProfile_Bio: String { return self._s[1690]! }
- public var ChatList_UndoArchiveMultipleTitle: String { return self._s[1691]! }
- public var Passport_Identity_NativeNameGenericTitle: String { return self._s[1692]! }
+ public var Channel_Management_LabelCreator: String { return self._s[1694]! }
+ public var Conversation_ReportSpamAndLeave: String { return self._s[1695]! }
+ public var SettingsSearch_Synonyms_EditProfile_Bio: String { return self._s[1696]! }
+ public var ChatList_UndoArchiveMultipleTitle: String { return self._s[1697]! }
+ public var Passport_Identity_NativeNameGenericTitle: String { return self._s[1698]! }
public func Login_EmailPhoneBody(_ _0: String, _ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1693]!, self._r[1693]!, [_0, _1, _2])
+ return formatWithArgumentRanges(self._s[1699]!, self._r[1699]!, [_0, _1, _2])
}
- public var Login_PhoneNumberHelp: String { return self._s[1694]! }
- public var LastSeen_ALongTimeAgo: String { return self._s[1695]! }
- public var Channel_AdminLog_CanPinMessages: String { return self._s[1696]! }
- public var ChannelIntro_CreateChannel: String { return self._s[1697]! }
- public var Conversation_UnreadMessages: String { return self._s[1698]! }
- public var SettingsSearch_Synonyms_Stickers_ArchivedPacks: String { return self._s[1699]! }
- public var Channel_AdminLog_EmptyText: String { return self._s[1700]! }
- public var Theme_Context_Apply: String { return self._s[1701]! }
- public var Notification_GroupActivated: String { return self._s[1702]! }
- public var NotificationSettings_ContactJoinedInfo: String { return self._s[1703]! }
- public var Wallet_Intro_CreateWallet: String { return self._s[1704]! }
+ public var Login_PhoneNumberHelp: String { return self._s[1700]! }
+ public var LastSeen_ALongTimeAgo: String { return self._s[1701]! }
+ public var Channel_AdminLog_CanPinMessages: String { return self._s[1702]! }
+ public var ChannelIntro_CreateChannel: String { return self._s[1703]! }
+ public var Conversation_UnreadMessages: String { return self._s[1704]! }
+ public var SettingsSearch_Synonyms_Stickers_ArchivedPacks: String { return self._s[1705]! }
+ public var Channel_AdminLog_EmptyText: String { return self._s[1706]! }
+ public var Theme_Context_Apply: String { return self._s[1707]! }
+ public var Notification_GroupActivated: String { return self._s[1708]! }
+ public var NotificationSettings_ContactJoinedInfo: String { return self._s[1709]! }
+ public var Wallet_Intro_CreateWallet: String { return self._s[1710]! }
public func Notification_PinnedContactMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1705]!, self._r[1705]!, [_0])
+ return formatWithArgumentRanges(self._s[1711]!, self._r[1711]!, [_0])
}
public func DownloadingStatus(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1706]!, self._r[1706]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[1712]!, self._r[1712]!, [_0, _1])
}
- public var GroupInfo_ConvertToSupergroup: String { return self._s[1708]! }
+ public var GroupInfo_ConvertToSupergroup: String { return self._s[1714]! }
public func PrivacyPolicy_AgeVerificationMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1709]!, self._r[1709]!, [_0])
+ return formatWithArgumentRanges(self._s[1715]!, self._r[1715]!, [_0])
}
- public var Undo_DeletedChannel: String { return self._s[1710]! }
- public var CallFeedback_AddComment: String { return self._s[1711]! }
+ public var Undo_DeletedChannel: String { return self._s[1716]! }
+ public var CallFeedback_AddComment: String { return self._s[1717]! }
public func Conversation_OpenBotLinkAllowMessages(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1712]!, self._r[1712]!, [_0])
+ return formatWithArgumentRanges(self._s[1718]!, self._r[1718]!, [_0])
}
- public var Document_TargetConfirmationFormat: String { return self._s[1713]! }
+ public var Document_TargetConfirmationFormat: String { return self._s[1719]! }
public func Call_StatusOngoing(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1714]!, self._r[1714]!, [_0])
+ return formatWithArgumentRanges(self._s[1720]!, self._r[1720]!, [_0])
}
- public var LogoutOptions_SetPasscodeTitle: String { return self._s[1715]! }
+ public var LogoutOptions_SetPasscodeTitle: String { return self._s[1721]! }
public func PUSH_CHAT_MESSAGE_GAME_SCORE(_ _1: String, _ _2: String, _ _3: String, _ _4: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1716]!, self._r[1716]!, [_1, _2, _3, _4])
+ return formatWithArgumentRanges(self._s[1722]!, self._r[1722]!, [_1, _2, _3, _4])
}
- public var Wallet_SecureStorageChanged_PasscodeText: String { return self._s[1717]! }
- public var Theme_ErrorNotFound: String { return self._s[1718]! }
- public var Contacts_SortByName: String { return self._s[1719]! }
- public var SettingsSearch_Synonyms_Privacy_Forwards: String { return self._s[1720]! }
+ public var Wallet_SecureStorageChanged_PasscodeText: String { return self._s[1723]! }
+ public var Theme_ErrorNotFound: String { return self._s[1724]! }
+ public var Contacts_SortByName: String { return self._s[1725]! }
+ public var SettingsSearch_Synonyms_Privacy_Forwards: String { return self._s[1726]! }
public func CHAT_MESSAGE_INVOICE(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1722]!, self._r[1722]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1728]!, self._r[1728]!, [_1, _2, _3])
}
- public var Notification_Exceptions_RemoveFromExceptions: String { return self._s[1723]! }
- public var ScheduledMessages_EditTime: String { return self._s[1724]! }
- public var Conversation_ClearSelfHistory: String { return self._s[1725]! }
- public var Checkout_NewCard_PostcodePlaceholder: String { return self._s[1726]! }
- public var PasscodeSettings_DoNotMatch: String { return self._s[1727]! }
- public var Stickers_SuggestNone: String { return self._s[1728]! }
- public var ChatSettings_Cache: String { return self._s[1729]! }
- public var Settings_SaveIncomingPhotos: String { return self._s[1730]! }
- public var Media_ShareThisPhoto: String { return self._s[1731]! }
- public var Chat_SlowmodeTooltipPending: String { return self._s[1732]! }
- public var InfoPlist_NSContactsUsageDescription: String { return self._s[1733]! }
- public var Conversation_ContextMenuCopyLink: String { return self._s[1734]! }
- public var PrivacyPolicy_AgeVerificationTitle: String { return self._s[1735]! }
- public var SettingsSearch_Synonyms_Stickers_Masks: String { return self._s[1736]! }
- public var TwoStepAuth_SetupPasswordEnterPasswordNew: String { return self._s[1737]! }
- public var Appearance_ThemePreview_Chat_6_Text: String { return self._s[1738]! }
+ public var Notification_Exceptions_RemoveFromExceptions: String { return self._s[1729]! }
+ public var ScheduledMessages_EditTime: String { return self._s[1730]! }
+ public var Conversation_ClearSelfHistory: String { return self._s[1731]! }
+ public var Checkout_NewCard_PostcodePlaceholder: String { return self._s[1732]! }
+ public var PasscodeSettings_DoNotMatch: String { return self._s[1733]! }
+ public var Stickers_SuggestNone: String { return self._s[1734]! }
+ public var ChatSettings_Cache: String { return self._s[1735]! }
+ public var Settings_SaveIncomingPhotos: String { return self._s[1736]! }
+ public var Media_ShareThisPhoto: String { return self._s[1737]! }
+ public var Chat_SlowmodeTooltipPending: String { return self._s[1738]! }
+ public var InfoPlist_NSContactsUsageDescription: String { return self._s[1739]! }
+ public var Conversation_ContextMenuCopyLink: String { return self._s[1740]! }
+ public var PrivacyPolicy_AgeVerificationTitle: String { return self._s[1741]! }
+ public var SettingsSearch_Synonyms_Stickers_Masks: String { return self._s[1742]! }
+ public var TwoStepAuth_SetupPasswordEnterPasswordNew: String { return self._s[1743]! }
+ public var Appearance_ThemePreview_Chat_6_Text: String { return self._s[1744]! }
public func Wallet_SecureStorageReset_BiometryText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1739]!, self._r[1739]!, [_0])
+ return formatWithArgumentRanges(self._s[1745]!, self._r[1745]!, [_0])
}
- public var Permissions_CellularDataTitle_v0: String { return self._s[1740]! }
- public var WallpaperSearch_ColorWhite: String { return self._s[1742]! }
- public var Channel_AdminLog_DefaultRestrictionsUpdated: String { return self._s[1743]! }
- public var Conversation_ErrorInaccessibleMessage: String { return self._s[1744]! }
- public var Map_OpenIn: String { return self._s[1745]! }
+ public var Permissions_CellularDataTitle_v0: String { return self._s[1746]! }
+ public var WallpaperSearch_ColorWhite: String { return self._s[1748]! }
+ public var Channel_AdminLog_DefaultRestrictionsUpdated: String { return self._s[1749]! }
+ public var Conversation_ErrorInaccessibleMessage: String { return self._s[1750]! }
+ public var Map_OpenIn: String { return self._s[1751]! }
public func PUSH_PHONE_CALL_MISSED(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1748]!, self._r[1748]!, [_1])
+ return formatWithArgumentRanges(self._s[1754]!, self._r[1754]!, [_1])
}
public func ChannelInfo_AddParticipantConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1749]!, self._r[1749]!, [_0])
+ return formatWithArgumentRanges(self._s[1755]!, self._r[1755]!, [_0])
}
- public var GroupInfo_Permissions_SlowmodeHeader: String { return self._s[1750]! }
- public var MessagePoll_LabelClosed: String { return self._s[1751]! }
- public var GroupPermission_PermissionGloballyDisabled: String { return self._s[1753]! }
- public var Wallet_Send_SendAnyway: String { return self._s[1754]! }
- public var Passport_Identity_MiddleNamePlaceholder: String { return self._s[1755]! }
- public var UserInfo_FirstNamePlaceholder: String { return self._s[1756]! }
- public var PrivacyLastSeenSettings_WhoCanSeeMyTimestamp: String { return self._s[1757]! }
- public var Map_SetThisPlace: String { return self._s[1758]! }
- public var Login_SelectCountry_Title: String { return self._s[1759]! }
- public var Channel_EditAdmin_PermissionBanUsers: String { return self._s[1760]! }
+ public var GroupInfo_Permissions_SlowmodeHeader: String { return self._s[1756]! }
+ public var MessagePoll_LabelClosed: String { return self._s[1757]! }
+ public var GroupPermission_PermissionGloballyDisabled: String { return self._s[1759]! }
+ public var Wallet_Send_SendAnyway: String { return self._s[1760]! }
+ public var Passport_Identity_MiddleNamePlaceholder: String { return self._s[1761]! }
+ public var UserInfo_FirstNamePlaceholder: String { return self._s[1762]! }
+ public var PrivacyLastSeenSettings_WhoCanSeeMyTimestamp: String { return self._s[1763]! }
+ public var Map_SetThisPlace: String { return self._s[1764]! }
+ public var Login_SelectCountry_Title: String { return self._s[1765]! }
+ public var Channel_EditAdmin_PermissionBanUsers: String { return self._s[1766]! }
public func Conversation_OpenBotLinkLogin(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1761]!, self._r[1761]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1767]!, self._r[1767]!, [_1, _2])
}
- public var Channel_AdminLog_ChangeInfo: String { return self._s[1762]! }
- public var Watch_Suggestion_BRB: String { return self._s[1763]! }
- public var Passport_Identity_EditIdentityCard: String { return self._s[1764]! }
- public var Contacts_PermissionsTitle: String { return self._s[1765]! }
- public var Conversation_RestrictedInline: String { return self._s[1766]! }
- public var Appearance_RemoveThemeColor: String { return self._s[1768]! }
- public var StickerPack_ViewPack: String { return self._s[1769]! }
- public var Wallet_UnknownError: String { return self._s[1770]! }
+ public var Channel_AdminLog_ChangeInfo: String { return self._s[1768]! }
+ public var Watch_Suggestion_BRB: String { return self._s[1769]! }
+ public var Passport_Identity_EditIdentityCard: String { return self._s[1770]! }
+ public var Contacts_PermissionsTitle: String { return self._s[1771]! }
+ public var Conversation_RestrictedInline: String { return self._s[1772]! }
+ public var Appearance_RemoveThemeColor: String { return self._s[1774]! }
+ public var StickerPack_ViewPack: String { return self._s[1775]! }
+ public var Wallet_UnknownError: String { return self._s[1776]! }
public func Update_AppVersion(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1771]!, self._r[1771]!, [_0])
+ return formatWithArgumentRanges(self._s[1777]!, self._r[1777]!, [_0])
}
- public var Compose_NewChannel: String { return self._s[1773]! }
- public var ChatSettings_AutoDownloadSettings_TypePhoto: String { return self._s[1776]! }
- public var MessagePoll_LabelQuiz: String { return self._s[1778]! }
- public var Conversation_ReportSpamGroupConfirmation: String { return self._s[1779]! }
- public var Channel_Info_Stickers: String { return self._s[1780]! }
- public var AutoNightTheme_PreferredTheme: String { return self._s[1781]! }
- public var PrivacyPolicy_AgeVerificationAgree: String { return self._s[1782]! }
- public var Passport_DeletePersonalDetails: String { return self._s[1783]! }
- public var LogoutOptions_AddAccountTitle: String { return self._s[1784]! }
- public var Channel_DiscussionGroupInfo: String { return self._s[1785]! }
- public var Group_EditAdmin_RankOwnerPlaceholder: String { return self._s[1786]! }
- public var Conversation_SearchNoResults: String { return self._s[1789]! }
- public var Wallet_Configuration_ApplyErrorTextURLInvalid: String { return self._s[1790]! }
- public var MessagePoll_LabelAnonymous: String { return self._s[1791]! }
- public var Channel_Members_AddAdminErrorNotAMember: String { return self._s[1792]! }
- public var Login_Code: String { return self._s[1793]! }
- public var EditTheme_Create_BottomInfo: String { return self._s[1794]! }
- public var Watch_Suggestion_WhatsUp: String { return self._s[1795]! }
- public var Weekday_ShortThursday: String { return self._s[1796]! }
- public var Resolve_ErrorNotFound: String { return self._s[1798]! }
- public var LastSeen_Offline: String { return self._s[1799]! }
- public var PeopleNearby_NoMembers: String { return self._s[1800]! }
- public var GroupPermission_AddMembersNotAvailable: String { return self._s[1801]! }
- public var Privacy_Calls_AlwaysAllow_Title: String { return self._s[1802]! }
- public var GroupInfo_Title: String { return self._s[1804]! }
- public var NotificationsSound_Note: String { return self._s[1805]! }
- public var Conversation_EditingMessagePanelTitle: String { return self._s[1806]! }
- public var Watch_Message_Poll: String { return self._s[1807]! }
- public var Privacy_Calls: String { return self._s[1808]! }
+ public var Compose_NewChannel: String { return self._s[1779]! }
+ public var ChatSettings_AutoDownloadSettings_TypePhoto: String { return self._s[1782]! }
+ public var MessagePoll_LabelQuiz: String { return self._s[1784]! }
+ public var Conversation_ReportSpamGroupConfirmation: String { return self._s[1785]! }
+ public var Channel_Info_Stickers: String { return self._s[1786]! }
+ public var AutoNightTheme_PreferredTheme: String { return self._s[1787]! }
+ public var PrivacyPolicy_AgeVerificationAgree: String { return self._s[1788]! }
+ public var Passport_DeletePersonalDetails: String { return self._s[1789]! }
+ public var LogoutOptions_AddAccountTitle: String { return self._s[1790]! }
+ public var Channel_DiscussionGroupInfo: String { return self._s[1791]! }
+ public var Group_EditAdmin_RankOwnerPlaceholder: String { return self._s[1792]! }
+ public var Conversation_SearchNoResults: String { return self._s[1795]! }
+ public var Wallet_Configuration_ApplyErrorTextURLInvalid: String { return self._s[1796]! }
+ public var MessagePoll_LabelAnonymous: String { return self._s[1797]! }
+ public var Channel_Members_AddAdminErrorNotAMember: String { return self._s[1798]! }
+ public var Login_Code: String { return self._s[1799]! }
+ public var EditTheme_Create_BottomInfo: String { return self._s[1800]! }
+ public var Watch_Suggestion_WhatsUp: String { return self._s[1801]! }
+ public var Weekday_ShortThursday: String { return self._s[1802]! }
+ public var Resolve_ErrorNotFound: String { return self._s[1804]! }
+ public var LastSeen_Offline: String { return self._s[1805]! }
+ public var PeopleNearby_NoMembers: String { return self._s[1806]! }
+ public var GroupPermission_AddMembersNotAvailable: String { return self._s[1807]! }
+ public var Privacy_Calls_AlwaysAllow_Title: String { return self._s[1808]! }
+ public var GroupInfo_Title: String { return self._s[1810]! }
+ public var NotificationsSound_Note: String { return self._s[1811]! }
+ public var Conversation_EditingMessagePanelTitle: String { return self._s[1812]! }
+ public var Watch_Message_Poll: String { return self._s[1813]! }
+ public var Privacy_Calls: String { return self._s[1814]! }
public func Channel_AdminLog_MessageRankUsername(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1809]!, self._r[1809]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1815]!, self._r[1815]!, [_1, _2, _3])
}
- public var Month_ShortAugust: String { return self._s[1810]! }
- public var TwoStepAuth_SetPasswordHelp: String { return self._s[1811]! }
- public var Notifications_Reset: String { return self._s[1812]! }
- public var Conversation_Pin: String { return self._s[1813]! }
- public var Passport_Language_lv: String { return self._s[1814]! }
- public var Permissions_PeopleNearbyAllowInSettings_v0: String { return self._s[1815]! }
- public var BlockedUsers_Info: String { return self._s[1816]! }
- public var SettingsSearch_Synonyms_Data_AutoplayVideos: String { return self._s[1818]! }
- public var Watch_Conversation_Unblock: String { return self._s[1820]! }
+ public var Month_ShortAugust: String { return self._s[1816]! }
+ public var TwoStepAuth_SetPasswordHelp: String { return self._s[1817]! }
+ public var Notifications_Reset: String { return self._s[1818]! }
+ public var Conversation_Pin: String { return self._s[1819]! }
+ public var Passport_Language_lv: String { return self._s[1820]! }
+ public var Permissions_PeopleNearbyAllowInSettings_v0: String { return self._s[1821]! }
+ public var BlockedUsers_Info: String { return self._s[1822]! }
+ public var SettingsSearch_Synonyms_Data_AutoplayVideos: String { return self._s[1824]! }
+ public var Watch_Conversation_Unblock: String { return self._s[1826]! }
public func Time_MonthOfYear_m9(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1821]!, self._r[1821]!, [_0])
+ return formatWithArgumentRanges(self._s[1827]!, self._r[1827]!, [_0])
}
- public var CloudStorage_Title: String { return self._s[1822]! }
- public var GroupInfo_DeleteAndExitConfirmation: String { return self._s[1823]! }
+ public var CloudStorage_Title: String { return self._s[1828]! }
+ public var GroupInfo_DeleteAndExitConfirmation: String { return self._s[1829]! }
public func NetworkUsageSettings_WifiUsageSince(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1824]!, self._r[1824]!, [_0])
+ return formatWithArgumentRanges(self._s[1830]!, self._r[1830]!, [_0])
}
- public var Channel_AdminLogFilter_AdminsTitle: String { return self._s[1825]! }
- public var Watch_Suggestion_OnMyWay: String { return self._s[1826]! }
- public var TwoStepAuth_RecoveryEmailTitle: String { return self._s[1827]! }
- public var Passport_Address_EditBankStatement: String { return self._s[1828]! }
+ public var Channel_AdminLogFilter_AdminsTitle: String { return self._s[1831]! }
+ public var Watch_Suggestion_OnMyWay: String { return self._s[1832]! }
+ public var TwoStepAuth_RecoveryEmailTitle: String { return self._s[1833]! }
+ public var Passport_Address_EditBankStatement: String { return self._s[1834]! }
public func Channel_AdminLog_MessageChangedUnlinkedGroup(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1829]!, self._r[1829]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1835]!, self._r[1835]!, [_1, _2])
}
- public var ChatSettings_DownloadInBackgroundInfo: String { return self._s[1830]! }
- public var ShareMenu_Comment: String { return self._s[1831]! }
- public var Permissions_ContactsTitle_v0: String { return self._s[1832]! }
- public var Notifications_PermissionsTitle: String { return self._s[1833]! }
- public var GroupPermission_NoSendLinks: String { return self._s[1834]! }
- public var Privacy_Forwards_NeverAllow_Title: String { return self._s[1835]! }
- public var Wallet_SecureStorageChanged_ImportWallet: String { return self._s[1836]! }
- public var Settings_Support: String { return self._s[1837]! }
- public var Notifications_ChannelNotificationsSound: String { return self._s[1838]! }
- public var SettingsSearch_Synonyms_Data_AutoDownloadReset: String { return self._s[1839]! }
- public var Privacy_Forwards_Preview: String { return self._s[1840]! }
- public var GroupPermission_ApplyAlertAction: String { return self._s[1841]! }
- public var Watch_Stickers_StickerPacks: String { return self._s[1842]! }
- public var Common_Select: String { return self._s[1844]! }
- public var CheckoutInfo_ErrorEmailInvalid: String { return self._s[1845]! }
- public var WallpaperSearch_ColorGray: String { return self._s[1848]! }
- public var TwoFactorSetup_Password_PlaceholderPassword: String { return self._s[1849]! }
- public var TwoFactorSetup_Hint_SkipAction: String { return self._s[1850]! }
- public var ChatAdmins_AllMembersAreAdminsOffHelp: String { return self._s[1851]! }
- public var PollResults_Title: String { return self._s[1852]! }
- public var PasscodeSettings_AutoLock_IfAwayFor_5hours: String { return self._s[1853]! }
- public var Appearance_PreviewReplyAuthor: String { return self._s[1854]! }
- public var TwoStepAuth_RecoveryTitle: String { return self._s[1855]! }
- public var Widget_AuthRequired: String { return self._s[1856]! }
- public var Camera_FlashOn: String { return self._s[1857]! }
- public var Conversation_ContextMenuLookUp: String { return self._s[1858]! }
- public var Channel_Stickers_NotFoundHelp: String { return self._s[1859]! }
- public var Watch_Suggestion_OK: String { return self._s[1860]! }
+ public var ChatSettings_DownloadInBackgroundInfo: String { return self._s[1836]! }
+ public var ShareMenu_Comment: String { return self._s[1837]! }
+ public var Permissions_ContactsTitle_v0: String { return self._s[1838]! }
+ public var Notifications_PermissionsTitle: String { return self._s[1839]! }
+ public var GroupPermission_NoSendLinks: String { return self._s[1840]! }
+ public var Privacy_Forwards_NeverAllow_Title: String { return self._s[1841]! }
+ public var Wallet_SecureStorageChanged_ImportWallet: String { return self._s[1842]! }
+ public var Settings_Support: String { return self._s[1843]! }
+ public var Notifications_ChannelNotificationsSound: String { return self._s[1844]! }
+ public var SettingsSearch_Synonyms_Data_AutoDownloadReset: String { return self._s[1845]! }
+ public var Privacy_Forwards_Preview: String { return self._s[1846]! }
+ public var GroupPermission_ApplyAlertAction: String { return self._s[1847]! }
+ public var Watch_Stickers_StickerPacks: String { return self._s[1848]! }
+ public var Common_Select: String { return self._s[1850]! }
+ public var CheckoutInfo_ErrorEmailInvalid: String { return self._s[1851]! }
+ public var WallpaperSearch_ColorGray: String { return self._s[1854]! }
+ public var TwoFactorSetup_Password_PlaceholderPassword: String { return self._s[1855]! }
+ public var TwoFactorSetup_Hint_SkipAction: String { return self._s[1856]! }
+ public var ChatAdmins_AllMembersAreAdminsOffHelp: String { return self._s[1857]! }
+ public var PollResults_Title: String { return self._s[1858]! }
+ public var PasscodeSettings_AutoLock_IfAwayFor_5hours: String { return self._s[1859]! }
+ public var Appearance_PreviewReplyAuthor: String { return self._s[1860]! }
+ public var TwoStepAuth_RecoveryTitle: String { return self._s[1861]! }
+ public var Widget_AuthRequired: String { return self._s[1862]! }
+ public var Camera_FlashOn: String { return self._s[1863]! }
+ public var Conversation_ContextMenuLookUp: String { return self._s[1864]! }
+ public var Channel_Stickers_NotFoundHelp: String { return self._s[1865]! }
+ public var Watch_Suggestion_OK: String { return self._s[1866]! }
public func Username_LinkHint(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1862]!, self._r[1862]!, [_0])
+ return formatWithArgumentRanges(self._s[1868]!, self._r[1868]!, [_0])
}
public func Notification_PinnedLiveLocationMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1864]!, self._r[1864]!, [_0])
+ return formatWithArgumentRanges(self._s[1870]!, self._r[1870]!, [_0])
}
- public var TextFormat_Strikethrough: String { return self._s[1865]! }
- public var DialogList_AdLabel: String { return self._s[1866]! }
- public var WatchRemote_NotificationText: String { return self._s[1867]! }
- public var IntentsSettings_SuggestedChatsSavedMessages: String { return self._s[1868]! }
- public var SettingsSearch_Synonyms_Notifications_MessageNotificationsAlert: String { return self._s[1869]! }
- public var Conversation_ReportSpam: String { return self._s[1870]! }
- public var SettingsSearch_Synonyms_Privacy_Data_TopPeers: String { return self._s[1871]! }
- public var Settings_LogoutConfirmationTitle: String { return self._s[1873]! }
- public var PhoneLabel_Title: String { return self._s[1874]! }
- public var Passport_Address_EditRentalAgreement: String { return self._s[1875]! }
- public var Settings_ChangePhoneNumber: String { return self._s[1876]! }
- public var Notifications_ExceptionsTitle: String { return self._s[1877]! }
- public var Notifications_AlertTones: String { return self._s[1878]! }
- public var Call_ReportIncludeLogDescription: String { return self._s[1879]! }
- public var SettingsSearch_Synonyms_Notifications_ResetAllNotifications: String { return self._s[1880]! }
- public var AutoDownloadSettings_PrivateChats: String { return self._s[1881]! }
- public var VoiceOver_Chat_Photo: String { return self._s[1883]! }
- public var TwoStepAuth_AddHintTitle: String { return self._s[1884]! }
- public var ReportPeer_ReasonOther: String { return self._s[1885]! }
- public var ChatList_Context_JoinChannel: String { return self._s[1886]! }
- public var KeyCommand_ScrollDown: String { return self._s[1888]! }
- public var Conversation_ScheduleMessage_Title: String { return self._s[1889]! }
+ public var TextFormat_Strikethrough: String { return self._s[1871]! }
+ public var DialogList_AdLabel: String { return self._s[1872]! }
+ public var WatchRemote_NotificationText: String { return self._s[1873]! }
+ public var IntentsSettings_SuggestedChatsSavedMessages: String { return self._s[1874]! }
+ public var SettingsSearch_Synonyms_Notifications_MessageNotificationsAlert: String { return self._s[1875]! }
+ public var Conversation_ReportSpam: String { return self._s[1876]! }
+ public var SettingsSearch_Synonyms_Privacy_Data_TopPeers: String { return self._s[1877]! }
+ public var Settings_LogoutConfirmationTitle: String { return self._s[1879]! }
+ public var PhoneLabel_Title: String { return self._s[1880]! }
+ public var Passport_Address_EditRentalAgreement: String { return self._s[1881]! }
+ public var Settings_ChangePhoneNumber: String { return self._s[1882]! }
+ public var Notifications_ExceptionsTitle: String { return self._s[1883]! }
+ public var Notifications_AlertTones: String { return self._s[1884]! }
+ public var Call_ReportIncludeLogDescription: String { return self._s[1885]! }
+ public var SettingsSearch_Synonyms_Notifications_ResetAllNotifications: String { return self._s[1886]! }
+ public var AutoDownloadSettings_PrivateChats: String { return self._s[1887]! }
+ public var VoiceOver_Chat_Photo: String { return self._s[1889]! }
+ public var TwoStepAuth_AddHintTitle: String { return self._s[1890]! }
+ public var ReportPeer_ReasonOther: String { return self._s[1891]! }
+ public var ChatList_Context_JoinChannel: String { return self._s[1892]! }
+ public var KeyCommand_ScrollDown: String { return self._s[1894]! }
+ public var Conversation_ScheduleMessage_Title: String { return self._s[1895]! }
public func Login_BannedPhoneSubject(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1890]!, self._r[1890]!, [_0])
+ return formatWithArgumentRanges(self._s[1896]!, self._r[1896]!, [_0])
}
- public var NetworkUsageSettings_MediaVideoDataSection: String { return self._s[1891]! }
- public var ChannelInfo_DeleteGroupConfirmation: String { return self._s[1892]! }
- public var AuthSessions_LogOut: String { return self._s[1893]! }
- public var Passport_Identity_TypeInternalPassport: String { return self._s[1894]! }
- public var ChatSettings_AutoDownloadVoiceMessages: String { return self._s[1895]! }
- public var Passport_Phone_Title: String { return self._s[1896]! }
- public var ContactList_Context_StartSecretChat: String { return self._s[1897]! }
- public var Settings_PhoneNumber: String { return self._s[1898]! }
+ public var NetworkUsageSettings_MediaVideoDataSection: String { return self._s[1897]! }
+ public var ChannelInfo_DeleteGroupConfirmation: String { return self._s[1898]! }
+ public var AuthSessions_LogOut: String { return self._s[1899]! }
+ public var Passport_Identity_TypeInternalPassport: String { return self._s[1900]! }
+ public var ChatSettings_AutoDownloadVoiceMessages: String { return self._s[1901]! }
+ public var Passport_Phone_Title: String { return self._s[1902]! }
+ public var ContactList_Context_StartSecretChat: String { return self._s[1903]! }
+ public var Settings_PhoneNumber: String { return self._s[1904]! }
public func Conversation_ScheduleMessage_SendToday(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1899]!, self._r[1899]!, [_0])
+ return formatWithArgumentRanges(self._s[1905]!, self._r[1905]!, [_0])
}
- public var NotificationsSound_Alert: String { return self._s[1901]! }
- public var Wallet_SecureStorageChanged_CreateWallet: String { return self._s[1902]! }
- public var WebSearch_SearchNoResults: String { return self._s[1903]! }
- public var Privacy_ProfilePhoto_AlwaysShareWith_Title: String { return self._s[1905]! }
- public var Wallet_Configuration_SourceInfo: String { return self._s[1906]! }
- public var LogoutOptions_AlternativeOptionsSection: String { return self._s[1907]! }
- public var SettingsSearch_Synonyms_Passport: String { return self._s[1908]! }
- public var PhotoEditor_CurvesTool: String { return self._s[1909]! }
- public var Checkout_PaymentMethod: String { return self._s[1911]! }
+ public var NotificationsSound_Alert: String { return self._s[1907]! }
+ public var Wallet_SecureStorageChanged_CreateWallet: String { return self._s[1908]! }
+ public var WebSearch_SearchNoResults: String { return self._s[1909]! }
+ public var Privacy_ProfilePhoto_AlwaysShareWith_Title: String { return self._s[1911]! }
+ public var Wallet_Configuration_SourceInfo: String { return self._s[1912]! }
+ public var LogoutOptions_AlternativeOptionsSection: String { return self._s[1913]! }
+ public var SettingsSearch_Synonyms_Passport: String { return self._s[1914]! }
+ public var PhotoEditor_CurvesTool: String { return self._s[1915]! }
+ public var Checkout_PaymentMethod: String { return self._s[1917]! }
public func PUSH_CHAT_ADD_YOU(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1912]!, self._r[1912]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1918]!, self._r[1918]!, [_1, _2])
}
- public var Contacts_AccessDeniedError: String { return self._s[1913]! }
- public var Camera_PhotoMode: String { return self._s[1916]! }
- public var EditTheme_Expand_Preview_IncomingText: String { return self._s[1917]! }
- public var Appearance_TextSize_Apply: String { return self._s[1918]! }
- public var Passport_Address_AddUtilityBill: String { return self._s[1920]! }
- public var CallSettings_OnMobile: String { return self._s[1921]! }
- public var Tour_Text2: String { return self._s[1922]! }
+ public var Contacts_AccessDeniedError: String { return self._s[1919]! }
+ public var Camera_PhotoMode: String { return self._s[1922]! }
+ public var EditTheme_Expand_Preview_IncomingText: String { return self._s[1923]! }
+ public var Appearance_TextSize_Apply: String { return self._s[1924]! }
+ public var Passport_Address_AddUtilityBill: String { return self._s[1926]! }
+ public var CallSettings_OnMobile: String { return self._s[1927]! }
+ public var Tour_Text2: String { return self._s[1928]! }
public func PUSH_CHAT_MESSAGE_ROUND(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1923]!, self._r[1923]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1929]!, self._r[1929]!, [_1, _2])
}
- public var DialogList_EncryptionProcessing: String { return self._s[1925]! }
- public var Permissions_Skip: String { return self._s[1926]! }
- public var Wallet_Words_NotDoneOk: String { return self._s[1927]! }
- public var SecretImage_Title: String { return self._s[1928]! }
- public var Watch_MessageView_Title: String { return self._s[1929]! }
- public var Channel_DiscussionGroupAdd: String { return self._s[1930]! }
- public var AttachmentMenu_Poll: String { return self._s[1931]! }
+ public var DialogList_EncryptionProcessing: String { return self._s[1931]! }
+ public var Permissions_Skip: String { return self._s[1932]! }
+ public var Wallet_Words_NotDoneOk: String { return self._s[1933]! }
+ public var SecretImage_Title: String { return self._s[1934]! }
+ public var Watch_MessageView_Title: String { return self._s[1935]! }
+ public var Channel_DiscussionGroupAdd: String { return self._s[1936]! }
+ public var AttachmentMenu_Poll: String { return self._s[1937]! }
public func Notification_GroupInviter(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1932]!, self._r[1932]!, [_0])
+ return formatWithArgumentRanges(self._s[1938]!, self._r[1938]!, [_0])
}
public func Channel_DiscussionGroup_PrivateChannelLink(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1933]!, self._r[1933]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[1939]!, self._r[1939]!, [_1, _2])
}
- public var Notification_CallCanceled: String { return self._s[1934]! }
- public var WallpaperPreview_Title: String { return self._s[1935]! }
- public var Privacy_PaymentsClear_PaymentInfo: String { return self._s[1936]! }
- public var Settings_ProxyConnecting: String { return self._s[1937]! }
- public var Settings_CheckPhoneNumberText: String { return self._s[1939]! }
- public var VoiceOver_Chat_YourVideo: String { return self._s[1940]! }
- public var Wallet_Intro_Title: String { return self._s[1941]! }
- public var TwoFactorSetup_Password_Action: String { return self._s[1942]! }
- public var Profile_MessageLifetime5s: String { return self._s[1943]! }
- public var Username_InvalidCharacters: String { return self._s[1944]! }
- public var VoiceOver_Media_PlaybackRateFast: String { return self._s[1945]! }
- public var ScheduledMessages_ClearAll: String { return self._s[1946]! }
- public var WallpaperPreview_CropBottomText: String { return self._s[1947]! }
- public var AutoDownloadSettings_LimitBySize: String { return self._s[1948]! }
- public var Settings_AddAccount: String { return self._s[1949]! }
- public var Notification_CreatedChannel: String { return self._s[1952]! }
+ public var Notification_CallCanceled: String { return self._s[1940]! }
+ public var WallpaperPreview_Title: String { return self._s[1941]! }
+ public var Privacy_PaymentsClear_PaymentInfo: String { return self._s[1942]! }
+ public var Settings_ProxyConnecting: String { return self._s[1943]! }
+ public var Settings_CheckPhoneNumberText: String { return self._s[1945]! }
+ public var VoiceOver_Chat_YourVideo: String { return self._s[1946]! }
+ public var Wallet_Intro_Title: String { return self._s[1947]! }
+ public var TwoFactorSetup_Password_Action: String { return self._s[1948]! }
+ public var Profile_MessageLifetime5s: String { return self._s[1949]! }
+ public var Username_InvalidCharacters: String { return self._s[1950]! }
+ public var VoiceOver_Media_PlaybackRateFast: String { return self._s[1951]! }
+ public var ScheduledMessages_ClearAll: String { return self._s[1952]! }
+ public var WallpaperPreview_CropBottomText: String { return self._s[1953]! }
+ public var AutoDownloadSettings_LimitBySize: String { return self._s[1954]! }
+ public var Settings_AddAccount: String { return self._s[1955]! }
+ public var Notification_CreatedChannel: String { return self._s[1958]! }
public func PUSH_CHAT_DELETE_MEMBER(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1953]!, self._r[1953]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[1959]!, self._r[1959]!, [_1, _2, _3])
}
- public var Passcode_AppLockedAlert: String { return self._s[1955]! }
- public var StickerPacksSettings_AnimatedStickersInfo: String { return self._s[1956]! }
- public var VoiceOver_Media_PlaybackStop: String { return self._s[1957]! }
- public var Contacts_TopSection: String { return self._s[1958]! }
- public var ChatList_DeleteForEveryoneConfirmationAction: String { return self._s[1959]! }
+ public var Passcode_AppLockedAlert: String { return self._s[1961]! }
+ public var StickerPacksSettings_AnimatedStickersInfo: String { return self._s[1962]! }
+ public var VoiceOver_Media_PlaybackStop: String { return self._s[1963]! }
+ public var Contacts_TopSection: String { return self._s[1964]! }
+ public var ChatList_DeleteForEveryoneConfirmationAction: String { return self._s[1965]! }
public func Conversation_SetReminder_RemindOn(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1960]!, self._r[1960]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[1966]!, self._r[1966]!, [_0, _1])
}
- public var Wallet_Info_Receive: String { return self._s[1961]! }
- public var Wallet_Completed_ViewWallet: String { return self._s[1962]! }
+ public var Wallet_Info_Receive: String { return self._s[1967]! }
+ public var Wallet_Completed_ViewWallet: String { return self._s[1968]! }
public func Time_MonthOfYear_m6(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1963]!, self._r[1963]!, [_0])
+ return formatWithArgumentRanges(self._s[1969]!, self._r[1969]!, [_0])
}
- public var ReportPeer_ReasonSpam: String { return self._s[1964]! }
- public var UserInfo_TapToCall: String { return self._s[1965]! }
- public var Conversation_ForwardAuthorHiddenTooltip: String { return self._s[1967]! }
- public var AutoDownloadSettings_DataUsageCustom: String { return self._s[1968]! }
- public var Common_Search: String { return self._s[1969]! }
- public var ScheduledMessages_EmptyPlaceholder: String { return self._s[1970]! }
+ public var ReportPeer_ReasonSpam: String { return self._s[1970]! }
+ public var UserInfo_TapToCall: String { return self._s[1971]! }
+ public var Conversation_ForwardAuthorHiddenTooltip: String { return self._s[1973]! }
+ public var AutoDownloadSettings_DataUsageCustom: String { return self._s[1974]! }
+ public var Common_Search: String { return self._s[1975]! }
+ public var ScheduledMessages_EmptyPlaceholder: String { return self._s[1976]! }
public func Channel_AdminLog_MessageChangedGroupGeoLocation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1971]!, self._r[1971]!, [_0])
+ return formatWithArgumentRanges(self._s[1977]!, self._r[1977]!, [_0])
}
- public var Wallet_Month_ShortJuly: String { return self._s[1972]! }
- public var AuthSessions_IncompleteAttemptsInfo: String { return self._s[1974]! }
- public var Message_InvoiceLabel: String { return self._s[1975]! }
- public var Conversation_InputTextPlaceholder: String { return self._s[1976]! }
- public var NetworkUsageSettings_MediaImageDataSection: String { return self._s[1977]! }
+ public var Wallet_Month_ShortJuly: String { return self._s[1978]! }
+ public var AuthSessions_IncompleteAttemptsInfo: String { return self._s[1980]! }
+ public var Message_InvoiceLabel: String { return self._s[1981]! }
+ public var Conversation_InputTextPlaceholder: String { return self._s[1982]! }
+ public var NetworkUsageSettings_MediaImageDataSection: String { return self._s[1983]! }
public func Passport_Address_UploadOneOfScan(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[1978]!, self._r[1978]!, [_0])
+ return formatWithArgumentRanges(self._s[1984]!, self._r[1984]!, [_0])
}
- public var IntentsSettings_Reset: String { return self._s[1979]! }
- public var Conversation_Info: String { return self._s[1980]! }
- public var Login_InfoDeletePhoto: String { return self._s[1981]! }
- public var Passport_Language_vi: String { return self._s[1983]! }
- public var UserInfo_ScamUserWarning: String { return self._s[1984]! }
- public var Conversation_Search: String { return self._s[1985]! }
- public var DialogList_DeleteBotConversationConfirmation: String { return self._s[1987]! }
- public var ReportPeer_ReasonPornography: String { return self._s[1988]! }
- public var AutoDownloadSettings_PhotosTitle: String { return self._s[1989]! }
- public var Conversation_SendMessageErrorGroupRestricted: String { return self._s[1990]! }
- public var Map_LiveLocationGroupDescription: String { return self._s[1991]! }
- public var Channel_Setup_TypeHeader: String { return self._s[1992]! }
- public var AuthSessions_LoggedIn: String { return self._s[1993]! }
- public var Privacy_Forwards_AlwaysAllow_Title: String { return self._s[1994]! }
- public var Login_SmsRequestState3: String { return self._s[1995]! }
- public var Passport_Address_EditUtilityBill: String { return self._s[1996]! }
- public var Appearance_ReduceMotionInfo: String { return self._s[1997]! }
- public var Join_ChannelsTooMuch: String { return self._s[1998]! }
- public var Channel_Edit_LinkItem: String { return self._s[1999]! }
- public var Privacy_Calls_P2PNever: String { return self._s[2000]! }
- public var Conversation_AddToReadingList: String { return self._s[2002]! }
- public var Share_MultipleMessagesDisabled: String { return self._s[2003]! }
- public var Message_Animation: String { return self._s[2004]! }
- public var Conversation_DefaultRestrictedMedia: String { return self._s[2005]! }
- public var Map_Unknown: String { return self._s[2006]! }
- public var AutoDownloadSettings_LastDelimeter: String { return self._s[2007]! }
+ public var IntentsSettings_Reset: String { return self._s[1985]! }
+ public var Conversation_Info: String { return self._s[1986]! }
+ public var Login_InfoDeletePhoto: String { return self._s[1987]! }
+ public var Passport_Language_vi: String { return self._s[1989]! }
+ public var UserInfo_ScamUserWarning: String { return self._s[1990]! }
+ public var Conversation_Search: String { return self._s[1991]! }
+ public var DialogList_DeleteBotConversationConfirmation: String { return self._s[1993]! }
+ public var ReportPeer_ReasonPornography: String { return self._s[1994]! }
+ public var AutoDownloadSettings_PhotosTitle: String { return self._s[1995]! }
+ public var Conversation_SendMessageErrorGroupRestricted: String { return self._s[1996]! }
+ public var Map_LiveLocationGroupDescription: String { return self._s[1997]! }
+ public var Channel_Setup_TypeHeader: String { return self._s[1998]! }
+ public var AuthSessions_LoggedIn: String { return self._s[1999]! }
+ public var Privacy_Forwards_AlwaysAllow_Title: String { return self._s[2000]! }
+ public var Login_SmsRequestState3: String { return self._s[2001]! }
+ public var Passport_Address_EditUtilityBill: String { return self._s[2002]! }
+ public var Appearance_ReduceMotionInfo: String { return self._s[2003]! }
+ public var Join_ChannelsTooMuch: String { return self._s[2004]! }
+ public var Channel_Edit_LinkItem: String { return self._s[2005]! }
+ public var Privacy_Calls_P2PNever: String { return self._s[2006]! }
+ public var Conversation_AddToReadingList: String { return self._s[2008]! }
+ public var Share_MultipleMessagesDisabled: String { return self._s[2009]! }
+ public var Message_Animation: String { return self._s[2010]! }
+ public var Conversation_DefaultRestrictedMedia: String { return self._s[2011]! }
+ public var Map_Unknown: String { return self._s[2012]! }
+ public var AutoDownloadSettings_LastDelimeter: String { return self._s[2013]! }
public func PUSH_PINNED_TEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2008]!, self._r[2008]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2014]!, self._r[2014]!, [_1, _2])
}
public func Passport_FieldOneOf_Or(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2009]!, self._r[2009]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2015]!, self._r[2015]!, [_1, _2])
}
- public var Call_StatusRequesting: String { return self._s[2010]! }
- public var Conversation_SecretChatContextBotAlert: String { return self._s[2011]! }
- public var SocksProxySetup_ProxyStatusChecking: String { return self._s[2012]! }
+ public var Call_StatusRequesting: String { return self._s[2016]! }
+ public var Conversation_SecretChatContextBotAlert: String { return self._s[2017]! }
+ public var SocksProxySetup_ProxyStatusChecking: String { return self._s[2018]! }
public func PUSH_CHAT_MESSAGE_DOC(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2013]!, self._r[2013]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2019]!, self._r[2019]!, [_1, _2])
}
public func Notification_PinnedLocationMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2014]!, self._r[2014]!, [_0])
+ return formatWithArgumentRanges(self._s[2020]!, self._r[2020]!, [_0])
}
- public var Update_Skip: String { return self._s[2015]! }
- public var Group_Username_RemoveExistingUsernamesInfo: String { return self._s[2016]! }
- public var Message_PinnedPollMessage: String { return self._s[2017]! }
- public var BlockedUsers_Title: String { return self._s[2018]! }
+ public var Update_Skip: String { return self._s[2021]! }
+ public var Group_Username_RemoveExistingUsernamesInfo: String { return self._s[2022]! }
+ public var Message_PinnedPollMessage: String { return self._s[2023]! }
+ public var BlockedUsers_Title: String { return self._s[2024]! }
public func PUSH_CHANNEL_MESSAGE_AUDIO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2019]!, self._r[2019]!, [_1])
+ return formatWithArgumentRanges(self._s[2025]!, self._r[2025]!, [_1])
}
- public var Username_CheckingUsername: String { return self._s[2020]! }
- public var NotificationsSound_Bell: String { return self._s[2021]! }
- public var Conversation_SendMessageErrorFlood: String { return self._s[2022]! }
- public var Weekday_Monday: String { return self._s[2023]! }
- public var SettingsSearch_Synonyms_Notifications_DisplayNamesOnLockScreen: String { return self._s[2024]! }
- public var ChannelMembers_ChannelAdminsTitle: String { return self._s[2025]! }
- public var ChatSettings_Groups: String { return self._s[2026]! }
- public var WallpaperPreview_PatternPaternDiscard: String { return self._s[2027]! }
+ public var Username_CheckingUsername: String { return self._s[2026]! }
+ public var NotificationsSound_Bell: String { return self._s[2027]! }
+ public var Conversation_SendMessageErrorFlood: String { return self._s[2028]! }
+ public var Weekday_Monday: String { return self._s[2029]! }
+ public var SettingsSearch_Synonyms_Notifications_DisplayNamesOnLockScreen: String { return self._s[2030]! }
+ public var ChannelMembers_ChannelAdminsTitle: String { return self._s[2031]! }
+ public var ChatSettings_Groups: String { return self._s[2032]! }
+ public var WallpaperPreview_PatternPaternDiscard: String { return self._s[2033]! }
public func Conversation_SetReminder_RemindTomorrow(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2028]!, self._r[2028]!, [_0])
+ return formatWithArgumentRanges(self._s[2034]!, self._r[2034]!, [_0])
}
- public var Your_card_was_declined: String { return self._s[2029]! }
- public var TwoStepAuth_EnterPasswordHelp: String { return self._s[2031]! }
- public var Wallet_Month_ShortApril: String { return self._s[2032]! }
- public var ChatList_Unmute: String { return self._s[2033]! }
- public var AuthSessions_AddDevice_ScanTitle: String { return self._s[2034]! }
- public var PhotoEditor_CurvesAll: String { return self._s[2035]! }
- public var Weekday_ShortTuesday: String { return self._s[2036]! }
- public var DialogList_Read: String { return self._s[2037]! }
- public var Appearance_AppIconClassic: String { return self._s[2038]! }
- public var ChannelMembers_WhoCanAddMembers_AllMembers: String { return self._s[2039]! }
- public var Passport_Identity_Gender: String { return self._s[2040]! }
+ public var Your_card_was_declined: String { return self._s[2035]! }
+ public var TwoStepAuth_EnterPasswordHelp: String { return self._s[2037]! }
+ public var Wallet_Month_ShortApril: String { return self._s[2038]! }
+ public var ChatList_Unmute: String { return self._s[2039]! }
+ public var AuthSessions_AddDevice_ScanTitle: String { return self._s[2040]! }
+ public var PhotoEditor_CurvesAll: String { return self._s[2041]! }
+ public var Weekday_ShortTuesday: String { return self._s[2042]! }
+ public var DialogList_Read: String { return self._s[2043]! }
+ public var Appearance_AppIconClassic: String { return self._s[2044]! }
+ public var ChannelMembers_WhoCanAddMembers_AllMembers: String { return self._s[2045]! }
+ public var Passport_Identity_Gender: String { return self._s[2046]! }
public func Target_ShareGameConfirmationPrivate(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2041]!, self._r[2041]!, [_0])
+ return formatWithArgumentRanges(self._s[2047]!, self._r[2047]!, [_0])
}
- public var Target_SelectGroup: String { return self._s[2042]! }
- public var Map_HomeAndWorkInfo: String { return self._s[2044]! }
+ public var Target_SelectGroup: String { return self._s[2048]! }
+ public var Map_HomeAndWorkInfo: String { return self._s[2050]! }
public func DialogList_EncryptedChatStartedIncoming(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2045]!, self._r[2045]!, [_0])
+ return formatWithArgumentRanges(self._s[2051]!, self._r[2051]!, [_0])
}
- public var Passport_Language_en: String { return self._s[2046]! }
- public var AutoDownloadSettings_AutodownloadPhotos: String { return self._s[2047]! }
- public var Channel_Username_CreatePublicLinkHelp: String { return self._s[2048]! }
- public var Login_CancelPhoneVerificationContinue: String { return self._s[2049]! }
- public var ScheduledMessages_SendNow: String { return self._s[2050]! }
- public var Checkout_NewCard_PaymentCard: String { return self._s[2052]! }
- public var Login_InfoHelp: String { return self._s[2053]! }
- public var Contacts_PermissionsSuppressWarningTitle: String { return self._s[2054]! }
- public var SettingsSearch_Synonyms_Stickers_FeaturedPacks: String { return self._s[2055]! }
+ public var Passport_Language_en: String { return self._s[2052]! }
+ public var AutoDownloadSettings_AutodownloadPhotos: String { return self._s[2053]! }
+ public var Channel_Username_CreatePublicLinkHelp: String { return self._s[2054]! }
+ public var Login_CancelPhoneVerificationContinue: String { return self._s[2055]! }
+ public var ScheduledMessages_SendNow: String { return self._s[2056]! }
+ public var Checkout_NewCard_PaymentCard: String { return self._s[2058]! }
+ public var Login_InfoHelp: String { return self._s[2059]! }
+ public var Contacts_PermissionsSuppressWarningTitle: String { return self._s[2060]! }
+ public var SettingsSearch_Synonyms_Stickers_FeaturedPacks: String { return self._s[2061]! }
public func Channel_AdminLog_MessageChangedLinkedChannel(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2056]!, self._r[2056]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2062]!, self._r[2062]!, [_1, _2])
}
- public var SocksProxySetup_AddProxy: String { return self._s[2059]! }
- public var CreatePoll_Title: String { return self._s[2060]! }
- public var MessagePoll_QuizNoUsers: String { return self._s[2061]! }
- public var Conversation_ViewTheme: String { return self._s[2062]! }
- public var SettingsSearch_Synonyms_Privacy_Data_SecretChatLinkPreview: String { return self._s[2063]! }
- public var PasscodeSettings_SimplePasscodeHelp: String { return self._s[2064]! }
- public var TwoFactorSetup_Intro_Text: String { return self._s[2065]! }
- public var UserInfo_GroupsInCommon: String { return self._s[2066]! }
- public var TelegramWallet_Intro_TermsUrl: String { return self._s[2067]! }
- public var Call_AudioRouteHide: String { return self._s[2068]! }
+ public var SocksProxySetup_AddProxy: String { return self._s[2065]! }
+ public var CreatePoll_Title: String { return self._s[2066]! }
+ public var MessagePoll_QuizNoUsers: String { return self._s[2067]! }
+ public var Conversation_ViewTheme: String { return self._s[2068]! }
+ public var SettingsSearch_Synonyms_Privacy_Data_SecretChatLinkPreview: String { return self._s[2069]! }
+ public var PasscodeSettings_SimplePasscodeHelp: String { return self._s[2070]! }
+ public var TwoFactorSetup_Intro_Text: String { return self._s[2071]! }
+ public var UserInfo_GroupsInCommon: String { return self._s[2072]! }
+ public var TelegramWallet_Intro_TermsUrl: String { return self._s[2073]! }
+ public var Call_AudioRouteHide: String { return self._s[2074]! }
public func Wallet_Info_TransactionDateHeader(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2070]!, self._r[2070]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2076]!, self._r[2076]!, [_1, _2])
}
- public var ContactInfo_PhoneLabelMobile: String { return self._s[2071]! }
- public var IntentsSettings_SuggestedChatsInfo: String { return self._s[2072]! }
- public var CreatePoll_QuizOptionsHeader: String { return self._s[2073]! }
+ public var ContactInfo_PhoneLabelMobile: String { return self._s[2077]! }
+ public var IntentsSettings_SuggestedChatsInfo: String { return self._s[2078]! }
+ public var CreatePoll_QuizOptionsHeader: String { return self._s[2079]! }
public func ChatList_LeaveGroupConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2074]!, self._r[2074]!, [_0])
+ return formatWithArgumentRanges(self._s[2080]!, self._r[2080]!, [_0])
}
- public var TextFormat_Bold: String { return self._s[2075]! }
- public var FastTwoStepSetup_EmailSection: String { return self._s[2076]! }
- public var StickerPackActionInfo_AddedTitle: String { return self._s[2077]! }
- public var Notifications_Title: String { return self._s[2078]! }
- public var Group_Username_InvalidTooShort: String { return self._s[2079]! }
- public var Channel_ErrorAddTooMuch: String { return self._s[2080]! }
+ public var TextFormat_Bold: String { return self._s[2081]! }
+ public var FastTwoStepSetup_EmailSection: String { return self._s[2082]! }
+ public var StickerPackActionInfo_AddedTitle: String { return self._s[2083]! }
+ public var Notifications_Title: String { return self._s[2084]! }
+ public var Group_Username_InvalidTooShort: String { return self._s[2085]! }
+ public var Channel_ErrorAddTooMuch: String { return self._s[2086]! }
public func DialogList_MultipleTypingSuffix(_ _0: Int) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2081]!, self._r[2081]!, ["\(_0)"])
+ return formatWithArgumentRanges(self._s[2087]!, self._r[2087]!, ["\(_0)"])
}
- public var VoiceOver_DiscardPreparedContent: String { return self._s[2083]! }
- public var Stickers_SuggestAdded: String { return self._s[2084]! }
- public var Login_CountryCode: String { return self._s[2085]! }
- public var ChatSettings_AutoPlayVideos: String { return self._s[2086]! }
- public var Map_GetDirections: String { return self._s[2087]! }
- public var Wallet_Receive_ShareInvoiceUrl: String { return self._s[2088]! }
- public var Login_PhoneFloodError: String { return self._s[2089]! }
+ public var VoiceOver_DiscardPreparedContent: String { return self._s[2089]! }
+ public var Stickers_SuggestAdded: String { return self._s[2090]! }
+ public var Login_CountryCode: String { return self._s[2091]! }
+ public var ChatSettings_AutoPlayVideos: String { return self._s[2092]! }
+ public var Map_GetDirections: String { return self._s[2093]! }
+ public var Wallet_Receive_ShareInvoiceUrl: String { return self._s[2094]! }
+ public var Login_PhoneFloodError: String { return self._s[2095]! }
public func Time_MonthOfYear_m3(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2090]!, self._r[2090]!, [_0])
+ return formatWithArgumentRanges(self._s[2096]!, self._r[2096]!, [_0])
}
public func Wallet_Time_PreciseDate_m10(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2091]!, self._r[2091]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[2097]!, self._r[2097]!, [_1, _2, _3])
}
- public var IntentsSettings_SuggestedChatsPrivateChats: String { return self._s[2092]! }
- public var Settings_SetUsername: String { return self._s[2094]! }
- public var Group_Location_ChangeLocation: String { return self._s[2095]! }
- public var Notification_GroupInviterSelf: String { return self._s[2096]! }
- public var InstantPage_TapToOpenLink: String { return self._s[2097]! }
+ public var IntentsSettings_SuggestedChatsPrivateChats: String { return self._s[2098]! }
+ public var Settings_SetUsername: String { return self._s[2100]! }
+ public var Group_Location_ChangeLocation: String { return self._s[2101]! }
+ public var Notification_GroupInviterSelf: String { return self._s[2102]! }
+ public var InstantPage_TapToOpenLink: String { return self._s[2103]! }
public func Notification_ChannelInviter(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2098]!, self._r[2098]!, [_0])
+ return formatWithArgumentRanges(self._s[2104]!, self._r[2104]!, [_0])
}
- public var Watch_Suggestion_TalkLater: String { return self._s[2099]! }
- public var SecretChat_Title: String { return self._s[2100]! }
- public var Group_UpgradeNoticeText1: String { return self._s[2101]! }
- public var AuthSessions_Title: String { return self._s[2102]! }
+ public var Watch_Suggestion_TalkLater: String { return self._s[2105]! }
+ public var SecretChat_Title: String { return self._s[2106]! }
+ public var Group_UpgradeNoticeText1: String { return self._s[2107]! }
+ public var AuthSessions_Title: String { return self._s[2108]! }
public func TextFormat_AddLinkText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2103]!, self._r[2103]!, [_0])
+ return formatWithArgumentRanges(self._s[2109]!, self._r[2109]!, [_0])
}
- public var PhotoEditor_CropAuto: String { return self._s[2104]! }
- public var Channel_About_Title: String { return self._s[2105]! }
- public var Theme_ThemeChanged: String { return self._s[2106]! }
- public var FastTwoStepSetup_EmailHelp: String { return self._s[2107]! }
+ public var PhotoEditor_CropAuto: String { return self._s[2110]! }
+ public var Channel_About_Title: String { return self._s[2111]! }
+ public var Theme_ThemeChanged: String { return self._s[2112]! }
+ public var FastTwoStepSetup_EmailHelp: String { return self._s[2113]! }
public func Conversation_Bytes(_ _0: Int) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2109]!, self._r[2109]!, ["\(_0)"])
+ return formatWithArgumentRanges(self._s[2115]!, self._r[2115]!, ["\(_0)"])
}
- public var VoiceOver_MessageContextReport: String { return self._s[2110]! }
- public var Conversation_PinMessageAlert_OnlyPin: String { return self._s[2112]! }
- public var Group_Setup_HistoryVisibleHelp: String { return self._s[2113]! }
+ public var VoiceOver_MessageContextReport: String { return self._s[2116]! }
+ public var Conversation_PinMessageAlert_OnlyPin: String { return self._s[2118]! }
+ public var Group_Setup_HistoryVisibleHelp: String { return self._s[2119]! }
public func PUSH_MESSAGE_GIF(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2114]!, self._r[2114]!, [_1])
+ return formatWithArgumentRanges(self._s[2120]!, self._r[2120]!, [_1])
}
public func SharedMedia_SearchNoResultsDescription(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2116]!, self._r[2116]!, [_0])
+ return formatWithArgumentRanges(self._s[2122]!, self._r[2122]!, [_0])
}
public func TwoStepAuth_RecoveryEmailUnavailable(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2117]!, self._r[2117]!, [_0])
+ return formatWithArgumentRanges(self._s[2123]!, self._r[2123]!, [_0])
}
- public var Privacy_PaymentsClearInfoHelp: String { return self._s[2118]! }
- public var Presence_online: String { return self._s[2121]! }
- public var PasscodeSettings_Title: String { return self._s[2122]! }
- public var Passport_Identity_ExpiryDatePlaceholder: String { return self._s[2123]! }
- public var Web_OpenExternal: String { return self._s[2124]! }
- public var AutoDownloadSettings_AutoDownload: String { return self._s[2126]! }
- public var Channel_OwnershipTransfer_EnterPasswordText: String { return self._s[2127]! }
- public var LocalGroup_Title: String { return self._s[2128]! }
+ public var Privacy_PaymentsClearInfoHelp: String { return self._s[2124]! }
+ public var PeopleNearby_DiscoverDescription: String { return self._s[2126]! }
+ public var Presence_online: String { return self._s[2128]! }
+ public var PasscodeSettings_Title: String { return self._s[2129]! }
+ public var Passport_Identity_ExpiryDatePlaceholder: String { return self._s[2130]! }
+ public var Web_OpenExternal: String { return self._s[2131]! }
+ public var AutoDownloadSettings_AutoDownload: String { return self._s[2133]! }
+ public var Channel_OwnershipTransfer_EnterPasswordText: String { return self._s[2134]! }
+ public var LocalGroup_Title: String { return self._s[2135]! }
public func AutoNightTheme_AutomaticHelp(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2129]!, self._r[2129]!, [_0])
+ return formatWithArgumentRanges(self._s[2136]!, self._r[2136]!, [_0])
}
- public var FastTwoStepSetup_PasswordConfirmationPlaceholder: String { return self._s[2130]! }
- public var Conversation_StopQuizConfirmation: String { return self._s[2131]! }
- public var Map_YouAreHere: String { return self._s[2132]! }
+ public var FastTwoStepSetup_PasswordConfirmationPlaceholder: String { return self._s[2137]! }
+ public var Conversation_StopQuizConfirmation: String { return self._s[2138]! }
+ public var Map_YouAreHere: String { return self._s[2139]! }
public func AuthSessions_Message(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2133]!, self._r[2133]!, [_0])
+ return formatWithArgumentRanges(self._s[2140]!, self._r[2140]!, [_0])
}
public func ChatList_DeleteChatConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2134]!, self._r[2134]!, [_0])
+ return formatWithArgumentRanges(self._s[2141]!, self._r[2141]!, [_0])
}
- public var Theme_Context_ChangeColors: String { return self._s[2135]! }
- public var PrivacyLastSeenSettings_AlwaysShareWith: String { return self._s[2136]! }
- public var Target_InviteToGroupErrorAlreadyInvited: String { return self._s[2137]! }
+ public var Theme_Context_ChangeColors: String { return self._s[2142]! }
+ public var PrivacyLastSeenSettings_AlwaysShareWith: String { return self._s[2143]! }
+ public var Target_InviteToGroupErrorAlreadyInvited: String { return self._s[2144]! }
public func AuthSessions_AppUnofficial(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2138]!, self._r[2138]!, [_0])
+ return formatWithArgumentRanges(self._s[2145]!, self._r[2145]!, [_0])
}
public func DialogList_LiveLocationSharingTo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2139]!, self._r[2139]!, [_0])
+ return formatWithArgumentRanges(self._s[2146]!, self._r[2146]!, [_0])
}
- public var SocksProxySetup_Username: String { return self._s[2140]! }
- public var Bot_Start: String { return self._s[2141]! }
+ public var SocksProxySetup_Username: String { return self._s[2147]! }
+ public var Bot_Start: String { return self._s[2148]! }
public func Channel_AdminLog_EmptyFilterQueryText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2142]!, self._r[2142]!, [_0])
- }
- public func Channel_AdminLog_MessagePinned(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2143]!, self._r[2143]!, [_0])
- }
- public var Contacts_SortByPresence: String { return self._s[2144]! }
- public var AccentColor_Title: String { return self._s[2146]! }
- public var Conversation_DiscardVoiceMessageTitle: String { return self._s[2147]! }
- public func PUSH_CHAT_CREATED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2148]!, self._r[2148]!, [_1, _2])
- }
- public func PrivacySettings_LastSeenContactsMinus(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[2149]!, self._r[2149]!, [_0])
}
+ public func Channel_AdminLog_MessagePinned(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[2150]!, self._r[2150]!, [_0])
+ }
+ public var Contacts_SortByPresence: String { return self._s[2151]! }
+ public var AccentColor_Title: String { return self._s[2153]! }
+ public var Conversation_DiscardVoiceMessageTitle: String { return self._s[2154]! }
+ public func PUSH_CHAT_CREATED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[2155]!, self._r[2155]!, [_1, _2])
+ }
+ public func PrivacySettings_LastSeenContactsMinus(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[2156]!, self._r[2156]!, [_0])
+ }
public func Channel_AdminLog_MessageChangedLinkedGroup(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2150]!, self._r[2150]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2157]!, self._r[2157]!, [_1, _2])
}
- public var Passport_Email_EnterOtherEmail: String { return self._s[2151]! }
- public var Login_InfoAvatarPhoto: String { return self._s[2152]! }
- public var Privacy_PaymentsClear_ShippingInfo: String { return self._s[2153]! }
- public var Tour_Title4: String { return self._s[2154]! }
- public var Passport_Identity_Translation: String { return self._s[2155]! }
- public var SettingsSearch_Synonyms_Notifications_ContactJoined: String { return self._s[2156]! }
- public var Login_TermsOfServiceLabel: String { return self._s[2158]! }
- public var Passport_Language_it: String { return self._s[2159]! }
- public var KeyCommand_JumpToNextUnreadChat: String { return self._s[2160]! }
- public var Passport_Identity_SelfieHelp: String { return self._s[2161]! }
- public var Conversation_ClearAll: String { return self._s[2163]! }
- public var Wallet_Send_UninitializedText: String { return self._s[2165]! }
- public var Channel_OwnershipTransfer_Title: String { return self._s[2166]! }
- public var TwoStepAuth_FloodError: String { return self._s[2167]! }
+ public var Passport_Email_EnterOtherEmail: String { return self._s[2158]! }
+ public var Login_InfoAvatarPhoto: String { return self._s[2159]! }
+ public var Privacy_PaymentsClear_ShippingInfo: String { return self._s[2160]! }
+ public var Tour_Title4: String { return self._s[2161]! }
+ public var Passport_Identity_Translation: String { return self._s[2162]! }
+ public var SettingsSearch_Synonyms_Notifications_ContactJoined: String { return self._s[2163]! }
+ public var Login_TermsOfServiceLabel: String { return self._s[2165]! }
+ public var Passport_Language_it: String { return self._s[2166]! }
+ public var KeyCommand_JumpToNextUnreadChat: String { return self._s[2167]! }
+ public var Passport_Identity_SelfieHelp: String { return self._s[2168]! }
+ public var Conversation_ClearAll: String { return self._s[2170]! }
+ public var Wallet_Send_UninitializedText: String { return self._s[2172]! }
+ public var Channel_OwnershipTransfer_Title: String { return self._s[2173]! }
+ public var TwoStepAuth_FloodError: String { return self._s[2174]! }
public func PUSH_CHANNEL_MESSAGE_GEO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2168]!, self._r[2168]!, [_1])
+ return formatWithArgumentRanges(self._s[2175]!, self._r[2175]!, [_1])
}
- public var Paint_Delete: String { return self._s[2169]! }
+ public var Paint_Delete: String { return self._s[2176]! }
public func Wallet_Sent_Text(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2170]!, self._r[2170]!, [_0])
+ return formatWithArgumentRanges(self._s[2177]!, self._r[2177]!, [_0])
}
- public var Privacy_AddNewPeer: String { return self._s[2171]! }
+ public var Privacy_AddNewPeer: String { return self._s[2178]! }
public func Channel_AdminLog_MessageRank(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2172]!, self._r[2172]!, [_1])
+ return formatWithArgumentRanges(self._s[2179]!, self._r[2179]!, [_1])
}
- public var LogoutOptions_SetPasscodeText: String { return self._s[2173]! }
+ public var LogoutOptions_SetPasscodeText: String { return self._s[2180]! }
public func Passport_AcceptHelp(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2174]!, self._r[2174]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2181]!, self._r[2181]!, [_1, _2])
}
- public var Message_PinnedAudioMessage: String { return self._s[2175]! }
+ public var Message_PinnedAudioMessage: String { return self._s[2182]! }
public func Watch_Time_ShortTodayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2176]!, self._r[2176]!, [_0])
+ return formatWithArgumentRanges(self._s[2183]!, self._r[2183]!, [_0])
}
- public var Notification_Mute1hMin: String { return self._s[2177]! }
- public var Notifications_GroupNotificationsSound: String { return self._s[2178]! }
- public var Wallet_Month_GenNovember: String { return self._s[2179]! }
- public var SocksProxySetup_ShareProxyList: String { return self._s[2180]! }
- public var Conversation_MessageEditedLabel: String { return self._s[2181]! }
+ public var Notification_Mute1hMin: String { return self._s[2184]! }
+ public var Notifications_GroupNotificationsSound: String { return self._s[2185]! }
+ public var Wallet_Month_GenNovember: String { return self._s[2186]! }
+ public var SocksProxySetup_ShareProxyList: String { return self._s[2187]! }
+ public var Conversation_MessageEditedLabel: String { return self._s[2188]! }
public func ClearCache_Success(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2182]!, self._r[2182]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[2189]!, self._r[2189]!, [_0, _1])
}
- public var Notification_Exceptions_AlwaysOff: String { return self._s[2183]! }
- public var Notification_Exceptions_NewException_MessagePreviewHeader: String { return self._s[2184]! }
+ public var Notification_Exceptions_AlwaysOff: String { return self._s[2190]! }
+ public var Notification_Exceptions_NewException_MessagePreviewHeader: String { return self._s[2191]! }
public func Channel_AdminLog_MessageAdmin(_ _0: String, _ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2185]!, self._r[2185]!, [_0, _1, _2])
+ return formatWithArgumentRanges(self._s[2192]!, self._r[2192]!, [_0, _1, _2])
}
- public var NetworkUsageSettings_ResetStats: String { return self._s[2186]! }
+ public var NetworkUsageSettings_ResetStats: String { return self._s[2193]! }
public func PUSH_MESSAGE_GEOLIVE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2187]!, self._r[2187]!, [_1])
+ return formatWithArgumentRanges(self._s[2194]!, self._r[2194]!, [_1])
}
- public var AccessDenied_LocationTracking: String { return self._s[2188]! }
- public var Month_GenOctober: String { return self._s[2189]! }
- public var GroupInfo_InviteLink_RevokeAlert_Revoke: String { return self._s[2190]! }
- public var EnterPasscode_EnterPasscode: String { return self._s[2191]! }
- public var MediaPicker_TimerTooltip: String { return self._s[2193]! }
- public var SharedMedia_TitleAll: String { return self._s[2194]! }
- public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsExceptions: String { return self._s[2197]! }
- public var Conversation_RestrictedMedia: String { return self._s[2198]! }
- public var AccessDenied_PhotosRestricted: String { return self._s[2199]! }
- public var Privacy_Forwards_WhoCanForward: String { return self._s[2201]! }
- public var ChangePhoneNumberCode_Called: String { return self._s[2202]! }
+ public var AccessDenied_LocationTracking: String { return self._s[2195]! }
+ public var Month_GenOctober: String { return self._s[2196]! }
+ public var GroupInfo_InviteLink_RevokeAlert_Revoke: String { return self._s[2197]! }
+ public var EnterPasscode_EnterPasscode: String { return self._s[2198]! }
+ public var MediaPicker_TimerTooltip: String { return self._s[2200]! }
+ public var SharedMedia_TitleAll: String { return self._s[2201]! }
+ public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsExceptions: String { return self._s[2204]! }
+ public var Conversation_RestrictedMedia: String { return self._s[2205]! }
+ public var AccessDenied_PhotosRestricted: String { return self._s[2206]! }
+ public var Privacy_Forwards_WhoCanForward: String { return self._s[2208]! }
+ public var ChangePhoneNumberCode_Called: String { return self._s[2209]! }
public func Notification_PinnedDocumentMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2203]!, self._r[2203]!, [_0])
+ return formatWithArgumentRanges(self._s[2210]!, self._r[2210]!, [_0])
}
- public var Conversation_SavedMessages: String { return self._s[2206]! }
- public var Your_cards_expiration_month_is_invalid: String { return self._s[2208]! }
- public var FastTwoStepSetup_PasswordPlaceholder: String { return self._s[2209]! }
+ public var Conversation_SavedMessages: String { return self._s[2213]! }
+ public var Your_cards_expiration_month_is_invalid: String { return self._s[2215]! }
+ public var FastTwoStepSetup_PasswordPlaceholder: String { return self._s[2216]! }
public func Target_ShareGameConfirmationGroup(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2211]!, self._r[2211]!, [_0])
+ return formatWithArgumentRanges(self._s[2218]!, self._r[2218]!, [_0])
}
- public var VoiceOver_Chat_YourMessage: String { return self._s[2212]! }
+ public var VoiceOver_Chat_YourMessage: String { return self._s[2219]! }
public func VoiceOver_Chat_Title(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2213]!, self._r[2213]!, [_0])
+ return formatWithArgumentRanges(self._s[2220]!, self._r[2220]!, [_0])
}
- public var ReportPeer_AlertSuccess: String { return self._s[2214]! }
- public var PhotoEditor_CropAspectRatioOriginal: String { return self._s[2215]! }
+ public var ReportPeer_AlertSuccess: String { return self._s[2221]! }
+ public var PhotoEditor_CropAspectRatioOriginal: String { return self._s[2222]! }
public func InstantPage_RelatedArticleAuthorAndDateTitle(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2216]!, self._r[2216]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2223]!, self._r[2223]!, [_1, _2])
}
- public var Checkout_PasswordEntry_Title: String { return self._s[2217]! }
- public var PhotoEditor_FadeTool: String { return self._s[2218]! }
- public var Privacy_ContactsReset: String { return self._s[2219]! }
+ public var Checkout_PasswordEntry_Title: String { return self._s[2224]! }
+ public var PhotoEditor_FadeTool: String { return self._s[2225]! }
+ public var Privacy_ContactsReset: String { return self._s[2226]! }
public func Channel_AdminLog_MessageRestrictedUntil(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2221]!, self._r[2221]!, [_0])
+ return formatWithArgumentRanges(self._s[2228]!, self._r[2228]!, [_0])
}
- public var Message_PinnedVideoMessage: String { return self._s[2222]! }
- public var ChatList_Mute: String { return self._s[2223]! }
+ public var Message_PinnedVideoMessage: String { return self._s[2229]! }
+ public var ChatList_Mute: String { return self._s[2230]! }
public func Wallet_Time_PreciseDate_m5(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2224]!, self._r[2224]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[2231]!, self._r[2231]!, [_1, _2, _3])
}
- public var Permissions_CellularDataText_v0: String { return self._s[2225]! }
- public var ShareMenu_SelectChats: String { return self._s[2228]! }
- public var ChatList_Context_Unarchive: String { return self._s[2229]! }
- public var MusicPlayer_VoiceNote: String { return self._s[2230]! }
- public var Conversation_RestrictedText: String { return self._s[2231]! }
- public var SettingsSearch_Synonyms_Privacy_Data_DeleteDrafts: String { return self._s[2232]! }
- public var Wallet_Month_GenApril: String { return self._s[2233]! }
- public var Wallet_Month_ShortMarch: String { return self._s[2234]! }
- public var TwoStepAuth_DisableSuccess: String { return self._s[2235]! }
- public var Cache_Videos: String { return self._s[2236]! }
- public var PrivacySettings_PhoneNumber: String { return self._s[2237]! }
- public var Wallet_Month_GenFebruary: String { return self._s[2238]! }
- public var FeatureDisabled_Oops: String { return self._s[2240]! }
- public var Passport_Address_PostcodePlaceholder: String { return self._s[2241]! }
+ public var Permissions_CellularDataText_v0: String { return self._s[2232]! }
+ public var ShareMenu_SelectChats: String { return self._s[2235]! }
+ public var ChatList_Context_Unarchive: String { return self._s[2236]! }
+ public var MusicPlayer_VoiceNote: String { return self._s[2237]! }
+ public var Conversation_RestrictedText: String { return self._s[2238]! }
+ public var SettingsSearch_Synonyms_Privacy_Data_DeleteDrafts: String { return self._s[2239]! }
+ public var Wallet_Month_GenApril: String { return self._s[2240]! }
+ public var Wallet_Month_ShortMarch: String { return self._s[2241]! }
+ public var TwoStepAuth_DisableSuccess: String { return self._s[2242]! }
+ public var Cache_Videos: String { return self._s[2243]! }
+ public var PrivacySettings_PhoneNumber: String { return self._s[2244]! }
+ public var Wallet_Month_GenFebruary: String { return self._s[2245]! }
+ public var FeatureDisabled_Oops: String { return self._s[2247]! }
+ public var Passport_Address_PostcodePlaceholder: String { return self._s[2248]! }
public func AddContact_StatusSuccess(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2242]!, self._r[2242]!, [_0])
+ return formatWithArgumentRanges(self._s[2249]!, self._r[2249]!, [_0])
}
- public var Stickers_GroupStickersHelp: String { return self._s[2243]! }
- public var GroupPermission_NoSendPolls: String { return self._s[2244]! }
- public var Wallet_Qr_ScanCode: String { return self._s[2245]! }
- public var Message_VideoExpired: String { return self._s[2247]! }
- public var GroupInfo_GroupHistoryVisible: String { return self._s[2248]! }
- public var Notifications_Badge: String { return self._s[2249]! }
- public var Wallet_Receive_AddressCopied: String { return self._s[2250]! }
- public var CreatePoll_OptionPlaceholder: String { return self._s[2251]! }
- public var Username_InvalidTooShort: String { return self._s[2252]! }
- public var EnterPasscode_EnterNewPasscodeChange: String { return self._s[2253]! }
- public var Channel_AdminLog_PinMessages: String { return self._s[2254]! }
- public var ArchivedChats_IntroTitle3: String { return self._s[2255]! }
+ public var Stickers_GroupStickersHelp: String { return self._s[2251]! }
+ public var GroupPermission_NoSendPolls: String { return self._s[2252]! }
+ public var Wallet_Qr_ScanCode: String { return self._s[2253]! }
+ public var Message_VideoExpired: String { return self._s[2255]! }
+ public var GroupInfo_GroupHistoryVisible: String { return self._s[2256]! }
+ public var Notifications_Badge: String { return self._s[2257]! }
+ public var Wallet_Receive_AddressCopied: String { return self._s[2258]! }
+ public var CreatePoll_OptionPlaceholder: String { return self._s[2259]! }
+ public var Username_InvalidTooShort: String { return self._s[2260]! }
+ public var EnterPasscode_EnterNewPasscodeChange: String { return self._s[2261]! }
+ public var Channel_AdminLog_PinMessages: String { return self._s[2262]! }
+ public var ArchivedChats_IntroTitle3: String { return self._s[2263]! }
public func Notification_MessageLifetimeRemoved(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2256]!, self._r[2256]!, [_1])
+ return formatWithArgumentRanges(self._s[2264]!, self._r[2264]!, [_1])
}
- public var Permissions_SiriAllowInSettings_v0: String { return self._s[2257]! }
- public var Conversation_DefaultRestrictedText: String { return self._s[2258]! }
- public var SharedMedia_CategoryDocs: String { return self._s[2261]! }
+ public var Permissions_SiriAllowInSettings_v0: String { return self._s[2265]! }
+ public var Conversation_DefaultRestrictedText: String { return self._s[2266]! }
+ public var SharedMedia_CategoryDocs: String { return self._s[2269]! }
public func PUSH_MESSAGE_CONTACT(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2262]!, self._r[2262]!, [_1])
+ return formatWithArgumentRanges(self._s[2270]!, self._r[2270]!, [_1])
}
- public var Wallet_Send_UninitializedTitle: String { return self._s[2263]! }
- public var StickerPackActionInfo_ArchivedTitle: String { return self._s[2264]! }
- public var Privacy_Forwards_NeverLink: String { return self._s[2266]! }
+ public var Wallet_Send_UninitializedTitle: String { return self._s[2271]! }
+ public var StickerPackActionInfo_ArchivedTitle: String { return self._s[2272]! }
+ public var Privacy_Forwards_NeverLink: String { return self._s[2274]! }
public func Notification_MessageLifetimeChangedOutgoing(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2267]!, self._r[2267]!, [_1])
+ return formatWithArgumentRanges(self._s[2275]!, self._r[2275]!, [_1])
}
- public var CheckoutInfo_ErrorShippingNotAvailable: String { return self._s[2268]! }
+ public var CheckoutInfo_ErrorShippingNotAvailable: String { return self._s[2276]! }
public func Time_MonthOfYear_m12(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2269]!, self._r[2269]!, [_0])
+ return formatWithArgumentRanges(self._s[2277]!, self._r[2277]!, [_0])
}
- public var ChatSettings_PrivateChats: String { return self._s[2270]! }
- public var SettingsSearch_Synonyms_EditProfile_Logout: String { return self._s[2271]! }
- public var Conversation_PrivateMessageLinkCopied: String { return self._s[2272]! }
- public var Channel_UpdatePhotoItem: String { return self._s[2273]! }
- public var GroupInfo_LeftStatus: String { return self._s[2274]! }
- public var Watch_MessageView_Forward: String { return self._s[2276]! }
- public var ReportPeer_ReasonChildAbuse: String { return self._s[2277]! }
- public var Cache_ClearEmpty: String { return self._s[2279]! }
- public var Localization_LanguageName: String { return self._s[2280]! }
- public var Wallet_AccessDenied_Title: String { return self._s[2281]! }
- public var WebSearch_GIFs: String { return self._s[2282]! }
- public var Notifications_DisplayNamesOnLockScreenInfoWithLink: String { return self._s[2283]! }
- public var Wallet_AccessDenied_Settings: String { return self._s[2284]! }
- public var Username_InvalidStartsWithNumber: String { return self._s[2285]! }
- public var Common_Back: String { return self._s[2286]! }
- public var GroupInfo_Permissions_EditingDisabled: String { return self._s[2287]! }
- public var Passport_Identity_DateOfBirthPlaceholder: String { return self._s[2288]! }
- public var Wallet_Send_Send: String { return self._s[2289]! }
+ public var ChatSettings_PrivateChats: String { return self._s[2278]! }
+ public var SettingsSearch_Synonyms_EditProfile_Logout: String { return self._s[2279]! }
+ public var Conversation_PrivateMessageLinkCopied: String { return self._s[2280]! }
+ public var Channel_UpdatePhotoItem: String { return self._s[2281]! }
+ public var GroupInfo_LeftStatus: String { return self._s[2282]! }
+ public var Watch_MessageView_Forward: String { return self._s[2284]! }
+ public var ReportPeer_ReasonChildAbuse: String { return self._s[2285]! }
+ public var Cache_ClearEmpty: String { return self._s[2287]! }
+ public var Localization_LanguageName: String { return self._s[2288]! }
+ public var Wallet_AccessDenied_Title: String { return self._s[2289]! }
+ public var WebSearch_GIFs: String { return self._s[2290]! }
+ public var Notifications_DisplayNamesOnLockScreenInfoWithLink: String { return self._s[2291]! }
+ public var Wallet_AccessDenied_Settings: String { return self._s[2292]! }
+ public var Username_InvalidStartsWithNumber: String { return self._s[2293]! }
+ public var Common_Back: String { return self._s[2294]! }
+ public var GroupInfo_Permissions_EditingDisabled: String { return self._s[2295]! }
+ public var Passport_Identity_DateOfBirthPlaceholder: String { return self._s[2296]! }
+ public var Wallet_Send_Send: String { return self._s[2297]! }
public func PUSH_CHANNEL_MESSAGE_STICKER(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2291]!, self._r[2291]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2299]!, self._r[2299]!, [_1, _2])
}
- public var Wallet_Info_RefreshErrorTitle: String { return self._s[2292]! }
- public var Wallet_Month_GenJune: String { return self._s[2293]! }
- public var Passport_Email_Help: String { return self._s[2294]! }
- public var Watch_Conversation_Reply: String { return self._s[2296]! }
- public var Conversation_EditingMessageMediaChange: String { return self._s[2299]! }
- public var Passport_Identity_IssueDatePlaceholder: String { return self._s[2300]! }
- public var Channel_BanUser_Unban: String { return self._s[2302]! }
- public var Channel_EditAdmin_PermissionPostMessages: String { return self._s[2303]! }
- public var Group_Username_CreatePublicLinkHelp: String { return self._s[2304]! }
- public var TwoStepAuth_ConfirmEmailCodePlaceholder: String { return self._s[2306]! }
- public var Wallet_Send_AddressHeader: String { return self._s[2307]! }
- public var Passport_Identity_Name: String { return self._s[2308]! }
+ public var Wallet_Info_RefreshErrorTitle: String { return self._s[2300]! }
+ public var Wallet_Month_GenJune: String { return self._s[2301]! }
+ public var Passport_Email_Help: String { return self._s[2302]! }
+ public var Watch_Conversation_Reply: String { return self._s[2304]! }
+ public var Conversation_EditingMessageMediaChange: String { return self._s[2307]! }
+ public var Passport_Identity_IssueDatePlaceholder: String { return self._s[2308]! }
+ public var Channel_BanUser_Unban: String { return self._s[2310]! }
+ public var Channel_EditAdmin_PermissionPostMessages: String { return self._s[2311]! }
+ public var Group_Username_CreatePublicLinkHelp: String { return self._s[2312]! }
+ public var TwoStepAuth_ConfirmEmailCodePlaceholder: String { return self._s[2314]! }
+ public var Wallet_Send_AddressHeader: String { return self._s[2315]! }
+ public var Passport_Identity_Name: String { return self._s[2316]! }
public func Channel_DiscussionGroup_HeaderGroupSet(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2309]!, self._r[2309]!, [_0])
+ return formatWithArgumentRanges(self._s[2317]!, self._r[2317]!, [_0])
}
- public var GroupRemoved_ViewUserInfo: String { return self._s[2310]! }
- public var Conversation_BlockUser: String { return self._s[2311]! }
- public var Month_GenJanuary: String { return self._s[2312]! }
- public var ChatSettings_TextSize: String { return self._s[2313]! }
- public var Notification_PassportValuePhone: String { return self._s[2314]! }
- public var MediaPlayer_UnknownArtist: String { return self._s[2315]! }
- public var Passport_Language_ne: String { return self._s[2316]! }
- public var Notification_CallBack: String { return self._s[2317]! }
- public var Wallet_SecureStorageReset_BiometryTouchId: String { return self._s[2318]! }
- public var TwoStepAuth_EmailHelp: String { return self._s[2319]! }
+ public var GroupRemoved_ViewUserInfo: String { return self._s[2318]! }
+ public var Conversation_BlockUser: String { return self._s[2319]! }
+ public var Month_GenJanuary: String { return self._s[2320]! }
+ public var ChatSettings_TextSize: String { return self._s[2321]! }
+ public var Notification_PassportValuePhone: String { return self._s[2322]! }
+ public var MediaPlayer_UnknownArtist: String { return self._s[2323]! }
+ public var Passport_Language_ne: String { return self._s[2324]! }
+ public var Notification_CallBack: String { return self._s[2325]! }
+ public var Wallet_SecureStorageReset_BiometryTouchId: String { return self._s[2326]! }
+ public var TwoStepAuth_EmailHelp: String { return self._s[2327]! }
public func Time_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2320]!, self._r[2320]!, [_0])
+ return formatWithArgumentRanges(self._s[2328]!, self._r[2328]!, [_0])
}
- public var Channel_Info_Management: String { return self._s[2321]! }
- public var Passport_FieldIdentityUploadHelp: String { return self._s[2322]! }
- public var Stickers_FrequentlyUsed: String { return self._s[2323]! }
- public var Channel_BanUser_PermissionSendMessages: String { return self._s[2324]! }
- public var Passport_Address_OneOfTypeUtilityBill: String { return self._s[2326]! }
+ public var Channel_Info_Management: String { return self._s[2329]! }
+ public var Passport_FieldIdentityUploadHelp: String { return self._s[2330]! }
+ public var Stickers_FrequentlyUsed: String { return self._s[2331]! }
+ public var Channel_BanUser_PermissionSendMessages: String { return self._s[2332]! }
+ public var Passport_Address_OneOfTypeUtilityBill: String { return self._s[2334]! }
public func LOCAL_CHANNEL_MESSAGE_FWDS(_ _1: String, _ _2: Int) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2327]!, self._r[2327]!, [_1, "\(_2)"])
+ return formatWithArgumentRanges(self._s[2335]!, self._r[2335]!, [_1, "\(_2)"])
}
- public var TwoFactorSetup_Password_Title: String { return self._s[2328]! }
- public var Passport_Address_EditResidentialAddress: String { return self._s[2329]! }
- public var PrivacyPolicy_DeclineTitle: String { return self._s[2330]! }
- public var CreatePoll_TextHeader: String { return self._s[2331]! }
+ public var TwoFactorSetup_Password_Title: String { return self._s[2336]! }
+ public var Passport_Address_EditResidentialAddress: String { return self._s[2337]! }
+ public var PrivacyPolicy_DeclineTitle: String { return self._s[2338]! }
+ public var CreatePoll_TextHeader: String { return self._s[2339]! }
public func Checkout_SavePasswordTimeoutAndTouchId(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2332]!, self._r[2332]!, [_0])
+ return formatWithArgumentRanges(self._s[2340]!, self._r[2340]!, [_0])
}
- public var PhotoEditor_QualityMedium: String { return self._s[2333]! }
- public var InfoPlist_NSMicrophoneUsageDescription: String { return self._s[2334]! }
- public var Conversation_StatusKickedFromChannel: String { return self._s[2336]! }
- public var CheckoutInfo_ReceiverInfoName: String { return self._s[2337]! }
- public var Group_ErrorSendRestrictedStickers: String { return self._s[2338]! }
+ public var PhotoEditor_QualityMedium: String { return self._s[2341]! }
+ public var InfoPlist_NSMicrophoneUsageDescription: String { return self._s[2342]! }
+ public var Conversation_StatusKickedFromChannel: String { return self._s[2344]! }
+ public var CheckoutInfo_ReceiverInfoName: String { return self._s[2345]! }
+ public var Group_ErrorSendRestrictedStickers: String { return self._s[2346]! }
public func Conversation_RestrictedInlineTimed(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2339]!, self._r[2339]!, [_0])
+ return formatWithArgumentRanges(self._s[2347]!, self._r[2347]!, [_0])
}
public func Channel_AdminLog_MessageTransferedName(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2340]!, self._r[2340]!, [_1])
+ return formatWithArgumentRanges(self._s[2348]!, self._r[2348]!, [_1])
}
- public var LogoutOptions_LogOutWalletInfo: String { return self._s[2341]! }
- public var TwoFactorSetup_Email_SkipConfirmationTitle: String { return self._s[2342]! }
- public var Conversation_LinkDialogOpen: String { return self._s[2344]! }
- public var TwoFactorSetup_Hint_Title: String { return self._s[2345]! }
- public var VoiceOver_Chat_PollNoVotes: String { return self._s[2346]! }
- public var Settings_Username: String { return self._s[2348]! }
- public var Conversation_Block: String { return self._s[2350]! }
- public var Wallpaper_Wallpaper: String { return self._s[2351]! }
- public var SocksProxySetup_UseProxy: String { return self._s[2353]! }
- public var Wallet_Send_Confirmation: String { return self._s[2354]! }
- public var EditTheme_UploadEditedTheme: String { return self._s[2355]! }
- public var UserInfo_ShareMyContactInfo: String { return self._s[2356]! }
- public var MessageTimer_Forever: String { return self._s[2357]! }
- public var Privacy_Calls_WhoCanCallMe: String { return self._s[2358]! }
- public var PhotoEditor_DiscardChanges: String { return self._s[2359]! }
- public var AuthSessions_TerminateOtherSessionsHelp: String { return self._s[2360]! }
- public var Passport_Language_da: String { return self._s[2361]! }
- public var SocksProxySetup_PortPlaceholder: String { return self._s[2362]! }
+ public var LogoutOptions_LogOutWalletInfo: String { return self._s[2349]! }
+ public var TwoFactorSetup_Email_SkipConfirmationTitle: String { return self._s[2350]! }
+ public var Conversation_LinkDialogOpen: String { return self._s[2352]! }
+ public var TwoFactorSetup_Hint_Title: String { return self._s[2353]! }
+ public var VoiceOver_Chat_PollNoVotes: String { return self._s[2354]! }
+ public var Settings_Username: String { return self._s[2356]! }
+ public var Conversation_Block: String { return self._s[2358]! }
+ public var Wallpaper_Wallpaper: String { return self._s[2359]! }
+ public var SocksProxySetup_UseProxy: String { return self._s[2361]! }
+ public var Wallet_Send_Confirmation: String { return self._s[2362]! }
+ public var EditTheme_UploadEditedTheme: String { return self._s[2363]! }
+ public var UserInfo_ShareMyContactInfo: String { return self._s[2364]! }
+ public var MessageTimer_Forever: String { return self._s[2365]! }
+ public var Privacy_Calls_WhoCanCallMe: String { return self._s[2366]! }
+ public var PhotoEditor_DiscardChanges: String { return self._s[2367]! }
+ public var AuthSessions_TerminateOtherSessionsHelp: String { return self._s[2368]! }
+ public var Passport_Language_da: String { return self._s[2369]! }
+ public var SocksProxySetup_PortPlaceholder: String { return self._s[2370]! }
public func SecretGIF_NotViewedYet(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2363]!, self._r[2363]!, [_0])
+ return formatWithArgumentRanges(self._s[2371]!, self._r[2371]!, [_0])
}
- public var Passport_Address_EditPassportRegistration: String { return self._s[2364]! }
+ public var Passport_Address_EditPassportRegistration: String { return self._s[2372]! }
public func Channel_AdminLog_MessageChangedGroupAbout(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2366]!, self._r[2366]!, [_0])
+ return formatWithArgumentRanges(self._s[2374]!, self._r[2374]!, [_0])
}
- public var Settings_AddDevice: String { return self._s[2367]! }
- public var Passport_Identity_ResidenceCountryPlaceholder: String { return self._s[2369]! }
- public var AuthSessions_AddDeviceIntro_Text1: String { return self._s[2370]! }
- public var Conversation_SearchByName_Prefix: String { return self._s[2371]! }
- public var Conversation_PinnedPoll: String { return self._s[2372]! }
- public var AuthSessions_AddDeviceIntro_Text2: String { return self._s[2373]! }
- public var Conversation_EmptyGifPanelPlaceholder: String { return self._s[2374]! }
- public var AuthSessions_AddDeviceIntro_Text3: String { return self._s[2375]! }
+ public var Settings_AddDevice: String { return self._s[2375]! }
+ public var Passport_Identity_ResidenceCountryPlaceholder: String { return self._s[2377]! }
+ public var AuthSessions_AddDeviceIntro_Text1: String { return self._s[2378]! }
+ public var Conversation_SearchByName_Prefix: String { return self._s[2379]! }
+ public var Conversation_PinnedPoll: String { return self._s[2380]! }
+ public var AuthSessions_AddDeviceIntro_Text2: String { return self._s[2381]! }
+ public var Conversation_EmptyGifPanelPlaceholder: String { return self._s[2382]! }
+ public var AuthSessions_AddDeviceIntro_Text3: String { return self._s[2383]! }
public func PUSH_ENCRYPTION_ACCEPT(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2376]!, self._r[2376]!, [_1])
+ return formatWithArgumentRanges(self._s[2384]!, self._r[2384]!, [_1])
}
- public var WallpaperSearch_ColorPurple: String { return self._s[2377]! }
- public var Cache_ByPeerHeader: String { return self._s[2378]! }
+ public var WallpaperSearch_ColorPurple: String { return self._s[2385]! }
+ public var Cache_ByPeerHeader: String { return self._s[2386]! }
public func Conversation_EncryptedPlaceholderTitleIncoming(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2379]!, self._r[2379]!, [_0])
+ return formatWithArgumentRanges(self._s[2387]!, self._r[2387]!, [_0])
}
- public var ChatSettings_AutoDownloadDocuments: String { return self._s[2380]! }
- public var Appearance_ThemePreview_Chat_3_Text: String { return self._s[2383]! }
- public var Wallet_Completed_Title: String { return self._s[2384]! }
- public var Notification_PinnedMessage: String { return self._s[2385]! }
- public var TwoFactorSetup_EmailVerification_Placeholder: String { return self._s[2386]! }
- public var VoiceOver_Chat_RecordModeVideoMessage: String { return self._s[2388]! }
- public var Contacts_SortBy: String { return self._s[2389]! }
+ public var ChatSettings_AutoDownloadDocuments: String { return self._s[2388]! }
+ public var Appearance_ThemePreview_Chat_3_Text: String { return self._s[2391]! }
+ public var Wallet_Completed_Title: String { return self._s[2392]! }
+ public var Notification_PinnedMessage: String { return self._s[2393]! }
+ public var TwoFactorSetup_EmailVerification_Placeholder: String { return self._s[2394]! }
+ public var VoiceOver_Chat_RecordModeVideoMessage: String { return self._s[2396]! }
+ public var Contacts_SortBy: String { return self._s[2397]! }
public func PUSH_CHANNEL_MESSAGE_NOTEXT(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2390]!, self._r[2390]!, [_1])
+ return formatWithArgumentRanges(self._s[2398]!, self._r[2398]!, [_1])
}
- public var Appearance_ColorThemeNight: String { return self._s[2392]! }
+ public var Appearance_ColorThemeNight: String { return self._s[2400]! }
public func PUSH_MESSAGE_GAME(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2393]!, self._r[2393]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2401]!, self._r[2401]!, [_1, _2])
}
- public var Call_EncryptionKey_Title: String { return self._s[2394]! }
- public var Watch_UserInfo_Service: String { return self._s[2395]! }
- public var SettingsSearch_Synonyms_Data_SaveEditedPhotos: String { return self._s[2397]! }
- public var Conversation_Unpin: String { return self._s[2399]! }
- public var CancelResetAccount_Title: String { return self._s[2400]! }
- public var Map_LiveLocationFor15Minutes: String { return self._s[2401]! }
+ public var Call_EncryptionKey_Title: String { return self._s[2402]! }
+ public var Watch_UserInfo_Service: String { return self._s[2403]! }
+ public var SettingsSearch_Synonyms_Data_SaveEditedPhotos: String { return self._s[2405]! }
+ public var Conversation_Unpin: String { return self._s[2407]! }
+ public var CancelResetAccount_Title: String { return self._s[2408]! }
+ public var Map_LiveLocationFor15Minutes: String { return self._s[2409]! }
public func Time_PreciseDate_m8(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2403]!, self._r[2403]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[2411]!, self._r[2411]!, [_1, _2, _3])
}
- public var Group_Members_AddMemberBotErrorNotAllowed: String { return self._s[2404]! }
- public var CallSettings_Title: String { return self._s[2405]! }
- public var SettingsSearch_Synonyms_Appearance_ChatBackground: String { return self._s[2406]! }
- public var PasscodeSettings_EncryptDataHelp: String { return self._s[2408]! }
- public var AutoDownloadSettings_Contacts: String { return self._s[2409]! }
+ public var Group_Members_AddMemberBotErrorNotAllowed: String { return self._s[2412]! }
+ public var CallSettings_Title: String { return self._s[2413]! }
+ public var SettingsSearch_Synonyms_Appearance_ChatBackground: String { return self._s[2414]! }
+ public var PasscodeSettings_EncryptDataHelp: String { return self._s[2416]! }
+ public var AutoDownloadSettings_Contacts: String { return self._s[2417]! }
public func Channel_AdminLog_MessageRankName(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2410]!, self._r[2410]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2418]!, self._r[2418]!, [_1, _2])
}
- public var Passport_Identity_DocumentDetails: String { return self._s[2411]! }
- public var LoginPassword_PasswordHelp: String { return self._s[2412]! }
- public var SettingsSearch_Synonyms_Data_AutoDownloadUsingWifi: String { return self._s[2413]! }
- public var PrivacyLastSeenSettings_CustomShareSettings_Delete: String { return self._s[2414]! }
- public var ChatContextMenu_TextSelectionTip: String { return self._s[2415]! }
- public var Checkout_TotalPaidAmount: String { return self._s[2416]! }
+ public var Passport_Identity_DocumentDetails: String { return self._s[2419]! }
+ public var LoginPassword_PasswordHelp: String { return self._s[2420]! }
+ public var SettingsSearch_Synonyms_Data_AutoDownloadUsingWifi: String { return self._s[2421]! }
+ public var PrivacyLastSeenSettings_CustomShareSettings_Delete: String { return self._s[2422]! }
+ public var ChatContextMenu_TextSelectionTip: String { return self._s[2423]! }
+ public var Checkout_TotalPaidAmount: String { return self._s[2424]! }
public func FileSize_KB(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2417]!, self._r[2417]!, [_0])
+ return formatWithArgumentRanges(self._s[2425]!, self._r[2425]!, [_0])
}
- public var PasscodeSettings_ChangePasscode: String { return self._s[2418]! }
- public var Conversation_SecretLinkPreviewAlert: String { return self._s[2420]! }
- public var Privacy_SecretChatsLinkPreviews: String { return self._s[2421]! }
+ public var PasscodeSettings_ChangePasscode: String { return self._s[2426]! }
+ public var Conversation_SecretLinkPreviewAlert: String { return self._s[2428]! }
+ public var Privacy_SecretChatsLinkPreviews: String { return self._s[2429]! }
public func PUSH_CHANNEL_MESSAGE_DOC(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2422]!, self._r[2422]!, [_1])
+ return formatWithArgumentRanges(self._s[2430]!, self._r[2430]!, [_1])
}
- public var VoiceOver_Chat_ReplyToYourMessage: String { return self._s[2423]! }
- public var Contacts_InviteFriends: String { return self._s[2425]! }
- public var Map_ChooseLocationTitle: String { return self._s[2426]! }
- public var Conversation_StopPoll: String { return self._s[2428]! }
+ public var VoiceOver_Chat_ReplyToYourMessage: String { return self._s[2431]! }
+ public var Contacts_InviteFriends: String { return self._s[2433]! }
+ public var Map_ChooseLocationTitle: String { return self._s[2434]! }
+ public var Conversation_StopPoll: String { return self._s[2436]! }
public func WebSearch_SearchNoResultsDescription(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2429]!, self._r[2429]!, [_0])
+ return formatWithArgumentRanges(self._s[2437]!, self._r[2437]!, [_0])
}
- public var Call_Camera: String { return self._s[2430]! }
- public var LogoutOptions_ChangePhoneNumberTitle: String { return self._s[2431]! }
- public var AppWallet_Intro_Text: String { return self._s[2432]! }
- public var Calls_RatingFeedback: String { return self._s[2433]! }
- public var GroupInfo_BroadcastListNamePlaceholder: String { return self._s[2435]! }
- public var Wallet_Alert_OK: String { return self._s[2436]! }
- public var NotificationsSound_Pulse: String { return self._s[2437]! }
- public var Watch_LastSeen_Lately: String { return self._s[2438]! }
- public var ReportGroupLocation_Report: String { return self._s[2441]! }
- public var Widget_NoUsers: String { return self._s[2442]! }
- public var Conversation_UnvotePoll: String { return self._s[2443]! }
- public var SettingsSearch_Synonyms_Privacy_ProfilePhoto: String { return self._s[2445]! }
- public var Privacy_ProfilePhoto_WhoCanSeeMyPhoto: String { return self._s[2446]! }
- public var NotificationsSound_Circles: String { return self._s[2447]! }
- public var PrivacyLastSeenSettings_AlwaysShareWith_Title: String { return self._s[2450]! }
- public var Wallet_Settings_DeleteWallet: String { return self._s[2451]! }
- public var TwoStepAuth_RecoveryCodeExpired: String { return self._s[2452]! }
- public var Proxy_TooltipUnavailable: String { return self._s[2453]! }
- public var Passport_Identity_CountryPlaceholder: String { return self._s[2455]! }
- public var GroupInfo_Permissions_SlowmodeInfo: String { return self._s[2457]! }
- public var Conversation_FileDropbox: String { return self._s[2458]! }
- public var Notifications_ExceptionsUnmuted: String { return self._s[2459]! }
- public var Tour_Text3: String { return self._s[2461]! }
- public var Login_ResetAccountProtected_Title: String { return self._s[2463]! }
- public var GroupPermission_NoSendMessages: String { return self._s[2464]! }
- public var WallpaperSearch_ColorTitle: String { return self._s[2465]! }
- public var ChatAdmins_AllMembersAreAdminsOnHelp: String { return self._s[2466]! }
+ public var Call_Camera: String { return self._s[2438]! }
+ public var LogoutOptions_ChangePhoneNumberTitle: String { return self._s[2439]! }
+ public var AppWallet_Intro_Text: String { return self._s[2440]! }
+ public var Calls_RatingFeedback: String { return self._s[2441]! }
+ public var GroupInfo_BroadcastListNamePlaceholder: String { return self._s[2443]! }
+ public var Wallet_Alert_OK: String { return self._s[2444]! }
+ public var NotificationsSound_Pulse: String { return self._s[2445]! }
+ public var Watch_LastSeen_Lately: String { return self._s[2446]! }
+ public var ReportGroupLocation_Report: String { return self._s[2449]! }
+ public var Widget_NoUsers: String { return self._s[2450]! }
+ public var Conversation_UnvotePoll: String { return self._s[2451]! }
+ public var SettingsSearch_Synonyms_Privacy_ProfilePhoto: String { return self._s[2453]! }
+ public var Privacy_ProfilePhoto_WhoCanSeeMyPhoto: String { return self._s[2454]! }
+ public var NotificationsSound_Circles: String { return self._s[2455]! }
+ public var PrivacyLastSeenSettings_AlwaysShareWith_Title: String { return self._s[2458]! }
+ public var Wallet_Settings_DeleteWallet: String { return self._s[2459]! }
+ public var TwoStepAuth_RecoveryCodeExpired: String { return self._s[2460]! }
+ public var Proxy_TooltipUnavailable: String { return self._s[2461]! }
+ public var Passport_Identity_CountryPlaceholder: String { return self._s[2463]! }
+ public var GroupInfo_Permissions_SlowmodeInfo: String { return self._s[2465]! }
+ public var Conversation_FileDropbox: String { return self._s[2466]! }
+ public var Notifications_ExceptionsUnmuted: String { return self._s[2467]! }
+ public var Tour_Text3: String { return self._s[2469]! }
+ public var Login_ResetAccountProtected_Title: String { return self._s[2471]! }
+ public var GroupPermission_NoSendMessages: String { return self._s[2472]! }
+ public var WallpaperSearch_ColorTitle: String { return self._s[2473]! }
+ public var ChatAdmins_AllMembersAreAdminsOnHelp: String { return self._s[2474]! }
public func Conversation_LiveLocationYouAnd(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2468]!, self._r[2468]!, [_0])
+ return formatWithArgumentRanges(self._s[2476]!, self._r[2476]!, [_0])
}
- public var GroupInfo_AddParticipantTitle: String { return self._s[2469]! }
- public var Checkout_ShippingOption_Title: String { return self._s[2470]! }
- public var ChatSettings_AutoDownloadTitle: String { return self._s[2471]! }
+ public var GroupInfo_AddParticipantTitle: String { return self._s[2477]! }
+ public var Checkout_ShippingOption_Title: String { return self._s[2478]! }
+ public var ChatSettings_AutoDownloadTitle: String { return self._s[2479]! }
public func DialogList_SingleTypingSuffix(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2472]!, self._r[2472]!, [_0])
+ return formatWithArgumentRanges(self._s[2480]!, self._r[2480]!, [_0])
}
public func ChatSettings_AutoDownloadSettings_TypeVideo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2473]!, self._r[2473]!, [_0])
+ return formatWithArgumentRanges(self._s[2481]!, self._r[2481]!, [_0])
}
- public var Channel_Management_LabelAdministrator: String { return self._s[2474]! }
- public var EditTheme_FileReadError: String { return self._s[2475]! }
- public var OwnershipTransfer_ComeBackLater: String { return self._s[2476]! }
- public var PrivacyLastSeenSettings_NeverShareWith_Placeholder: String { return self._s[2477]! }
- public var AutoDownloadSettings_Photos: String { return self._s[2479]! }
- public var Appearance_PreviewIncomingText: String { return self._s[2480]! }
- public var ChatList_Context_MarkAllAsRead: String { return self._s[2481]! }
- public var ChannelInfo_ConfirmLeave: String { return self._s[2482]! }
- public var MediaPicker_MomentsDateRangeSameMonthYearFormat: String { return self._s[2483]! }
- public var Passport_Identity_DocumentNumberPlaceholder: String { return self._s[2484]! }
- public var Channel_AdminLogFilter_EventsNewMembers: String { return self._s[2485]! }
- public var PasscodeSettings_AutoLock_IfAwayFor_5minutes: String { return self._s[2486]! }
- public var GroupInfo_SetGroupPhotoStop: String { return self._s[2487]! }
- public var Notification_SecretChatScreenshot: String { return self._s[2488]! }
- public var AccessDenied_Wallpapers: String { return self._s[2489]! }
- public var ChatList_Context_Mute: String { return self._s[2491]! }
- public var Passport_Address_City: String { return self._s[2492]! }
- public var InfoPlist_NSPhotoLibraryAddUsageDescription: String { return self._s[2493]! }
- public var Appearance_ThemeCarouselClassic: String { return self._s[2494]! }
- public var SocksProxySetup_SecretPlaceholder: String { return self._s[2495]! }
- public var AccessDenied_LocationDisabled: String { return self._s[2496]! }
- public var Group_Location_Title: String { return self._s[2497]! }
- public var SocksProxySetup_HostnamePlaceholder: String { return self._s[2499]! }
- public var GroupInfo_Sound: String { return self._s[2500]! }
- public var SettingsSearch_Synonyms_ChatSettings_OpenLinksIn: String { return self._s[2501]! }
- public var ChannelInfo_ScamChannelWarning: String { return self._s[2502]! }
- public var Stickers_RemoveFromFavorites: String { return self._s[2503]! }
- public var Contacts_Title: String { return self._s[2504]! }
- public var EditTheme_ThemeTemplateAlertText: String { return self._s[2505]! }
- public var Passport_Language_fr: String { return self._s[2506]! }
- public var TwoFactorSetup_EmailVerification_Action: String { return self._s[2507]! }
- public var Notifications_ResetAllNotifications: String { return self._s[2508]! }
- public var IntentsSettings_SuggestedChats: String { return self._s[2510]! }
- public var PrivacySettings_SecurityTitle: String { return self._s[2512]! }
- public var Checkout_NewCard_Title: String { return self._s[2513]! }
- public var Login_HaveNotReceivedCodeInternal: String { return self._s[2514]! }
- public var Conversation_ForwardChats: String { return self._s[2515]! }
- public var Wallet_SecureStorageReset_PasscodeText: String { return self._s[2517]! }
- public var PasscodeSettings_4DigitCode: String { return self._s[2518]! }
- public var Settings_FAQ: String { return self._s[2520]! }
- public var AutoDownloadSettings_DocumentsTitle: String { return self._s[2521]! }
- public var Conversation_ContextMenuForward: String { return self._s[2522]! }
- public var VoiceOver_Chat_YourPhoto: String { return self._s[2525]! }
- public var PrivacyPolicy_Title: String { return self._s[2528]! }
- public var Notifications_TextTone: String { return self._s[2529]! }
- public var Profile_CreateNewContact: String { return self._s[2530]! }
- public var PrivacyPhoneNumberSettings_WhoCanSeeMyPhoneNumber: String { return self._s[2531]! }
- public var TwoFactorSetup_EmailVerification_Title: String { return self._s[2533]! }
- public var Call_Speaker: String { return self._s[2534]! }
- public var AutoNightTheme_AutomaticSection: String { return self._s[2535]! }
- public var Channel_OwnershipTransfer_EnterPassword: String { return self._s[2537]! }
- public var Channel_Username_InvalidCharacters: String { return self._s[2538]! }
+ public var Channel_Management_LabelAdministrator: String { return self._s[2482]! }
+ public var EditTheme_FileReadError: String { return self._s[2483]! }
+ public var OwnershipTransfer_ComeBackLater: String { return self._s[2484]! }
+ public var PrivacyLastSeenSettings_NeverShareWith_Placeholder: String { return self._s[2485]! }
+ public var AutoDownloadSettings_Photos: String { return self._s[2487]! }
+ public var Appearance_PreviewIncomingText: String { return self._s[2488]! }
+ public var ChatList_Context_MarkAllAsRead: String { return self._s[2489]! }
+ public var ChannelInfo_ConfirmLeave: String { return self._s[2490]! }
+ public var MediaPicker_MomentsDateRangeSameMonthYearFormat: String { return self._s[2491]! }
+ public var Passport_Identity_DocumentNumberPlaceholder: String { return self._s[2492]! }
+ public var Channel_AdminLogFilter_EventsNewMembers: String { return self._s[2493]! }
+ public var PasscodeSettings_AutoLock_IfAwayFor_5minutes: String { return self._s[2494]! }
+ public var GroupInfo_SetGroupPhotoStop: String { return self._s[2495]! }
+ public var Notification_SecretChatScreenshot: String { return self._s[2496]! }
+ public var AccessDenied_Wallpapers: String { return self._s[2497]! }
+ public var ChatList_Context_Mute: String { return self._s[2499]! }
+ public var Passport_Address_City: String { return self._s[2500]! }
+ public var InfoPlist_NSPhotoLibraryAddUsageDescription: String { return self._s[2501]! }
+ public var Appearance_ThemeCarouselClassic: String { return self._s[2502]! }
+ public var SocksProxySetup_SecretPlaceholder: String { return self._s[2503]! }
+ public var AccessDenied_LocationDisabled: String { return self._s[2504]! }
+ public var Group_Location_Title: String { return self._s[2505]! }
+ public var SocksProxySetup_HostnamePlaceholder: String { return self._s[2507]! }
+ public var GroupInfo_Sound: String { return self._s[2508]! }
+ public var SettingsSearch_Synonyms_ChatSettings_OpenLinksIn: String { return self._s[2509]! }
+ public var ChannelInfo_ScamChannelWarning: String { return self._s[2510]! }
+ public var Stickers_RemoveFromFavorites: String { return self._s[2511]! }
+ public var Contacts_Title: String { return self._s[2512]! }
+ public var EditTheme_ThemeTemplateAlertText: String { return self._s[2513]! }
+ public var Passport_Language_fr: String { return self._s[2514]! }
+ public var TwoFactorSetup_EmailVerification_Action: String { return self._s[2515]! }
+ public var Notifications_ResetAllNotifications: String { return self._s[2516]! }
+ public var IntentsSettings_SuggestedChats: String { return self._s[2518]! }
+ public var PrivacySettings_SecurityTitle: String { return self._s[2520]! }
+ public var Checkout_NewCard_Title: String { return self._s[2521]! }
+ public var Login_HaveNotReceivedCodeInternal: String { return self._s[2522]! }
+ public var Conversation_ForwardChats: String { return self._s[2523]! }
+ public var Wallet_SecureStorageReset_PasscodeText: String { return self._s[2525]! }
+ public var PasscodeSettings_4DigitCode: String { return self._s[2526]! }
+ public var Settings_FAQ: String { return self._s[2528]! }
+ public var AutoDownloadSettings_DocumentsTitle: String { return self._s[2529]! }
+ public var Conversation_ContextMenuForward: String { return self._s[2530]! }
+ public var VoiceOver_Chat_YourPhoto: String { return self._s[2533]! }
+ public var PrivacyPolicy_Title: String { return self._s[2536]! }
+ public var Notifications_TextTone: String { return self._s[2537]! }
+ public var Profile_CreateNewContact: String { return self._s[2538]! }
+ public var PrivacyPhoneNumberSettings_WhoCanSeeMyPhoneNumber: String { return self._s[2539]! }
+ public var TwoFactorSetup_EmailVerification_Title: String { return self._s[2541]! }
+ public var Call_Speaker: String { return self._s[2542]! }
+ public var AutoNightTheme_AutomaticSection: String { return self._s[2543]! }
+ public var Channel_OwnershipTransfer_EnterPassword: String { return self._s[2545]! }
+ public var Channel_Username_InvalidCharacters: String { return self._s[2546]! }
public func Channel_AdminLog_MessageChangedChannelUsername(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2539]!, self._r[2539]!, [_0])
+ return formatWithArgumentRanges(self._s[2547]!, self._r[2547]!, [_0])
}
- public var AutoDownloadSettings_AutodownloadFiles: String { return self._s[2540]! }
- public var PrivacySettings_LastSeenTitle: String { return self._s[2541]! }
- public var Channel_AdminLog_CanInviteUsers: String { return self._s[2542]! }
- public var SettingsSearch_Synonyms_Privacy_Data_ClearPaymentsInfo: String { return self._s[2543]! }
- public var OwnershipTransfer_SecurityCheck: String { return self._s[2544]! }
- public var Conversation_MessageDeliveryFailed: String { return self._s[2545]! }
- public var Watch_ChatList_NoConversationsText: String { return self._s[2546]! }
- public var Bot_Unblock: String { return self._s[2547]! }
- public var TextFormat_Italic: String { return self._s[2548]! }
- public var WallpaperSearch_ColorPink: String { return self._s[2549]! }
- public var Settings_About_Help: String { return self._s[2551]! }
- public var SearchImages_Title: String { return self._s[2552]! }
- public var Weekday_Wednesday: String { return self._s[2553]! }
- public var Conversation_ClousStorageInfo_Description1: String { return self._s[2554]! }
- public var ExplicitContent_AlertTitle: String { return self._s[2555]! }
+ public var AutoDownloadSettings_AutodownloadFiles: String { return self._s[2548]! }
+ public var PrivacySettings_LastSeenTitle: String { return self._s[2549]! }
+ public var Channel_AdminLog_CanInviteUsers: String { return self._s[2550]! }
+ public var SettingsSearch_Synonyms_Privacy_Data_ClearPaymentsInfo: String { return self._s[2551]! }
+ public var OwnershipTransfer_SecurityCheck: String { return self._s[2552]! }
+ public var Conversation_MessageDeliveryFailed: String { return self._s[2553]! }
+ public var Watch_ChatList_NoConversationsText: String { return self._s[2554]! }
+ public var Bot_Unblock: String { return self._s[2555]! }
+ public var TextFormat_Italic: String { return self._s[2556]! }
+ public var WallpaperSearch_ColorPink: String { return self._s[2557]! }
+ public var Settings_About_Help: String { return self._s[2559]! }
+ public var SearchImages_Title: String { return self._s[2560]! }
+ public var Weekday_Wednesday: String { return self._s[2561]! }
+ public var Conversation_ClousStorageInfo_Description1: String { return self._s[2562]! }
+ public var ExplicitContent_AlertTitle: String { return self._s[2563]! }
public func Time_PreciseDate_m5(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2556]!, self._r[2556]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[2564]!, self._r[2564]!, [_1, _2, _3])
}
- public var Channel_DiscussionGroup_Create: String { return self._s[2557]! }
- public var Weekday_Thursday: String { return self._s[2558]! }
- public var Channel_BanUser_PermissionChangeGroupInfo: String { return self._s[2559]! }
- public var Channel_Members_AddMembersHelp: String { return self._s[2560]! }
+ public var Channel_DiscussionGroup_Create: String { return self._s[2565]! }
+ public var Weekday_Thursday: String { return self._s[2566]! }
+ public var Channel_BanUser_PermissionChangeGroupInfo: String { return self._s[2567]! }
+ public var Channel_Members_AddMembersHelp: String { return self._s[2568]! }
public func Checkout_SavePasswordTimeout(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2561]!, self._r[2561]!, [_0])
+ return formatWithArgumentRanges(self._s[2569]!, self._r[2569]!, [_0])
}
- public var Channel_DiscussionGroup_LinkGroup: String { return self._s[2562]! }
- public var SettingsSearch_Synonyms_Notifications_InAppNotificationsVibrate: String { return self._s[2563]! }
- public var Passport_RequestedInformation: String { return self._s[2564]! }
- public var Login_PhoneAndCountryHelp: String { return self._s[2565]! }
- public var Conversation_EncryptionProcessing: String { return self._s[2567]! }
- public var Notifications_PermissionsSuppressWarningTitle: String { return self._s[2568]! }
- public var PhotoEditor_EnhanceTool: String { return self._s[2570]! }
- public var Channel_Setup_Title: String { return self._s[2571]! }
- public var Conversation_SearchPlaceholder: String { return self._s[2572]! }
- public var OldChannels_GroupEmptyFormat: String { return self._s[2573]! }
- public var AccessDenied_LocationAlwaysDenied: String { return self._s[2574]! }
- public var Checkout_ErrorGeneric: String { return self._s[2575]! }
- public var Passport_Language_hu: String { return self._s[2576]! }
- public var GroupPermission_EditingDisabled: String { return self._s[2577]! }
- public var Wallet_Month_ShortSeptember: String { return self._s[2579]! }
+ public var Channel_DiscussionGroup_LinkGroup: String { return self._s[2570]! }
+ public var SettingsSearch_Synonyms_Notifications_InAppNotificationsVibrate: String { return self._s[2571]! }
+ public var Passport_RequestedInformation: String { return self._s[2572]! }
+ public var Login_PhoneAndCountryHelp: String { return self._s[2573]! }
+ public var Conversation_EncryptionProcessing: String { return self._s[2575]! }
+ public var Notifications_PermissionsSuppressWarningTitle: String { return self._s[2576]! }
+ public var PhotoEditor_EnhanceTool: String { return self._s[2578]! }
+ public var Channel_Setup_Title: String { return self._s[2579]! }
+ public var Conversation_SearchPlaceholder: String { return self._s[2580]! }
+ public var OldChannels_GroupEmptyFormat: String { return self._s[2581]! }
+ public var AccessDenied_LocationAlwaysDenied: String { return self._s[2582]! }
+ public var Checkout_ErrorGeneric: String { return self._s[2583]! }
+ public var Passport_Language_hu: String { return self._s[2584]! }
+ public var GroupPermission_EditingDisabled: String { return self._s[2585]! }
+ public var Wallet_Month_ShortSeptember: String { return self._s[2587]! }
public func Passport_Identity_UploadOneOfScan(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2580]!, self._r[2580]!, [_0])
+ return formatWithArgumentRanges(self._s[2588]!, self._r[2588]!, [_0])
}
public func PUSH_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2583]!, self._r[2583]!, [_1])
+ return formatWithArgumentRanges(self._s[2591]!, self._r[2591]!, [_1])
}
- public var ChatList_DeleteSavedMessagesConfirmationTitle: String { return self._s[2584]! }
+ public var ChatList_DeleteSavedMessagesConfirmationTitle: String { return self._s[2592]! }
public func UserInfo_BlockConfirmationTitle(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2585]!, self._r[2585]!, [_0])
+ return formatWithArgumentRanges(self._s[2593]!, self._r[2593]!, [_0])
}
- public var Conversation_CloudStorageInfo_Title: String { return self._s[2586]! }
- public var Group_Location_Info: String { return self._s[2587]! }
- public var PhotoEditor_CropAspectRatioSquare: String { return self._s[2588]! }
- public var Permissions_PeopleNearbyAllow_v0: String { return self._s[2589]! }
+ public var Conversation_CloudStorageInfo_Title: String { return self._s[2594]! }
+ public var Group_Location_Info: String { return self._s[2595]! }
+ public var PhotoEditor_CropAspectRatioSquare: String { return self._s[2596]! }
+ public var Permissions_PeopleNearbyAllow_v0: String { return self._s[2597]! }
public func Notification_Exceptions_MutedUntil(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2590]!, self._r[2590]!, [_0])
+ return formatWithArgumentRanges(self._s[2598]!, self._r[2598]!, [_0])
}
- public var Conversation_ClearPrivateHistory: String { return self._s[2591]! }
- public var ContactInfo_PhoneLabelHome: String { return self._s[2592]! }
- public var Appearance_RemoveThemeConfirmation: String { return self._s[2593]! }
- public var PrivacySettings_LastSeenContacts: String { return self._s[2594]! }
+ public var Conversation_ClearPrivateHistory: String { return self._s[2599]! }
+ public var ContactInfo_PhoneLabelHome: String { return self._s[2600]! }
+ public var Appearance_RemoveThemeConfirmation: String { return self._s[2601]! }
+ public var PrivacySettings_LastSeenContacts: String { return self._s[2602]! }
public func ChangePhone_ErrorOccupied(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2595]!, self._r[2595]!, [_0])
+ return formatWithArgumentRanges(self._s[2603]!, self._r[2603]!, [_0])
}
- public var Passport_Language_cs: String { return self._s[2596]! }
- public var Message_PinnedAnimationMessage: String { return self._s[2598]! }
- public var Passport_Identity_ReverseSideHelp: String { return self._s[2600]! }
- public var SettingsSearch_Synonyms_Data_Storage_Title: String { return self._s[2601]! }
- public var Wallet_Info_TransactionTo: String { return self._s[2603]! }
- public var ChatList_DeleteForEveryoneConfirmationText: String { return self._s[2604]! }
- public var SettingsSearch_Synonyms_Privacy_PasscodeAndTouchId: String { return self._s[2605]! }
- public var Embed_PlayingInPIP: String { return self._s[2606]! }
- public var Appearance_ThemePreview_Chat_3_TextWithLink: String { return self._s[2607]! }
- public var AutoNightTheme_ScheduleSection: String { return self._s[2608]! }
+ public var Passport_Language_cs: String { return self._s[2604]! }
+ public var Message_PinnedAnimationMessage: String { return self._s[2606]! }
+ public var Passport_Identity_ReverseSideHelp: String { return self._s[2608]! }
+ public var SettingsSearch_Synonyms_Data_Storage_Title: String { return self._s[2609]! }
+ public var Wallet_Info_TransactionTo: String { return self._s[2611]! }
+ public var ChatList_DeleteForEveryoneConfirmationText: String { return self._s[2612]! }
+ public var SettingsSearch_Synonyms_Privacy_PasscodeAndTouchId: String { return self._s[2613]! }
+ public var Embed_PlayingInPIP: String { return self._s[2614]! }
+ public var Appearance_ThemePreview_Chat_3_TextWithLink: String { return self._s[2615]! }
+ public var AutoNightTheme_ScheduleSection: String { return self._s[2616]! }
public func Call_EmojiDescription(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2609]!, self._r[2609]!, [_0])
+ return formatWithArgumentRanges(self._s[2617]!, self._r[2617]!, [_0])
}
- public var MediaPicker_LivePhotoDescription: String { return self._s[2610]! }
+ public var MediaPicker_LivePhotoDescription: String { return self._s[2618]! }
public func Channel_AdminLog_MessageRestrictedName(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2611]!, self._r[2611]!, [_1])
+ return formatWithArgumentRanges(self._s[2619]!, self._r[2619]!, [_1])
}
- public var Notification_PaymentSent: String { return self._s[2612]! }
- public var PhotoEditor_CurvesGreen: String { return self._s[2613]! }
- public var Notification_Exceptions_PreviewAlwaysOff: String { return self._s[2614]! }
- public var AutoNightTheme_System: String { return self._s[2615]! }
- public var SaveIncomingPhotosSettings_Title: String { return self._s[2616]! }
- public var CreatePoll_QuizTitle: String { return self._s[2617]! }
- public var NotificationSettings_ShowNotificationsAllAccounts: String { return self._s[2618]! }
- public var VoiceOver_Chat_PagePreview: String { return self._s[2619]! }
+ public var Notification_PaymentSent: String { return self._s[2620]! }
+ public var PhotoEditor_CurvesGreen: String { return self._s[2621]! }
+ public var Notification_Exceptions_PreviewAlwaysOff: String { return self._s[2622]! }
+ public var AutoNightTheme_System: String { return self._s[2623]! }
+ public var SaveIncomingPhotosSettings_Title: String { return self._s[2624]! }
+ public var CreatePoll_QuizTitle: String { return self._s[2625]! }
+ public var NotificationSettings_ShowNotificationsAllAccounts: String { return self._s[2626]! }
+ public var VoiceOver_Chat_PagePreview: String { return self._s[2627]! }
public func PUSH_MESSAGE_SCREENSHOT(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2622]!, self._r[2622]!, [_1])
+ return formatWithArgumentRanges(self._s[2630]!, self._r[2630]!, [_1])
}
public func PUSH_MESSAGE_PHOTO_SECRET(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2623]!, self._r[2623]!, [_1])
+ return formatWithArgumentRanges(self._s[2631]!, self._r[2631]!, [_1])
}
public func ApplyLanguage_UnsufficientDataText(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2624]!, self._r[2624]!, [_1])
+ return formatWithArgumentRanges(self._s[2632]!, self._r[2632]!, [_1])
}
- public var NetworkUsageSettings_CallDataSection: String { return self._s[2626]! }
- public var PasscodeSettings_HelpTop: String { return self._s[2627]! }
- public var Conversation_WalletRequiredTitle: String { return self._s[2628]! }
- public var Group_OwnershipTransfer_ErrorAdminsTooMuch: String { return self._s[2629]! }
- public var Passport_Address_TypeRentalAgreement: String { return self._s[2630]! }
- public var EditTheme_ShortLink: String { return self._s[2631]! }
- public var Theme_Colors_ColorWallpaperWarning: String { return self._s[2632]! }
- public var ProxyServer_VoiceOver_Active: String { return self._s[2633]! }
- public var ReportPeer_ReasonOther_Placeholder: String { return self._s[2634]! }
- public var CheckoutInfo_ErrorPhoneInvalid: String { return self._s[2635]! }
- public var Call_Accept: String { return self._s[2637]! }
- public var GroupRemoved_RemoveInfo: String { return self._s[2638]! }
- public var Month_GenMarch: String { return self._s[2640]! }
- public var PhotoEditor_ShadowsTool: String { return self._s[2641]! }
- public var LoginPassword_Title: String { return self._s[2642]! }
- public var Call_End: String { return self._s[2643]! }
- public var Watch_Conversation_GroupInfo: String { return self._s[2644]! }
- public var VoiceOver_Chat_Contact: String { return self._s[2645]! }
- public var EditTheme_Create_Preview_IncomingText: String { return self._s[2646]! }
- public var CallSettings_Always: String { return self._s[2647]! }
- public var CallFeedback_Success: String { return self._s[2648]! }
- public var TwoStepAuth_SetupHint: String { return self._s[2649]! }
+ public var NetworkUsageSettings_CallDataSection: String { return self._s[2634]! }
+ public var PasscodeSettings_HelpTop: String { return self._s[2635]! }
+ public var Conversation_WalletRequiredTitle: String { return self._s[2636]! }
+ public var Group_OwnershipTransfer_ErrorAdminsTooMuch: String { return self._s[2637]! }
+ public var Passport_Address_TypeRentalAgreement: String { return self._s[2638]! }
+ public var EditTheme_ShortLink: String { return self._s[2639]! }
+ public var Theme_Colors_ColorWallpaperWarning: String { return self._s[2640]! }
+ public var ProxyServer_VoiceOver_Active: String { return self._s[2641]! }
+ public var ReportPeer_ReasonOther_Placeholder: String { return self._s[2642]! }
+ public var CheckoutInfo_ErrorPhoneInvalid: String { return self._s[2643]! }
+ public var Call_Accept: String { return self._s[2645]! }
+ public var GroupRemoved_RemoveInfo: String { return self._s[2646]! }
+ public var Month_GenMarch: String { return self._s[2648]! }
+ public var PhotoEditor_ShadowsTool: String { return self._s[2649]! }
+ public var LoginPassword_Title: String { return self._s[2650]! }
+ public var Call_End: String { return self._s[2651]! }
+ public var Watch_Conversation_GroupInfo: String { return self._s[2652]! }
+ public var VoiceOver_Chat_Contact: String { return self._s[2653]! }
+ public var EditTheme_Create_Preview_IncomingText: String { return self._s[2654]! }
+ public var CallSettings_Always: String { return self._s[2655]! }
+ public var CallFeedback_Success: String { return self._s[2656]! }
+ public var TwoStepAuth_SetupHint: String { return self._s[2657]! }
public func AddContact_ContactWillBeSharedAfterMutual(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2650]!, self._r[2650]!, [_1])
+ return formatWithArgumentRanges(self._s[2658]!, self._r[2658]!, [_1])
}
- public var ConversationProfile_UsersTooMuchError: String { return self._s[2651]! }
- public var Login_PhoneTitle: String { return self._s[2652]! }
- public var Passport_FieldPhoneHelp: String { return self._s[2653]! }
- public var Weekday_ShortSunday: String { return self._s[2654]! }
- public var Passport_InfoFAQ_URL: String { return self._s[2655]! }
- public var ContactInfo_Job: String { return self._s[2657]! }
- public var UserInfo_InviteBotToGroup: String { return self._s[2658]! }
- public var Appearance_ThemeCarouselNightBlue: String { return self._s[2659]! }
- public var CreatePoll_QuizTip: String { return self._s[2660]! }
- public var TwoFactorSetup_Email_Text: String { return self._s[2661]! }
- public var TwoStepAuth_PasswordRemovePassportConfirmation: String { return self._s[2662]! }
- public var Invite_ChannelsTooMuch: String { return self._s[2663]! }
- public var Wallet_Send_ConfirmationConfirm: String { return self._s[2664]! }
- public var Wallet_TransactionInfo_OtherFeeInfo: String { return self._s[2665]! }
- public var SettingsSearch_Synonyms_Notifications_InAppNotificationsPreview: String { return self._s[2666]! }
- public var Wallet_Receive_AmountText: String { return self._s[2667]! }
- public var Passport_DeletePersonalDetailsConfirmation: String { return self._s[2668]! }
- public var CallFeedback_ReasonNoise: String { return self._s[2669]! }
- public var Appearance_AppIconDefault: String { return self._s[2671]! }
- public var Passport_Identity_AddInternalPassport: String { return self._s[2672]! }
- public var MediaPicker_AddCaption: String { return self._s[2673]! }
- public var CallSettings_TabIconDescription: String { return self._s[2674]! }
+ public var ConversationProfile_UsersTooMuchError: String { return self._s[2659]! }
+ public var Login_PhoneTitle: String { return self._s[2660]! }
+ public var Passport_FieldPhoneHelp: String { return self._s[2661]! }
+ public var Weekday_ShortSunday: String { return self._s[2662]! }
+ public var Passport_InfoFAQ_URL: String { return self._s[2663]! }
+ public var ContactInfo_Job: String { return self._s[2665]! }
+ public var UserInfo_InviteBotToGroup: String { return self._s[2666]! }
+ public var Appearance_ThemeCarouselNightBlue: String { return self._s[2667]! }
+ public var CreatePoll_QuizTip: String { return self._s[2668]! }
+ public var TwoFactorSetup_Email_Text: String { return self._s[2669]! }
+ public var TwoStepAuth_PasswordRemovePassportConfirmation: String { return self._s[2670]! }
+ public var Invite_ChannelsTooMuch: String { return self._s[2671]! }
+ public var Wallet_Send_ConfirmationConfirm: String { return self._s[2672]! }
+ public var Wallet_TransactionInfo_OtherFeeInfo: String { return self._s[2673]! }
+ public var SettingsSearch_Synonyms_Notifications_InAppNotificationsPreview: String { return self._s[2674]! }
+ public var Wallet_Receive_AmountText: String { return self._s[2675]! }
+ public var Passport_DeletePersonalDetailsConfirmation: String { return self._s[2676]! }
+ public var CallFeedback_ReasonNoise: String { return self._s[2677]! }
+ public var Appearance_AppIconDefault: String { return self._s[2679]! }
+ public var Passport_Identity_AddInternalPassport: String { return self._s[2680]! }
+ public var MediaPicker_AddCaption: String { return self._s[2681]! }
+ public var CallSettings_TabIconDescription: String { return self._s[2682]! }
public func VoiceOver_Chat_Caption(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2675]!, self._r[2675]!, [_0])
+ return formatWithArgumentRanges(self._s[2683]!, self._r[2683]!, [_0])
}
- public var IntentsSettings_SuggestedChatsGroups: String { return self._s[2676]! }
+ public var IntentsSettings_SuggestedChatsGroups: String { return self._s[2684]! }
public func Map_SearchNoResultsDescription(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2677]!, self._r[2677]!, [_0])
+ return formatWithArgumentRanges(self._s[2685]!, self._r[2685]!, [_0])
}
- public var ChatList_UndoArchiveHiddenTitle: String { return self._s[2678]! }
- public var Privacy_GroupsAndChannels_AlwaysAllow: String { return self._s[2679]! }
- public var Passport_Identity_TypePersonalDetails: String { return self._s[2680]! }
- public var DialogList_SearchSectionRecent: String { return self._s[2681]! }
- public var PrivacyPolicy_DeclineMessage: String { return self._s[2682]! }
- public var CreatePoll_Anonymous: String { return self._s[2683]! }
- public var LogoutOptions_ClearCacheText: String { return self._s[2686]! }
- public var LastSeen_WithinAWeek: String { return self._s[2687]! }
- public var ChannelMembers_GroupAdminsTitle: String { return self._s[2688]! }
- public var Conversation_CloudStorage_ChatStatus: String { return self._s[2690]! }
- public var VoiceOver_Media_PlaybackRateNormal: String { return self._s[2691]! }
+ public var ChatList_UndoArchiveHiddenTitle: String { return self._s[2686]! }
+ public var Privacy_GroupsAndChannels_AlwaysAllow: String { return self._s[2687]! }
+ public var Passport_Identity_TypePersonalDetails: String { return self._s[2688]! }
+ public var DialogList_SearchSectionRecent: String { return self._s[2689]! }
+ public var PrivacyPolicy_DeclineMessage: String { return self._s[2690]! }
+ public var CreatePoll_Anonymous: String { return self._s[2691]! }
+ public var LogoutOptions_ClearCacheText: String { return self._s[2694]! }
+ public var LastSeen_WithinAWeek: String { return self._s[2695]! }
+ public var ChannelMembers_GroupAdminsTitle: String { return self._s[2696]! }
+ public var Conversation_CloudStorage_ChatStatus: String { return self._s[2698]! }
+ public var VoiceOver_Media_PlaybackRateNormal: String { return self._s[2699]! }
public func AddContact_SharedContactExceptionInfo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2692]!, self._r[2692]!, [_0])
+ return formatWithArgumentRanges(self._s[2700]!, self._r[2700]!, [_0])
}
- public var Passport_Address_TypeResidentialAddress: String { return self._s[2693]! }
- public var Conversation_StatusLeftGroup: String { return self._s[2694]! }
- public var SocksProxySetup_ProxyDetailsTitle: String { return self._s[2695]! }
- public var SettingsSearch_Synonyms_Calls_Title: String { return self._s[2697]! }
- public var GroupPermission_AddSuccess: String { return self._s[2698]! }
- public var PhotoEditor_BlurToolRadial: String { return self._s[2700]! }
- public var Conversation_ContextMenuCopy: String { return self._s[2701]! }
- public var AccessDenied_CallMicrophone: String { return self._s[2702]! }
+ public var Passport_Address_TypeResidentialAddress: String { return self._s[2701]! }
+ public var Conversation_StatusLeftGroup: String { return self._s[2702]! }
+ public var SocksProxySetup_ProxyDetailsTitle: String { return self._s[2703]! }
+ public var SettingsSearch_Synonyms_Calls_Title: String { return self._s[2705]! }
+ public var GroupPermission_AddSuccess: String { return self._s[2706]! }
+ public var PhotoEditor_BlurToolRadial: String { return self._s[2708]! }
+ public var Conversation_ContextMenuCopy: String { return self._s[2709]! }
+ public var AccessDenied_CallMicrophone: String { return self._s[2710]! }
public func Time_PreciseDate_m2(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2703]!, self._r[2703]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[2711]!, self._r[2711]!, [_1, _2, _3])
}
- public var Login_InvalidFirstNameError: String { return self._s[2704]! }
- public var Notifications_Badge_CountUnreadMessages_InfoOn: String { return self._s[2705]! }
- public var Checkout_PaymentMethod_New: String { return self._s[2706]! }
- public var ShareMenu_CopyShareLinkGame: String { return self._s[2707]! }
- public var PhotoEditor_QualityTool: String { return self._s[2708]! }
- public var Login_SendCodeViaSms: String { return self._s[2709]! }
- public var SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor: String { return self._s[2710]! }
- public var Chat_SlowmodeAttachmentLimitReached: String { return self._s[2711]! }
- public var Wallet_Receive_CopyAddress: String { return self._s[2712]! }
- public var Login_EmailNotConfiguredError: String { return self._s[2713]! }
- public var SocksProxySetup_Status: String { return self._s[2714]! }
- public var Conversation_ScheduleMessage_SendWhenOnline: String { return self._s[2715]! }
- public var PrivacyPolicy_Accept: String { return self._s[2716]! }
- public var Notifications_ExceptionsMessagePlaceholder: String { return self._s[2717]! }
- public var Appearance_AppIconClassicX: String { return self._s[2718]! }
+ public var Login_InvalidFirstNameError: String { return self._s[2712]! }
+ public var Notifications_Badge_CountUnreadMessages_InfoOn: String { return self._s[2713]! }
+ public var Checkout_PaymentMethod_New: String { return self._s[2714]! }
+ public var ShareMenu_CopyShareLinkGame: String { return self._s[2715]! }
+ public var PhotoEditor_QualityTool: String { return self._s[2716]! }
+ public var Login_SendCodeViaSms: String { return self._s[2717]! }
+ public var SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor: String { return self._s[2718]! }
+ public var Chat_SlowmodeAttachmentLimitReached: String { return self._s[2719]! }
+ public var Wallet_Receive_CopyAddress: String { return self._s[2720]! }
+ public var Login_EmailNotConfiguredError: String { return self._s[2721]! }
+ public var SocksProxySetup_Status: String { return self._s[2722]! }
+ public var Conversation_ScheduleMessage_SendWhenOnline: String { return self._s[2723]! }
+ public var PrivacyPolicy_Accept: String { return self._s[2724]! }
+ public var Notifications_ExceptionsMessagePlaceholder: String { return self._s[2725]! }
+ public var Appearance_AppIconClassicX: String { return self._s[2726]! }
public func PUSH_CHAT_MESSAGE_TEXT(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2719]!, self._r[2719]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[2727]!, self._r[2727]!, [_1, _2, _3])
}
- public var OwnershipTransfer_SecurityRequirements: String { return self._s[2720]! }
- public var InfoPlist_NSLocationAlwaysUsageDescription: String { return self._s[2722]! }
- public var AutoNightTheme_Automatic: String { return self._s[2723]! }
- public var Channel_Username_InvalidStartsWithNumber: String { return self._s[2724]! }
- public var Privacy_ContactsSyncHelp: String { return self._s[2725]! }
- public var Cache_Help: String { return self._s[2726]! }
- public var Group_ErrorAccessDenied: String { return self._s[2727]! }
- public var Passport_Language_fa: String { return self._s[2728]! }
- public var Wallet_Intro_Text: String { return self._s[2729]! }
- public var Login_ResetAccountProtected_TimerTitle: String { return self._s[2730]! }
- public var VoiceOver_Chat_YourVideoMessage: String { return self._s[2731]! }
- public var PrivacySettings_LastSeen: String { return self._s[2732]! }
+ public var OwnershipTransfer_SecurityRequirements: String { return self._s[2728]! }
+ public var InfoPlist_NSLocationAlwaysUsageDescription: String { return self._s[2730]! }
+ public var AutoNightTheme_Automatic: String { return self._s[2731]! }
+ public var Channel_Username_InvalidStartsWithNumber: String { return self._s[2732]! }
+ public var Privacy_ContactsSyncHelp: String { return self._s[2733]! }
+ public var Cache_Help: String { return self._s[2734]! }
+ public var Group_ErrorAccessDenied: String { return self._s[2735]! }
+ public var Passport_Language_fa: String { return self._s[2736]! }
+ public var Wallet_Intro_Text: String { return self._s[2737]! }
+ public var Login_ResetAccountProtected_TimerTitle: String { return self._s[2738]! }
+ public var VoiceOver_Chat_YourVideoMessage: String { return self._s[2739]! }
+ public var PrivacySettings_LastSeen: String { return self._s[2740]! }
public func DialogList_MultipleTyping(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2733]!, self._r[2733]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[2741]!, self._r[2741]!, [_0, _1])
}
- public var Wallet_Configuration_Apply: String { return self._s[2737]! }
- public var Preview_SaveGif: String { return self._s[2738]! }
- public var SettingsSearch_Synonyms_Privacy_TwoStepAuth: String { return self._s[2739]! }
- public var Profile_About: String { return self._s[2740]! }
- public var Channel_About_Placeholder: String { return self._s[2741]! }
- public var Login_InfoTitle: String { return self._s[2742]! }
+ public var Wallet_Configuration_Apply: String { return self._s[2745]! }
+ public var Preview_SaveGif: String { return self._s[2746]! }
+ public var SettingsSearch_Synonyms_Privacy_TwoStepAuth: String { return self._s[2747]! }
+ public var Profile_About: String { return self._s[2748]! }
+ public var Channel_About_Placeholder: String { return self._s[2749]! }
+ public var Login_InfoTitle: String { return self._s[2750]! }
public func TwoStepAuth_SetupPendingEmail(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2743]!, self._r[2743]!, [_0])
+ return formatWithArgumentRanges(self._s[2751]!, self._r[2751]!, [_0])
}
- public var EditTheme_Expand_Preview_IncomingReplyText: String { return self._s[2744]! }
- public var Watch_Suggestion_CantTalk: String { return self._s[2746]! }
- public var ContactInfo_Title: String { return self._s[2747]! }
- public var Media_ShareThisVideo: String { return self._s[2748]! }
- public var Weekday_ShortFriday: String { return self._s[2749]! }
- public var AccessDenied_Contacts: String { return self._s[2751]! }
- public var Notification_CallIncomingShort: String { return self._s[2752]! }
- public var Group_Setup_TypePublic: String { return self._s[2753]! }
- public var Notifications_MessageNotificationsExceptions: String { return self._s[2754]! }
- public var Notifications_Badge_IncludeChannels: String { return self._s[2755]! }
- public var Notifications_MessageNotificationsPreview: String { return self._s[2758]! }
- public var ConversationProfile_ErrorCreatingConversation: String { return self._s[2759]! }
- public var Group_ErrorAddTooMuchBots: String { return self._s[2760]! }
- public var Privacy_GroupsAndChannels_CustomShareHelp: String { return self._s[2761]! }
- public var Permissions_CellularDataAllowInSettings_v0: String { return self._s[2762]! }
+ public var EditTheme_Expand_Preview_IncomingReplyText: String { return self._s[2752]! }
+ public var Watch_Suggestion_CantTalk: String { return self._s[2754]! }
+ public var ContactInfo_Title: String { return self._s[2755]! }
+ public var Media_ShareThisVideo: String { return self._s[2756]! }
+ public var Weekday_ShortFriday: String { return self._s[2757]! }
+ public var AccessDenied_Contacts: String { return self._s[2759]! }
+ public var Notification_CallIncomingShort: String { return self._s[2760]! }
+ public var Group_Setup_TypePublic: String { return self._s[2761]! }
+ public var Notifications_MessageNotificationsExceptions: String { return self._s[2762]! }
+ public var Notifications_Badge_IncludeChannels: String { return self._s[2763]! }
+ public var Notifications_MessageNotificationsPreview: String { return self._s[2766]! }
+ public var ConversationProfile_ErrorCreatingConversation: String { return self._s[2767]! }
+ public var Group_ErrorAddTooMuchBots: String { return self._s[2768]! }
+ public var Privacy_GroupsAndChannels_CustomShareHelp: String { return self._s[2769]! }
+ public var Permissions_CellularDataAllowInSettings_v0: String { return self._s[2770]! }
public func Wallet_SecureStorageChanged_BiometryText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2763]!, self._r[2763]!, [_0])
+ return formatWithArgumentRanges(self._s[2771]!, self._r[2771]!, [_0])
}
- public var DialogList_Typing: String { return self._s[2764]! }
- public var CallFeedback_IncludeLogs: String { return self._s[2766]! }
- public var Checkout_Phone: String { return self._s[2768]! }
- public var Login_InfoFirstNamePlaceholder: String { return self._s[2771]! }
- public var Privacy_Calls_Integration: String { return self._s[2772]! }
- public var Notifications_PermissionsAllow: String { return self._s[2773]! }
- public var TwoStepAuth_AddHintDescription: String { return self._s[2777]! }
- public var Settings_ChatSettings: String { return self._s[2778]! }
- public var Conversation_SendingOptionsTooltip: String { return self._s[2779]! }
+ public var DialogList_Typing: String { return self._s[2772]! }
+ public var CallFeedback_IncludeLogs: String { return self._s[2774]! }
+ public var Checkout_Phone: String { return self._s[2776]! }
+ public var Login_InfoFirstNamePlaceholder: String { return self._s[2779]! }
+ public var Privacy_Calls_Integration: String { return self._s[2780]! }
+ public var Notifications_PermissionsAllow: String { return self._s[2781]! }
+ public var TwoStepAuth_AddHintDescription: String { return self._s[2786]! }
+ public var Settings_ChatSettings: String { return self._s[2787]! }
+ public var Conversation_SendingOptionsTooltip: String { return self._s[2788]! }
public func UserInfo_StartSecretChatConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2781]!, self._r[2781]!, [_0])
+ return formatWithArgumentRanges(self._s[2790]!, self._r[2790]!, [_0])
}
public func Channel_AdminLog_MessageInvitedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2782]!, self._r[2782]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2791]!, self._r[2791]!, [_1, _2])
}
- public var GroupRemoved_DeleteUser: String { return self._s[2784]! }
+ public var GroupRemoved_DeleteUser: String { return self._s[2793]! }
public func Channel_AdminLog_PollStopped(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2785]!, self._r[2785]!, [_0])
+ return formatWithArgumentRanges(self._s[2794]!, self._r[2794]!, [_0])
}
public func PUSH_MESSAGE_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2786]!, self._r[2786]!, [_1])
+ return formatWithArgumentRanges(self._s[2795]!, self._r[2795]!, [_1])
}
- public var Login_ContinueWithLocalization: String { return self._s[2787]! }
- public var Watch_Message_ForwardedFrom: String { return self._s[2788]! }
- public var TwoStepAuth_EnterEmailCode: String { return self._s[2790]! }
- public var Conversation_Unblock: String { return self._s[2791]! }
- public var PrivacySettings_DataSettings: String { return self._s[2792]! }
- public var WallpaperPreview_PatternPaternApply: String { return self._s[2793]! }
- public var Group_PublicLink_Info: String { return self._s[2794]! }
+ public var Login_ContinueWithLocalization: String { return self._s[2796]! }
+ public var Watch_Message_ForwardedFrom: String { return self._s[2797]! }
+ public var TwoStepAuth_EnterEmailCode: String { return self._s[2799]! }
+ public var Conversation_Unblock: String { return self._s[2800]! }
+ public var PrivacySettings_DataSettings: String { return self._s[2801]! }
+ public var WallpaperPreview_PatternPaternApply: String { return self._s[2802]! }
+ public var Group_PublicLink_Info: String { return self._s[2803]! }
public func Wallet_Time_PreciseDate_m1(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2795]!, self._r[2795]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[2804]!, self._r[2804]!, [_1, _2, _3])
}
- public var Notifications_InAppNotificationsVibrate: String { return self._s[2796]! }
+ public var Notifications_InAppNotificationsVibrate: String { return self._s[2805]! }
public func Privacy_GroupsAndChannels_InviteToChannelError(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2797]!, self._r[2797]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[2806]!, self._r[2806]!, [_0, _1])
}
- public var OldChannels_ChannelsHeader: String { return self._s[2799]! }
- public var Wallet_RestoreFailed_CreateWallet: String { return self._s[2800]! }
- public var PrivacySettings_Passcode: String { return self._s[2802]! }
- public var Call_Mute: String { return self._s[2803]! }
- public var Wallet_Weekday_Yesterday: String { return self._s[2804]! }
- public var Passport_Language_dz: String { return self._s[2805]! }
- public var Wallet_Receive_AmountHeader: String { return self._s[2806]! }
- public var Wallet_TransactionInfo_OtherFeeInfoUrl: String { return self._s[2807]! }
- public var Passport_Language_tk: String { return self._s[2808]! }
+ public var OldChannels_ChannelsHeader: String { return self._s[2808]! }
+ public var Wallet_RestoreFailed_CreateWallet: String { return self._s[2809]! }
+ public var PrivacySettings_Passcode: String { return self._s[2811]! }
+ public var Call_Mute: String { return self._s[2812]! }
+ public var Wallet_Weekday_Yesterday: String { return self._s[2813]! }
+ public var Passport_Language_dz: String { return self._s[2814]! }
+ public var Wallet_Receive_AmountHeader: String { return self._s[2815]! }
+ public var Wallet_TransactionInfo_OtherFeeInfoUrl: String { return self._s[2816]! }
+ public var Passport_Language_tk: String { return self._s[2817]! }
public func Login_EmailCodeSubject(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2809]!, self._r[2809]!, [_0])
+ return formatWithArgumentRanges(self._s[2818]!, self._r[2818]!, [_0])
}
- public var Settings_Search: String { return self._s[2810]! }
- public var Wallet_Month_ShortFebruary: String { return self._s[2811]! }
- public var InfoPlist_NSPhotoLibraryUsageDescription: String { return self._s[2812]! }
- public var Wallet_Configuration_SourceJSON: String { return self._s[2813]! }
- public var Conversation_ContextMenuReply: String { return self._s[2814]! }
- public var WallpaperSearch_ColorBrown: String { return self._s[2815]! }
- public var Chat_AttachmentMultipleForwardDisabled: String { return self._s[2816]! }
- public var Tour_Title1: String { return self._s[2817]! }
- public var Wallet_Alert_Cancel: String { return self._s[2818]! }
- public var Conversation_ClearGroupHistory: String { return self._s[2820]! }
- public var Wallet_TransactionInfo_RecipientHeader: String { return self._s[2821]! }
- public var WallpaperPreview_Motion: String { return self._s[2822]! }
+ public var Settings_Search: String { return self._s[2819]! }
+ public var Wallet_Month_ShortFebruary: String { return self._s[2820]! }
+ public var InfoPlist_NSPhotoLibraryUsageDescription: String { return self._s[2821]! }
+ public var Wallet_Configuration_SourceJSON: String { return self._s[2822]! }
+ public var Conversation_ContextMenuReply: String { return self._s[2823]! }
+ public var WallpaperSearch_ColorBrown: String { return self._s[2824]! }
+ public var Chat_AttachmentMultipleForwardDisabled: String { return self._s[2825]! }
+ public var Tour_Title1: String { return self._s[2826]! }
+ public var Wallet_Alert_Cancel: String { return self._s[2827]! }
+ public var Conversation_ClearGroupHistory: String { return self._s[2829]! }
+ public var Wallet_TransactionInfo_RecipientHeader: String { return self._s[2830]! }
+ public var WallpaperPreview_Motion: String { return self._s[2831]! }
public func Checkout_PasswordEntry_Text(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2823]!, self._r[2823]!, [_0])
- }
- public var Wallet_Configuration_ApplyErrorTextJSONInvalidData: String { return self._s[2824]! }
- public var Call_RateCall: String { return self._s[2825]! }
- public var Channel_AdminLog_BanSendStickersAndGifs: String { return self._s[2826]! }
- public var Passport_PasswordCompleteSetup: String { return self._s[2827]! }
- public var Conversation_InputTextSilentBroadcastPlaceholder: String { return self._s[2828]! }
- public var UserInfo_LastNamePlaceholder: String { return self._s[2830]! }
- public func Login_WillCallYou(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[2832]!, self._r[2832]!, [_0])
}
- public var Compose_Create: String { return self._s[2833]! }
- public var Contacts_InviteToTelegram: String { return self._s[2834]! }
- public var GroupInfo_Notifications: String { return self._s[2835]! }
- public var ChatList_DeleteSavedMessagesConfirmationAction: String { return self._s[2837]! }
- public var Message_PinnedLiveLocationMessage: String { return self._s[2838]! }
- public var Month_GenApril: String { return self._s[2839]! }
- public var Appearance_AutoNightTheme: String { return self._s[2840]! }
- public var ChatSettings_AutomaticAudioDownload: String { return self._s[2842]! }
- public var Login_CodeSentSms: String { return self._s[2844]! }
+ public var Wallet_Configuration_ApplyErrorTextJSONInvalidData: String { return self._s[2833]! }
+ public var Call_RateCall: String { return self._s[2834]! }
+ public var Channel_AdminLog_BanSendStickersAndGifs: String { return self._s[2835]! }
+ public var Passport_PasswordCompleteSetup: String { return self._s[2836]! }
+ public var Conversation_InputTextSilentBroadcastPlaceholder: String { return self._s[2837]! }
+ public var UserInfo_LastNamePlaceholder: String { return self._s[2839]! }
+ public func Login_WillCallYou(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[2841]!, self._r[2841]!, [_0])
+ }
+ public var Compose_Create: String { return self._s[2842]! }
+ public var Contacts_InviteToTelegram: String { return self._s[2843]! }
+ public var GroupInfo_Notifications: String { return self._s[2844]! }
+ public var ChatList_DeleteSavedMessagesConfirmationAction: String { return self._s[2846]! }
+ public var Message_PinnedLiveLocationMessage: String { return self._s[2847]! }
+ public var Month_GenApril: String { return self._s[2848]! }
+ public var Appearance_AutoNightTheme: String { return self._s[2849]! }
+ public var ChatSettings_AutomaticAudioDownload: String { return self._s[2851]! }
+ public var Login_CodeSentSms: String { return self._s[2853]! }
public func UserInfo_UnblockConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2845]!, self._r[2845]!, [_0])
+ return formatWithArgumentRanges(self._s[2854]!, self._r[2854]!, [_0])
}
- public var EmptyGroupInfo_Line3: String { return self._s[2846]! }
- public var LogoutOptions_ContactSupportText: String { return self._s[2847]! }
- public var Passport_Language_hr: String { return self._s[2848]! }
- public var Common_ActionNotAllowedError: String { return self._s[2849]! }
+ public var EmptyGroupInfo_Line3: String { return self._s[2855]! }
+ public var LogoutOptions_ContactSupportText: String { return self._s[2856]! }
+ public var Passport_Language_hr: String { return self._s[2857]! }
+ public var Common_ActionNotAllowedError: String { return self._s[2858]! }
public func Channel_AdminLog_MessageRestrictedNewSetting(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2850]!, self._r[2850]!, [_0])
+ return formatWithArgumentRanges(self._s[2859]!, self._r[2859]!, [_0])
}
- public var GroupInfo_InviteLink_CopyLink: String { return self._s[2851]! }
- public var Wallet_Info_TransactionFrom: String { return self._s[2852]! }
- public var Wallet_Send_ErrorDecryptionFailed: String { return self._s[2853]! }
- public var Conversation_InputTextBroadcastPlaceholder: String { return self._s[2854]! }
- public var Privacy_SecretChatsTitle: String { return self._s[2855]! }
- public var Notification_SecretChatMessageScreenshotSelf: String { return self._s[2857]! }
- public var GroupInfo_AddUserLeftError: String { return self._s[2858]! }
- public var AutoDownloadSettings_TypePrivateChats: String { return self._s[2859]! }
- public var LogoutOptions_ContactSupportTitle: String { return self._s[2860]! }
- public var Appearance_ThemePreview_Chat_7_Text: String { return self._s[2861]! }
- public var Channel_AddBotErrorHaveRights: String { return self._s[2862]! }
- public var Preview_DeleteGif: String { return self._s[2863]! }
- public var GroupInfo_Permissions_Exceptions: String { return self._s[2864]! }
- public var Group_ErrorNotMutualContact: String { return self._s[2865]! }
- public var Notification_MessageLifetime5s: String { return self._s[2866]! }
- public var Wallet_Send_OwnAddressAlertText: String { return self._s[2867]! }
- public var OldChannels_ChannelFormat: String { return self._s[2868]! }
+ public var GroupInfo_InviteLink_CopyLink: String { return self._s[2860]! }
+ public var Wallet_Info_TransactionFrom: String { return self._s[2861]! }
+ public var Wallet_Send_ErrorDecryptionFailed: String { return self._s[2862]! }
+ public var Conversation_InputTextBroadcastPlaceholder: String { return self._s[2863]! }
+ public var Privacy_SecretChatsTitle: String { return self._s[2864]! }
+ public var Notification_SecretChatMessageScreenshotSelf: String { return self._s[2866]! }
+ public var GroupInfo_AddUserLeftError: String { return self._s[2867]! }
+ public var AutoDownloadSettings_TypePrivateChats: String { return self._s[2868]! }
+ public var LogoutOptions_ContactSupportTitle: String { return self._s[2869]! }
+ public var Appearance_ThemePreview_Chat_7_Text: String { return self._s[2870]! }
+ public var Channel_AddBotErrorHaveRights: String { return self._s[2871]! }
+ public var Preview_DeleteGif: String { return self._s[2872]! }
+ public var GroupInfo_Permissions_Exceptions: String { return self._s[2873]! }
+ public var Group_ErrorNotMutualContact: String { return self._s[2874]! }
+ public var Notification_MessageLifetime5s: String { return self._s[2875]! }
+ public var Wallet_Send_OwnAddressAlertText: String { return self._s[2876]! }
+ public var OldChannels_ChannelFormat: String { return self._s[2877]! }
public func Watch_LastSeen_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2869]!, self._r[2869]!, [_0])
+ return formatWithArgumentRanges(self._s[2878]!, self._r[2878]!, [_0])
}
- public var VoiceOver_Chat_Video: String { return self._s[2870]! }
- public var Channel_OwnershipTransfer_ErrorPublicChannelsTooMuch: String { return self._s[2872]! }
- public var ReportSpam_DeleteThisChat: String { return self._s[2873]! }
- public var Passport_Address_AddBankStatement: String { return self._s[2874]! }
- public var Notification_CallIncoming: String { return self._s[2875]! }
- public var Wallet_Words_NotDoneTitle: String { return self._s[2876]! }
- public var Compose_NewGroupTitle: String { return self._s[2877]! }
- public var TwoStepAuth_RecoveryCodeHelp: String { return self._s[2879]! }
- public var Passport_Address_Postcode: String { return self._s[2881]! }
+ public var VoiceOver_Chat_Video: String { return self._s[2879]! }
+ public var Channel_OwnershipTransfer_ErrorPublicChannelsTooMuch: String { return self._s[2881]! }
+ public var ReportSpam_DeleteThisChat: String { return self._s[2882]! }
+ public var Passport_Address_AddBankStatement: String { return self._s[2883]! }
+ public var Notification_CallIncoming: String { return self._s[2884]! }
+ public var Wallet_Words_NotDoneTitle: String { return self._s[2885]! }
+ public var Compose_NewGroupTitle: String { return self._s[2886]! }
+ public var TwoStepAuth_RecoveryCodeHelp: String { return self._s[2888]! }
+ public var Passport_Address_Postcode: String { return self._s[2890]! }
public func LastSeen_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2882]!, self._r[2882]!, [_0])
+ return formatWithArgumentRanges(self._s[2891]!, self._r[2891]!, [_0])
}
- public var Checkout_NewCard_SaveInfoHelp: String { return self._s[2883]! }
- public var Wallet_Month_ShortOctober: String { return self._s[2884]! }
- public var VoiceOver_Chat_YourMusic: String { return self._s[2885]! }
- public var WallpaperColors_Title: String { return self._s[2886]! }
- public var SocksProxySetup_ShareQRCodeInfo: String { return self._s[2887]! }
- public var VoiceOver_MessageContextForward: String { return self._s[2888]! }
- public var GroupPermission_Duration: String { return self._s[2889]! }
+ public var Checkout_NewCard_SaveInfoHelp: String { return self._s[2892]! }
+ public var Wallet_Month_ShortOctober: String { return self._s[2893]! }
+ public var VoiceOver_Chat_YourMusic: String { return self._s[2894]! }
+ public var WallpaperColors_Title: String { return self._s[2895]! }
+ public var SocksProxySetup_ShareQRCodeInfo: String { return self._s[2896]! }
+ public var VoiceOver_MessageContextForward: String { return self._s[2897]! }
+ public var GroupPermission_Duration: String { return self._s[2898]! }
public func Cache_Clear(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2890]!, self._r[2890]!, [_0])
+ return formatWithArgumentRanges(self._s[2899]!, self._r[2899]!, [_0])
}
- public var Bot_GroupStatusDoesNotReadHistory: String { return self._s[2891]! }
- public var Username_Placeholder: String { return self._s[2892]! }
- public var CallFeedback_WhatWentWrong: String { return self._s[2893]! }
- public var Passport_FieldAddressUploadHelp: String { return self._s[2894]! }
- public var Permissions_NotificationsAllowInSettings_v0: String { return self._s[2895]! }
+ public var Bot_GroupStatusDoesNotReadHistory: String { return self._s[2900]! }
+ public var Username_Placeholder: String { return self._s[2901]! }
+ public var CallFeedback_WhatWentWrong: String { return self._s[2902]! }
+ public var Passport_FieldAddressUploadHelp: String { return self._s[2903]! }
+ public var Permissions_NotificationsAllowInSettings_v0: String { return self._s[2904]! }
public func Channel_AdminLog_MessageChangedUnlinkedChannel(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2897]!, self._r[2897]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2906]!, self._r[2906]!, [_1, _2])
}
- public var Passport_PasswordDescription: String { return self._s[2898]! }
- public var Channel_MessagePhotoUpdated: String { return self._s[2899]! }
- public var MediaPicker_TapToUngroupDescription: String { return self._s[2900]! }
- public var SettingsSearch_Synonyms_Notifications_BadgeCountUnreadMessages: String { return self._s[2901]! }
- public var AttachmentMenu_PhotoOrVideo: String { return self._s[2902]! }
- public var Conversation_ContextMenuMore: String { return self._s[2903]! }
- public var Privacy_PaymentsClearInfo: String { return self._s[2904]! }
- public var CallSettings_TabIcon: String { return self._s[2905]! }
- public var KeyCommand_Find: String { return self._s[2906]! }
- public var ClearCache_FreeSpaceDescription: String { return self._s[2907]! }
- public var Appearance_ThemePreview_ChatList_7_Text: String { return self._s[2908]! }
- public var EditTheme_Edit_Preview_IncomingText: String { return self._s[2909]! }
- public var Message_PinnedGame: String { return self._s[2910]! }
- public var VoiceOver_Chat_ForwardedFromYou: String { return self._s[2911]! }
- public var Notifications_Badge_CountUnreadMessages_InfoOff: String { return self._s[2913]! }
- public var Login_CallRequestState2: String { return self._s[2915]! }
- public var CheckoutInfo_ReceiverInfoNamePlaceholder: String { return self._s[2917]! }
+ public var Passport_PasswordDescription: String { return self._s[2907]! }
+ public var Channel_MessagePhotoUpdated: String { return self._s[2908]! }
+ public var MediaPicker_TapToUngroupDescription: String { return self._s[2909]! }
+ public var SettingsSearch_Synonyms_Notifications_BadgeCountUnreadMessages: String { return self._s[2910]! }
+ public var AttachmentMenu_PhotoOrVideo: String { return self._s[2911]! }
+ public var Conversation_ContextMenuMore: String { return self._s[2912]! }
+ public var Privacy_PaymentsClearInfo: String { return self._s[2913]! }
+ public var CallSettings_TabIcon: String { return self._s[2914]! }
+ public var KeyCommand_Find: String { return self._s[2915]! }
+ public var ClearCache_FreeSpaceDescription: String { return self._s[2916]! }
+ public var Appearance_ThemePreview_ChatList_7_Text: String { return self._s[2917]! }
+ public var EditTheme_Edit_Preview_IncomingText: String { return self._s[2918]! }
+ public var Message_PinnedGame: String { return self._s[2919]! }
+ public var VoiceOver_Chat_ForwardedFromYou: String { return self._s[2920]! }
+ public var Notifications_Badge_CountUnreadMessages_InfoOff: String { return self._s[2922]! }
+ public var Login_CallRequestState2: String { return self._s[2924]! }
+ public var CheckoutInfo_ReceiverInfoNamePlaceholder: String { return self._s[2926]! }
public func VoiceOver_Chat_PhotoFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2918]!, self._r[2918]!, [_0])
+ return formatWithArgumentRanges(self._s[2927]!, self._r[2927]!, [_0])
}
public func Checkout_PayPrice(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2920]!, self._r[2920]!, [_0])
+ return formatWithArgumentRanges(self._s[2929]!, self._r[2929]!, [_0])
}
- public var AuthSessions_AddDevice: String { return self._s[2921]! }
- public var WallpaperPreview_Blurred: String { return self._s[2922]! }
- public var Conversation_InstantPagePreview: String { return self._s[2923]! }
+ public var AuthSessions_AddDevice: String { return self._s[2930]! }
+ public var WallpaperPreview_Blurred: String { return self._s[2931]! }
+ public var Conversation_InstantPagePreview: String { return self._s[2932]! }
public func DialogList_SingleUploadingVideoSuffix(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2924]!, self._r[2924]!, [_0])
+ return formatWithArgumentRanges(self._s[2933]!, self._r[2933]!, [_0])
}
- public var SecretTimer_VideoDescription: String { return self._s[2927]! }
- public var WallpaperSearch_ColorRed: String { return self._s[2928]! }
- public var GroupPermission_NoPinMessages: String { return self._s[2929]! }
- public var Passport_Language_es: String { return self._s[2930]! }
- public var Permissions_ContactsAllow_v0: String { return self._s[2932]! }
- public var Conversation_EditingMessageMediaEditCurrentVideo: String { return self._s[2933]! }
+ public var SecretTimer_VideoDescription: String { return self._s[2936]! }
+ public var WallpaperSearch_ColorRed: String { return self._s[2937]! }
+ public var GroupPermission_NoPinMessages: String { return self._s[2938]! }
+ public var Passport_Language_es: String { return self._s[2939]! }
+ public var Permissions_ContactsAllow_v0: String { return self._s[2941]! }
+ public var Conversation_EditingMessageMediaEditCurrentVideo: String { return self._s[2942]! }
public func PUSH_CHAT_MESSAGE_CONTACT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2934]!, self._r[2934]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[2943]!, self._r[2943]!, [_1, _2])
}
- public var Privacy_Forwards_CustomHelp: String { return self._s[2935]! }
- public var WebPreview_GettingLinkInfo: String { return self._s[2936]! }
- public var Watch_UserInfo_Unmute: String { return self._s[2937]! }
- public var GroupInfo_ChannelListNamePlaceholder: String { return self._s[2938]! }
- public var AccessDenied_CameraRestricted: String { return self._s[2940]! }
+ public var Privacy_Forwards_CustomHelp: String { return self._s[2944]! }
+ public var WebPreview_GettingLinkInfo: String { return self._s[2945]! }
+ public var Watch_UserInfo_Unmute: String { return self._s[2946]! }
+ public var GroupInfo_ChannelListNamePlaceholder: String { return self._s[2947]! }
+ public var AccessDenied_CameraRestricted: String { return self._s[2949]! }
public func Conversation_Kilobytes(_ _0: Int) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2941]!, self._r[2941]!, ["\(_0)"])
+ return formatWithArgumentRanges(self._s[2950]!, self._r[2950]!, ["\(_0)"])
}
- public var ChatList_ReadAll: String { return self._s[2943]! }
- public var Settings_CopyUsername: String { return self._s[2944]! }
- public var Contacts_SearchLabel: String { return self._s[2945]! }
- public var Map_OpenInYandexNavigator: String { return self._s[2947]! }
- public var PasscodeSettings_EncryptData: String { return self._s[2948]! }
- public var Settings_Wallet: String { return self._s[2949]! }
- public var Group_ErrorSupergroupConversionNotPossible: String { return self._s[2950]! }
- public var WallpaperSearch_ColorPrefix: String { return self._s[2951]! }
- public var Notifications_GroupNotificationsPreview: String { return self._s[2952]! }
- public var DialogList_AdNoticeAlert: String { return self._s[2953]! }
- public var Wallet_Month_GenMay: String { return self._s[2955]! }
- public var CheckoutInfo_ShippingInfoAddress1: String { return self._s[2956]! }
- public var CheckoutInfo_ShippingInfoAddress2: String { return self._s[2957]! }
- public var Localization_LanguageCustom: String { return self._s[2958]! }
- public var Passport_Identity_TypeDriversLicenseUploadScan: String { return self._s[2959]! }
- public var CallFeedback_Title: String { return self._s[2960]! }
- public var VoiceOver_Chat_RecordPreviewVoiceMessage: String { return self._s[2963]! }
- public var Passport_Address_OneOfTypePassportRegistration: String { return self._s[2964]! }
- public var Wallet_Intro_CreateErrorTitle: String { return self._s[2965]! }
- public var Conversation_InfoGroup: String { return self._s[2966]! }
- public var Compose_NewMessage: String { return self._s[2967]! }
- public var FastTwoStepSetup_HintPlaceholder: String { return self._s[2968]! }
- public var ChatSettings_AutoDownloadVideoMessages: String { return self._s[2969]! }
- public var Wallet_SecureStorageReset_BiometryFaceId: String { return self._s[2970]! }
- public var Channel_DiscussionGroup_UnlinkChannel: String { return self._s[2971]! }
+ public var ChatList_ReadAll: String { return self._s[2952]! }
+ public var Settings_CopyUsername: String { return self._s[2953]! }
+ public var Contacts_SearchLabel: String { return self._s[2954]! }
+ public var Map_OpenInYandexNavigator: String { return self._s[2956]! }
+ public var PasscodeSettings_EncryptData: String { return self._s[2957]! }
+ public var Settings_Wallet: String { return self._s[2958]! }
+ public var Group_ErrorSupergroupConversionNotPossible: String { return self._s[2959]! }
+ public var WallpaperSearch_ColorPrefix: String { return self._s[2960]! }
+ public var Notifications_GroupNotificationsPreview: String { return self._s[2961]! }
+ public var DialogList_AdNoticeAlert: String { return self._s[2962]! }
+ public var Wallet_Month_GenMay: String { return self._s[2964]! }
+ public var CheckoutInfo_ShippingInfoAddress1: String { return self._s[2965]! }
+ public var CheckoutInfo_ShippingInfoAddress2: String { return self._s[2966]! }
+ public var Localization_LanguageCustom: String { return self._s[2967]! }
+ public var Passport_Identity_TypeDriversLicenseUploadScan: String { return self._s[2968]! }
+ public var CallFeedback_Title: String { return self._s[2969]! }
+ public var VoiceOver_Chat_RecordPreviewVoiceMessage: String { return self._s[2972]! }
+ public var Passport_Address_OneOfTypePassportRegistration: String { return self._s[2973]! }
+ public var Wallet_Intro_CreateErrorTitle: String { return self._s[2974]! }
+ public var Conversation_InfoGroup: String { return self._s[2975]! }
+ public var Compose_NewMessage: String { return self._s[2976]! }
+ public var FastTwoStepSetup_HintPlaceholder: String { return self._s[2977]! }
+ public var ChatSettings_AutoDownloadVideoMessages: String { return self._s[2978]! }
+ public var Wallet_SecureStorageReset_BiometryFaceId: String { return self._s[2979]! }
+ public var Channel_DiscussionGroup_UnlinkChannel: String { return self._s[2980]! }
public func Passport_Scans_ScanIndex(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2972]!, self._r[2972]!, [_0])
+ return formatWithArgumentRanges(self._s[2981]!, self._r[2981]!, [_0])
}
- public var Channel_AdminLog_CanDeleteMessages: String { return self._s[2973]! }
- public var Login_CancelSignUpConfirmation: String { return self._s[2974]! }
- public var ChangePhoneNumberCode_Help: String { return self._s[2975]! }
- public var PrivacySettings_DeleteAccountHelp: String { return self._s[2976]! }
- public var Channel_BlackList_Title: String { return self._s[2977]! }
- public var UserInfo_PhoneCall: String { return self._s[2978]! }
- public var Passport_Address_OneOfTypeBankStatement: String { return self._s[2980]! }
- public var Wallet_Month_ShortJanuary: String { return self._s[2981]! }
- public var State_connecting: String { return self._s[2982]! }
- public var Appearance_ThemePreview_ChatList_6_Text: String { return self._s[2983]! }
- public var Wallet_Month_GenMarch: String { return self._s[2984]! }
- public var EditTheme_Expand_BottomInfo: String { return self._s[2985]! }
- public var AuthSessions_AddedDeviceTerminate: String { return self._s[2986]! }
+ public var Channel_AdminLog_CanDeleteMessages: String { return self._s[2982]! }
+ public var Login_CancelSignUpConfirmation: String { return self._s[2983]! }
+ public var ChangePhoneNumberCode_Help: String { return self._s[2984]! }
+ public var PrivacySettings_DeleteAccountHelp: String { return self._s[2985]! }
+ public var Channel_BlackList_Title: String { return self._s[2986]! }
+ public var UserInfo_PhoneCall: String { return self._s[2987]! }
+ public var Passport_Address_OneOfTypeBankStatement: String { return self._s[2989]! }
+ public var Wallet_Month_ShortJanuary: String { return self._s[2990]! }
+ public var State_connecting: String { return self._s[2991]! }
+ public var Appearance_ThemePreview_ChatList_6_Text: String { return self._s[2992]! }
+ public var Wallet_Month_GenMarch: String { return self._s[2993]! }
+ public var EditTheme_Expand_BottomInfo: String { return self._s[2994]! }
+ public var AuthSessions_AddedDeviceTerminate: String { return self._s[2995]! }
public func LastSeen_TodayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2987]!, self._r[2987]!, [_0])
+ return formatWithArgumentRanges(self._s[2996]!, self._r[2996]!, [_0])
}
public func DialogList_SingleRecordingAudioSuffix(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[2988]!, self._r[2988]!, [_0])
+ return formatWithArgumentRanges(self._s[2997]!, self._r[2997]!, [_0])
}
- public var Notifications_GroupNotifications: String { return self._s[2989]! }
- public var Conversation_SendMessageErrorTooMuchScheduled: String { return self._s[2990]! }
- public var Passport_Identity_EditPassport: String { return self._s[2991]! }
- public var EnterPasscode_RepeatNewPasscode: String { return self._s[2993]! }
- public var Localization_EnglishLanguageName: String { return self._s[2994]! }
- public var Share_AuthDescription: String { return self._s[2995]! }
- public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsAlert: String { return self._s[2996]! }
- public var Passport_Identity_Surname: String { return self._s[2997]! }
- public var Compose_TokenListPlaceholder: String { return self._s[2998]! }
- public var Wallet_AccessDenied_Camera: String { return self._s[2999]! }
- public var Passport_Identity_OneOfTypePassport: String { return self._s[3000]! }
- public var Settings_AboutEmpty: String { return self._s[3001]! }
- public var Conversation_Unmute: String { return self._s[3002]! }
- public var CreateGroup_ChannelsTooMuch: String { return self._s[3004]! }
- public var Wallet_Sending_Text: String { return self._s[3005]! }
+ public var Notifications_GroupNotifications: String { return self._s[2998]! }
+ public var Conversation_SendMessageErrorTooMuchScheduled: String { return self._s[2999]! }
+ public var Passport_Identity_EditPassport: String { return self._s[3000]! }
+ public var EnterPasscode_RepeatNewPasscode: String { return self._s[3002]! }
+ public var Localization_EnglishLanguageName: String { return self._s[3003]! }
+ public var Share_AuthDescription: String { return self._s[3004]! }
+ public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsAlert: String { return self._s[3005]! }
+ public var Passport_Identity_Surname: String { return self._s[3006]! }
+ public var Compose_TokenListPlaceholder: String { return self._s[3007]! }
+ public var Wallet_AccessDenied_Camera: String { return self._s[3008]! }
+ public var Passport_Identity_OneOfTypePassport: String { return self._s[3009]! }
+ public var Settings_AboutEmpty: String { return self._s[3010]! }
+ public var Conversation_Unmute: String { return self._s[3011]! }
+ public var CreateGroup_ChannelsTooMuch: String { return self._s[3013]! }
+ public var Wallet_Sending_Text: String { return self._s[3014]! }
public func PUSH_CONTACT_JOINED(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3006]!, self._r[3006]!, [_1])
+ return formatWithArgumentRanges(self._s[3015]!, self._r[3015]!, [_1])
}
- public var Login_CodeSentCall: String { return self._s[3007]! }
- public var ContactInfo_PhoneLabelHomeFax: String { return self._s[3009]! }
- public var ChatSettings_Appearance: String { return self._s[3010]! }
- public var ClearCache_StorageUsage: String { return self._s[3011]! }
- public var Appearance_PickAccentColor: String { return self._s[3012]! }
+ public var Login_CodeSentCall: String { return self._s[3016]! }
+ public var ContactInfo_PhoneLabelHomeFax: String { return self._s[3018]! }
+ public var ChatSettings_Appearance: String { return self._s[3019]! }
+ public var ClearCache_StorageUsage: String { return self._s[3020]! }
+ public var Appearance_PickAccentColor: String { return self._s[3021]! }
public func PUSH_CHAT_MESSAGE_NOTEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3013]!, self._r[3013]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3022]!, self._r[3022]!, [_1, _2])
}
public func PUSH_MESSAGE_GEO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3014]!, self._r[3014]!, [_1])
+ return formatWithArgumentRanges(self._s[3023]!, self._r[3023]!, [_1])
}
- public var Notification_CallMissed: String { return self._s[3015]! }
- public var SettingsSearch_Synonyms_Appearance_ChatBackground_Custom: String { return self._s[3016]! }
- public var Channel_AdminLogFilter_EventsInfo: String { return self._s[3017]! }
- public var Wallet_Month_GenOctober: String { return self._s[3019]! }
- public var ChatAdmins_AdminLabel: String { return self._s[3020]! }
- public var KeyCommand_JumpToNextChat: String { return self._s[3021]! }
- public var Conversation_StopPollConfirmationTitle: String { return self._s[3023]! }
- public var ChangePhoneNumberCode_CodePlaceholder: String { return self._s[3024]! }
- public var Month_GenJune: String { return self._s[3025]! }
- public var IntentsSettings_MainAccountInfo: String { return self._s[3026]! }
- public var Watch_Location_Current: String { return self._s[3027]! }
- public var Wallet_Receive_CopyInvoiceUrl: String { return self._s[3028]! }
- public var Conversation_TitleMute: String { return self._s[3029]! }
- public var Map_PlacesInThisArea: String { return self._s[3030]! }
+ public var Notification_CallMissed: String { return self._s[3024]! }
+ public var SettingsSearch_Synonyms_Appearance_ChatBackground_Custom: String { return self._s[3025]! }
+ public var Channel_AdminLogFilter_EventsInfo: String { return self._s[3026]! }
+ public var Wallet_Month_GenOctober: String { return self._s[3028]! }
+ public var ChatAdmins_AdminLabel: String { return self._s[3029]! }
+ public var KeyCommand_JumpToNextChat: String { return self._s[3030]! }
+ public var Conversation_StopPollConfirmationTitle: String { return self._s[3032]! }
+ public var ChangePhoneNumberCode_CodePlaceholder: String { return self._s[3033]! }
+ public var Month_GenJune: String { return self._s[3034]! }
+ public var IntentsSettings_MainAccountInfo: String { return self._s[3035]! }
+ public var Watch_Location_Current: String { return self._s[3036]! }
+ public var Wallet_Receive_CopyInvoiceUrl: String { return self._s[3037]! }
+ public var Conversation_TitleMute: String { return self._s[3038]! }
+ public var Map_PlacesInThisArea: String { return self._s[3039]! }
public func PUSH_CHANNEL_MESSAGE_ROUND(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3031]!, self._r[3031]!, [_1])
+ return formatWithArgumentRanges(self._s[3040]!, self._r[3040]!, [_1])
}
- public var GroupInfo_DeleteAndExit: String { return self._s[3032]! }
+ public var GroupInfo_DeleteAndExit: String { return self._s[3041]! }
public func Conversation_Moderate_DeleteAllMessages(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3033]!, self._r[3033]!, [_0])
+ return formatWithArgumentRanges(self._s[3042]!, self._r[3042]!, [_0])
}
- public var Call_ReportPlaceholder: String { return self._s[3034]! }
- public var Chat_SlowmodeSendError: String { return self._s[3035]! }
- public var MaskStickerSettings_Info: String { return self._s[3036]! }
- public var EditTheme_Expand_TopInfo: String { return self._s[3037]! }
+ public var Call_ReportPlaceholder: String { return self._s[3043]! }
+ public var Chat_SlowmodeSendError: String { return self._s[3044]! }
+ public var MaskStickerSettings_Info: String { return self._s[3045]! }
+ public var EditTheme_Expand_TopInfo: String { return self._s[3046]! }
public func GroupInfo_AddParticipantConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3038]!, self._r[3038]!, [_0])
+ return formatWithArgumentRanges(self._s[3047]!, self._r[3047]!, [_0])
}
- public var Checkout_NewCard_PostcodeTitle: String { return self._s[3039]! }
- public var Passport_Address_RegionPlaceholder: String { return self._s[3041]! }
- public var Contacts_ShareTelegram: String { return self._s[3042]! }
- public var EnterPasscode_EnterNewPasscodeNew: String { return self._s[3043]! }
- public var Map_AddressOnMap: String { return self._s[3044]! }
- public var Channel_ErrorAccessDenied: String { return self._s[3045]! }
- public var UserInfo_ScamBotWarning: String { return self._s[3047]! }
- public var Stickers_GroupChooseStickerPack: String { return self._s[3048]! }
- public var Call_ConnectionErrorTitle: String { return self._s[3049]! }
- public var UserInfo_NotificationsEnable: String { return self._s[3050]! }
- public var ArchivedChats_IntroText1: String { return self._s[3051]! }
- public var Tour_Text4: String { return self._s[3054]! }
- public var WallpaperSearch_Recent: String { return self._s[3055]! }
- public var GroupInfo_ScamGroupWarning: String { return self._s[3056]! }
- public var Profile_MessageLifetime2s: String { return self._s[3058]! }
- public var Appearance_ThemePreview_ChatList_5_Text: String { return self._s[3059]! }
- public var Notification_MessageLifetime2s: String { return self._s[3060]! }
+ public var Checkout_NewCard_PostcodeTitle: String { return self._s[3048]! }
+ public var Passport_Address_RegionPlaceholder: String { return self._s[3050]! }
+ public var Contacts_ShareTelegram: String { return self._s[3051]! }
+ public var EnterPasscode_EnterNewPasscodeNew: String { return self._s[3052]! }
+ public var Map_AddressOnMap: String { return self._s[3053]! }
+ public var Channel_ErrorAccessDenied: String { return self._s[3054]! }
+ public var UserInfo_ScamBotWarning: String { return self._s[3056]! }
+ public var Stickers_GroupChooseStickerPack: String { return self._s[3057]! }
+ public var Call_ConnectionErrorTitle: String { return self._s[3058]! }
+ public var UserInfo_NotificationsEnable: String { return self._s[3059]! }
+ public var ArchivedChats_IntroText1: String { return self._s[3060]! }
+ public var Tour_Text4: String { return self._s[3063]! }
+ public var WallpaperSearch_Recent: String { return self._s[3064]! }
+ public var GroupInfo_ScamGroupWarning: String { return self._s[3065]! }
+ public var PeopleNearby_MakeVisibleTitle: String { return self._s[3066]! }
+ public var Profile_MessageLifetime2s: String { return self._s[3068]! }
+ public var Appearance_ThemePreview_ChatList_5_Text: String { return self._s[3069]! }
+ public var Notification_MessageLifetime2s: String { return self._s[3070]! }
public func Time_PreciseDate_m10(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3061]!, self._r[3061]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3071]!, self._r[3071]!, [_1, _2, _3])
}
- public var Cache_ClearCache: String { return self._s[3062]! }
- public var AutoNightTheme_UpdateLocation: String { return self._s[3063]! }
- public var Permissions_NotificationsUnreachableText_v0: String { return self._s[3064]! }
+ public var Cache_ClearCache: String { return self._s[3072]! }
+ public var AutoNightTheme_UpdateLocation: String { return self._s[3073]! }
+ public var Permissions_NotificationsUnreachableText_v0: String { return self._s[3074]! }
public func Channel_AdminLog_MessageChangedGroupUsername(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3068]!, self._r[3068]!, [_0])
+ return formatWithArgumentRanges(self._s[3078]!, self._r[3078]!, [_0])
}
public func Conversation_ShareMyPhoneNumber_StatusSuccess(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3070]!, self._r[3070]!, [_0])
+ return formatWithArgumentRanges(self._s[3080]!, self._r[3080]!, [_0])
}
- public var LocalGroup_Text: String { return self._s[3071]! }
- public var Channel_AdminLog_EmptyFilterTitle: String { return self._s[3072]! }
- public var SocksProxySetup_TypeSocks: String { return self._s[3073]! }
- public var ChatList_UnarchiveAction: String { return self._s[3074]! }
- public var AutoNightTheme_Title: String { return self._s[3075]! }
- public var InstantPage_FeedbackButton: String { return self._s[3076]! }
- public var Passport_FieldAddress: String { return self._s[3077]! }
+ public var LocalGroup_Text: String { return self._s[3081]! }
+ public var Channel_AdminLog_EmptyFilterTitle: String { return self._s[3082]! }
+ public var SocksProxySetup_TypeSocks: String { return self._s[3083]! }
+ public var ChatList_UnarchiveAction: String { return self._s[3084]! }
+ public var AutoNightTheme_Title: String { return self._s[3085]! }
+ public var InstantPage_FeedbackButton: String { return self._s[3086]! }
+ public var Passport_FieldAddress: String { return self._s[3087]! }
public func Channel_AdminLog_SetSlowmode(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3078]!, self._r[3078]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3088]!, self._r[3088]!, [_1, _2])
}
- public var Month_ShortMarch: String { return self._s[3079]! }
+ public var Month_ShortMarch: String { return self._s[3089]! }
public func PUSH_MESSAGE_INVOICE(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3080]!, self._r[3080]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3090]!, self._r[3090]!, [_1, _2])
}
- public var SocksProxySetup_UsernamePlaceholder: String { return self._s[3081]! }
- public var Conversation_ShareInlineBotLocationConfirmation: String { return self._s[3082]! }
- public var Passport_FloodError: String { return self._s[3083]! }
- public var SecretGif_Title: String { return self._s[3084]! }
- public var NotificationSettings_ShowNotificationsAllAccountsInfoOn: String { return self._s[3085]! }
- public var ChatList_Context_UnhideArchive: String { return self._s[3086]! }
- public var Passport_Language_th: String { return self._s[3088]! }
- public var Passport_Address_Address: String { return self._s[3089]! }
- public var Login_InvalidLastNameError: String { return self._s[3090]! }
- public var Notifications_InAppNotificationsPreview: String { return self._s[3091]! }
- public var Notifications_PermissionsUnreachableTitle: String { return self._s[3092]! }
- public var ChatList_Context_Archive: String { return self._s[3093]! }
- public var SettingsSearch_FAQ: String { return self._s[3094]! }
- public var ShareMenu_Send: String { return self._s[3095]! }
- public var WallpaperSearch_ColorYellow: String { return self._s[3097]! }
- public var Month_GenNovember: String { return self._s[3099]! }
- public var SettingsSearch_Synonyms_Appearance_LargeEmoji: String { return self._s[3101]! }
+ public var SocksProxySetup_UsernamePlaceholder: String { return self._s[3091]! }
+ public var Conversation_ShareInlineBotLocationConfirmation: String { return self._s[3092]! }
+ public var Passport_FloodError: String { return self._s[3093]! }
+ public var SecretGif_Title: String { return self._s[3094]! }
+ public var NotificationSettings_ShowNotificationsAllAccountsInfoOn: String { return self._s[3095]! }
+ public var ChatList_Context_UnhideArchive: String { return self._s[3096]! }
+ public var Passport_Language_th: String { return self._s[3098]! }
+ public var Passport_Address_Address: String { return self._s[3099]! }
+ public var Login_InvalidLastNameError: String { return self._s[3100]! }
+ public var Notifications_InAppNotificationsPreview: String { return self._s[3101]! }
+ public var Notifications_PermissionsUnreachableTitle: String { return self._s[3102]! }
+ public var ChatList_Context_Archive: String { return self._s[3103]! }
+ public var SettingsSearch_FAQ: String { return self._s[3104]! }
+ public var ShareMenu_Send: String { return self._s[3105]! }
+ public var WallpaperSearch_ColorYellow: String { return self._s[3107]! }
+ public var Month_GenNovember: String { return self._s[3109]! }
+ public var SettingsSearch_Synonyms_Appearance_LargeEmoji: String { return self._s[3111]! }
public func Conversation_ShareMyPhoneNumberConfirmation(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3102]!, self._r[3102]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3112]!, self._r[3112]!, [_1, _2])
}
- public var Conversation_SwipeToReplyHintText: String { return self._s[3103]! }
- public var Checkout_Email: String { return self._s[3104]! }
- public var NotificationsSound_Tritone: String { return self._s[3105]! }
- public var StickerPacksSettings_ManagingHelp: String { return self._s[3107]! }
- public var Wallet_ContextMenuCopy: String { return self._s[3109]! }
+ public var Conversation_SwipeToReplyHintText: String { return self._s[3113]! }
+ public var Checkout_Email: String { return self._s[3114]! }
+ public var NotificationsSound_Tritone: String { return self._s[3115]! }
+ public var StickerPacksSettings_ManagingHelp: String { return self._s[3117]! }
+ public var Wallet_ContextMenuCopy: String { return self._s[3119]! }
public func Wallet_Time_PreciseDate_m6(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3111]!, self._r[3111]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3121]!, self._r[3121]!, [_1, _2, _3])
}
- public var Appearance_TextSize_Automatic: String { return self._s[3112]! }
+ public var Appearance_TextSize_Automatic: String { return self._s[3122]! }
public func PUSH_PINNED_ROUND(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3113]!, self._r[3113]!, [_1])
+ return formatWithArgumentRanges(self._s[3123]!, self._r[3123]!, [_1])
}
public func StickerPackActionInfo_AddedText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3114]!, self._r[3114]!, [_0])
+ return formatWithArgumentRanges(self._s[3124]!, self._r[3124]!, [_0])
}
- public var ChangePhoneNumberNumber_Help: String { return self._s[3115]! }
+ public var ChangePhoneNumberNumber_Help: String { return self._s[3125]! }
public func Checkout_LiabilityAlert(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3116]!, self._r[3116]!, [_1, _1, _1, _2])
+ return formatWithArgumentRanges(self._s[3126]!, self._r[3126]!, [_1, _1, _1, _2])
}
- public var ChatList_UndoArchiveTitle: String { return self._s[3117]! }
- public var Notification_Exceptions_Add: String { return self._s[3118]! }
- public var DialogList_You: String { return self._s[3119]! }
- public var MediaPicker_Send: String { return self._s[3122]! }
- public var SettingsSearch_Synonyms_Stickers_Title: String { return self._s[3123]! }
- public var Appearance_ThemePreview_ChatList_4_Text: String { return self._s[3124]! }
- public var Call_AudioRouteSpeaker: String { return self._s[3125]! }
- public var Watch_UserInfo_Title: String { return self._s[3126]! }
- public var VoiceOver_Chat_PollFinalResults: String { return self._s[3127]! }
- public var Appearance_AccentColor: String { return self._s[3129]! }
+ public var ChatList_UndoArchiveTitle: String { return self._s[3127]! }
+ public var Notification_Exceptions_Add: String { return self._s[3128]! }
+ public var DialogList_You: String { return self._s[3129]! }
+ public var MediaPicker_Send: String { return self._s[3132]! }
+ public var SettingsSearch_Synonyms_Stickers_Title: String { return self._s[3133]! }
+ public var Appearance_ThemePreview_ChatList_4_Text: String { return self._s[3134]! }
+ public var Call_AudioRouteSpeaker: String { return self._s[3135]! }
+ public var Watch_UserInfo_Title: String { return self._s[3136]! }
+ public var VoiceOver_Chat_PollFinalResults: String { return self._s[3137]! }
+ public var Appearance_AccentColor: String { return self._s[3139]! }
public func Login_EmailPhoneSubject(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3130]!, self._r[3130]!, [_0])
+ return formatWithArgumentRanges(self._s[3140]!, self._r[3140]!, [_0])
}
- public var Permissions_ContactsAllowInSettings_v0: String { return self._s[3131]! }
+ public var Permissions_ContactsAllowInSettings_v0: String { return self._s[3141]! }
public func PUSH_CHANNEL_MESSAGE_GAME(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3132]!, self._r[3132]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3142]!, self._r[3142]!, [_1, _2])
}
- public var Conversation_ClousStorageInfo_Description2: String { return self._s[3133]! }
- public var WebSearch_RecentClearConfirmation: String { return self._s[3134]! }
- public var Notification_CallOutgoing: String { return self._s[3135]! }
- public var PrivacySettings_PasscodeAndFaceId: String { return self._s[3136]! }
- public var Channel_DiscussionGroup_MakeHistoryPublic: String { return self._s[3137]! }
- public var Call_RecordingDisabledMessage: String { return self._s[3138]! }
- public var Message_Game: String { return self._s[3139]! }
- public var Conversation_PressVolumeButtonForSound: String { return self._s[3140]! }
- public var PrivacyLastSeenSettings_CustomHelp: String { return self._s[3141]! }
- public var Channel_DiscussionGroup_PrivateGroup: String { return self._s[3142]! }
- public var Channel_EditAdmin_PermissionAddAdmins: String { return self._s[3143]! }
- public var Date_DialogDateFormat: String { return self._s[3145]! }
- public var WallpaperColors_SetCustomColor: String { return self._s[3146]! }
- public var Notifications_InAppNotifications: String { return self._s[3147]! }
+ public var Conversation_ClousStorageInfo_Description2: String { return self._s[3143]! }
+ public var WebSearch_RecentClearConfirmation: String { return self._s[3144]! }
+ public var Notification_CallOutgoing: String { return self._s[3145]! }
+ public var PrivacySettings_PasscodeAndFaceId: String { return self._s[3146]! }
+ public var Channel_DiscussionGroup_MakeHistoryPublic: String { return self._s[3147]! }
+ public var Call_RecordingDisabledMessage: String { return self._s[3148]! }
+ public var Message_Game: String { return self._s[3149]! }
+ public var Conversation_PressVolumeButtonForSound: String { return self._s[3150]! }
+ public var PrivacyLastSeenSettings_CustomHelp: String { return self._s[3151]! }
+ public var Channel_DiscussionGroup_PrivateGroup: String { return self._s[3152]! }
+ public var Channel_EditAdmin_PermissionAddAdmins: String { return self._s[3153]! }
+ public var Date_DialogDateFormat: String { return self._s[3155]! }
+ public var WallpaperColors_SetCustomColor: String { return self._s[3156]! }
+ public var Notifications_InAppNotifications: String { return self._s[3157]! }
public func Channel_Management_RemovedBy(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3148]!, self._r[3148]!, [_0])
+ return formatWithArgumentRanges(self._s[3158]!, self._r[3158]!, [_0])
}
public func Settings_ApplyProxyAlert(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3149]!, self._r[3149]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3159]!, self._r[3159]!, [_1, _2])
}
- public var NewContact_Title: String { return self._s[3150]! }
+ public var NewContact_Title: String { return self._s[3160]! }
public func AutoDownloadSettings_UpToForAll(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3151]!, self._r[3151]!, [_0])
+ return formatWithArgumentRanges(self._s[3161]!, self._r[3161]!, [_0])
}
- public var Conversation_ViewContactDetails: String { return self._s[3152]! }
+ public var Conversation_ViewContactDetails: String { return self._s[3162]! }
public func PUSH_CHANNEL_MESSAGE_CONTACT(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3154]!, self._r[3154]!, [_1])
+ return formatWithArgumentRanges(self._s[3164]!, self._r[3164]!, [_1])
}
- public var Checkout_NewCard_CardholderNameTitle: String { return self._s[3155]! }
- public var Passport_Identity_ExpiryDateNone: String { return self._s[3156]! }
- public var PrivacySettings_Title: String { return self._s[3157]! }
- public var Conversation_SilentBroadcastTooltipOff: String { return self._s[3160]! }
- public var GroupRemoved_UsersSectionTitle: String { return self._s[3161]! }
- public var VoiceOver_Chat_ContactEmail: String { return self._s[3162]! }
- public var Contacts_PhoneNumber: String { return self._s[3163]! }
- public var TwoFactorSetup_Password_PlaceholderConfirmPassword: String { return self._s[3165]! }
- public var Map_ShowPlaces: String { return self._s[3166]! }
- public var ChatAdmins_Title: String { return self._s[3167]! }
- public var InstantPage_Reference: String { return self._s[3169]! }
- public var Wallet_Info_Updating: String { return self._s[3170]! }
- public var ReportGroupLocation_Text: String { return self._s[3171]! }
+ public var Checkout_NewCard_CardholderNameTitle: String { return self._s[3165]! }
+ public var Passport_Identity_ExpiryDateNone: String { return self._s[3166]! }
+ public var PrivacySettings_Title: String { return self._s[3167]! }
+ public var Conversation_SilentBroadcastTooltipOff: String { return self._s[3170]! }
+ public var GroupRemoved_UsersSectionTitle: String { return self._s[3171]! }
+ public var VoiceOver_Chat_ContactEmail: String { return self._s[3172]! }
+ public var Contacts_PhoneNumber: String { return self._s[3173]! }
+ public var TwoFactorSetup_Password_PlaceholderConfirmPassword: String { return self._s[3175]! }
+ public var Map_ShowPlaces: String { return self._s[3176]! }
+ public var ChatAdmins_Title: String { return self._s[3177]! }
+ public var InstantPage_Reference: String { return self._s[3179]! }
+ public var Wallet_Info_Updating: String { return self._s[3180]! }
+ public var ReportGroupLocation_Text: String { return self._s[3181]! }
public func PUSH_CHAT_MESSAGE_FWD(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3172]!, self._r[3172]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3182]!, self._r[3182]!, [_1, _2])
}
- public var Camera_FlashOff: String { return self._s[3173]! }
- public var Watch_UserInfo_Block: String { return self._s[3174]! }
- public var ChatSettings_Stickers: String { return self._s[3175]! }
- public var ChatSettings_DownloadInBackground: String { return self._s[3176]! }
- public var Appearance_ThemeCarouselTintedNight: String { return self._s[3177]! }
+ public var Camera_FlashOff: String { return self._s[3183]! }
+ public var Watch_UserInfo_Block: String { return self._s[3184]! }
+ public var ChatSettings_Stickers: String { return self._s[3185]! }
+ public var ChatSettings_DownloadInBackground: String { return self._s[3186]! }
+ public var Appearance_ThemeCarouselTintedNight: String { return self._s[3187]! }
public func UserInfo_BlockConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3178]!, self._r[3178]!, [_0])
+ return formatWithArgumentRanges(self._s[3188]!, self._r[3188]!, [_0])
}
- public var Settings_ViewPhoto: String { return self._s[3179]! }
- public var Login_CheckOtherSessionMessages: String { return self._s[3180]! }
- public var AutoDownloadSettings_Cellular: String { return self._s[3181]! }
- public var Wallet_Created_ExportErrorTitle: String { return self._s[3182]! }
- public var SettingsSearch_Synonyms_Notifications_GroupNotificationsExceptions: String { return self._s[3183]! }
- public var VoiceOver_MessageContextShare: String { return self._s[3184]! }
+ public var Settings_ViewPhoto: String { return self._s[3189]! }
+ public var Login_CheckOtherSessionMessages: String { return self._s[3190]! }
+ public var AutoDownloadSettings_Cellular: String { return self._s[3191]! }
+ public var Wallet_Created_ExportErrorTitle: String { return self._s[3192]! }
+ public var SettingsSearch_Synonyms_Notifications_GroupNotificationsExceptions: String { return self._s[3193]! }
+ public var VoiceOver_MessageContextShare: String { return self._s[3194]! }
public func Target_InviteToGroupConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3186]!, self._r[3186]!, [_0])
+ return formatWithArgumentRanges(self._s[3196]!, self._r[3196]!, [_0])
}
- public var Privacy_DeleteDrafts: String { return self._s[3187]! }
- public var Wallpaper_SetCustomBackgroundInfo: String { return self._s[3188]! }
+ public var Privacy_DeleteDrafts: String { return self._s[3197]! }
+ public var Wallpaper_SetCustomBackgroundInfo: String { return self._s[3198]! }
public func LastSeen_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3189]!, self._r[3189]!, [_0])
+ return formatWithArgumentRanges(self._s[3199]!, self._r[3199]!, [_0])
}
- public var DialogList_SavedMessagesHelp: String { return self._s[3190]! }
- public var Wallet_SecureStorageNotAvailable_Title: String { return self._s[3191]! }
- public var DialogList_SavedMessages: String { return self._s[3192]! }
- public var GroupInfo_UpgradeButton: String { return self._s[3193]! }
- public var Appearance_ThemePreview_ChatList_3_Text: String { return self._s[3195]! }
- public var DialogList_Pin: String { return self._s[3196]! }
+ public var DialogList_SavedMessagesHelp: String { return self._s[3200]! }
+ public var Wallet_SecureStorageNotAvailable_Title: String { return self._s[3201]! }
+ public var DialogList_SavedMessages: String { return self._s[3202]! }
+ public var GroupInfo_UpgradeButton: String { return self._s[3203]! }
+ public var Appearance_ThemePreview_ChatList_3_Text: String { return self._s[3205]! }
+ public var DialogList_Pin: String { return self._s[3206]! }
public func ForwardedAuthors2(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3197]!, self._r[3197]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[3207]!, self._r[3207]!, [_0, _1])
}
public func Login_PhoneGenericEmailSubject(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3198]!, self._r[3198]!, [_0])
+ return formatWithArgumentRanges(self._s[3208]!, self._r[3208]!, [_0])
}
- public var Notification_Exceptions_AlwaysOn: String { return self._s[3199]! }
- public var UserInfo_NotificationsDisable: String { return self._s[3200]! }
- public var Conversation_ContextMenuCancelEditing: String { return self._s[3201]! }
- public var Paint_Outlined: String { return self._s[3202]! }
- public var Activity_PlayingGame: String { return self._s[3203]! }
- public var SearchImages_NoImagesFound: String { return self._s[3204]! }
- public var SocksProxySetup_ProxyType: String { return self._s[3205]! }
- public var AppleWatch_ReplyPresetsHelp: String { return self._s[3207]! }
- public var Conversation_ContextMenuCancelSending: String { return self._s[3208]! }
- public var Settings_AppLanguage: String { return self._s[3209]! }
- public var TwoStepAuth_ResetAccountHelp: String { return self._s[3210]! }
- public var Common_ChoosePhoto: String { return self._s[3211]! }
- public var AuthSessions_AddDevice_InvalidQRCode: String { return self._s[3212]! }
- public var CallFeedback_ReasonEcho: String { return self._s[3213]! }
+ public var Notification_Exceptions_AlwaysOn: String { return self._s[3209]! }
+ public var UserInfo_NotificationsDisable: String { return self._s[3210]! }
+ public var Conversation_ContextMenuCancelEditing: String { return self._s[3211]! }
+ public var Paint_Outlined: String { return self._s[3212]! }
+ public var Activity_PlayingGame: String { return self._s[3213]! }
+ public var SearchImages_NoImagesFound: String { return self._s[3214]! }
+ public var SocksProxySetup_ProxyType: String { return self._s[3215]! }
+ public var AppleWatch_ReplyPresetsHelp: String { return self._s[3217]! }
+ public var Conversation_ContextMenuCancelSending: String { return self._s[3218]! }
+ public var Settings_AppLanguage: String { return self._s[3219]! }
+ public var TwoStepAuth_ResetAccountHelp: String { return self._s[3220]! }
+ public var Common_ChoosePhoto: String { return self._s[3221]! }
+ public var AuthSessions_AddDevice_InvalidQRCode: String { return self._s[3222]! }
+ public var CallFeedback_ReasonEcho: String { return self._s[3223]! }
public func PUSH_PINNED_AUDIO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3214]!, self._r[3214]!, [_1])
+ return formatWithArgumentRanges(self._s[3224]!, self._r[3224]!, [_1])
}
- public var Privacy_Calls_AlwaysAllow: String { return self._s[3215]! }
- public var PollResults_Collapse: String { return self._s[3216]! }
- public var Activity_UploadingVideo: String { return self._s[3217]! }
- public var Conversation_WalletRequiredNotNow: String { return self._s[3218]! }
- public var ChannelInfo_DeleteChannelConfirmation: String { return self._s[3219]! }
- public var NetworkUsageSettings_Wifi: String { return self._s[3220]! }
- public var VoiceOver_Editing_ClearText: String { return self._s[3221]! }
- public var PUSH_SENDER_YOU: String { return self._s[3222]! }
- public var Channel_BanUser_PermissionReadMessages: String { return self._s[3223]! }
- public var Checkout_PayWithTouchId: String { return self._s[3224]! }
- public var Wallpaper_ResetWallpapersConfirmation: String { return self._s[3225]! }
+ public var Privacy_Calls_AlwaysAllow: String { return self._s[3225]! }
+ public var PollResults_Collapse: String { return self._s[3226]! }
+ public var Activity_UploadingVideo: String { return self._s[3227]! }
+ public var Conversation_WalletRequiredNotNow: String { return self._s[3228]! }
+ public var ChannelInfo_DeleteChannelConfirmation: String { return self._s[3229]! }
+ public var NetworkUsageSettings_Wifi: String { return self._s[3230]! }
+ public var VoiceOver_Editing_ClearText: String { return self._s[3231]! }
+ public var PUSH_SENDER_YOU: String { return self._s[3232]! }
+ public var Channel_BanUser_PermissionReadMessages: String { return self._s[3233]! }
+ public var Checkout_PayWithTouchId: String { return self._s[3234]! }
+ public var Wallpaper_ResetWallpapersConfirmation: String { return self._s[3235]! }
public func PUSH_LOCKED_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3227]!, self._r[3227]!, [_1])
+ return formatWithArgumentRanges(self._s[3237]!, self._r[3237]!, [_1])
}
- public var Notifications_ExceptionsNone: String { return self._s[3228]! }
+ public var Notifications_ExceptionsNone: String { return self._s[3238]! }
public func Message_ForwardedMessageShort(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3229]!, self._r[3229]!, [_0])
+ return formatWithArgumentRanges(self._s[3239]!, self._r[3239]!, [_0])
}
public func PUSH_PINNED_GEO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3230]!, self._r[3230]!, [_1])
+ return formatWithArgumentRanges(self._s[3240]!, self._r[3240]!, [_1])
}
- public var AuthSessions_IncompleteAttempts: String { return self._s[3232]! }
- public var Passport_Address_Region: String { return self._s[3235]! }
- public var ChatList_DeleteChat: String { return self._s[3236]! }
- public var LogoutOptions_ClearCacheTitle: String { return self._s[3237]! }
- public var PhotoEditor_TiltShift: String { return self._s[3238]! }
- public var Settings_FAQ_URL: String { return self._s[3239]! }
- public var TwoFactorSetup_EmailVerification_ChangeAction: String { return self._s[3240]! }
- public var Passport_Language_sl: String { return self._s[3241]! }
- public var Settings_PrivacySettings: String { return self._s[3243]! }
- public var SharedMedia_TitleLink: String { return self._s[3244]! }
- public var Passport_Identity_TypePassportUploadScan: String { return self._s[3245]! }
- public var Settings_SetProfilePhoto: String { return self._s[3246]! }
- public var Channel_About_Help: String { return self._s[3247]! }
- public var Contacts_PermissionsEnable: String { return self._s[3248]! }
- public var Wallet_Sending_Title: String { return self._s[3249]! }
- public var SettingsSearch_Synonyms_Notifications_GroupNotificationsAlert: String { return self._s[3250]! }
- public var AttachmentMenu_SendAsFiles: String { return self._s[3251]! }
- public var CallFeedback_ReasonInterruption: String { return self._s[3253]! }
- public var Passport_Address_AddTemporaryRegistration: String { return self._s[3254]! }
- public var AutoDownloadSettings_AutodownloadVideos: String { return self._s[3255]! }
- public var ChatSettings_AutoDownloadSettings_Delimeter: String { return self._s[3256]! }
- public var OldChannels_Title: String { return self._s[3257]! }
- public var PrivacySettings_DeleteAccountTitle: String { return self._s[3258]! }
- public var AccessDenied_VideoMessageCamera: String { return self._s[3260]! }
- public var Map_OpenInYandexMaps: String { return self._s[3262]! }
- public var CreateGroup_ErrorLocatedGroupsTooMuch: String { return self._s[3263]! }
- public var VoiceOver_MessageContextReply: String { return self._s[3264]! }
- public var PhotoEditor_SaturationTool: String { return self._s[3266]! }
+ public var AuthSessions_IncompleteAttempts: String { return self._s[3242]! }
+ public var Passport_Address_Region: String { return self._s[3245]! }
+ public var ChatList_DeleteChat: String { return self._s[3246]! }
+ public var LogoutOptions_ClearCacheTitle: String { return self._s[3247]! }
+ public var PhotoEditor_TiltShift: String { return self._s[3248]! }
+ public var Settings_FAQ_URL: String { return self._s[3249]! }
+ public var TwoFactorSetup_EmailVerification_ChangeAction: String { return self._s[3250]! }
+ public var Passport_Language_sl: String { return self._s[3251]! }
+ public var Settings_PrivacySettings: String { return self._s[3253]! }
+ public var SharedMedia_TitleLink: String { return self._s[3254]! }
+ public var Passport_Identity_TypePassportUploadScan: String { return self._s[3255]! }
+ public var Settings_SetProfilePhoto: String { return self._s[3256]! }
+ public var Channel_About_Help: String { return self._s[3257]! }
+ public var Contacts_PermissionsEnable: String { return self._s[3258]! }
+ public var Wallet_Sending_Title: String { return self._s[3259]! }
+ public var SettingsSearch_Synonyms_Notifications_GroupNotificationsAlert: String { return self._s[3260]! }
+ public var AttachmentMenu_SendAsFiles: String { return self._s[3261]! }
+ public var CallFeedback_ReasonInterruption: String { return self._s[3263]! }
+ public var Passport_Address_AddTemporaryRegistration: String { return self._s[3264]! }
+ public var AutoDownloadSettings_AutodownloadVideos: String { return self._s[3265]! }
+ public var ChatSettings_AutoDownloadSettings_Delimeter: String { return self._s[3266]! }
+ public var OldChannels_Title: String { return self._s[3267]! }
+ public var PrivacySettings_DeleteAccountTitle: String { return self._s[3268]! }
+ public var AccessDenied_VideoMessageCamera: String { return self._s[3270]! }
+ public var Map_OpenInYandexMaps: String { return self._s[3272]! }
+ public var CreateGroup_ErrorLocatedGroupsTooMuch: String { return self._s[3273]! }
+ public var VoiceOver_MessageContextReply: String { return self._s[3274]! }
+ public var PhotoEditor_SaturationTool: String { return self._s[3276]! }
public func PUSH_MESSAGE_STICKER(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3267]!, self._r[3267]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3277]!, self._r[3277]!, [_1, _2])
}
- public var PrivacyPhoneNumberSettings_CustomHelp: String { return self._s[3268]! }
- public var Notification_Exceptions_NewException_NotificationHeader: String { return self._s[3269]! }
- public var Group_OwnershipTransfer_ErrorLocatedGroupsTooMuch: String { return self._s[3270]! }
+ public var PrivacyPhoneNumberSettings_CustomHelp: String { return self._s[3278]! }
+ public var Notification_Exceptions_NewException_NotificationHeader: String { return self._s[3279]! }
+ public var Group_OwnershipTransfer_ErrorLocatedGroupsTooMuch: String { return self._s[3280]! }
public func LOCAL_MESSAGE_FWDS(_ _1: String, _ _2: Int) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3271]!, self._r[3271]!, [_1, "\(_2)"])
+ return formatWithArgumentRanges(self._s[3281]!, self._r[3281]!, [_1, "\(_2)"])
}
- public var Appearance_ThemePreview_ChatList_2_Text: String { return self._s[3272]! }
- public var Channel_Username_InvalidTooShort: String { return self._s[3274]! }
- public var SettingsSearch_Synonyms_Wallet: String { return self._s[3275]! }
+ public var Appearance_ThemePreview_ChatList_2_Text: String { return self._s[3282]! }
+ public var Channel_Username_InvalidTooShort: String { return self._s[3284]! }
+ public var SettingsSearch_Synonyms_Wallet: String { return self._s[3285]! }
public func Group_OwnershipTransfer_DescriptionInfo(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3276]!, self._r[3276]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3286]!, self._r[3286]!, [_1, _2])
}
- public var Forward_ErrorPublicPollDisabledInChannels: String { return self._s[3277]! }
+ public var Forward_ErrorPublicPollDisabledInChannels: String { return self._s[3287]! }
public func PUSH_CHAT_MESSAGE_GAME(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3278]!, self._r[3278]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3288]!, self._r[3288]!, [_1, _2, _3])
}
- public var WallpaperPreview_PatternTitle: String { return self._s[3279]! }
- public var GroupInfo_PublicLinkAdd: String { return self._s[3280]! }
- public var Passport_PassportInformation: String { return self._s[3283]! }
- public var Theme_Unsupported: String { return self._s[3284]! }
- public var WatchRemote_AlertTitle: String { return self._s[3285]! }
- public var Privacy_GroupsAndChannels_NeverAllow: String { return self._s[3286]! }
- public var ConvertToSupergroup_HelpText: String { return self._s[3288]! }
+ public var WallpaperPreview_PatternTitle: String { return self._s[3289]! }
+ public var GroupInfo_PublicLinkAdd: String { return self._s[3290]! }
+ public var Passport_PassportInformation: String { return self._s[3293]! }
+ public var Theme_Unsupported: String { return self._s[3294]! }
+ public var WatchRemote_AlertTitle: String { return self._s[3295]! }
+ public var Privacy_GroupsAndChannels_NeverAllow: String { return self._s[3296]! }
+ public var ConvertToSupergroup_HelpText: String { return self._s[3298]! }
public func Time_MonthOfYear_m7(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3289]!, self._r[3289]!, [_0])
+ return formatWithArgumentRanges(self._s[3299]!, self._r[3299]!, [_0])
}
public func PUSH_PHONE_CALL_REQUEST(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3290]!, self._r[3290]!, [_1])
+ return formatWithArgumentRanges(self._s[3300]!, self._r[3300]!, [_1])
}
- public var Privacy_GroupsAndChannels_CustomHelp: String { return self._s[3291]! }
- public var Wallet_Navigation_Done: String { return self._s[3293]! }
- public var TwoStepAuth_RecoveryCodeInvalid: String { return self._s[3294]! }
- public var AccessDenied_CameraDisabled: String { return self._s[3295]! }
+ public var Privacy_GroupsAndChannels_CustomHelp: String { return self._s[3301]! }
+ public var Wallet_Navigation_Done: String { return self._s[3303]! }
+ public var TwoStepAuth_RecoveryCodeInvalid: String { return self._s[3304]! }
+ public var AccessDenied_CameraDisabled: String { return self._s[3305]! }
public func Channel_Username_UsernameIsAvailable(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3296]!, self._r[3296]!, [_0])
+ return formatWithArgumentRanges(self._s[3306]!, self._r[3306]!, [_0])
}
- public var ClearCache_Forever: String { return self._s[3297]! }
- public var AuthSessions_AddDeviceIntro_Title: String { return self._s[3298]! }
- public var CreatePoll_Quiz: String { return self._s[3299]! }
- public var PhotoEditor_ContrastTool: String { return self._s[3302]! }
+ public var ClearCache_Forever: String { return self._s[3307]! }
+ public var AuthSessions_AddDeviceIntro_Title: String { return self._s[3308]! }
+ public var CreatePoll_Quiz: String { return self._s[3309]! }
+ public var PhotoEditor_ContrastTool: String { return self._s[3312]! }
public func PUSH_PINNED_DOC(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3303]!, self._r[3303]!, [_1])
+ return formatWithArgumentRanges(self._s[3313]!, self._r[3313]!, [_1])
}
- public var DialogList_Draft: String { return self._s[3304]! }
- public var Wallet_Configuration_BlockchainIdInfo: String { return self._s[3305]! }
- public var Privacy_TopPeersDelete: String { return self._s[3307]! }
- public var LoginPassword_PasswordPlaceholder: String { return self._s[3308]! }
- public var Passport_Identity_TypeIdentityCardUploadScan: String { return self._s[3309]! }
- public var WebSearch_RecentSectionClear: String { return self._s[3310]! }
- public var EditTheme_ErrorInvalidCharacters: String { return self._s[3311]! }
- public var Watch_ChatList_NoConversationsTitle: String { return self._s[3313]! }
- public var Common_Done: String { return self._s[3315]! }
- public var Shortcut_SwitchAccount: String { return self._s[3316]! }
- public var AuthSessions_EmptyText: String { return self._s[3317]! }
- public var Wallet_Configuration_BlockchainNameChangedTitle: String { return self._s[3318]! }
- public var Conversation_ShareBotContactConfirmation: String { return self._s[3319]! }
- public var Tour_Title5: String { return self._s[3320]! }
- public var Wallet_Settings_Title: String { return self._s[3321]! }
+ public var DialogList_Draft: String { return self._s[3314]! }
+ public var Wallet_Configuration_BlockchainIdInfo: String { return self._s[3315]! }
+ public func PeopleNearby_VisibleUntil(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[3316]!, self._r[3316]!, [_0])
+ }
+ public var Privacy_TopPeersDelete: String { return self._s[3318]! }
+ public var LoginPassword_PasswordPlaceholder: String { return self._s[3319]! }
+ public var Passport_Identity_TypeIdentityCardUploadScan: String { return self._s[3320]! }
+ public var WebSearch_RecentSectionClear: String { return self._s[3321]! }
+ public var EditTheme_ErrorInvalidCharacters: String { return self._s[3322]! }
+ public var Watch_ChatList_NoConversationsTitle: String { return self._s[3324]! }
+ public var Common_Done: String { return self._s[3326]! }
+ public var Shortcut_SwitchAccount: String { return self._s[3327]! }
+ public var AuthSessions_EmptyText: String { return self._s[3328]! }
+ public var Wallet_Configuration_BlockchainNameChangedTitle: String { return self._s[3329]! }
+ public var Conversation_ShareBotContactConfirmation: String { return self._s[3330]! }
+ public var Tour_Title5: String { return self._s[3331]! }
+ public var Wallet_Settings_Title: String { return self._s[3332]! }
public func Map_DirectionsDriveEta(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3322]!, self._r[3322]!, [_0])
+ return formatWithArgumentRanges(self._s[3333]!, self._r[3333]!, [_0])
}
- public var ApplyLanguage_UnsufficientDataTitle: String { return self._s[3323]! }
- public var Conversation_LinkDialogSave: String { return self._s[3324]! }
- public var GroupInfo_ActionRestrict: String { return self._s[3325]! }
- public var Checkout_Title: String { return self._s[3326]! }
- public var Channel_DiscussionGroup_HeaderLabel: String { return self._s[3328]! }
- public var Channel_AdminLog_CanChangeInfo: String { return self._s[3330]! }
- public var Notification_RenamedGroup: String { return self._s[3331]! }
- public var PeopleNearby_Groups: String { return self._s[3332]! }
- public var Checkout_PayWithFaceId: String { return self._s[3333]! }
- public var Channel_BanList_BlockedTitle: String { return self._s[3334]! }
- public var SettingsSearch_Synonyms_Notifications_InAppNotificationsSound: String { return self._s[3336]! }
- public var Checkout_WebConfirmation_Title: String { return self._s[3337]! }
- public var Notifications_MessageNotificationsAlert: String { return self._s[3338]! }
+ public var ApplyLanguage_UnsufficientDataTitle: String { return self._s[3334]! }
+ public var Conversation_LinkDialogSave: String { return self._s[3335]! }
+ public var GroupInfo_ActionRestrict: String { return self._s[3336]! }
+ public var Checkout_Title: String { return self._s[3337]! }
+ public var Channel_DiscussionGroup_HeaderLabel: String { return self._s[3339]! }
+ public var Channel_AdminLog_CanChangeInfo: String { return self._s[3341]! }
+ public var Notification_RenamedGroup: String { return self._s[3342]! }
+ public var PeopleNearby_Groups: String { return self._s[3343]! }
+ public var Checkout_PayWithFaceId: String { return self._s[3344]! }
+ public var Channel_BanList_BlockedTitle: String { return self._s[3345]! }
+ public var SettingsSearch_Synonyms_Notifications_InAppNotificationsSound: String { return self._s[3347]! }
+ public var Checkout_WebConfirmation_Title: String { return self._s[3348]! }
+ public var Notifications_MessageNotificationsAlert: String { return self._s[3349]! }
public func Activity_RemindAboutGroup(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3339]!, self._r[3339]!, [_0])
+ return formatWithArgumentRanges(self._s[3350]!, self._r[3350]!, [_0])
}
- public var Profile_AddToExisting: String { return self._s[3341]! }
+ public var Profile_AddToExisting: String { return self._s[3352]! }
public func Profile_CreateEncryptedChatOutdatedError(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3342]!, self._r[3342]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[3353]!, self._r[3353]!, [_0, _1])
}
- public var Cache_Files: String { return self._s[3344]! }
- public var Permissions_PrivacyPolicy: String { return self._s[3345]! }
- public var SocksProxySetup_ConnectAndSave: String { return self._s[3346]! }
- public var UserInfo_NotificationsDefaultDisabled: String { return self._s[3347]! }
- public var AutoDownloadSettings_TypeContacts: String { return self._s[3349]! }
- public var Appearance_ThemePreview_ChatList_1_Text: String { return self._s[3351]! }
- public var Calls_NoCallsPlaceholder: String { return self._s[3352]! }
+ public var Cache_Files: String { return self._s[3355]! }
+ public var Permissions_PrivacyPolicy: String { return self._s[3356]! }
+ public var SocksProxySetup_ConnectAndSave: String { return self._s[3357]! }
+ public var UserInfo_NotificationsDefaultDisabled: String { return self._s[3358]! }
+ public var AutoDownloadSettings_TypeContacts: String { return self._s[3360]! }
+ public var Appearance_ThemePreview_ChatList_1_Text: String { return self._s[3362]! }
+ public var Calls_NoCallsPlaceholder: String { return self._s[3363]! }
public func Wallet_Receive_ShareInvoiceUrlInfo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3353]!, self._r[3353]!, [_0])
+ return formatWithArgumentRanges(self._s[3364]!, self._r[3364]!, [_0])
}
- public var Channel_Username_RevokeExistingUsernamesInfo: String { return self._s[3354]! }
- public var VoiceOver_AttachMedia: String { return self._s[3357]! }
- public var Notifications_ExceptionsGroupPlaceholder: String { return self._s[3358]! }
+ public var Channel_Username_RevokeExistingUsernamesInfo: String { return self._s[3365]! }
+ public var VoiceOver_AttachMedia: String { return self._s[3368]! }
+ public var Notifications_ExceptionsGroupPlaceholder: String { return self._s[3369]! }
public func PUSH_CHAT_MESSAGE_INVOICE(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3359]!, self._r[3359]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3370]!, self._r[3370]!, [_1, _2, _3])
}
- public var SettingsSearch_Synonyms_Notifications_GroupNotificationsSound: String { return self._s[3360]! }
- public var Conversation_SetReminder_Title: String { return self._s[3361]! }
- public var Passport_FieldAddressHelp: String { return self._s[3362]! }
- public var Privacy_GroupsAndChannels_InviteToChannelMultipleError: String { return self._s[3363]! }
- public var PUSH_REMINDER_TITLE: String { return self._s[3364]! }
+ public var SettingsSearch_Synonyms_Notifications_GroupNotificationsSound: String { return self._s[3371]! }
+ public var Conversation_SetReminder_Title: String { return self._s[3372]! }
+ public var Passport_FieldAddressHelp: String { return self._s[3373]! }
+ public var Privacy_GroupsAndChannels_InviteToChannelMultipleError: String { return self._s[3374]! }
+ public var PUSH_REMINDER_TITLE: String { return self._s[3375]! }
public func Login_TermsOfService_ProceedBot(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3365]!, self._r[3365]!, [_0])
+ return formatWithArgumentRanges(self._s[3376]!, self._r[3376]!, [_0])
}
- public var Channel_AdminLog_EmptyTitle: String { return self._s[3366]! }
- public var Privacy_Calls_NeverAllow_Title: String { return self._s[3367]! }
- public var Login_UnknownError: String { return self._s[3368]! }
- public var Group_UpgradeNoticeText2: String { return self._s[3371]! }
- public var Watch_Compose_AddContact: String { return self._s[3372]! }
- public var ClearCache_StorageServiceFiles: String { return self._s[3373]! }
- public var Web_Error: String { return self._s[3374]! }
- public var Gif_Search: String { return self._s[3375]! }
- public var Profile_MessageLifetime1h: String { return self._s[3376]! }
- public var CheckoutInfo_ReceiverInfoEmailPlaceholder: String { return self._s[3377]! }
- public var Channel_Username_CheckingUsername: String { return self._s[3378]! }
- public var CallFeedback_ReasonSilentRemote: String { return self._s[3379]! }
- public var AutoDownloadSettings_TypeChannels: String { return self._s[3380]! }
- public var Channel_AboutItem: String { return self._s[3381]! }
- public var Privacy_GroupsAndChannels_AlwaysAllow_Placeholder: String { return self._s[3383]! }
- public var VoiceOver_Chat_VoiceMessage: String { return self._s[3384]! }
- public var GroupInfo_SharedMedia: String { return self._s[3385]! }
+ public var Channel_AdminLog_EmptyTitle: String { return self._s[3377]! }
+ public var Privacy_Calls_NeverAllow_Title: String { return self._s[3378]! }
+ public var Login_UnknownError: String { return self._s[3379]! }
+ public var Group_UpgradeNoticeText2: String { return self._s[3382]! }
+ public var Watch_Compose_AddContact: String { return self._s[3383]! }
+ public var ClearCache_StorageServiceFiles: String { return self._s[3384]! }
+ public var Web_Error: String { return self._s[3385]! }
+ public var Gif_Search: String { return self._s[3386]! }
+ public var Profile_MessageLifetime1h: String { return self._s[3387]! }
+ public var CheckoutInfo_ReceiverInfoEmailPlaceholder: String { return self._s[3388]! }
+ public var Channel_Username_CheckingUsername: String { return self._s[3389]! }
+ public var CallFeedback_ReasonSilentRemote: String { return self._s[3390]! }
+ public var AutoDownloadSettings_TypeChannels: String { return self._s[3391]! }
+ public var Channel_AboutItem: String { return self._s[3392]! }
+ public var Privacy_GroupsAndChannels_AlwaysAllow_Placeholder: String { return self._s[3394]! }
+ public var VoiceOver_Chat_VoiceMessage: String { return self._s[3395]! }
+ public var GroupInfo_SharedMedia: String { return self._s[3396]! }
public func Channel_AdminLog_MessagePromotedName(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3386]!, self._r[3386]!, [_1])
+ return formatWithArgumentRanges(self._s[3397]!, self._r[3397]!, [_1])
}
- public var Call_PhoneCallInProgressMessage: String { return self._s[3387]! }
+ public var Call_PhoneCallInProgressMessage: String { return self._s[3398]! }
public func PUSH_CHANNEL_ALBUM(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3388]!, self._r[3388]!, [_1])
+ return formatWithArgumentRanges(self._s[3399]!, self._r[3399]!, [_1])
}
- public var ChatList_UndoArchiveRevealedText: String { return self._s[3389]! }
- public var GroupInfo_InviteLink_RevokeAlert_Text: String { return self._s[3390]! }
- public var Conversation_SearchByName_Placeholder: String { return self._s[3391]! }
- public var CreatePoll_AddOption: String { return self._s[3392]! }
- public var GroupInfo_Permissions_SearchPlaceholder: String { return self._s[3393]! }
- public var Group_UpgradeNoticeHeader: String { return self._s[3394]! }
- public var Channel_Management_AddModerator: String { return self._s[3395]! }
- public var AutoDownloadSettings_MaxFileSize: String { return self._s[3396]! }
- public var StickerPacksSettings_ShowStickersButton: String { return self._s[3397]! }
- public var Wallet_Info_RefreshErrorNetworkText: String { return self._s[3398]! }
- public var Theme_Colors_Background: String { return self._s[3399]! }
- public var NotificationsSound_Hello: String { return self._s[3401]! }
- public var SocksProxySetup_SavedProxies: String { return self._s[3402]! }
- public var Channel_Stickers_Placeholder: String { return self._s[3404]! }
+ public var ChatList_UndoArchiveRevealedText: String { return self._s[3400]! }
+ public var GroupInfo_InviteLink_RevokeAlert_Text: String { return self._s[3401]! }
+ public var Conversation_SearchByName_Placeholder: String { return self._s[3402]! }
+ public var CreatePoll_AddOption: String { return self._s[3403]! }
+ public var GroupInfo_Permissions_SearchPlaceholder: String { return self._s[3404]! }
+ public var Group_UpgradeNoticeHeader: String { return self._s[3405]! }
+ public var Channel_Management_AddModerator: String { return self._s[3406]! }
+ public var AutoDownloadSettings_MaxFileSize: String { return self._s[3407]! }
+ public var StickerPacksSettings_ShowStickersButton: String { return self._s[3408]! }
+ public var Wallet_Info_RefreshErrorNetworkText: String { return self._s[3409]! }
+ public var Theme_Colors_Background: String { return self._s[3410]! }
+ public var NotificationsSound_Hello: String { return self._s[3412]! }
+ public var SocksProxySetup_SavedProxies: String { return self._s[3413]! }
+ public var Channel_Stickers_Placeholder: String { return self._s[3415]! }
public func Login_EmailCodeBody(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3405]!, self._r[3405]!, [_0])
+ return formatWithArgumentRanges(self._s[3416]!, self._r[3416]!, [_0])
}
- public var PrivacyPolicy_DeclineDeclineAndDelete: String { return self._s[3406]! }
- public var Channel_Management_AddModeratorHelp: String { return self._s[3407]! }
- public var ContactInfo_BirthdayLabel: String { return self._s[3408]! }
- public var ChangePhoneNumberCode_RequestingACall: String { return self._s[3409]! }
- public var AutoDownloadSettings_Channels: String { return self._s[3410]! }
- public var Passport_Language_mn: String { return self._s[3411]! }
- public var Notifications_ResetAllNotificationsHelp: String { return self._s[3414]! }
- public var GroupInfo_Permissions_SlowmodeValue_Off: String { return self._s[3415]! }
- public var Passport_Language_ja: String { return self._s[3417]! }
- public var Settings_About_Title: String { return self._s[3418]! }
- public var Settings_NotificationsAndSounds: String { return self._s[3419]! }
- public var ChannelInfo_DeleteGroup: String { return self._s[3420]! }
- public var Settings_BlockedUsers: String { return self._s[3421]! }
+ public var PrivacyPolicy_DeclineDeclineAndDelete: String { return self._s[3417]! }
+ public var Channel_Management_AddModeratorHelp: String { return self._s[3418]! }
+ public var ContactInfo_BirthdayLabel: String { return self._s[3419]! }
+ public var ChangePhoneNumberCode_RequestingACall: String { return self._s[3420]! }
+ public var AutoDownloadSettings_Channels: String { return self._s[3421]! }
+ public var Passport_Language_mn: String { return self._s[3422]! }
+ public var Notifications_ResetAllNotificationsHelp: String { return self._s[3425]! }
+ public var GroupInfo_Permissions_SlowmodeValue_Off: String { return self._s[3426]! }
+ public var Passport_Language_ja: String { return self._s[3428]! }
+ public var Settings_About_Title: String { return self._s[3429]! }
+ public var Settings_NotificationsAndSounds: String { return self._s[3430]! }
+ public var ChannelInfo_DeleteGroup: String { return self._s[3431]! }
+ public var Settings_BlockedUsers: String { return self._s[3432]! }
public func Time_MonthOfYear_m4(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3422]!, self._r[3422]!, [_0])
+ return formatWithArgumentRanges(self._s[3433]!, self._r[3433]!, [_0])
}
- public var EditTheme_Create_Preview_OutgoingText: String { return self._s[3423]! }
- public var Wallet_Weekday_Today: String { return self._s[3424]! }
- public var AutoDownloadSettings_PreloadVideo: String { return self._s[3425]! }
- public var Widget_ApplicationLocked: String { return self._s[3426]! }
- public var Passport_Address_AddResidentialAddress: String { return self._s[3427]! }
- public var Channel_Username_Title: String { return self._s[3428]! }
+ public var EditTheme_Create_Preview_OutgoingText: String { return self._s[3434]! }
+ public var Wallet_Weekday_Today: String { return self._s[3435]! }
+ public var AutoDownloadSettings_PreloadVideo: String { return self._s[3436]! }
+ public var Widget_ApplicationLocked: String { return self._s[3437]! }
+ public var Passport_Address_AddResidentialAddress: String { return self._s[3438]! }
+ public var Channel_Username_Title: String { return self._s[3439]! }
public func Notification_RemovedGroupPhoto(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3429]!, self._r[3429]!, [_0])
+ return formatWithArgumentRanges(self._s[3440]!, self._r[3440]!, [_0])
}
- public var AttachmentMenu_File: String { return self._s[3431]! }
- public var AppleWatch_Title: String { return self._s[3432]! }
- public var Activity_RecordingVideoMessage: String { return self._s[3433]! }
+ public var AttachmentMenu_File: String { return self._s[3442]! }
+ public var AppleWatch_Title: String { return self._s[3443]! }
+ public var Activity_RecordingVideoMessage: String { return self._s[3444]! }
public func Channel_DiscussionGroup_PublicChannelLink(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3434]!, self._r[3434]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3445]!, self._r[3445]!, [_1, _2])
}
- public var Theme_Colors_Messages: String { return self._s[3435]! }
- public var Weekday_Saturday: String { return self._s[3436]! }
- public var WallpaperPreview_SwipeColorsTopText: String { return self._s[3437]! }
- public var Profile_CreateEncryptedChatError: String { return self._s[3438]! }
- public var Common_Next: String { return self._s[3440]! }
- public var Channel_Stickers_YourStickers: String { return self._s[3442]! }
- public var Message_Theme: String { return self._s[3443]! }
- public var Call_AudioRouteHeadphones: String { return self._s[3444]! }
- public var TwoStepAuth_EnterPasswordForgot: String { return self._s[3446]! }
- public var Watch_Contacts_NoResults: String { return self._s[3448]! }
- public var PhotoEditor_TintTool: String { return self._s[3451]! }
- public var LoginPassword_ResetAccount: String { return self._s[3453]! }
- public var Settings_SavedMessages: String { return self._s[3454]! }
- public var SettingsSearch_Synonyms_Appearance_Animations: String { return self._s[3455]! }
- public var Bot_GenericSupportStatus: String { return self._s[3456]! }
- public var StickerPack_Add: String { return self._s[3457]! }
- public var Checkout_TotalAmount: String { return self._s[3458]! }
- public var Your_cards_number_is_invalid: String { return self._s[3459]! }
- public var SettingsSearch_Synonyms_Appearance_AutoNightTheme: String { return self._s[3460]! }
- public var VoiceOver_Chat_VideoMessage: String { return self._s[3461]! }
+ public var Theme_Colors_Messages: String { return self._s[3446]! }
+ public var Weekday_Saturday: String { return self._s[3447]! }
+ public var WallpaperPreview_SwipeColorsTopText: String { return self._s[3448]! }
+ public var Profile_CreateEncryptedChatError: String { return self._s[3449]! }
+ public var Common_Next: String { return self._s[3451]! }
+ public var Channel_Stickers_YourStickers: String { return self._s[3453]! }
+ public var Message_Theme: String { return self._s[3454]! }
+ public var Call_AudioRouteHeadphones: String { return self._s[3455]! }
+ public var TwoStepAuth_EnterPasswordForgot: String { return self._s[3457]! }
+ public var Watch_Contacts_NoResults: String { return self._s[3459]! }
+ public var PhotoEditor_TintTool: String { return self._s[3462]! }
+ public var LoginPassword_ResetAccount: String { return self._s[3464]! }
+ public var Settings_SavedMessages: String { return self._s[3465]! }
+ public var SettingsSearch_Synonyms_Appearance_Animations: String { return self._s[3466]! }
+ public var Bot_GenericSupportStatus: String { return self._s[3467]! }
+ public var StickerPack_Add: String { return self._s[3468]! }
+ public var Checkout_TotalAmount: String { return self._s[3469]! }
+ public var Your_cards_number_is_invalid: String { return self._s[3470]! }
+ public var SettingsSearch_Synonyms_Appearance_AutoNightTheme: String { return self._s[3471]! }
+ public var VoiceOver_Chat_VideoMessage: String { return self._s[3472]! }
public func ChangePhoneNumberCode_CallTimer(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3462]!, self._r[3462]!, [_0])
+ return formatWithArgumentRanges(self._s[3473]!, self._r[3473]!, [_0])
}
public func GroupPermission_AddedInfo(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3463]!, self._r[3463]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3474]!, self._r[3474]!, [_1, _2])
}
- public var ChatSettings_ConnectionType_UseSocks5: String { return self._s[3464]! }
+ public var ChatSettings_ConnectionType_UseSocks5: String { return self._s[3475]! }
public func PUSH_CHAT_PHOTO_EDITED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3466]!, self._r[3466]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3477]!, self._r[3477]!, [_1, _2])
}
public func Conversation_RestrictedTextTimed(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3467]!, self._r[3467]!, [_0])
+ return formatWithArgumentRanges(self._s[3478]!, self._r[3478]!, [_0])
}
- public var GroupInfo_InviteLink_ShareLink: String { return self._s[3468]! }
- public var StickerPack_Share: String { return self._s[3469]! }
- public var Passport_DeleteAddress: String { return self._s[3470]! }
- public var Settings_Passport: String { return self._s[3471]! }
- public var SharedMedia_EmptyFilesText: String { return self._s[3472]! }
- public var Conversation_DeleteMessagesForMe: String { return self._s[3473]! }
- public var PasscodeSettings_AutoLock_IfAwayFor_1hour: String { return self._s[3474]! }
- public var Contacts_PermissionsText: String { return self._s[3475]! }
- public var Group_Setup_HistoryVisible: String { return self._s[3476]! }
- public var Wallet_Month_ShortDecember: String { return self._s[3478]! }
- public var Channel_EditAdmin_PermissionEnabledByDefault: String { return self._s[3479]! }
- public var Passport_Address_AddRentalAgreement: String { return self._s[3480]! }
- public var SocksProxySetup_Title: String { return self._s[3481]! }
- public var Notification_Mute1h: String { return self._s[3482]! }
+ public var GroupInfo_InviteLink_ShareLink: String { return self._s[3479]! }
+ public var StickerPack_Share: String { return self._s[3480]! }
+ public var Passport_DeleteAddress: String { return self._s[3481]! }
+ public var Settings_Passport: String { return self._s[3482]! }
+ public var SharedMedia_EmptyFilesText: String { return self._s[3483]! }
+ public var Conversation_DeleteMessagesForMe: String { return self._s[3484]! }
+ public var PasscodeSettings_AutoLock_IfAwayFor_1hour: String { return self._s[3485]! }
+ public var Contacts_PermissionsText: String { return self._s[3486]! }
+ public var Group_Setup_HistoryVisible: String { return self._s[3487]! }
+ public var Wallet_Month_ShortDecember: String { return self._s[3489]! }
+ public var Channel_EditAdmin_PermissionEnabledByDefault: String { return self._s[3490]! }
+ public var Passport_Address_AddRentalAgreement: String { return self._s[3491]! }
+ public var SocksProxySetup_Title: String { return self._s[3492]! }
+ public var Notification_Mute1h: String { return self._s[3493]! }
public func Passport_Email_CodeHelp(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3483]!, self._r[3483]!, [_0])
+ return formatWithArgumentRanges(self._s[3494]!, self._r[3494]!, [_0])
}
- public var NotificationSettings_ShowNotificationsAllAccountsInfoOff: String { return self._s[3484]! }
+ public var NotificationSettings_ShowNotificationsAllAccountsInfoOff: String { return self._s[3495]! }
public func PUSH_PINNED_GEOLIVE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3485]!, self._r[3485]!, [_1])
+ return formatWithArgumentRanges(self._s[3496]!, self._r[3496]!, [_1])
}
- public var FastTwoStepSetup_PasswordSection: String { return self._s[3486]! }
- public var NetworkUsageSettings_ResetStatsConfirmation: String { return self._s[3489]! }
- public var InfoPlist_NSFaceIDUsageDescription: String { return self._s[3491]! }
- public var DialogList_NoMessagesText: String { return self._s[3492]! }
- public var Privacy_ContactsResetConfirmation: String { return self._s[3493]! }
- public var Privacy_Calls_P2PHelp: String { return self._s[3494]! }
- public var Channel_DiscussionGroup_SearchPlaceholder: String { return self._s[3496]! }
- public var Your_cards_expiration_year_is_invalid: String { return self._s[3497]! }
- public var Common_TakePhotoOrVideo: String { return self._s[3498]! }
- public var Wallet_Words_Text: String { return self._s[3499]! }
- public var Call_StatusBusy: String { return self._s[3500]! }
- public var Conversation_PinnedMessage: String { return self._s[3501]! }
- public var AutoDownloadSettings_VoiceMessagesTitle: String { return self._s[3502]! }
- public var Wallet_Configuration_BlockchainNameChangedProceed: String { return self._s[3503]! }
- public var TwoStepAuth_SetupPasswordConfirmFailed: String { return self._s[3504]! }
- public var Undo_ChatCleared: String { return self._s[3505]! }
- public var AppleWatch_ReplyPresets: String { return self._s[3506]! }
- public var Passport_DiscardMessageDescription: String { return self._s[3508]! }
- public var Login_NetworkError: String { return self._s[3509]! }
+ public var FastTwoStepSetup_PasswordSection: String { return self._s[3497]! }
+ public var NetworkUsageSettings_ResetStatsConfirmation: String { return self._s[3500]! }
+ public var InfoPlist_NSFaceIDUsageDescription: String { return self._s[3502]! }
+ public var DialogList_NoMessagesText: String { return self._s[3503]! }
+ public var Privacy_ContactsResetConfirmation: String { return self._s[3504]! }
+ public var Privacy_Calls_P2PHelp: String { return self._s[3505]! }
+ public var Channel_DiscussionGroup_SearchPlaceholder: String { return self._s[3507]! }
+ public var Your_cards_expiration_year_is_invalid: String { return self._s[3508]! }
+ public var Common_TakePhotoOrVideo: String { return self._s[3509]! }
+ public var Wallet_Words_Text: String { return self._s[3510]! }
+ public var Call_StatusBusy: String { return self._s[3511]! }
+ public var Conversation_PinnedMessage: String { return self._s[3512]! }
+ public var AutoDownloadSettings_VoiceMessagesTitle: String { return self._s[3513]! }
+ public var Wallet_Configuration_BlockchainNameChangedProceed: String { return self._s[3514]! }
+ public var TwoStepAuth_SetupPasswordConfirmFailed: String { return self._s[3515]! }
+ public var Undo_ChatCleared: String { return self._s[3516]! }
+ public var AppleWatch_ReplyPresets: String { return self._s[3517]! }
+ public var Passport_DiscardMessageDescription: String { return self._s[3519]! }
+ public var Login_NetworkError: String { return self._s[3520]! }
public func Notification_PinnedRoundMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3510]!, self._r[3510]!, [_0])
+ return formatWithArgumentRanges(self._s[3521]!, self._r[3521]!, [_0])
}
public func Channel_AdminLog_MessageRemovedChannelUsername(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3511]!, self._r[3511]!, [_0])
+ return formatWithArgumentRanges(self._s[3522]!, self._r[3522]!, [_0])
}
- public var SocksProxySetup_PasswordPlaceholder: String { return self._s[3512]! }
- public var Wallet_WordCheck_ViewWords: String { return self._s[3514]! }
- public var Login_ResetAccountProtected_LimitExceeded: String { return self._s[3515]! }
+ public var SocksProxySetup_PasswordPlaceholder: String { return self._s[3523]! }
+ public var Wallet_WordCheck_ViewWords: String { return self._s[3525]! }
+ public var Login_ResetAccountProtected_LimitExceeded: String { return self._s[3526]! }
public func Watch_LastSeen_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3517]!, self._r[3517]!, [_0])
+ return formatWithArgumentRanges(self._s[3528]!, self._r[3528]!, [_0])
}
- public var Call_ConnectionErrorMessage: String { return self._s[3518]! }
- public var VoiceOver_Chat_Music: String { return self._s[3519]! }
- public var SettingsSearch_Synonyms_Notifications_MessageNotificationsSound: String { return self._s[3520]! }
- public var Compose_GroupTokenListPlaceholder: String { return self._s[3522]! }
- public var ConversationMedia_Title: String { return self._s[3523]! }
- public var EncryptionKey_Title: String { return self._s[3525]! }
- public var TwoStepAuth_EnterPasswordTitle: String { return self._s[3526]! }
- public var Notification_Exceptions_AddException: String { return self._s[3527]! }
- public var PrivacySettings_BlockedPeersEmpty: String { return self._s[3528]! }
- public var Profile_MessageLifetime1m: String { return self._s[3529]! }
+ public var Call_ConnectionErrorMessage: String { return self._s[3529]! }
+ public var VoiceOver_Chat_Music: String { return self._s[3530]! }
+ public var SettingsSearch_Synonyms_Notifications_MessageNotificationsSound: String { return self._s[3531]! }
+ public var Compose_GroupTokenListPlaceholder: String { return self._s[3533]! }
+ public var ConversationMedia_Title: String { return self._s[3534]! }
+ public var EncryptionKey_Title: String { return self._s[3536]! }
+ public var TwoStepAuth_EnterPasswordTitle: String { return self._s[3537]! }
+ public var Notification_Exceptions_AddException: String { return self._s[3538]! }
+ public var PrivacySettings_BlockedPeersEmpty: String { return self._s[3539]! }
+ public var Profile_MessageLifetime1m: String { return self._s[3540]! }
public func Channel_AdminLog_MessageUnkickedName(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3530]!, self._r[3530]!, [_1])
+ return formatWithArgumentRanges(self._s[3541]!, self._r[3541]!, [_1])
}
- public var Month_GenMay: String { return self._s[3531]! }
+ public var Month_GenMay: String { return self._s[3542]! }
public func LiveLocationUpdated_TodayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3532]!, self._r[3532]!, [_0])
+ return formatWithArgumentRanges(self._s[3543]!, self._r[3543]!, [_0])
}
- public var PeopleNearby_Users: String { return self._s[3533]! }
- public var Wallet_Send_AddressInfo: String { return self._s[3534]! }
- public var ChannelMembers_WhoCanAddMembersAllHelp: String { return self._s[3535]! }
- public var AutoDownloadSettings_ResetSettings: String { return self._s[3536]! }
+ public var PeopleNearby_Users: String { return self._s[3544]! }
+ public var Wallet_Send_AddressInfo: String { return self._s[3545]! }
+ public var ChannelMembers_WhoCanAddMembersAllHelp: String { return self._s[3546]! }
+ public var AutoDownloadSettings_ResetSettings: String { return self._s[3547]! }
public func Wallet_Updated_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3538]!, self._r[3538]!, [_0])
+ return formatWithArgumentRanges(self._s[3549]!, self._r[3549]!, [_0])
}
- public var Conversation_EmptyPlaceholder: String { return self._s[3539]! }
- public var Passport_Address_AddPassportRegistration: String { return self._s[3540]! }
- public var Notifications_ChannelNotificationsAlert: String { return self._s[3541]! }
- public var ChatSettings_AutoDownloadUsingCellular: String { return self._s[3542]! }
- public var Camera_TapAndHoldForVideo: String { return self._s[3543]! }
- public var Channel_JoinChannel: String { return self._s[3545]! }
- public var Appearance_Animations: String { return self._s[3548]! }
+ public var Conversation_EmptyPlaceholder: String { return self._s[3550]! }
+ public var Passport_Address_AddPassportRegistration: String { return self._s[3551]! }
+ public var Notifications_ChannelNotificationsAlert: String { return self._s[3552]! }
+ public var ChatSettings_AutoDownloadUsingCellular: String { return self._s[3553]! }
+ public var Camera_TapAndHoldForVideo: String { return self._s[3554]! }
+ public var Channel_JoinChannel: String { return self._s[3556]! }
+ public var Appearance_Animations: String { return self._s[3559]! }
public func Notification_MessageLifetimeChanged(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3549]!, self._r[3549]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3560]!, self._r[3560]!, [_1, _2])
}
- public var Stickers_GroupStickers: String { return self._s[3551]! }
- public var Appearance_ShareTheme: String { return self._s[3552]! }
- public var TwoFactorSetup_Hint_Placeholder: String { return self._s[3553]! }
- public var ConvertToSupergroup_HelpTitle: String { return self._s[3555]! }
- public var StickerPackActionInfo_RemovedTitle: String { return self._s[3556]! }
- public var Passport_Address_Street: String { return self._s[3557]! }
- public var Conversation_AddContact: String { return self._s[3558]! }
- public var Login_PhonePlaceholder: String { return self._s[3559]! }
- public var Channel_Members_InviteLink: String { return self._s[3561]! }
- public var Bot_Stop: String { return self._s[3562]! }
- public var SettingsSearch_Synonyms_Proxy_UseForCalls: String { return self._s[3564]! }
- public var Notification_PassportValueAddress: String { return self._s[3565]! }
- public var Month_ShortJuly: String { return self._s[3566]! }
- public var Passport_Address_TypeTemporaryRegistrationUploadScan: String { return self._s[3567]! }
- public var Channel_AdminLog_BanSendMedia: String { return self._s[3568]! }
- public var Passport_Identity_ReverseSide: String { return self._s[3569]! }
- public var Watch_Stickers_Recents: String { return self._s[3572]! }
- public var PrivacyLastSeenSettings_EmpryUsersPlaceholder: String { return self._s[3574]! }
- public var Map_SendThisLocation: String { return self._s[3575]! }
+ public var Stickers_GroupStickers: String { return self._s[3562]! }
+ public var Appearance_ShareTheme: String { return self._s[3563]! }
+ public var TwoFactorSetup_Hint_Placeholder: String { return self._s[3564]! }
+ public var ConvertToSupergroup_HelpTitle: String { return self._s[3566]! }
+ public var StickerPackActionInfo_RemovedTitle: String { return self._s[3567]! }
+ public var Passport_Address_Street: String { return self._s[3568]! }
+ public var Conversation_AddContact: String { return self._s[3569]! }
+ public var Login_PhonePlaceholder: String { return self._s[3570]! }
+ public var Channel_Members_InviteLink: String { return self._s[3572]! }
+ public var Bot_Stop: String { return self._s[3573]! }
+ public var SettingsSearch_Synonyms_Proxy_UseForCalls: String { return self._s[3575]! }
+ public var Notification_PassportValueAddress: String { return self._s[3576]! }
+ public var Month_ShortJuly: String { return self._s[3577]! }
+ public var Passport_Address_TypeTemporaryRegistrationUploadScan: String { return self._s[3578]! }
+ public var Channel_AdminLog_BanSendMedia: String { return self._s[3579]! }
+ public var Passport_Identity_ReverseSide: String { return self._s[3580]! }
+ public var Watch_Stickers_Recents: String { return self._s[3583]! }
+ public var PrivacyLastSeenSettings_EmpryUsersPlaceholder: String { return self._s[3585]! }
+ public var Map_SendThisLocation: String { return self._s[3586]! }
public func Time_MonthOfYear_m1(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3576]!, self._r[3576]!, [_0])
+ return formatWithArgumentRanges(self._s[3587]!, self._r[3587]!, [_0])
}
public func InviteText_SingleContact(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3577]!, self._r[3577]!, [_0])
+ return formatWithArgumentRanges(self._s[3588]!, self._r[3588]!, [_0])
}
- public var ConvertToSupergroup_Note: String { return self._s[3578]! }
- public var Wallet_Intro_NotNow: String { return self._s[3579]! }
+ public var ConvertToSupergroup_Note: String { return self._s[3589]! }
+ public var Wallet_Intro_NotNow: String { return self._s[3590]! }
public func FileSize_MB(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3580]!, self._r[3580]!, [_0])
+ return formatWithArgumentRanges(self._s[3591]!, self._r[3591]!, [_0])
}
- public var NetworkUsageSettings_GeneralDataSection: String { return self._s[3581]! }
+ public var NetworkUsageSettings_GeneralDataSection: String { return self._s[3592]! }
public func Compatibility_SecretMediaVersionTooLow(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3582]!, self._r[3582]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[3593]!, self._r[3593]!, [_0, _1])
}
- public var Login_CallRequestState3: String { return self._s[3584]! }
- public var Wallpaper_SearchShort: String { return self._s[3585]! }
- public var SettingsSearch_Synonyms_Appearance_ColorTheme: String { return self._s[3587]! }
- public var PasscodeSettings_UnlockWithFaceId: String { return self._s[3588]! }
- public var Channel_BotDoesntSupportGroups: String { return self._s[3589]! }
+ public var Login_CallRequestState3: String { return self._s[3595]! }
+ public var Wallpaper_SearchShort: String { return self._s[3596]! }
+ public var SettingsSearch_Synonyms_Appearance_ColorTheme: String { return self._s[3598]! }
+ public var PasscodeSettings_UnlockWithFaceId: String { return self._s[3599]! }
+ public var Channel_BotDoesntSupportGroups: String { return self._s[3600]! }
public func PUSH_CHAT_MESSAGE_GEOLIVE(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3590]!, self._r[3590]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3601]!, self._r[3601]!, [_1, _2])
}
- public var Channel_AdminLogFilter_Title: String { return self._s[3591]! }
- public var Appearance_ThemePreview_Chat_4_Text: String { return self._s[3593]! }
- public var Notifications_GroupNotificationsExceptions: String { return self._s[3596]! }
+ public var Channel_AdminLogFilter_Title: String { return self._s[3602]! }
+ public var Appearance_ThemePreview_Chat_4_Text: String { return self._s[3604]! }
+ public var Notifications_GroupNotificationsExceptions: String { return self._s[3607]! }
public func FileSize_B(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3597]!, self._r[3597]!, [_0])
+ return formatWithArgumentRanges(self._s[3608]!, self._r[3608]!, [_0])
}
- public var Passport_CorrectErrors: String { return self._s[3598]! }
- public var VoiceOver_Chat_YourAnonymousPoll: String { return self._s[3599]! }
+ public var Passport_CorrectErrors: String { return self._s[3609]! }
+ public var VoiceOver_Chat_YourAnonymousPoll: String { return self._s[3610]! }
public func Channel_MessageTitleUpdated(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3600]!, self._r[3600]!, [_0])
+ return formatWithArgumentRanges(self._s[3611]!, self._r[3611]!, [_0])
}
- public var Map_SendMyCurrentLocation: String { return self._s[3601]! }
- public var Channel_DiscussionGroup: String { return self._s[3602]! }
- public var TwoFactorSetup_Email_SkipConfirmationSkip: String { return self._s[3603]! }
+ public var Map_SendMyCurrentLocation: String { return self._s[3612]! }
+ public var Channel_DiscussionGroup: String { return self._s[3613]! }
+ public var TwoFactorSetup_Email_SkipConfirmationSkip: String { return self._s[3614]! }
public func PUSH_PINNED_CONTACT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3604]!, self._r[3604]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3615]!, self._r[3615]!, [_1, _2])
}
- public var SharedMedia_SearchNoResults: String { return self._s[3605]! }
- public var Permissions_NotificationsText_v0: String { return self._s[3606]! }
- public var Channel_EditAdmin_PermissionDeleteMessagesOfOthers: String { return self._s[3607]! }
- public var Appearance_AppIcon: String { return self._s[3608]! }
- public var Appearance_ThemePreview_ChatList_3_AuthorName: String { return self._s[3609]! }
- public var LoginPassword_FloodError: String { return self._s[3610]! }
- public var Wallet_Send_OwnAddressAlertProceed: String { return self._s[3612]! }
- public var Group_Setup_HistoryHiddenHelp: String { return self._s[3613]! }
+ public var SharedMedia_SearchNoResults: String { return self._s[3616]! }
+ public var Permissions_NotificationsText_v0: String { return self._s[3617]! }
+ public var Channel_EditAdmin_PermissionDeleteMessagesOfOthers: String { return self._s[3618]! }
+ public var Appearance_AppIcon: String { return self._s[3619]! }
+ public var Appearance_ThemePreview_ChatList_3_AuthorName: String { return self._s[3620]! }
+ public var LoginPassword_FloodError: String { return self._s[3621]! }
+ public var Wallet_Send_OwnAddressAlertProceed: String { return self._s[3623]! }
+ public var Group_Setup_HistoryHiddenHelp: String { return self._s[3624]! }
public func TwoStepAuth_PendingEmailHelp(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3614]!, self._r[3614]!, [_0])
+ return formatWithArgumentRanges(self._s[3625]!, self._r[3625]!, [_0])
}
- public var Passport_Language_bn: String { return self._s[3615]! }
+ public var Passport_Language_bn: String { return self._s[3626]! }
public func DialogList_SingleUploadingPhotoSuffix(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3616]!, self._r[3616]!, [_0])
+ return formatWithArgumentRanges(self._s[3627]!, self._r[3627]!, [_0])
}
- public var ChatList_Context_Pin: String { return self._s[3617]! }
+ public var ChatList_Context_Pin: String { return self._s[3628]! }
public func Notification_PinnedAudioMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3618]!, self._r[3618]!, [_0])
+ return formatWithArgumentRanges(self._s[3629]!, self._r[3629]!, [_0])
}
public func Channel_AdminLog_MessageChangedGroupStickerPack(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3619]!, self._r[3619]!, [_0])
+ return formatWithArgumentRanges(self._s[3630]!, self._r[3630]!, [_0])
}
- public var Wallet_Navigation_Close: String { return self._s[3620]! }
- public var GroupInfo_InvitationLinkGroupFull: String { return self._s[3624]! }
- public var Group_EditAdmin_PermissionChangeInfo: String { return self._s[3626]! }
- public var Wallet_Month_GenDecember: String { return self._s[3627]! }
- public var Contacts_PermissionsAllow: String { return self._s[3628]! }
- public var ReportPeer_ReasonCopyright: String { return self._s[3629]! }
- public var Channel_EditAdmin_PermissinAddAdminOn: String { return self._s[3630]! }
- public var WallpaperPreview_Pattern: String { return self._s[3631]! }
- public var Paint_Duplicate: String { return self._s[3632]! }
- public var Passport_Address_Country: String { return self._s[3633]! }
- public var Notification_RenamedChannel: String { return self._s[3635]! }
- public var ChatList_Context_Unmute: String { return self._s[3636]! }
- public var CheckoutInfo_ErrorPostcodeInvalid: String { return self._s[3637]! }
- public var Group_MessagePhotoUpdated: String { return self._s[3638]! }
- public var Channel_BanUser_PermissionSendMedia: String { return self._s[3639]! }
- public var Conversation_ContextMenuBan: String { return self._s[3640]! }
- public var TwoStepAuth_EmailSent: String { return self._s[3641]! }
- public var MessagePoll_NoVotes: String { return self._s[3642]! }
- public var Wallet_Send_ErrorNotEnoughFundsTitle: String { return self._s[3643]! }
- public var Passport_Language_is: String { return self._s[3645]! }
- public var PeopleNearby_UsersEmpty: String { return self._s[3647]! }
- public var Tour_Text5: String { return self._s[3648]! }
+ public var Wallet_Navigation_Close: String { return self._s[3631]! }
+ public var GroupInfo_InvitationLinkGroupFull: String { return self._s[3635]! }
+ public var Group_EditAdmin_PermissionChangeInfo: String { return self._s[3637]! }
+ public var Wallet_Month_GenDecember: String { return self._s[3638]! }
+ public var Contacts_PermissionsAllow: String { return self._s[3639]! }
+ public var ReportPeer_ReasonCopyright: String { return self._s[3640]! }
+ public var Channel_EditAdmin_PermissinAddAdminOn: String { return self._s[3641]! }
+ public var WallpaperPreview_Pattern: String { return self._s[3642]! }
+ public var Paint_Duplicate: String { return self._s[3643]! }
+ public var Passport_Address_Country: String { return self._s[3644]! }
+ public var Notification_RenamedChannel: String { return self._s[3646]! }
+ public var ChatList_Context_Unmute: String { return self._s[3647]! }
+ public var CheckoutInfo_ErrorPostcodeInvalid: String { return self._s[3648]! }
+ public var Group_MessagePhotoUpdated: String { return self._s[3649]! }
+ public var Channel_BanUser_PermissionSendMedia: String { return self._s[3650]! }
+ public var Conversation_ContextMenuBan: String { return self._s[3651]! }
+ public var TwoStepAuth_EmailSent: String { return self._s[3652]! }
+ public var MessagePoll_NoVotes: String { return self._s[3653]! }
+ public var Wallet_Send_ErrorNotEnoughFundsTitle: String { return self._s[3654]! }
+ public var Passport_Language_is: String { return self._s[3656]! }
+ public var PeopleNearby_UsersEmpty: String { return self._s[3658]! }
+ public var Tour_Text5: String { return self._s[3659]! }
public func Call_GroupFormat(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3651]!, self._r[3651]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[3662]!, self._r[3662]!, [_1, _2])
}
- public var Undo_SecretChatDeleted: String { return self._s[3652]! }
- public var SocksProxySetup_ShareQRCode: String { return self._s[3653]! }
+ public var Undo_SecretChatDeleted: String { return self._s[3663]! }
+ public var SocksProxySetup_ShareQRCode: String { return self._s[3664]! }
public func VoiceOver_Chat_Size(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3654]!, self._r[3654]!, [_0])
+ return formatWithArgumentRanges(self._s[3665]!, self._r[3665]!, [_0])
}
- public var Forward_ErrorDisabledForChat: String { return self._s[3655]! }
- public var LogoutOptions_ChangePhoneNumberText: String { return self._s[3656]! }
- public var Paint_Edit: String { return self._s[3658]! }
- public var ScheduledMessages_ReminderNotification: String { return self._s[3660]! }
- public var Undo_DeletedGroup: String { return self._s[3662]! }
- public var LoginPassword_ForgotPassword: String { return self._s[3663]! }
- public var Wallet_WordImport_IncorrectTitle: String { return self._s[3664]! }
- public var GroupInfo_GroupNamePlaceholder: String { return self._s[3665]! }
+ public var Forward_ErrorDisabledForChat: String { return self._s[3666]! }
+ public var LogoutOptions_ChangePhoneNumberText: String { return self._s[3667]! }
+ public var Paint_Edit: String { return self._s[3669]! }
+ public var ScheduledMessages_ReminderNotification: String { return self._s[3671]! }
+ public var Undo_DeletedGroup: String { return self._s[3673]! }
+ public var LoginPassword_ForgotPassword: String { return self._s[3674]! }
+ public var Wallet_WordImport_IncorrectTitle: String { return self._s[3675]! }
+ public var GroupInfo_GroupNamePlaceholder: String { return self._s[3676]! }
public func Notification_Kicked(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3666]!, self._r[3666]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[3677]!, self._r[3677]!, [_0, _1])
}
- public var AppWallet_TransactionInfo_FeeInfoURL: String { return self._s[3667]! }
- public var Conversation_InputTextCaptionPlaceholder: String { return self._s[3668]! }
- public var AutoDownloadSettings_VideoMessagesTitle: String { return self._s[3669]! }
- public var Passport_Language_uz: String { return self._s[3670]! }
- public var Conversation_PinMessageAlertGroup: String { return self._s[3671]! }
- public var SettingsSearch_Synonyms_Privacy_GroupsAndChannels: String { return self._s[3672]! }
- public var Map_StopLiveLocation: String { return self._s[3674]! }
- public var VoiceOver_MessageContextSend: String { return self._s[3676]! }
- public var PasscodeSettings_Help: String { return self._s[3677]! }
- public var NotificationsSound_Input: String { return self._s[3678]! }
- public var Share_Title: String { return self._s[3681]! }
- public var LogoutOptions_Title: String { return self._s[3682]! }
- public var Wallet_Send_AddressText: String { return self._s[3683]! }
- public var Login_TermsOfServiceAgree: String { return self._s[3684]! }
- public var Compose_NewEncryptedChatTitle: String { return self._s[3685]! }
- public var Channel_AdminLog_TitleSelectedEvents: String { return self._s[3686]! }
- public var Channel_EditAdmin_PermissionEditMessages: String { return self._s[3687]! }
- public var EnterPasscode_EnterTitle: String { return self._s[3688]! }
+ public var AppWallet_TransactionInfo_FeeInfoURL: String { return self._s[3678]! }
+ public var Conversation_InputTextCaptionPlaceholder: String { return self._s[3679]! }
+ public var AutoDownloadSettings_VideoMessagesTitle: String { return self._s[3680]! }
+ public var Passport_Language_uz: String { return self._s[3681]! }
+ public var Conversation_PinMessageAlertGroup: String { return self._s[3682]! }
+ public var SettingsSearch_Synonyms_Privacy_GroupsAndChannels: String { return self._s[3683]! }
+ public var Map_StopLiveLocation: String { return self._s[3685]! }
+ public var VoiceOver_MessageContextSend: String { return self._s[3687]! }
+ public var PasscodeSettings_Help: String { return self._s[3688]! }
+ public var NotificationsSound_Input: String { return self._s[3689]! }
+ public var Share_Title: String { return self._s[3692]! }
+ public var LogoutOptions_Title: String { return self._s[3693]! }
+ public var Wallet_Send_AddressText: String { return self._s[3694]! }
+ public var Login_TermsOfServiceAgree: String { return self._s[3695]! }
+ public var Compose_NewEncryptedChatTitle: String { return self._s[3696]! }
+ public var Channel_AdminLog_TitleSelectedEvents: String { return self._s[3697]! }
+ public var Channel_EditAdmin_PermissionEditMessages: String { return self._s[3698]! }
+ public var EnterPasscode_EnterTitle: String { return self._s[3699]! }
public func Call_PrivacyErrorMessage(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3689]!, self._r[3689]!, [_0])
+ return formatWithArgumentRanges(self._s[3700]!, self._r[3700]!, [_0])
}
- public var Settings_CopyPhoneNumber: String { return self._s[3690]! }
- public var Conversation_AddToContacts: String { return self._s[3691]! }
+ public var Settings_CopyPhoneNumber: String { return self._s[3701]! }
+ public var Conversation_AddToContacts: String { return self._s[3702]! }
public func VoiceOver_Chat_ReplyFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3692]!, self._r[3692]!, [_0])
- }
- public var NotificationsSound_Keys: String { return self._s[3693]! }
- public func Call_ParticipantVersionOutdatedError(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3694]!, self._r[3694]!, [_0])
- }
- public var Notification_MessageLifetime1w: String { return self._s[3695]! }
- public var Message_Video: String { return self._s[3696]! }
- public var AutoDownloadSettings_CellularTitle: String { return self._s[3697]! }
- public func PUSH_CHANNEL_MESSAGE_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3698]!, self._r[3698]!, [_1])
- }
- public var Wallet_Receive_AmountInfo: String { return self._s[3701]! }
- public func Notification_JoinedChat(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3702]!, self._r[3702]!, [_0])
- }
- public func PrivacySettings_LastSeenContactsPlus(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[3703]!, self._r[3703]!, [_0])
}
- public var Passport_Language_mk: String { return self._s[3704]! }
- public func Wallet_Time_PreciseDate_m2(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3705]!, self._r[3705]!, [_1, _2, _3])
+ public var NotificationsSound_Keys: String { return self._s[3704]! }
+ public func Call_ParticipantVersionOutdatedError(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[3705]!, self._r[3705]!, [_0])
}
- public var CreatePoll_CancelConfirmation: String { return self._s[3706]! }
- public var MessagePoll_LabelAnonymousQuiz: String { return self._s[3707]! }
- public var Conversation_SilentBroadcastTooltipOn: String { return self._s[3709]! }
- public var PrivacyPolicy_Decline: String { return self._s[3710]! }
- public var Passport_Identity_DoesNotExpire: String { return self._s[3711]! }
- public var Channel_AdminLogFilter_EventsRestrictions: String { return self._s[3712]! }
- public var AuthSessions_AddDeviceIntro_Action: String { return self._s[3713]! }
- public var Permissions_SiriAllow_v0: String { return self._s[3715]! }
- public var Wallet_Month_ShortAugust: String { return self._s[3716]! }
- public var Appearance_ThemeCarouselNight: String { return self._s[3717]! }
+ public var Notification_MessageLifetime1w: String { return self._s[3706]! }
+ public var Message_Video: String { return self._s[3707]! }
+ public var AutoDownloadSettings_CellularTitle: String { return self._s[3708]! }
+ public func PUSH_CHANNEL_MESSAGE_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[3709]!, self._r[3709]!, [_1])
+ }
+ public var Wallet_Receive_AmountInfo: String { return self._s[3712]! }
+ public func Notification_JoinedChat(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[3713]!, self._r[3713]!, [_0])
+ }
+ public func PrivacySettings_LastSeenContactsPlus(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[3714]!, self._r[3714]!, [_0])
+ }
+ public var Passport_Language_mk: String { return self._s[3715]! }
+ public func Wallet_Time_PreciseDate_m2(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[3716]!, self._r[3716]!, [_1, _2, _3])
+ }
+ public var CreatePoll_CancelConfirmation: String { return self._s[3717]! }
+ public var MessagePoll_LabelAnonymousQuiz: String { return self._s[3718]! }
+ public var Conversation_SilentBroadcastTooltipOn: String { return self._s[3720]! }
+ public var PrivacyPolicy_Decline: String { return self._s[3721]! }
+ public var Passport_Identity_DoesNotExpire: String { return self._s[3722]! }
+ public var Channel_AdminLogFilter_EventsRestrictions: String { return self._s[3723]! }
+ public var AuthSessions_AddDeviceIntro_Action: String { return self._s[3724]! }
+ public var Permissions_SiriAllow_v0: String { return self._s[3726]! }
+ public var Wallet_Month_ShortAugust: String { return self._s[3727]! }
+ public var Appearance_ThemeCarouselNight: String { return self._s[3728]! }
public func LOCAL_CHAT_MESSAGE_FWDS(_ _1: String, _ _2: Int) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3718]!, self._r[3718]!, [_1, "\(_2)"])
+ return formatWithArgumentRanges(self._s[3729]!, self._r[3729]!, [_1, "\(_2)"])
}
public func Notification_RenamedChat(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3719]!, self._r[3719]!, [_0])
+ return formatWithArgumentRanges(self._s[3730]!, self._r[3730]!, [_0])
}
- public var Paint_Regular: String { return self._s[3720]! }
- public var ChatSettings_AutoDownloadReset: String { return self._s[3721]! }
- public var SocksProxySetup_ShareLink: String { return self._s[3722]! }
- public var Wallet_Qr_Title: String { return self._s[3723]! }
- public var BlockedUsers_SelectUserTitle: String { return self._s[3724]! }
- public var VoiceOver_Chat_RecordModeVoiceMessage: String { return self._s[3726]! }
- public var Wallet_Settings_Configuration: String { return self._s[3727]! }
- public var GroupInfo_InviteByLink: String { return self._s[3728]! }
- public var MessageTimer_Custom: String { return self._s[3729]! }
- public var UserInfo_NotificationsDefaultEnabled: String { return self._s[3730]! }
- public var Conversation_StopQuizConfirmationTitle: String { return self._s[3731]! }
- public var Passport_Address_TypeTemporaryRegistration: String { return self._s[3733]! }
- public var Conversation_SendMessage_SetReminder: String { return self._s[3734]! }
- public var VoiceOver_Chat_Selected: String { return self._s[3735]! }
- public var ChatSettings_AutoDownloadUsingWiFi: String { return self._s[3736]! }
- public var Channel_Username_InvalidTaken: String { return self._s[3737]! }
- public var Conversation_ClousStorageInfo_Description3: String { return self._s[3738]! }
- public var Wallet_WordCheck_TryAgain: String { return self._s[3739]! }
- public var Wallet_Info_TransactionPendingHeader: String { return self._s[3740]! }
- public var Settings_ChatBackground: String { return self._s[3741]! }
- public var Channel_Subscribers_Title: String { return self._s[3742]! }
- public var Wallet_Receive_InvoiceUrlHeader: String { return self._s[3743]! }
- public var ApplyLanguage_ChangeLanguageTitle: String { return self._s[3744]! }
- public var Watch_ConnectionDescription: String { return self._s[3745]! }
- public var OldChannels_NoticeText: String { return self._s[3748]! }
- public var Wallet_Configuration_ApplyErrorTitle: String { return self._s[3749]! }
- public var IntentsSettings_SuggestBy: String { return self._s[3751]! }
- public var Theme_ThemeChangedText: String { return self._s[3752]! }
- public var ChatList_ArchivedChatsTitle: String { return self._s[3753]! }
- public var Wallpaper_ResetWallpapers: String { return self._s[3754]! }
- public var Wallet_Send_TransactionInProgress: String { return self._s[3755]! }
- public var EditProfile_Title: String { return self._s[3756]! }
- public var NotificationsSound_Bamboo: String { return self._s[3758]! }
- public var Channel_AdminLog_MessagePreviousMessage: String { return self._s[3760]! }
- public var Login_SmsRequestState2: String { return self._s[3761]! }
- public var Passport_Language_ar: String { return self._s[3762]! }
+ public var Paint_Regular: String { return self._s[3731]! }
+ public var ChatSettings_AutoDownloadReset: String { return self._s[3732]! }
+ public var SocksProxySetup_ShareLink: String { return self._s[3733]! }
+ public var Wallet_Qr_Title: String { return self._s[3734]! }
+ public var BlockedUsers_SelectUserTitle: String { return self._s[3735]! }
+ public var VoiceOver_Chat_RecordModeVoiceMessage: String { return self._s[3737]! }
+ public var Wallet_Settings_Configuration: String { return self._s[3738]! }
+ public var GroupInfo_InviteByLink: String { return self._s[3739]! }
+ public var MessageTimer_Custom: String { return self._s[3740]! }
+ public var UserInfo_NotificationsDefaultEnabled: String { return self._s[3741]! }
+ public var Conversation_StopQuizConfirmationTitle: String { return self._s[3742]! }
+ public var Passport_Address_TypeTemporaryRegistration: String { return self._s[3744]! }
+ public var Conversation_SendMessage_SetReminder: String { return self._s[3745]! }
+ public var VoiceOver_Chat_Selected: String { return self._s[3746]! }
+ public var ChatSettings_AutoDownloadUsingWiFi: String { return self._s[3747]! }
+ public var Channel_Username_InvalidTaken: String { return self._s[3748]! }
+ public var Conversation_ClousStorageInfo_Description3: String { return self._s[3749]! }
+ public var Wallet_WordCheck_TryAgain: String { return self._s[3750]! }
+ public var Wallet_Info_TransactionPendingHeader: String { return self._s[3751]! }
+ public var Settings_ChatBackground: String { return self._s[3752]! }
+ public var Channel_Subscribers_Title: String { return self._s[3753]! }
+ public var Wallet_Receive_InvoiceUrlHeader: String { return self._s[3754]! }
+ public var ApplyLanguage_ChangeLanguageTitle: String { return self._s[3755]! }
+ public var Watch_ConnectionDescription: String { return self._s[3756]! }
+ public var OldChannels_NoticeText: String { return self._s[3759]! }
+ public var Wallet_Configuration_ApplyErrorTitle: String { return self._s[3760]! }
+ public var IntentsSettings_SuggestBy: String { return self._s[3762]! }
+ public var Theme_ThemeChangedText: String { return self._s[3763]! }
+ public var ChatList_ArchivedChatsTitle: String { return self._s[3764]! }
+ public var Wallpaper_ResetWallpapers: String { return self._s[3765]! }
+ public var Wallet_Send_TransactionInProgress: String { return self._s[3766]! }
+ public var EditProfile_Title: String { return self._s[3767]! }
+ public var NotificationsSound_Bamboo: String { return self._s[3769]! }
+ public var Channel_AdminLog_MessagePreviousMessage: String { return self._s[3771]! }
+ public var Login_SmsRequestState2: String { return self._s[3772]! }
+ public var Passport_Language_ar: String { return self._s[3773]! }
public func Message_AuthorPinnedGame(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3763]!, self._r[3763]!, [_0])
+ return formatWithArgumentRanges(self._s[3774]!, self._r[3774]!, [_0])
}
- public var SettingsSearch_Synonyms_EditProfile_Title: String { return self._s[3764]! }
- public var Wallet_Created_Text: String { return self._s[3765]! }
- public var Conversation_MessageDialogEdit: String { return self._s[3767]! }
- public var Wallet_Created_Proceed: String { return self._s[3768]! }
- public var Wallet_Words_Done: String { return self._s[3769]! }
- public var VoiceOver_Media_PlaybackPause: String { return self._s[3770]! }
+ public var SettingsSearch_Synonyms_EditProfile_Title: String { return self._s[3775]! }
+ public var Wallet_Created_Text: String { return self._s[3776]! }
+ public var Conversation_MessageDialogEdit: String { return self._s[3778]! }
+ public var Wallet_Created_Proceed: String { return self._s[3779]! }
+ public var Wallet_Words_Done: String { return self._s[3780]! }
+ public var VoiceOver_Media_PlaybackPause: String { return self._s[3781]! }
public func PUSH_AUTH_UNKNOWN(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3771]!, self._r[3771]!, [_1])
+ return formatWithArgumentRanges(self._s[3782]!, self._r[3782]!, [_1])
}
- public var Common_Close: String { return self._s[3772]! }
- public var GroupInfo_PublicLink: String { return self._s[3773]! }
- public var Channel_OwnershipTransfer_ErrorPrivacyRestricted: String { return self._s[3774]! }
- public var SettingsSearch_Synonyms_Notifications_GroupNotificationsPreview: String { return self._s[3775]! }
+ public var Common_Close: String { return self._s[3783]! }
+ public var GroupInfo_PublicLink: String { return self._s[3784]! }
+ public var Channel_OwnershipTransfer_ErrorPrivacyRestricted: String { return self._s[3785]! }
+ public var SettingsSearch_Synonyms_Notifications_GroupNotificationsPreview: String { return self._s[3786]! }
public func Channel_AdminLog_MessageToggleInvitesOff(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3779]!, self._r[3779]!, [_0])
+ return formatWithArgumentRanges(self._s[3790]!, self._r[3790]!, [_0])
}
- public var UserInfo_About_Placeholder: String { return self._s[3780]! }
+ public var UserInfo_About_Placeholder: String { return self._s[3791]! }
public func Conversation_FileHowToText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3781]!, self._r[3781]!, [_0])
+ return formatWithArgumentRanges(self._s[3792]!, self._r[3792]!, [_0])
}
- public var GroupInfo_Permissions_SectionTitle: String { return self._s[3782]! }
- public var Channel_Info_Banned: String { return self._s[3784]! }
+ public var GroupInfo_Permissions_SectionTitle: String { return self._s[3793]! }
+ public var Channel_Info_Banned: String { return self._s[3795]! }
public func Time_MonthOfYear_m11(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3785]!, self._r[3785]!, [_0])
+ return formatWithArgumentRanges(self._s[3796]!, self._r[3796]!, [_0])
}
- public var Appearance_Other: String { return self._s[3786]! }
- public var Passport_Language_my: String { return self._s[3787]! }
- public var Group_Setup_BasicHistoryHiddenHelp: String { return self._s[3788]! }
+ public var Appearance_Other: String { return self._s[3797]! }
+ public var Passport_Language_my: String { return self._s[3798]! }
+ public var Group_Setup_BasicHistoryHiddenHelp: String { return self._s[3799]! }
public func Time_PreciseDate_m9(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3789]!, self._r[3789]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3800]!, self._r[3800]!, [_1, _2, _3])
}
- public var SettingsSearch_Synonyms_Privacy_PasscodeAndFaceId: String { return self._s[3790]! }
- public var IntentsSettings_SuggestedAndSpotlightChatsInfo: String { return self._s[3791]! }
- public var Preview_CopyAddress: String { return self._s[3792]! }
+ public var SettingsSearch_Synonyms_Privacy_PasscodeAndFaceId: String { return self._s[3801]! }
+ public var IntentsSettings_SuggestedAndSpotlightChatsInfo: String { return self._s[3802]! }
+ public var Preview_CopyAddress: String { return self._s[3803]! }
public func DialogList_SinglePlayingGameSuffix(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3793]!, self._r[3793]!, [_0])
+ return formatWithArgumentRanges(self._s[3804]!, self._r[3804]!, [_0])
}
- public var KeyCommand_JumpToPreviousChat: String { return self._s[3794]! }
- public var UserInfo_BotSettings: String { return self._s[3795]! }
- public var LiveLocation_MenuStopAll: String { return self._s[3797]! }
- public var Passport_PasswordCreate: String { return self._s[3798]! }
- public var StickerSettings_MaskContextInfo: String { return self._s[3799]! }
- public var Message_PinnedLocationMessage: String { return self._s[3800]! }
- public var Map_Satellite: String { return self._s[3801]! }
- public var Watch_Message_Unsupported: String { return self._s[3802]! }
- public var Username_TooManyPublicUsernamesError: String { return self._s[3803]! }
- public var TwoStepAuth_EnterPasswordInvalid: String { return self._s[3804]! }
+ public var KeyCommand_JumpToPreviousChat: String { return self._s[3805]! }
+ public var UserInfo_BotSettings: String { return self._s[3806]! }
+ public var LiveLocation_MenuStopAll: String { return self._s[3808]! }
+ public var Passport_PasswordCreate: String { return self._s[3809]! }
+ public var StickerSettings_MaskContextInfo: String { return self._s[3810]! }
+ public var Message_PinnedLocationMessage: String { return self._s[3811]! }
+ public var Map_Satellite: String { return self._s[3812]! }
+ public var Watch_Message_Unsupported: String { return self._s[3813]! }
+ public var Username_TooManyPublicUsernamesError: String { return self._s[3814]! }
+ public var TwoStepAuth_EnterPasswordInvalid: String { return self._s[3815]! }
public func Notification_PinnedTextMessage(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3805]!, self._r[3805]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[3816]!, self._r[3816]!, [_0, _1])
}
public func Conversation_OpenBotLinkText(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3806]!, self._r[3806]!, [_0])
+ return formatWithArgumentRanges(self._s[3817]!, self._r[3817]!, [_0])
}
- public var Wallet_WordImport_Continue: String { return self._s[3807]! }
+ public var Wallet_WordImport_Continue: String { return self._s[3818]! }
public func TwoFactorSetup_EmailVerification_Text(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3808]!, self._r[3808]!, [_0])
+ return formatWithArgumentRanges(self._s[3819]!, self._r[3819]!, [_0])
}
- public var Notifications_ChannelNotificationsHelp: String { return self._s[3809]! }
- public var Privacy_Calls_P2PContacts: String { return self._s[3810]! }
- public var NotificationsSound_None: String { return self._s[3811]! }
- public var Wallet_TransactionInfo_StorageFeeHeader: String { return self._s[3812]! }
- public var Channel_DiscussionGroup_UnlinkGroup: String { return self._s[3814]! }
- public var AccessDenied_VoiceMicrophone: String { return self._s[3815]! }
+ public var Notifications_ChannelNotificationsHelp: String { return self._s[3820]! }
+ public var Privacy_Calls_P2PContacts: String { return self._s[3821]! }
+ public var NotificationsSound_None: String { return self._s[3822]! }
+ public var Wallet_TransactionInfo_StorageFeeHeader: String { return self._s[3823]! }
+ public var Channel_DiscussionGroup_UnlinkGroup: String { return self._s[3825]! }
+ public var AccessDenied_VoiceMicrophone: String { return self._s[3826]! }
public func ApplyLanguage_ChangeLanguageAlreadyActive(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3816]!, self._r[3816]!, [_1])
+ return formatWithArgumentRanges(self._s[3827]!, self._r[3827]!, [_1])
}
- public var Cache_Indexing: String { return self._s[3817]! }
- public var DialogList_RecentTitlePeople: String { return self._s[3819]! }
- public var DialogList_EncryptionRejected: String { return self._s[3820]! }
- public var GroupInfo_Administrators: String { return self._s[3821]! }
- public var Passport_ScanPassportHelp: String { return self._s[3822]! }
- public var Application_Name: String { return self._s[3823]! }
- public var Channel_AdminLogFilter_ChannelEventsInfo: String { return self._s[3824]! }
- public var Appearance_ThemeCarouselDay: String { return self._s[3826]! }
- public var Passport_Identity_TranslationHelp: String { return self._s[3827]! }
+ public var Cache_Indexing: String { return self._s[3828]! }
+ public var DialogList_RecentTitlePeople: String { return self._s[3830]! }
+ public var DialogList_EncryptionRejected: String { return self._s[3831]! }
+ public var GroupInfo_Administrators: String { return self._s[3832]! }
+ public var Passport_ScanPassportHelp: String { return self._s[3833]! }
+ public var Application_Name: String { return self._s[3834]! }
+ public var Channel_AdminLogFilter_ChannelEventsInfo: String { return self._s[3835]! }
+ public var PeopleNearby_MakeVisible: String { return self._s[3837]! }
+ public var Appearance_ThemeCarouselDay: String { return self._s[3838]! }
+ public var Passport_Identity_TranslationHelp: String { return self._s[3839]! }
public func VoiceOver_Chat_VideoMessageFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3828]!, self._r[3828]!, [_0])
+ return formatWithArgumentRanges(self._s[3840]!, self._r[3840]!, [_0])
}
public func Notification_JoinedGroupByLink(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3829]!, self._r[3829]!, [_0])
+ return formatWithArgumentRanges(self._s[3841]!, self._r[3841]!, [_0])
}
public func DialogList_EncryptedChatStartedOutgoing(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3830]!, self._r[3830]!, [_0])
+ return formatWithArgumentRanges(self._s[3842]!, self._r[3842]!, [_0])
}
- public var Channel_EditAdmin_PermissionDeleteMessages: String { return self._s[3831]! }
- public var Privacy_ChatsTitle: String { return self._s[3832]! }
- public var DialogList_ClearHistoryConfirmation: String { return self._s[3833]! }
- public var SettingsSearch_Synonyms_Data_Storage_ClearCache: String { return self._s[3834]! }
- public var Watch_Suggestion_HoldOn: String { return self._s[3835]! }
- public var Group_EditAdmin_TransferOwnership: String { return self._s[3836]! }
- public var WebBrowser_Title: String { return self._s[3837]! }
- public var Group_LinkedChannel: String { return self._s[3838]! }
- public var VoiceOver_Chat_SeenByRecipient: String { return self._s[3839]! }
- public var SocksProxySetup_RequiredCredentials: String { return self._s[3840]! }
- public var Passport_Address_TypeRentalAgreementUploadScan: String { return self._s[3841]! }
- public var Appearance_TextSize_UseSystem: String { return self._s[3842]! }
- public var TwoStepAuth_EmailSkipAlert: String { return self._s[3843]! }
- public var ScheduledMessages_RemindersTitle: String { return self._s[3845]! }
- public var Channel_Setup_TypePublic: String { return self._s[3847]! }
+ public var Channel_EditAdmin_PermissionDeleteMessages: String { return self._s[3843]! }
+ public var Privacy_ChatsTitle: String { return self._s[3844]! }
+ public var DialogList_ClearHistoryConfirmation: String { return self._s[3845]! }
+ public var SettingsSearch_Synonyms_Data_Storage_ClearCache: String { return self._s[3846]! }
+ public var Watch_Suggestion_HoldOn: String { return self._s[3847]! }
+ public var Group_EditAdmin_TransferOwnership: String { return self._s[3848]! }
+ public var WebBrowser_Title: String { return self._s[3849]! }
+ public var Group_LinkedChannel: String { return self._s[3850]! }
+ public var VoiceOver_Chat_SeenByRecipient: String { return self._s[3851]! }
+ public var SocksProxySetup_RequiredCredentials: String { return self._s[3852]! }
+ public var Passport_Address_TypeRentalAgreementUploadScan: String { return self._s[3853]! }
+ public var Appearance_TextSize_UseSystem: String { return self._s[3854]! }
+ public var TwoStepAuth_EmailSkipAlert: String { return self._s[3855]! }
+ public var ScheduledMessages_RemindersTitle: String { return self._s[3857]! }
+ public var Channel_Setup_TypePublic: String { return self._s[3859]! }
public func Channel_AdminLog_MessageToggleInvitesOn(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3848]!, self._r[3848]!, [_0])
+ return formatWithArgumentRanges(self._s[3860]!, self._r[3860]!, [_0])
}
- public var Channel_TypeSetup_Title: String { return self._s[3850]! }
- public var MessagePoll_ViewResults: String { return self._s[3851]! }
- public var Map_OpenInMaps: String { return self._s[3853]! }
+ public var Channel_TypeSetup_Title: String { return self._s[3862]! }
+ public var MessagePoll_ViewResults: String { return self._s[3863]! }
+ public var Map_OpenInMaps: String { return self._s[3865]! }
public func PUSH_PINNED_NOTEXT(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3854]!, self._r[3854]!, [_1])
+ return formatWithArgumentRanges(self._s[3866]!, self._r[3866]!, [_1])
}
- public var NotificationsSound_Tremolo: String { return self._s[3856]! }
+ public var NotificationsSound_Tremolo: String { return self._s[3868]! }
public func Date_ChatDateHeaderYear(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3857]!, self._r[3857]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3869]!, self._r[3869]!, [_1, _2, _3])
}
- public var ConversationProfile_UnknownAddMemberError: String { return self._s[3858]! }
- public var Channel_OwnershipTransfer_PasswordPlaceholder: String { return self._s[3859]! }
- public var Passport_PasswordHelp: String { return self._s[3860]! }
- public var Login_CodeExpiredError: String { return self._s[3861]! }
- public var Channel_EditAdmin_PermissionChangeInfo: String { return self._s[3862]! }
- public var Conversation_TitleUnmute: String { return self._s[3863]! }
- public var Passport_Identity_ScansHelp: String { return self._s[3864]! }
- public var Passport_Language_lo: String { return self._s[3865]! }
- public var Camera_FlashAuto: String { return self._s[3866]! }
- public var Conversation_OpenBotLinkOpen: String { return self._s[3867]! }
- public var Common_Cancel: String { return self._s[3868]! }
- public var DialogList_SavedMessagesTooltip: String { return self._s[3869]! }
- public var TwoStepAuth_SetupPasswordTitle: String { return self._s[3870]! }
- public var Appearance_TintAllColors: String { return self._s[3871]! }
+ public var ConversationProfile_UnknownAddMemberError: String { return self._s[3870]! }
+ public var Channel_OwnershipTransfer_PasswordPlaceholder: String { return self._s[3871]! }
+ public var Passport_PasswordHelp: String { return self._s[3872]! }
+ public var Login_CodeExpiredError: String { return self._s[3873]! }
+ public var Channel_EditAdmin_PermissionChangeInfo: String { return self._s[3874]! }
+ public var Conversation_TitleUnmute: String { return self._s[3875]! }
+ public var Passport_Identity_ScansHelp: String { return self._s[3876]! }
+ public var Passport_Language_lo: String { return self._s[3877]! }
+ public var Camera_FlashAuto: String { return self._s[3878]! }
+ public var Conversation_OpenBotLinkOpen: String { return self._s[3879]! }
+ public var Common_Cancel: String { return self._s[3880]! }
+ public var DialogList_SavedMessagesTooltip: String { return self._s[3881]! }
+ public var TwoStepAuth_SetupPasswordTitle: String { return self._s[3882]! }
+ public var Appearance_TintAllColors: String { return self._s[3883]! }
public func PUSH_MESSAGE_FWD(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3872]!, self._r[3872]!, [_1])
+ return formatWithArgumentRanges(self._s[3884]!, self._r[3884]!, [_1])
}
- public var Conversation_ReportSpamConfirmation: String { return self._s[3873]! }
- public var ChatSettings_Title: String { return self._s[3875]! }
- public var Passport_PasswordReset: String { return self._s[3876]! }
- public var SocksProxySetup_TypeNone: String { return self._s[3877]! }
- public var EditTheme_Title: String { return self._s[3880]! }
- public var PhoneNumberHelp_Help: String { return self._s[3881]! }
- public var Checkout_EnterPassword: String { return self._s[3882]! }
- public var Share_AuthTitle: String { return self._s[3884]! }
- public var Activity_UploadingDocument: String { return self._s[3885]! }
- public var State_Connecting: String { return self._s[3886]! }
- public var Profile_MessageLifetime1w: String { return self._s[3887]! }
- public var Conversation_ContextMenuReport: String { return self._s[3888]! }
- public var CheckoutInfo_ReceiverInfoPhone: String { return self._s[3889]! }
- public var AutoNightTheme_ScheduledTo: String { return self._s[3890]! }
+ public var Conversation_ReportSpamConfirmation: String { return self._s[3885]! }
+ public var ChatSettings_Title: String { return self._s[3887]! }
+ public var Passport_PasswordReset: String { return self._s[3888]! }
+ public var SocksProxySetup_TypeNone: String { return self._s[3889]! }
+ public var EditTheme_Title: String { return self._s[3892]! }
+ public var PhoneNumberHelp_Help: String { return self._s[3893]! }
+ public var Checkout_EnterPassword: String { return self._s[3894]! }
+ public var Share_AuthTitle: String { return self._s[3896]! }
+ public var Activity_UploadingDocument: String { return self._s[3897]! }
+ public var State_Connecting: String { return self._s[3898]! }
+ public var Profile_MessageLifetime1w: String { return self._s[3899]! }
+ public var Conversation_ContextMenuReport: String { return self._s[3900]! }
+ public var CheckoutInfo_ReceiverInfoPhone: String { return self._s[3901]! }
+ public var AutoNightTheme_ScheduledTo: String { return self._s[3902]! }
public func VoiceOver_Chat_AnonymousPollFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3891]!, self._r[3891]!, [_0])
+ return formatWithArgumentRanges(self._s[3903]!, self._r[3903]!, [_0])
}
- public var AuthSessions_Terminate: String { return self._s[3892]! }
- public var Wallet_WordImport_CanNotRemember: String { return self._s[3893]! }
- public var Checkout_NewCard_CardholderNamePlaceholder: String { return self._s[3895]! }
- public var KeyCommand_JumpToPreviousUnreadChat: String { return self._s[3896]! }
- public var PhotoEditor_Set: String { return self._s[3897]! }
- public var EmptyGroupInfo_Title: String { return self._s[3898]! }
- public var Login_PadPhoneHelp: String { return self._s[3899]! }
- public var AutoDownloadSettings_TypeGroupChats: String { return self._s[3901]! }
- public var PrivacyPolicy_DeclineLastWarning: String { return self._s[3903]! }
- public var NotificationsSound_Complete: String { return self._s[3904]! }
- public var SettingsSearch_Synonyms_Privacy_Data_Title: String { return self._s[3905]! }
- public var Group_Info_AdminLog: String { return self._s[3906]! }
- public var GroupPermission_NotAvailableInPublicGroups: String { return self._s[3907]! }
+ public var AuthSessions_Terminate: String { return self._s[3904]! }
+ public var Wallet_WordImport_CanNotRemember: String { return self._s[3905]! }
+ public var Checkout_NewCard_CardholderNamePlaceholder: String { return self._s[3907]! }
+ public var KeyCommand_JumpToPreviousUnreadChat: String { return self._s[3908]! }
+ public var PhotoEditor_Set: String { return self._s[3909]! }
+ public var EmptyGroupInfo_Title: String { return self._s[3910]! }
+ public var Login_PadPhoneHelp: String { return self._s[3911]! }
+ public var AutoDownloadSettings_TypeGroupChats: String { return self._s[3913]! }
+ public var PrivacyPolicy_DeclineLastWarning: String { return self._s[3915]! }
+ public var NotificationsSound_Complete: String { return self._s[3916]! }
+ public var SettingsSearch_Synonyms_Privacy_Data_Title: String { return self._s[3917]! }
+ public var Group_Info_AdminLog: String { return self._s[3918]! }
+ public var GroupPermission_NotAvailableInPublicGroups: String { return self._s[3919]! }
public func Wallet_Time_PreciseDate_m11(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3908]!, self._r[3908]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3920]!, self._r[3920]!, [_1, _2, _3])
}
- public var Channel_AdminLog_InfoPanelAlertText: String { return self._s[3909]! }
- public var Group_Location_CreateInThisPlace: String { return self._s[3911]! }
- public var Conversation_Admin: String { return self._s[3912]! }
- public var Conversation_GifTooltip: String { return self._s[3913]! }
- public var Passport_NotLoggedInMessage: String { return self._s[3914]! }
+ public var Channel_AdminLog_InfoPanelAlertText: String { return self._s[3921]! }
+ public var Group_Location_CreateInThisPlace: String { return self._s[3923]! }
+ public var Conversation_Admin: String { return self._s[3924]! }
+ public var Conversation_GifTooltip: String { return self._s[3925]! }
+ public var Passport_NotLoggedInMessage: String { return self._s[3926]! }
public func AutoDownloadSettings_OnFor(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3916]!, self._r[3916]!, [_0])
+ return formatWithArgumentRanges(self._s[3928]!, self._r[3928]!, [_0])
}
- public var Profile_MessageLifetimeForever: String { return self._s[3917]! }
- public var SharedMedia_EmptyTitle: String { return self._s[3919]! }
- public var Channel_Edit_PrivatePublicLinkAlert: String { return self._s[3921]! }
- public var Username_Help: String { return self._s[3922]! }
- public var DialogList_LanguageTooltip: String { return self._s[3924]! }
- public var Map_LoadError: String { return self._s[3925]! }
- public var Login_PhoneNumberAlreadyAuthorized: String { return self._s[3926]! }
- public var Channel_AdminLog_AddMembers: String { return self._s[3927]! }
- public var ArchivedChats_IntroTitle2: String { return self._s[3928]! }
- public var Notification_Exceptions_NewException: String { return self._s[3929]! }
- public var TwoStepAuth_EmailTitle: String { return self._s[3930]! }
- public var WatchRemote_AlertText: String { return self._s[3931]! }
+ public var Profile_MessageLifetimeForever: String { return self._s[3929]! }
+ public var SharedMedia_EmptyTitle: String { return self._s[3931]! }
+ public var Channel_Edit_PrivatePublicLinkAlert: String { return self._s[3933]! }
+ public var Username_Help: String { return self._s[3934]! }
+ public var DialogList_LanguageTooltip: String { return self._s[3936]! }
+ public var Map_LoadError: String { return self._s[3937]! }
+ public var Login_PhoneNumberAlreadyAuthorized: String { return self._s[3938]! }
+ public var Channel_AdminLog_AddMembers: String { return self._s[3939]! }
+ public var ArchivedChats_IntroTitle2: String { return self._s[3940]! }
+ public var Notification_Exceptions_NewException: String { return self._s[3941]! }
+ public var TwoStepAuth_EmailTitle: String { return self._s[3942]! }
+ public var WatchRemote_AlertText: String { return self._s[3943]! }
public func Wallet_Send_ConfirmationText(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3932]!, self._r[3932]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3944]!, self._r[3944]!, [_1, _2, _3])
}
- public var ChatSettings_ConnectionType_Title: String { return self._s[3936]! }
- public var WebBrowser_DefaultBrowser: String { return self._s[3937]! }
+ public var ChatSettings_ConnectionType_Title: String { return self._s[3948]! }
+ public var WebBrowser_DefaultBrowser: String { return self._s[3949]! }
public func Settings_CheckPhoneNumberTitle(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3938]!, self._r[3938]!, [_0])
+ return formatWithArgumentRanges(self._s[3950]!, self._r[3950]!, [_0])
}
- public var SettingsSearch_Synonyms_Calls_CallTab: String { return self._s[3939]! }
- public var Passport_Address_CountryPlaceholder: String { return self._s[3940]! }
+ public var SettingsSearch_Synonyms_Calls_CallTab: String { return self._s[3951]! }
+ public var Passport_Address_CountryPlaceholder: String { return self._s[3952]! }
public func DialogList_AwaitingEncryption(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3941]!, self._r[3941]!, [_0])
+ return formatWithArgumentRanges(self._s[3953]!, self._r[3953]!, [_0])
}
public func Time_PreciseDate_m6(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3942]!, self._r[3942]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[3954]!, self._r[3954]!, [_1, _2, _3])
}
- public var Group_AdminLog_EmptyText: String { return self._s[3943]! }
- public var SettingsSearch_Synonyms_Appearance_Title: String { return self._s[3944]! }
- public var Conversation_PrivateChannelTooltip: String { return self._s[3946]! }
- public var Wallet_Created_ExportErrorText: String { return self._s[3947]! }
- public var ChatList_UndoArchiveText1: String { return self._s[3948]! }
- public var AccessDenied_VideoMicrophone: String { return self._s[3949]! }
- public var Conversation_ContextMenuStickerPackAdd: String { return self._s[3950]! }
- public var Cache_ClearNone: String { return self._s[3951]! }
- public var SocksProxySetup_FailedToConnect: String { return self._s[3952]! }
- public var Permissions_NotificationsTitle_v0: String { return self._s[3953]! }
+ public var Group_AdminLog_EmptyText: String { return self._s[3955]! }
+ public var SettingsSearch_Synonyms_Appearance_Title: String { return self._s[3956]! }
+ public var Conversation_PrivateChannelTooltip: String { return self._s[3958]! }
+ public var Wallet_Created_ExportErrorText: String { return self._s[3959]! }
+ public var ChatList_UndoArchiveText1: String { return self._s[3960]! }
+ public var AccessDenied_VideoMicrophone: String { return self._s[3961]! }
+ public var Conversation_ContextMenuStickerPackAdd: String { return self._s[3962]! }
+ public var Cache_ClearNone: String { return self._s[3963]! }
+ public var SocksProxySetup_FailedToConnect: String { return self._s[3964]! }
+ public var Permissions_NotificationsTitle_v0: String { return self._s[3965]! }
public func Channel_AdminLog_MessageEdited(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3954]!, self._r[3954]!, [_0])
+ return formatWithArgumentRanges(self._s[3966]!, self._r[3966]!, [_0])
}
- public var Passport_Identity_Country: String { return self._s[3955]! }
+ public var Passport_Identity_Country: String { return self._s[3967]! }
public func ChatSettings_AutoDownloadSettings_TypeFile(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3956]!, self._r[3956]!, [_0])
+ return formatWithArgumentRanges(self._s[3968]!, self._r[3968]!, [_0])
}
public func Notification_CreatedChat(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3957]!, self._r[3957]!, [_0])
+ return formatWithArgumentRanges(self._s[3969]!, self._r[3969]!, [_0])
}
- public var Exceptions_AddToExceptions: String { return self._s[3958]! }
- public var AccessDenied_Settings: String { return self._s[3959]! }
- public var Passport_Address_TypeUtilityBillUploadScan: String { return self._s[3960]! }
- public var Month_ShortMay: String { return self._s[3961]! }
- public var Compose_NewGroup: String { return self._s[3963]! }
- public var Group_Setup_TypePrivate: String { return self._s[3965]! }
- public var Login_PadPhoneHelpTitle: String { return self._s[3967]! }
- public var Appearance_ThemeDayClassic: String { return self._s[3968]! }
- public var Channel_AdminLog_MessagePreviousCaption: String { return self._s[3969]! }
- public var AutoDownloadSettings_OffForAll: String { return self._s[3970]! }
- public var Privacy_GroupsAndChannels_WhoCanAddMe: String { return self._s[3971]! }
- public var Conversation_typing: String { return self._s[3973]! }
- public var Undo_ScheduledMessagesCleared: String { return self._s[3974]! }
- public var Paint_Masks: String { return self._s[3975]! }
- public var Contacts_DeselectAll: String { return self._s[3976]! }
+ public var Exceptions_AddToExceptions: String { return self._s[3970]! }
+ public var AccessDenied_Settings: String { return self._s[3971]! }
+ public var Passport_Address_TypeUtilityBillUploadScan: String { return self._s[3972]! }
+ public var Month_ShortMay: String { return self._s[3973]! }
+ public var Compose_NewGroup: String { return self._s[3975]! }
+ public var Group_Setup_TypePrivate: String { return self._s[3977]! }
+ public var Login_PadPhoneHelpTitle: String { return self._s[3979]! }
+ public var Appearance_ThemeDayClassic: String { return self._s[3980]! }
+ public var Channel_AdminLog_MessagePreviousCaption: String { return self._s[3981]! }
+ public var AutoDownloadSettings_OffForAll: String { return self._s[3982]! }
+ public var Privacy_GroupsAndChannels_WhoCanAddMe: String { return self._s[3983]! }
+ public var Conversation_typing: String { return self._s[3985]! }
+ public var Undo_ScheduledMessagesCleared: String { return self._s[3986]! }
+ public var Paint_Masks: String { return self._s[3987]! }
+ public var Contacts_DeselectAll: String { return self._s[3988]! }
public func Wallet_Updated_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3977]!, self._r[3977]!, [_0])
+ return formatWithArgumentRanges(self._s[3989]!, self._r[3989]!, [_0])
}
- public var CreatePoll_MultipleChoiceQuizAlert: String { return self._s[3978]! }
- public var Username_InvalidTaken: String { return self._s[3979]! }
- public var Call_StatusNoAnswer: String { return self._s[3980]! }
- public var TwoStepAuth_EmailAddSuccess: String { return self._s[3981]! }
- public var SettingsSearch_Synonyms_Privacy_BlockedUsers: String { return self._s[3982]! }
- public var Passport_Identity_Selfie: String { return self._s[3983]! }
- public var Login_InfoLastNamePlaceholder: String { return self._s[3984]! }
- public var Privacy_SecretChatsLinkPreviewsHelp: String { return self._s[3985]! }
- public var Conversation_ClearSecretHistory: String { return self._s[3986]! }
- public var PeopleNearby_Description: String { return self._s[3988]! }
- public var NetworkUsageSettings_Title: String { return self._s[3989]! }
- public var Your_cards_security_code_is_invalid: String { return self._s[3991]! }
+ public var CreatePoll_MultipleChoiceQuizAlert: String { return self._s[3990]! }
+ public var Username_InvalidTaken: String { return self._s[3991]! }
+ public var Call_StatusNoAnswer: String { return self._s[3992]! }
+ public var TwoStepAuth_EmailAddSuccess: String { return self._s[3993]! }
+ public var SettingsSearch_Synonyms_Privacy_BlockedUsers: String { return self._s[3994]! }
+ public var Passport_Identity_Selfie: String { return self._s[3995]! }
+ public var Login_InfoLastNamePlaceholder: String { return self._s[3996]! }
+ public var Privacy_SecretChatsLinkPreviewsHelp: String { return self._s[3997]! }
+ public var Conversation_ClearSecretHistory: String { return self._s[3998]! }
+ public var PeopleNearby_Description: String { return self._s[4000]! }
+ public var NetworkUsageSettings_Title: String { return self._s[4001]! }
+ public var Your_cards_security_code_is_invalid: String { return self._s[4003]! }
public func Notification_LeftChannel(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3993]!, self._r[3993]!, [_0])
- }
- public func Call_CallInProgressMessage(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[3994]!, self._r[3994]!, [_1, _2])
- }
- public var SaveIncomingPhotosSettings_From: String { return self._s[3996]! }
- public var VoiceOver_Navigation_Search: String { return self._s[3997]! }
- public var Map_LiveLocationTitle: String { return self._s[3998]! }
- public var Login_InfoAvatarAdd: String { return self._s[3999]! }
- public var Passport_Identity_FilesView: String { return self._s[4000]! }
- public var UserInfo_GenericPhoneLabel: String { return self._s[4001]! }
- public var Privacy_Calls_NeverAllow: String { return self._s[4002]! }
- public var VoiceOver_Chat_File: String { return self._s[4003]! }
- public var Wallet_Settings_DeleteWalletInfo: String { return self._s[4004]! }
- public func Contacts_AddPhoneNumber(_ _0: String) -> (String, [(Int, NSRange)]) {
return formatWithArgumentRanges(self._s[4005]!, self._r[4005]!, [_0])
}
- public var ContactInfo_PhoneNumberHidden: String { return self._s[4006]! }
- public var TwoStepAuth_ConfirmationText: String { return self._s[4007]! }
- public var ChatSettings_AutomaticVideoMessageDownload: String { return self._s[4008]! }
+ public func Call_CallInProgressMessage(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[4006]!, self._r[4006]!, [_1, _2])
+ }
+ public var SaveIncomingPhotosSettings_From: String { return self._s[4008]! }
+ public var VoiceOver_Navigation_Search: String { return self._s[4009]! }
+ public var Map_LiveLocationTitle: String { return self._s[4010]! }
+ public var Login_InfoAvatarAdd: String { return self._s[4011]! }
+ public var Passport_Identity_FilesView: String { return self._s[4012]! }
+ public var UserInfo_GenericPhoneLabel: String { return self._s[4013]! }
+ public var Privacy_Calls_NeverAllow: String { return self._s[4014]! }
+ public var VoiceOver_Chat_File: String { return self._s[4015]! }
+ public var Wallet_Settings_DeleteWalletInfo: String { return self._s[4016]! }
+ public func Contacts_AddPhoneNumber(_ _0: String) -> (String, [(Int, NSRange)]) {
+ return formatWithArgumentRanges(self._s[4017]!, self._r[4017]!, [_0])
+ }
+ public var ContactInfo_PhoneNumberHidden: String { return self._s[4018]! }
+ public var TwoStepAuth_ConfirmationText: String { return self._s[4019]! }
+ public var ChatSettings_AutomaticVideoMessageDownload: String { return self._s[4020]! }
public func PUSH_CHAT_MESSAGE_VIDEOS(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4009]!, self._r[4009]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[4021]!, self._r[4021]!, [_1, _2, _3])
}
- public var Channel_AdminLogFilter_AdminsAll: String { return self._s[4010]! }
- public var Wallet_Intro_CreateErrorText: String { return self._s[4011]! }
- public var Tour_Title2: String { return self._s[4012]! }
- public var Wallet_Sent_ViewWallet: String { return self._s[4013]! }
- public var Conversation_FileOpenIn: String { return self._s[4014]! }
- public var Checkout_ErrorPrecheckoutFailed: String { return self._s[4015]! }
- public var Wallet_Send_ErrorInvalidAddress: String { return self._s[4016]! }
- public var Wallpaper_Set: String { return self._s[4017]! }
- public var Passport_Identity_Translations: String { return self._s[4019]! }
+ public var Channel_AdminLogFilter_AdminsAll: String { return self._s[4022]! }
+ public var Wallet_Intro_CreateErrorText: String { return self._s[4023]! }
+ public var Tour_Title2: String { return self._s[4024]! }
+ public var Wallet_Sent_ViewWallet: String { return self._s[4025]! }
+ public var Conversation_FileOpenIn: String { return self._s[4026]! }
+ public var Checkout_ErrorPrecheckoutFailed: String { return self._s[4027]! }
+ public var Wallet_Send_ErrorInvalidAddress: String { return self._s[4028]! }
+ public var Wallpaper_Set: String { return self._s[4029]! }
+ public var Passport_Identity_Translations: String { return self._s[4031]! }
public func Channel_AdminLog_MessageChangedChannelAbout(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4020]!, self._r[4020]!, [_0])
+ return formatWithArgumentRanges(self._s[4032]!, self._r[4032]!, [_0])
}
- public var Channel_LeaveChannel: String { return self._s[4021]! }
+ public var Channel_LeaveChannel: String { return self._s[4033]! }
public func PINNED_INVOICE(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4022]!, self._r[4022]!, [_1])
+ return formatWithArgumentRanges(self._s[4034]!, self._r[4034]!, [_1])
}
- public var SettingsSearch_Synonyms_Proxy_AddProxy: String { return self._s[4024]! }
- public var PhotoEditor_HighlightsTint: String { return self._s[4025]! }
- public var MessagePoll_LabelPoll: String { return self._s[4026]! }
- public var Passport_Email_Delete: String { return self._s[4027]! }
- public var Conversation_Mute: String { return self._s[4029]! }
- public var Channel_AddBotAsAdmin: String { return self._s[4030]! }
- public var Channel_AdminLog_CanSendMessages: String { return self._s[4032]! }
- public var Wallet_Configuration_BlockchainNameChangedText: String { return self._s[4033]! }
- public var ChatSettings_IntentsSettings: String { return self._s[4035]! }
- public var Channel_Management_LabelOwner: String { return self._s[4036]! }
+ public var SettingsSearch_Synonyms_Proxy_AddProxy: String { return self._s[4036]! }
+ public var PhotoEditor_HighlightsTint: String { return self._s[4037]! }
+ public var MessagePoll_LabelPoll: String { return self._s[4038]! }
+ public var Passport_Email_Delete: String { return self._s[4039]! }
+ public var Conversation_Mute: String { return self._s[4041]! }
+ public var Channel_AddBotAsAdmin: String { return self._s[4042]! }
+ public var Channel_AdminLog_CanSendMessages: String { return self._s[4044]! }
+ public var Wallet_Configuration_BlockchainNameChangedText: String { return self._s[4045]! }
+ public var ChatSettings_IntentsSettings: String { return self._s[4047]! }
+ public var Channel_Management_LabelOwner: String { return self._s[4048]! }
public func Notification_PassportValuesSentMessage(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4037]!, self._r[4037]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4049]!, self._r[4049]!, [_1, _2])
}
- public var Calls_CallTabDescription: String { return self._s[4038]! }
- public var Passport_Identity_NativeNameHelp: String { return self._s[4039]! }
- public var Common_No: String { return self._s[4040]! }
- public var Weekday_Sunday: String { return self._s[4041]! }
- public var Notification_Reply: String { return self._s[4042]! }
- public var Conversation_ViewMessage: String { return self._s[4043]! }
+ public var Calls_CallTabDescription: String { return self._s[4050]! }
+ public var Passport_Identity_NativeNameHelp: String { return self._s[4051]! }
+ public var Common_No: String { return self._s[4052]! }
+ public var Weekday_Sunday: String { return self._s[4053]! }
+ public var Notification_Reply: String { return self._s[4054]! }
+ public var Conversation_ViewMessage: String { return self._s[4055]! }
public func Checkout_SavePasswordTimeoutAndFaceId(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4044]!, self._r[4044]!, [_0])
+ return formatWithArgumentRanges(self._s[4056]!, self._r[4056]!, [_0])
}
public func Map_LiveLocationPrivateDescription(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4045]!, self._r[4045]!, [_0])
+ return formatWithArgumentRanges(self._s[4057]!, self._r[4057]!, [_0])
}
public func Wallet_Time_PreciseDate_m7(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4046]!, self._r[4046]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[4058]!, self._r[4058]!, [_1, _2, _3])
}
- public var SettingsSearch_Synonyms_EditProfile_AddAccount: String { return self._s[4047]! }
- public var Wallet_Send_Title: String { return self._s[4048]! }
- public var Message_PinnedDocumentMessage: String { return self._s[4049]! }
- public var Wallet_Info_RefreshErrorText: String { return self._s[4050]! }
- public var DialogList_TabTitle: String { return self._s[4052]! }
- public var ChatSettings_AutoPlayTitle: String { return self._s[4053]! }
- public var Passport_FieldEmail: String { return self._s[4054]! }
- public var Conversation_UnpinMessageAlert: String { return self._s[4055]! }
- public var Passport_Address_TypeBankStatement: String { return self._s[4056]! }
- public var Wallet_SecureStorageReset_Title: String { return self._s[4057]! }
- public var Passport_Identity_ExpiryDate: String { return self._s[4058]! }
- public var Privacy_Calls_P2P: String { return self._s[4059]! }
+ public var SettingsSearch_Synonyms_EditProfile_AddAccount: String { return self._s[4059]! }
+ public var Wallet_Send_Title: String { return self._s[4060]! }
+ public var Message_PinnedDocumentMessage: String { return self._s[4061]! }
+ public var Wallet_Info_RefreshErrorText: String { return self._s[4062]! }
+ public var DialogList_TabTitle: String { return self._s[4064]! }
+ public var ChatSettings_AutoPlayTitle: String { return self._s[4065]! }
+ public var Passport_FieldEmail: String { return self._s[4066]! }
+ public var Conversation_UnpinMessageAlert: String { return self._s[4067]! }
+ public var Passport_Address_TypeBankStatement: String { return self._s[4068]! }
+ public var Wallet_SecureStorageReset_Title: String { return self._s[4069]! }
+ public var Passport_Identity_ExpiryDate: String { return self._s[4070]! }
+ public var Privacy_Calls_P2P: String { return self._s[4071]! }
public func CancelResetAccount_Success(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4061]!, self._r[4061]!, [_0])
+ return formatWithArgumentRanges(self._s[4073]!, self._r[4073]!, [_0])
}
- public var SocksProxySetup_UseForCallsHelp: String { return self._s[4062]! }
+ public var SocksProxySetup_UseForCallsHelp: String { return self._s[4074]! }
public func PUSH_CHAT_ALBUM(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4063]!, self._r[4063]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4075]!, self._r[4075]!, [_1, _2])
}
- public var Stickers_ClearRecent: String { return self._s[4064]! }
- public var EnterPasscode_ChangeTitle: String { return self._s[4065]! }
- public var TwoFactorSetup_Email_Title: String { return self._s[4066]! }
- public var Passport_InfoText: String { return self._s[4067]! }
- public var Checkout_NewCard_SaveInfoEnableHelp: String { return self._s[4068]! }
+ public var Stickers_ClearRecent: String { return self._s[4076]! }
+ public var EnterPasscode_ChangeTitle: String { return self._s[4077]! }
+ public var TwoFactorSetup_Email_Title: String { return self._s[4078]! }
+ public var Passport_InfoText: String { return self._s[4079]! }
+ public var Checkout_NewCard_SaveInfoEnableHelp: String { return self._s[4080]! }
public func Login_InvalidPhoneEmailSubject(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4069]!, self._r[4069]!, [_0])
+ return formatWithArgumentRanges(self._s[4081]!, self._r[4081]!, [_0])
}
public func Time_PreciseDate_m3(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4070]!, self._r[4070]!, [_1, _2, _3])
+ return formatWithArgumentRanges(self._s[4082]!, self._r[4082]!, [_1, _2, _3])
}
- public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChannels: String { return self._s[4071]! }
- public var ScheduledMessages_PollUnavailable: String { return self._s[4072]! }
- public var VoiceOver_Navigation_Compose: String { return self._s[4073]! }
- public var Passport_Identity_EditDriversLicense: String { return self._s[4074]! }
- public var Conversation_TapAndHoldToRecord: String { return self._s[4076]! }
- public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChats: String { return self._s[4077]! }
+ public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChannels: String { return self._s[4083]! }
+ public var ScheduledMessages_PollUnavailable: String { return self._s[4084]! }
+ public var VoiceOver_Navigation_Compose: String { return self._s[4085]! }
+ public var Passport_Identity_EditDriversLicense: String { return self._s[4086]! }
+ public var Conversation_TapAndHoldToRecord: String { return self._s[4088]! }
+ public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChats: String { return self._s[4089]! }
public func Notification_CallTimeFormat(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4078]!, self._r[4078]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4090]!, self._r[4090]!, [_1, _2])
}
- public var Channel_EditAdmin_PermissionInviteViaLink: String { return self._s[4080]! }
- public var ChatSettings_OpenLinksIn: String { return self._s[4081]! }
- public var Map_HomeAndWorkTitle: String { return self._s[4082]! }
+ public var Channel_EditAdmin_PermissionInviteViaLink: String { return self._s[4093]! }
+ public var ChatSettings_OpenLinksIn: String { return self._s[4094]! }
+ public var Map_HomeAndWorkTitle: String { return self._s[4095]! }
public func Generic_OpenHiddenLinkAlert(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4084]!, self._r[4084]!, [_0])
+ return formatWithArgumentRanges(self._s[4097]!, self._r[4097]!, [_0])
}
- public var DialogList_Unread: String { return self._s[4085]! }
+ public var DialogList_Unread: String { return self._s[4098]! }
public func PUSH_CHAT_MESSAGE_GIF(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4086]!, self._r[4086]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4099]!, self._r[4099]!, [_1, _2])
}
- public var User_DeletedAccount: String { return self._s[4087]! }
- public var OwnershipTransfer_SetupTwoStepAuth: String { return self._s[4088]! }
+ public var User_DeletedAccount: String { return self._s[4100]! }
+ public var OwnershipTransfer_SetupTwoStepAuth: String { return self._s[4101]! }
public func Watch_Time_ShortYesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4089]!, self._r[4089]!, [_0])
+ return formatWithArgumentRanges(self._s[4102]!, self._r[4102]!, [_0])
}
- public var UserInfo_NotificationsDefault: String { return self._s[4090]! }
- public var SharedMedia_CategoryMedia: String { return self._s[4091]! }
- public var SocksProxySetup_ProxyStatusUnavailable: String { return self._s[4092]! }
- public var Channel_AdminLog_MessageRestrictedForever: String { return self._s[4093]! }
- public var Watch_ChatList_Compose: String { return self._s[4094]! }
- public var Notifications_MessageNotificationsExceptionsHelp: String { return self._s[4095]! }
- public var AutoDownloadSettings_Delimeter: String { return self._s[4096]! }
- public var Watch_Microphone_Access: String { return self._s[4097]! }
- public var Group_Setup_HistoryHeader: String { return self._s[4098]! }
- public var Map_SetThisLocation: String { return self._s[4099]! }
- public var Appearance_ThemePreview_Chat_2_ReplyName: String { return self._s[4100]! }
- public var Activity_UploadingPhoto: String { return self._s[4101]! }
- public var Conversation_Edit: String { return self._s[4103]! }
- public var Group_ErrorSendRestrictedMedia: String { return self._s[4104]! }
- public var Login_TermsOfServiceDecline: String { return self._s[4105]! }
- public var Message_PinnedContactMessage: String { return self._s[4106]! }
+ public var UserInfo_NotificationsDefault: String { return self._s[4103]! }
+ public var SharedMedia_CategoryMedia: String { return self._s[4104]! }
+ public var SocksProxySetup_ProxyStatusUnavailable: String { return self._s[4105]! }
+ public var Channel_AdminLog_MessageRestrictedForever: String { return self._s[4106]! }
+ public var Watch_ChatList_Compose: String { return self._s[4107]! }
+ public var Notifications_MessageNotificationsExceptionsHelp: String { return self._s[4108]! }
+ public var AutoDownloadSettings_Delimeter: String { return self._s[4109]! }
+ public var Watch_Microphone_Access: String { return self._s[4110]! }
+ public var Group_Setup_HistoryHeader: String { return self._s[4111]! }
+ public var Map_SetThisLocation: String { return self._s[4112]! }
+ public var Appearance_ThemePreview_Chat_2_ReplyName: String { return self._s[4113]! }
+ public var Activity_UploadingPhoto: String { return self._s[4114]! }
+ public var Conversation_Edit: String { return self._s[4116]! }
+ public var Group_ErrorSendRestrictedMedia: String { return self._s[4117]! }
+ public var Login_TermsOfServiceDecline: String { return self._s[4118]! }
+ public var Message_PinnedContactMessage: String { return self._s[4119]! }
public func Channel_AdminLog_MessageRestrictedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4107]!, self._r[4107]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4120]!, self._r[4120]!, [_1, _2])
}
public func Login_PhoneBannedEmailBody(_ _1: String, _ _2: String, _ _3: String, _ _4: String, _ _5: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4108]!, self._r[4108]!, [_1, _2, _3, _4, _5])
+ return formatWithArgumentRanges(self._s[4121]!, self._r[4121]!, [_1, _2, _3, _4, _5])
}
- public var Appearance_LargeEmoji: String { return self._s[4109]! }
- public var TwoStepAuth_AdditionalPassword: String { return self._s[4111]! }
- public var EditTheme_Edit_Preview_IncomingReplyText: String { return self._s[4112]! }
+ public var Appearance_LargeEmoji: String { return self._s[4122]! }
+ public var TwoStepAuth_AdditionalPassword: String { return self._s[4124]! }
+ public var EditTheme_Edit_Preview_IncomingReplyText: String { return self._s[4125]! }
public func PUSH_CHAT_DELETE_YOU(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4113]!, self._r[4113]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4126]!, self._r[4126]!, [_1, _2])
}
- public var Passport_Phone_EnterOtherNumber: String { return self._s[4114]! }
- public var Message_PinnedPhotoMessage: String { return self._s[4115]! }
- public var Passport_FieldPhone: String { return self._s[4116]! }
- public var TwoStepAuth_RecoveryEmailAddDescription: String { return self._s[4117]! }
- public var ChatSettings_AutoPlayGifs: String { return self._s[4118]! }
- public var InfoPlist_NSCameraUsageDescription: String { return self._s[4120]! }
- public var Conversation_Call: String { return self._s[4121]! }
- public var Common_TakePhoto: String { return self._s[4123]! }
- public var Group_EditAdmin_RankTitle: String { return self._s[4124]! }
- public var Wallet_Receive_CommentHeader: String { return self._s[4125]! }
- public var Channel_NotificationLoading: String { return self._s[4126]! }
+ public var Passport_Phone_EnterOtherNumber: String { return self._s[4127]! }
+ public var Message_PinnedPhotoMessage: String { return self._s[4128]! }
+ public var Passport_FieldPhone: String { return self._s[4129]! }
+ public var TwoStepAuth_RecoveryEmailAddDescription: String { return self._s[4130]! }
+ public var ChatSettings_AutoPlayGifs: String { return self._s[4131]! }
+ public var InfoPlist_NSCameraUsageDescription: String { return self._s[4133]! }
+ public var Conversation_Call: String { return self._s[4134]! }
+ public var Common_TakePhoto: String { return self._s[4136]! }
+ public var Group_EditAdmin_RankTitle: String { return self._s[4137]! }
+ public var Wallet_Receive_CommentHeader: String { return self._s[4138]! }
+ public var Channel_NotificationLoading: String { return self._s[4139]! }
public func Notification_Exceptions_Sound(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4127]!, self._r[4127]!, [_0])
+ return formatWithArgumentRanges(self._s[4140]!, self._r[4140]!, [_0])
}
public func ScheduledMessages_ScheduledDate(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4128]!, self._r[4128]!, [_0])
+ return formatWithArgumentRanges(self._s[4141]!, self._r[4141]!, [_0])
}
public func PUSH_CHANNEL_MESSAGE_VIDEO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4129]!, self._r[4129]!, [_1])
+ return formatWithArgumentRanges(self._s[4142]!, self._r[4142]!, [_1])
}
- public var Permissions_SiriTitle_v0: String { return self._s[4130]! }
+ public var Permissions_SiriTitle_v0: String { return self._s[4143]! }
public func VoiceOver_Chat_VoiceMessageFrom(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4131]!, self._r[4131]!, [_0])
+ return formatWithArgumentRanges(self._s[4144]!, self._r[4144]!, [_0])
}
public func Login_ResetAccountProtected_Text(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4132]!, self._r[4132]!, [_0])
+ return formatWithArgumentRanges(self._s[4145]!, self._r[4145]!, [_0])
}
- public var Channel_MessagePhotoRemoved: String { return self._s[4133]! }
- public var Wallet_Info_ReceiveGrams: String { return self._s[4134]! }
- public var ClearCache_FreeSpace: String { return self._s[4135]! }
- public var Common_edit: String { return self._s[4136]! }
- public var PrivacySettings_AuthSessions: String { return self._s[4137]! }
- public var Month_ShortJune: String { return self._s[4138]! }
- public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[4139]! }
- public var Call_ReportSend: String { return self._s[4140]! }
- public var Watch_LastSeen_JustNow: String { return self._s[4141]! }
- public var Notifications_MessageNotifications: String { return self._s[4142]! }
- public var WallpaperSearch_ColorGreen: String { return self._s[4143]! }
- public var BroadcastListInfo_AddRecipient: String { return self._s[4145]! }
- public var Group_Status: String { return self._s[4146]! }
+ public var Channel_MessagePhotoRemoved: String { return self._s[4146]! }
+ public var Wallet_Info_ReceiveGrams: String { return self._s[4147]! }
+ public var ClearCache_FreeSpace: String { return self._s[4148]! }
+ public var Common_edit: String { return self._s[4149]! }
+ public var PrivacySettings_AuthSessions: String { return self._s[4150]! }
+ public var Month_ShortJune: String { return self._s[4151]! }
+ public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[4152]! }
+ public var Call_ReportSend: String { return self._s[4153]! }
+ public var Watch_LastSeen_JustNow: String { return self._s[4154]! }
+ public var Notifications_MessageNotifications: String { return self._s[4155]! }
+ public var WallpaperSearch_ColorGreen: String { return self._s[4156]! }
+ public var BroadcastListInfo_AddRecipient: String { return self._s[4158]! }
+ public var Group_Status: String { return self._s[4159]! }
public func AutoNightTheme_LocationHelp(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4147]!, self._r[4147]!, [_0, _1])
+ return formatWithArgumentRanges(self._s[4160]!, self._r[4160]!, [_0, _1])
}
- public var TextFormat_AddLinkTitle: String { return self._s[4148]! }
- public var ShareMenu_ShareTo: String { return self._s[4149]! }
- public var Conversation_Moderate_Ban: String { return self._s[4150]! }
+ public var TextFormat_AddLinkTitle: String { return self._s[4161]! }
+ public var ShareMenu_ShareTo: String { return self._s[4162]! }
+ public var Conversation_Moderate_Ban: String { return self._s[4163]! }
public func Conversation_DeleteMessagesFor(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4151]!, self._r[4151]!, [_0])
+ return formatWithArgumentRanges(self._s[4164]!, self._r[4164]!, [_0])
}
- public var SharedMedia_ViewInChat: String { return self._s[4152]! }
- public var Map_LiveLocationFor8Hours: String { return self._s[4153]! }
+ public var SharedMedia_ViewInChat: String { return self._s[4165]! }
+ public var Map_LiveLocationFor8Hours: String { return self._s[4166]! }
public func PUSH_PINNED_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4154]!, self._r[4154]!, [_1])
+ return formatWithArgumentRanges(self._s[4167]!, self._r[4167]!, [_1])
}
public func PUSH_PINNED_POLL(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4155]!, self._r[4155]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4168]!, self._r[4168]!, [_1, _2])
}
public func Map_AccurateTo(_ _0: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4157]!, self._r[4157]!, [_0])
+ return formatWithArgumentRanges(self._s[4170]!, self._r[4170]!, [_0])
}
- public var Map_OpenInHereMaps: String { return self._s[4158]! }
- public var Appearance_ReduceMotion: String { return self._s[4159]! }
+ public var Map_OpenInHereMaps: String { return self._s[4171]! }
+ public var Appearance_ReduceMotion: String { return self._s[4172]! }
public func PUSH_MESSAGE_TEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) {
- return formatWithArgumentRanges(self._s[4160]!, self._r[4160]!, [_1, _2])
+ return formatWithArgumentRanges(self._s[4173]!, self._r[4173]!, [_1, _2])
}
- public var Channel_Setup_TypePublicHelp: String { return self._s[4161]! }
- public var Passport_Identity_EditInternalPassport: String { return self._s[4162]! }
- public var PhotoEditor_Skip: String { return self._s[4163]! }
- public func CreatePoll_AddMoreOptions(_ value: Int32) -> String {
+ public var Channel_Setup_TypePublicHelp: String { return self._s[4174]! }
+ public var Passport_Identity_EditInternalPassport: String { return self._s[4175]! }
+ public var PhotoEditor_Skip: String { return self._s[4176]! }
+ public func Notification_GameScoreSimple(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func GroupInfo_ShowMoreMembers(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Call_Minutes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_ShortWeeks(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func LastSeen_MinutesAgo(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, _2, _1, _3)
- }
- public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedStickers(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedPhotos(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func QuickSend_Photos(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_Minutes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Map_ETAMinutes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MuteFor_Days(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ChatList_DeleteConfirmation(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_ShortHours(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func SharedMedia_Generic(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedMessages(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue)
- }
public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, _2, _1, _3)
+ return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func StickerPack_RemoveStickerCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Contacts_InviteContacts(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func GroupInfo_ParticipantCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PollResults_ShowMore(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, _1, _2)
- }
- public func MessageTimer_Months(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, _1, _2)
- }
- public func InviteText_ContactsCountText(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Call_ShortMinutes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Media_ShareVideo(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Conversation_SelectedMessages(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_Years(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Passport_Scans(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, _0, _1)
- }
- public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, _1, _2)
- }
- public func AttachmentMenu_SendPhoto(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessagePoll_QuizCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, _1, _2)
- }
- public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, _1, _2)
- }
- public func SharedMedia_Video(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func OldChannels_InactiveYear(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func OldChannels_InactiveWeek(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func UserCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Call_ShortSeconds(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_Weeks(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MuteExpires_Hours(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Theme_UsersCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func AttachmentMenu_SendItem(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Notifications_Exceptions(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_ShortDays(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedFiles(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Contacts_ImportersCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedVideoMessages(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ChatList_SelectedChats(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Media_SharePhoto(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedGifs(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedVideos(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func StickerPack_AddStickerCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ChatList_DeletedChats(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func AttachmentMenu_SendGif(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Notification_GameScoreSelfSimple(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Media_ShareItem(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String {
+ public func Media_ShareVideo(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func MessageTimer_Seconds(_ value: Int32) -> String {
+ public func GroupInfo_ParticipantCount(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func MuteExpires_Days(_ value: Int32) -> String {
+ public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func OldChannels_InactiveMonth(_ value: Int32) -> String {
+ public func MuteExpires_Hours(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func StickerPack_AddMaskCount(_ value: Int32) -> String {
+ public func LastSeen_MinutesAgo(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func MessagePoll_VotedCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func SharedMedia_File(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Watch_UserInfo_Mute(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, _1, _2)
+ return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, _1, _2)
}
- public func Notification_GameScoreExtended(_ value: Int32) -> String {
+ public func Notifications_Exceptions(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func StickerPack_StickerCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func StickerPack_RemoveMaskCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MuteExpires_Minutes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Conversation_StatusOnline(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Call_Seconds(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, _1, _2)
- }
- public func Notification_GameScoreSelfExtended(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func Conversation_StatusMembers(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ForwardedLocations(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func OldChannels_GroupFormat(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, _2, _1, _3)
- }
- public func ForwardedAudios(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_Days(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, stringValue)
- }
- public func MessageTimer_Hours(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func LastSeen_HoursAgo(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Map_ETAHours(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedPhotos(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, _1, _2)
+ }
+ public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, _1, _2)
+ }
+ public func SharedMedia_File(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, _2, _1, _3)
+ }
+ public func Contacts_InviteContacts(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessageTimer_Seconds(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessageTimer_ShortWeeks(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Contacts_ImportersCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func StickerPack_AddMaskCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func InviteText_ContactsCountText(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortSeconds(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func LiveLocation_MenuChatsCount(_ value: Int32) -> String {
+ public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, _1, _2)
+ public func AttachmentMenu_SendVideo(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Passport_Scans(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Call_Minutes(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_Photo(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, stringValue)
+ return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Call_ShortMinutes(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, _1, _2)
+ }
+ public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessageTimer_ShortMinutes(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessageTimer_Weeks(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func UserCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func AttachmentMenu_SendItem(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ChatList_DeletedChats(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Invitation_Members(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedStickers(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Conversation_SelectedMessages(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func StickerPack_RemoveMaskCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func StickerPack_StickerCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, _1, _2)
+ }
+ public func MessageTimer_Hours(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func StickerPack_RemoveStickerCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, _1, _2)
+ }
+ public func ForwardedContacts(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Watch_UserInfo_Mute(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func AttachmentMenu_SendGif(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ChatList_SelectedChats(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func GroupInfo_ShowMoreMembers(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Conversation_StatusOnline(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func SharedMedia_Generic(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func SharedMedia_Video(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, _1, _2)
+ }
+ public func ForwardedFiles(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Call_Seconds(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Call_ShortSeconds(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MuteExpires_Days(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, _0, _1)
+ }
+ public func MessageTimer_ShortDays(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Conversation_StatusMembers(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue)
}
public func OldChannels_Leave(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessageTimer_Days(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Notification_GameScoreSelfExtended(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func StickerPack_AddStickerCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func OldChannels_InactiveYear(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedLocations(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessageTimer_Years(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PollResults_ShowMore(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Media_SharePhoto(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Conversation_StatusSubscribers(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessagePoll_VotedCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func OldChannels_GroupFormat(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func OldChannels_InactiveWeek(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedMessages(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Theme_UsersCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, _1, _2)
+ }
+ public func QuickSend_Photos(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Map_ETAMinutes(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Notification_GameScoreExtended(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedVideos(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, _2, _1, _3)
+ }
+ public func ChatList_DeleteConfirmation(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedPolls(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func Notification_GameScoreSelfSimple(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ForwardedAudios(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func LiveLocation_MenuChatsCount(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, stringValue)
+ }
+ public func MessagePoll_QuizCount(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[109 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func AttachmentMenu_SendVideo(_ value: Int32) -> String {
+ public func SharedMedia_Link(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[110 * 6 + Int(form.rawValue)]!, stringValue)
@@ -5235,30 +5245,30 @@ public final class PresentationStrings: Equatable {
let form = getPluralizationForm(self.lc, selector)
return String(format: self._ps[111 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
- public func MessageTimer_ShortMinutes(_ value: Int32) -> String {
- let form = getPluralizationForm(self.lc, value)
- let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
- return String(format: self._ps[112 * 6 + Int(form.rawValue)]!, stringValue)
+ public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ let form = getPluralizationForm(self.lc, selector)
+ return String(format: self._ps[112 * 6 + Int(form.rawValue)]!, _1, _2)
}
- public func Conversation_StatusSubscribers(_ value: Int32) -> String {
+ public func MuteFor_Days(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[113 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func ForwardedPolls(_ value: Int32) -> String {
+ public func ForwardedVideoMessages(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[114 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[115 * 6 + Int(form.rawValue)]!, _2, _1, _3)
+ public func OldChannels_InactiveMonth(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[115 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
+ public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[116 * 6 + Int(form.rawValue)]!, _1, _2)
+ return String(format: self._ps[116 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
- public func Map_ETAHours(_ value: Int32) -> String {
+ public func MessageTimer_Months(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[117 * 6 + Int(form.rawValue)]!, stringValue)
@@ -5268,40 +5278,46 @@ public final class PresentationStrings: Equatable {
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[118 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func Notification_GameScoreSimple(_ value: Int32) -> String {
+ public func CreatePoll_AddMoreOptions(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[119 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func ForwardedContacts(_ value: Int32) -> String {
+ public func ForwardedGifs(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[120 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String {
+ public func MessageTimer_Minutes(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[121 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String {
+ public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[122 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func SharedMedia_Link(_ value: Int32) -> String {
+ public func MessageTimer_ShortHours(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[123 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
- let form = getPluralizationForm(self.lc, selector)
- return String(format: self._ps[124 * 6 + Int(form.rawValue)]!, _1, _2)
+ public func PeopleNearby_ShowMorePeople(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[124 * 6 + Int(form.rawValue)]!, stringValue)
}
- public func Invitation_Members(_ value: Int32) -> String {
+ public func AttachmentMenu_SendPhoto(_ value: Int32) -> String {
let form = getPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[125 * 6 + Int(form.rawValue)]!, stringValue)
}
+ public func MuteExpires_Minutes(_ value: Int32) -> String {
+ let form = getPluralizationForm(self.lc, value)
+ let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
+ return String(format: self._ps[126 * 6 + Int(form.rawValue)]!, stringValue)
+ }
public init(primaryComponent: PresentationStringsComponent, secondaryComponent: PresentationStringsComponent?, groupingSeparator: String) {
self.primaryComponent = primaryComponent
diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift
index a1b0744fad..ff03ac0902 100644
--- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift
+++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift
@@ -48,6 +48,8 @@ public enum PresentationResourceKey: Int32 {
case itemListVerifiedPeerIcon
case itemListCloudFetchIcon
case itemListCloseIconImage
+ case itemListMakeVisibleIcon
+ case itemListMakeInvisibleIcon
case itemListCornersTop
case itemListCornersBottom
case itemListCornersBoth
diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift
index 53b0efb48f..8a3e6fc808 100644
--- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift
+++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift
@@ -152,6 +152,18 @@ public struct PresentationResourcesItemList {
})
}
+ public static func makeVisibleIcon(_ theme: PresentationTheme) -> UIImage? {
+ return theme.image(PresentationResourceKey.itemListMakeVisibleIcon.rawValue, { theme in
+ return generateTintedImage(image: UIImage(bundleImageName: "Contact List/MakeVisibleIcon"), color: theme.list.itemAccentColor)
+ })
+ }
+
+ public static func makeInvisibleIcon(_ theme: PresentationTheme) -> UIImage? {
+ return theme.image(PresentationResourceKey.itemListMakeInvisibleIcon.rawValue, { theme in
+ return generateTintedImage(image: UIImage(bundleImageName: "Contact List/MakeInvisibleIcon"), color: theme.list.itemDestructiveColor)
+ })
+ }
+
public static func cornersImage(_ theme: PresentationTheme, top: Bool, bottom: Bool) -> UIImage? {
if !top && !bottom {
return nil
diff --git a/submodules/TelegramStringFormatting/Sources/PresenceStrings.swift b/submodules/TelegramStringFormatting/Sources/PresenceStrings.swift
index b7bdd08a48..31893c0e27 100644
--- a/submodules/TelegramStringFormatting/Sources/PresenceStrings.swift
+++ b/submodules/TelegramStringFormatting/Sources/PresenceStrings.swift
@@ -109,12 +109,13 @@ public func stringForMonth(strings: PresentationStrings, month: Int32, ofYear ye
public enum RelativeTimestampFormatDay {
case today
case yesterday
+ case tomorrow
}
public func stringForUserPresence(strings: PresentationStrings, day: RelativeTimestampFormatDay, dateTimeFormat: PresentationDateTimeFormat, hours: Int32, minutes: Int32) -> String {
let dayString: String
switch day {
- case .today:
+ case .today, .tomorrow:
dayString = strings.LastSeen_TodayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0
case .yesterday:
dayString = strings.LastSeen_YesterdayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0
@@ -125,10 +126,13 @@ public func stringForUserPresence(strings: PresentationStrings, day: RelativeTim
private func humanReadableStringForTimestamp(strings: PresentationStrings, day: RelativeTimestampFormatDay, dateTimeFormat: PresentationDateTimeFormat, hours: Int32, minutes: Int32) -> String {
let dayString: String
switch day {
- case .today:
- dayString = strings.Time_TodayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0
- case .yesterday:
- dayString = strings.Time_YesterdayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0
+ case .today:
+ dayString = strings.Time_TodayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0
+ case .yesterday:
+ dayString = strings.Time_YesterdayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0
+ case .tomorrow:
+ dayString = strings.Time_TomorrowAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0
+
}
return dayString
}
@@ -148,12 +152,14 @@ public func humanReadableStringForTimestamp(strings: PresentationStrings, dateTi
}
let dayDifference = timeinfo.tm_yday - timeinfoNow.tm_yday
- if dayDifference == 0 || dayDifference == -1 {
+ if dayDifference == 0 || dayDifference == -1 || dayDifference == 1 {
let day: RelativeTimestampFormatDay
if dayDifference == 0 {
day = .today
- } else {
+ } else if dayDifference == -1 {
day = .yesterday
+ } else {
+ day = .tomorrow
}
return humanReadableStringForTimestamp(strings: strings, day: day, dateTimeFormat: dateTimeFormat, hours: timeinfo.tm_hour, minutes: timeinfo.tm_min)
} else {
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/Contents.json b/submodules/TelegramUI/Images.xcassets/Chart/Contents.json
new file mode 100644
index 0000000000..38f0c81fc2
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chart/Contents.json
@@ -0,0 +1,9 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "provides-namespace" : true
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/arrow_left.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chart/arrow_left.imageset/Contents.json
new file mode 100644
index 0000000000..78b05b5e2a
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chart/arrow_left.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "arrow_left.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/arrow_left.imageset/arrow_left.pdf b/submodules/TelegramUI/Images.xcassets/Chart/arrow_left.imageset/arrow_left.pdf
new file mode 100644
index 0000000000..7b20434672
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chart/arrow_left.imageset/arrow_left.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/arrow_right.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chart/arrow_right.imageset/Contents.json
new file mode 100644
index 0000000000..147027fa6d
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chart/arrow_right.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "arrow_right.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/arrow_right.imageset/arrow_right.pdf b/submodules/TelegramUI/Images.xcassets/Chart/arrow_right.imageset/arrow_right.pdf
new file mode 100644
index 0000000000..baf05c2435
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chart/arrow_right.imageset/arrow_right.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_dark.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_dark.imageset/Contents.json
new file mode 100644
index 0000000000..65481db2a7
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_dark.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "selection_frame_dark.pdf",
+ "resizing" : {
+ "mode" : "3-part-horizontal",
+ "center" : {
+ "mode" : "stretch",
+ "width" : 1
+ },
+ "cap-insets" : {
+ "right" : 11,
+ "left" : 11
+ }
+ }
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_dark.imageset/selection_frame_dark.pdf b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_dark.imageset/selection_frame_dark.pdf
new file mode 100644
index 0000000000..ae27128091
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_dark.imageset/selection_frame_dark.pdf
@@ -0,0 +1,61 @@
+%PDF-1.4
+%
+1 0 obj
+<>
+endobj
+2 0 obj
+<> stream
+xMN19H .,8bD{ 'vBZ$&(zv9#@[OG@$mޞyer:kptiک>) ԩS J) zKHf7.<Ul5(ez;n[fscwN5&oW\~ɷtm`v{*CK=N'|T[Rb35LdvuMUD-=1XׁTa'ۀzqncM="X+&
-yKS
+endstream
+endobj
+3 0 obj
+<>
+endobj
+4 0 obj
+<>
+endobj
+5 0 obj
+<>>>
+/MediaBox [0 0 114 42]
+/Contents 2 0 R
+/Parent 4 0 R>>
+endobj
+6 0 obj
+<>
+endobj
+7 0 obj
+<>
+endobj
+xref
+0 8
+0000000000 65535 f
+0000000015 00000 n
+0000000089 00000 n
+0000000482 00000 n
+0000000529 00000 n
+0000000584 00000 n
+0000000765 00000 n
+0000000802 00000 n
+trailer
+<>
+startxref
+880
+%%EOF
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_light.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_light.imageset/Contents.json
new file mode 100644
index 0000000000..8cc38ca79c
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_light.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "selection_frame_light.pdf",
+ "resizing" : {
+ "mode" : "3-part-horizontal",
+ "center" : {
+ "mode" : "stretch",
+ "width" : 1
+ },
+ "cap-insets" : {
+ "right" : 11,
+ "left" : 11
+ }
+ }
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_light.imageset/selection_frame_light.pdf b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_light.imageset/selection_frame_light.pdf
new file mode 100644
index 0000000000..c426c5d695
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chart/selection_frame_light.imageset/selection_frame_light.pdf
@@ -0,0 +1,62 @@
+%PDF-1.4
+%
+1 0 obj
+<>
+endobj
+2 0 obj
+<> stream
+xN0~
+'yp*NY6$5uH&M3!U;ur:(`PĒ8weT-)s+w0ofn2zrkM~q=[V{]]b5^8U '䖄&?ȽƋ1NdBuQZmP2{QDʠՆ8-,l
lx}
E>nr_1io|BV
+endstream
+endobj
+3 0 obj
+<>
+endobj
+4 0 obj
+<>
+endobj
+5 0 obj
+<>>>
+/MediaBox [0 0 114 42]
+/Contents 2 0 R
+/Parent 4 0 R>>
+endobj
+6 0 obj
+<>
+endobj
+7 0 obj
+<>
+endobj
+xref
+0 8
+0000000000 65535 f
+0000000015 00000 n
+0000000089 00000 n
+0000000482 00000 n
+0000000529 00000 n
+0000000584 00000 n
+0000000765 00000 n
+0000000802 00000 n
+trailer
+<>
+startxref
+880
+%%EOF
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/Contents.json
new file mode 100644
index 0000000000..38f0c81fc2
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/Contents.json
@@ -0,0 +1,9 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "provides-namespace" : true
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Contents.json
new file mode 100644
index 0000000000..9afc9c4e5d
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "ic_calls.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/ic_calls.pdf b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/ic_calls.pdf
new file mode 100644
index 0000000000..f42e5fe81b
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/ic_calls.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Contents.json
new file mode 100644
index 0000000000..3637003f27
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "ic_messages.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/ic_messages.pdf b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/ic_messages.pdf
new file mode 100644
index 0000000000..64aba1907d
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/ic_messages.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contents.json
new file mode 100644
index 0000000000..006f82fb71
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "ic_contacts.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/ic_contacts.pdf b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/ic_contacts.pdf
new file mode 100644
index 0000000000..41f48e4e2d
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/ic_contacts.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Contents.json
new file mode 100644
index 0000000000..261d9ff3a9
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "ic_settings.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/ic_settings.pdf b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/ic_settings.pdf
new file mode 100644
index 0000000000..0f3b0dc083
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/ic_settings.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Contact List/MakeInvisibleIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Contact List/MakeInvisibleIcon.imageset/Contents.json
new file mode 100644
index 0000000000..7abcd976aa
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Contact List/MakeInvisibleIcon.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "ic_stopshowme.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Contact List/MakeInvisibleIcon.imageset/ic_stopshowme.pdf b/submodules/TelegramUI/Images.xcassets/Contact List/MakeInvisibleIcon.imageset/ic_stopshowme.pdf
new file mode 100644
index 0000000000..9cc4c3d65a
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Contact List/MakeInvisibleIcon.imageset/ic_stopshowme.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Contact List/MakeVisibleIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Contact List/MakeVisibleIcon.imageset/Contents.json
new file mode 100644
index 0000000000..97cc9be019
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Contact List/MakeVisibleIcon.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "ic_showme.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Contact List/MakeVisibleIcon.imageset/ic_showme.pdf b/submodules/TelegramUI/Images.xcassets/Contact List/MakeVisibleIcon.imageset/ic_showme.pdf
new file mode 100644
index 0000000000..0c5a6e2133
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Contact List/MakeVisibleIcon.imageset/ic_showme.pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOff.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOff.imageset/Contents.json
new file mode 100644
index 0000000000..d2ce704e18
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOff.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "soundoff (2).pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOff.imageset/soundoff (2).pdf b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOff.imageset/soundoff (2).pdf
new file mode 100644
index 0000000000..8051a2a4e0
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOff.imageset/soundoff (2).pdf differ
diff --git a/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOn.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOn.imageset/Contents.json
new file mode 100644
index 0000000000..1d93d33a26
--- /dev/null
+++ b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOn.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "soundon (2).pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOn.imageset/soundon (2).pdf b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOn.imageset/soundon (2).pdf
new file mode 100644
index 0000000000..20236a226b
Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Media Gallery/SoundOn.imageset/soundon (2).pdf differ
diff --git a/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift b/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift
index be5f243176..7e6470fbf2 100644
--- a/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift
@@ -117,7 +117,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
break
case .ignore:
return .fail
- case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .tooltip:
+ case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip:
return .waitForSingleTap
}
}
diff --git a/submodules/TelegramUI/TelegramUI/ChatController.swift b/submodules/TelegramUI/TelegramUI/ChatController.swift
index b07dae10d7..d62259a257 100644
--- a/submodules/TelegramUI/TelegramUI/ChatController.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatController.swift
@@ -1358,6 +1358,33 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
])])
strongSelf.chatDisplayNode.dismissInput()
strongSelf.present(actionSheet, in: .window(.root))
+ case let .bankCard(number):
+ guard let message = message else {
+ return
+ }
+ let _ = (getBankCardInfo(account: strongSelf.context.account, cardNumber: number)
+ |> deliverOnMainQueue).start(next: { [weak self] info in
+ if let strongSelf = self, let info = info {
+ let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
+ var items: [ActionSheetItem] = []
+ items.append(ActionSheetTextItem(title: info.title))
+ if let url = info.url, let actionTitle = info.actionTitle {
+ items.append(ActionSheetButtonItem(title: actionTitle, color: .accent, action: { [weak actionSheet] in
+ actionSheet?.dismissAnimated()
+ if let strongSelf = self {
+ strongSelf.controllerInteraction?.openUrl(url, false, false, message)
+ }
+ }))
+ }
+ actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
+ ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
+ actionSheet?.dismissAnimated()
+ })
+ ])])
+ strongSelf.present(actionSheet, in: .window(.root))
+ }
+ })
+ strongSelf.chatDisplayNode.dismissInput()
}
}
}, openCheckoutOrReceipt: { [weak self] messageId in
diff --git a/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift b/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift
index fdae414c0a..e9b15f43af 100644
--- a/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift
@@ -42,6 +42,7 @@ public enum ChatControllerInteractionLongTapAction {
case command(String)
case hashtag(String)
case timecode(Double, String)
+ case bankCard(String)
}
struct ChatInterfacePollActionState: Equatable {
@@ -119,6 +120,7 @@ public final class ChatControllerInteraction {
var stickerSettings: ChatInterfaceStickerSettings
var searchTextHighightState: (String, [MessageIndex])?
var seenOneTimeAnimatedMedia = Set()
+ var seenDicePointsValue = [MessageId: Int]()
init(openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, Message?) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, TapLongTapOrDoubleTapGestureRecognizer?) -> Void, openMessageContextActions: @escaping (Message, ASDisplayNode, CGRect, ContextGesture?) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, tapMessage: ((Message) -> Void)?, clickThroughMessage: @escaping () -> Void, toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, sendCurrentMessage: @escaping (Bool) -> Void, sendMessage: @escaping (String) -> Void, sendSticker: @escaping (FileMediaReference, Bool, ASDisplayNode, CGRect) -> Bool, sendGif: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Bool, requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool) -> Void, requestMessageActionUrlAuth: @escaping (String, MessageId, Int32) -> Void, activateSwitchInline: @escaping (PeerId?, String) -> Void, openUrl: @escaping (String, Bool, Bool?, Message?) -> Void, shareCurrentLocation: @escaping () -> Void, shareAccountContact: @escaping () -> Void, sendBotCommand: @escaping (MessageId?, String) -> Void, openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, openWallpaper: @escaping (Message) -> Void, openTheme: @escaping (Message) -> Void, openHashtag: @escaping (String?, String) -> Void, updateInputState: @escaping ((ChatTextInputState) -> ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void, openMessageShareMenu: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?, chatControllerNode: @escaping () -> ASDisplayNode?, reactionContainerNode: @escaping () -> ReactionSelectionParentNode?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, callPeer: @escaping (PeerId) -> Void, longTap: @escaping (ChatControllerInteractionLongTapAction, Message?) -> Void, openCheckoutOrReceipt: @escaping (MessageId) -> Void, openSearch: @escaping () -> Void, setupReply: @escaping (MessageId) -> Void, canSetupReply: @escaping (Message) -> Bool, navigateToFirstDateMessage: @escaping(Int32) ->Void, requestRedeliveryOfFailedMessages: @escaping (MessageId) -> Void, addContact: @escaping (String) -> Void, rateCall: @escaping (Message, CallId) -> Void, requestSelectMessagePollOptions: @escaping (MessageId, [Data]) -> Void, requestOpenMessagePollResults: @escaping (MessageId, MediaId) -> Void, openAppStorePage: @escaping () -> Void, displayMessageTooltip: @escaping (MessageId, String, ASDisplayNode?, CGRect?) -> Void, seekToTimecode: @escaping (Message, Double, Bool) -> Void, scheduleCurrentMessage: @escaping () -> Void, sendScheduledMessagesNow: @escaping ([MessageId]) -> Void, editScheduledMessagesTime: @escaping ([MessageId]) -> Void, performTextSelectionAction: @escaping (UInt32, String, TextSelectionAction) -> Void, updateMessageReaction: @escaping (MessageId, String?) -> Void, openMessageReactions: @escaping (MessageId) -> Void, displaySwipeToReplyHint: @escaping () -> Void, dismissReplyMarkupMessage: @escaping (Message) -> Void, openMessagePollResults: @escaping (MessageId, Data) -> Void, openPollCreation: @escaping (Bool?) -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState, stickerSettings: ChatInterfaceStickerSettings) {
self.openMessage = openMessage
diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift
index ab032691e6..6fb53ab372 100644
--- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift
@@ -13,6 +13,7 @@ import AccountContext
import TemporaryCachedPeerDataManager
import ChatListSearchItemNode
import Emoji
+import AppBundle
private class ChatHistoryListSelectionRecognizer: UIPanGestureRecognizer {
private let selectionGestureActivationThreshold: CGFloat = 5.0
@@ -308,7 +309,7 @@ private final class ChatHistoryTransactionOpaqueState {
}
}
-private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHistoryView, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, animatedEmojiStickers: [String: StickerPackItem], isScheduledMessages: Bool) -> ChatMessageItemAssociatedData {
+private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHistoryView, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, animatedEmojiStickers: [String: [StickerPackItem]], isScheduledMessages: Bool) -> ChatMessageItemAssociatedData {
var automaticMediaDownloadPeerType: MediaAutoDownloadPeerType = .channel
var contactsPeerIds: Set = Set()
if case let .peer(peerId) = chatLocation {
@@ -605,19 +606,31 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|> distinctUntilChanged
let animatedEmojiStickers = loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .animatedEmoji, forceActualized: false)
- |> map { result -> [String: StickerPackItem] in
+ |> map { result -> [String: [StickerPackItem]] in
switch result {
case let .result(_, items, _):
- var animatedEmojiStickers: [String: StickerPackItem] = [:]
+ var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
for case let item as StickerPackItem in items {
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
- animatedEmojiStickers[emoji.basicEmoji.0] = item
+ animatedEmojiStickers[emoji.basicEmoji.0] = [item]
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
if animatedEmojiStickers[strippedEmoji] == nil {
- animatedEmojiStickers[strippedEmoji] = item
+ animatedEmojiStickers[strippedEmoji] = [item]
}
}
}
+
+ if let path = getAppBundle().path(forResource: "Dice_1", ofType: "tgs") {
+ var dices: [StickerPackItem] = []
+ for i in 1...6 {
+ let path = path.replacingOccurrences(of: "_1", with: "_\(i)")
+ let id = arc4random64()
+ let resource = LocalFileReferenceMediaResource(localFilePath: path, randomId: id)
+ dices.append(StickerPackItem(index: ItemCollectionItemIndex(index: Int32(i), id: Int64(i)), file: TelegramMediaFile(fileId: MediaId(namespace: 10, id: Int64(i)), partialReference: nil, resource: resource, previewRepresentations: [], immediateThumbnailData: nil, mimeType: "application/x-tgsticker", size: nil, attributes: []), indexKeys: []))
+ }
+ animatedEmojiStickers["🎲".strippedEmoji] = dices
+ }
+
return animatedEmojiStickers
default:
return [:]
diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift
index 0cbef84d24..0098397abf 100644
--- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift
@@ -255,9 +255,24 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
let (emoji, fitz) = item.message.text.basicEmoji
if self.telegramFile == nil {
- var emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.file
- if emojiFile == nil {
- emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.file
+ var emojiFile: TelegramMediaFile?
+
+ if emoji == "🎲" {
+ var pointsValue: Int
+ if let value = item.controllerInteraction.seenDicePointsValue[item.message.id] {
+ pointsValue = value
+ } else {
+ pointsValue = Int(arc4random_uniform(6))
+ item.controllerInteraction.seenDicePointsValue[item.message.id] = pointsValue
+ }
+ if let diceEmojis = item.associatedData.animatedEmojiStickers[emoji] {
+ emojiFile = diceEmojis[pointsValue].file
+ }
+ } else {
+ emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.first?.file
+ if emojiFile == nil {
+ emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file
+ }
}
if self.emojiFile?.id != emojiFile?.id {
@@ -293,8 +308,12 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
self.animationNode.visibility = isPlaying && !alreadySeen
+
if self.didSetUpAnimationNode && alreadySeen {
- self.animationNode.seekToStart()
+ if let emojiFile = self.emojiFile, emojiFile.resource is LocalFileReferenceMediaResource {
+ } else {
+ self.animationNode.seekTo(.start)
+ }
}
if self.isPlaying && !self.didSetUpAnimationNode {
@@ -313,7 +332,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
} else if let emojiFile = self.emojiFile {
isEmoji = true
file = emojiFile
- playbackMode = .once
+ if alreadySeen && emojiFile.resource is LocalFileReferenceMediaResource {
+ playbackMode = .still(.end)
+ } else {
+ playbackMode = .once
+ }
let (_, fitz) = item.message.text.basicEmoji
if let fitz = fitz {
fitzModifier = EmojiFitzModifier(emoji: fitz)
@@ -323,7 +346,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let file = file {
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fittedSize = isEmoji ? dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0)) : dimensions.cgSize.aspectFitted(CGSize(width: 384.0, height: 384.0))
- self.animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: file.resource, fitzModifier: fitzModifier), width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: .cached)
+ let mode: AnimatedStickerMode
+ if file.resource is LocalFileReferenceMediaResource {
+ mode = .direct
+ } else {
+ mode = .cached
+ }
+ self.animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: file.resource, fitzModifier: fitzModifier), width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: mode)
}
}
}
@@ -870,34 +899,59 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if self.telegramFile != nil {
let _ = item.controllerInteraction.openMessage(item.message, .default)
} else if let _ = self.emojiFile {
- var startTime: Signal
- if self.animationNode.playIfNeeded() {
- startTime = .single(0.0)
+ let (emoji, fitz) = item.message.text.basicEmoji
+ if emoji == "🎲" {
+ if !self.animationNode.isPlaying {
+ var pointsValue = Int(arc4random_uniform(6))
+ item.controllerInteraction.seenDicePointsValue[item.message.id] = pointsValue
+ item.controllerInteraction.seenOneTimeAnimatedMedia.remove(item.message.id)
+
+ var emojiFile: TelegramMediaFile?
+ if let diceEmojis = item.associatedData.animatedEmojiStickers[emoji] {
+ emojiFile = diceEmojis[pointsValue].file
+ }
+
+ self.emojiFile = emojiFile
+ if let emojiFile = emojiFile {
+ let dimensions = emojiFile.dimensions ?? PixelDimensions(width: 512, height: 512)
+ self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: emojiFile, small: false, size: dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0)), fitzModifier: nil, thumbnail: false))
+ self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .standalone(media: emojiFile)).start())
+ }
+ self.isPlaying = false
+ self.didSetUpAnimationNode = false
+ self.updateVisibility()
+ self.animationNode.playIfNeeded()
+ }
} else {
- startTime = self.animationNode.status
+ var startTime: Signal
+ if self.animationNode.playIfNeeded() {
+ startTime = .single(0.0)
+ } else {
+ startTime = self.animationNode.status
|> map { $0.timestamp }
|> take(1)
|> deliverOnMainQueue
- }
-
- if let text = self.item?.message.text, let firstScalar = text.unicodeScalars.first, firstScalar.value == 0x2764 {
- let _ = startTime.start(next: { [weak self] time in
- guard let strongSelf = self else {
- return
- }
-
- let heartbeatHaptic: ChatMessageHeartbeatHaptic
- if let current = strongSelf.heartbeatHaptic {
- heartbeatHaptic = current
- } else {
- heartbeatHaptic = ChatMessageHeartbeatHaptic()
- heartbeatHaptic.enabled = true
- strongSelf.heartbeatHaptic = heartbeatHaptic
- }
- if !heartbeatHaptic.active {
- heartbeatHaptic.start(time: time)
- }
- })
+ }
+
+ if let text = self.item?.message.text, let firstScalar = text.unicodeScalars.first, firstScalar.value == 0x2764 {
+ let _ = startTime.start(next: { [weak self] time in
+ guard let strongSelf = self else {
+ return
+ }
+
+ let heartbeatHaptic: ChatMessageHeartbeatHaptic
+ if let current = strongSelf.heartbeatHaptic {
+ heartbeatHaptic = current
+ } else {
+ heartbeatHaptic = ChatMessageHeartbeatHaptic()
+ heartbeatHaptic.enabled = true
+ strongSelf.heartbeatHaptic = heartbeatHaptic
+ }
+ if !heartbeatHaptic.active {
+ heartbeatHaptic.start(time: time)
+ }
+ })
+ }
}
}
return true
diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift
index 0e565d40fb..bfb409db6b 100644
--- a/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift
@@ -1019,7 +1019,8 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
TelegramTextAttributes.PeerMention,
TelegramTextAttributes.PeerTextMention,
TelegramTextAttributes.BotCommand,
- TelegramTextAttributes.Hashtag
+ TelegramTextAttributes.Hashtag,
+ TelegramTextAttributes.BankCard
]
for name in possibleNames {
if let _ = attributes[NSAttributedString.Key(rawValue: name)] {
diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift
index 4c10c8609a..0e2b2d8b2f 100644
--- a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift
@@ -80,6 +80,7 @@ enum ChatMessageBubbleContentTapAction {
case openMessage
case timecode(Double, String)
case tooltip(String, ASDisplayNode?, CGRect?)
+ case bankCard(String)
case ignore
}
diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift
index a507081fd5..93f968a020 100644
--- a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift
@@ -355,7 +355,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
break
case .ignore:
return .fail
- case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .tooltip:
+ case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip:
return .waitForSingleTap
}
}
@@ -2381,6 +2381,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
item.controllerInteraction.seekToTimecode(mediaMessage, timecode, forceOpen)
}
break loop
+ case let .bankCard(number):
+ foundTapAction = true
+ if let item = self.item {
+ item.controllerInteraction.longTap(.bankCard(number), item.message)
+ }
case let .tooltip(text, node, rect):
foundTapAction = true
if let item = self.item {
@@ -2447,6 +2452,9 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
item.controllerInteraction.longTap(.timecode(timecode, text), mediaMessage)
}
break loop
+ case let .bankCard(number):
+ foundTapAction = true
+ item.controllerInteraction.longTap(.bankCard(number), message)
case .tooltip:
break
}
diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift
index 26af9b2098..fe50b15654 100644
--- a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift
@@ -226,10 +226,10 @@ public final class ChatMessageItemAssociatedData: Equatable {
let isRecentActions: Bool
let isScheduledMessages: Bool
let contactsPeerIds: Set
- let animatedEmojiStickers: [String: StickerPackItem]
+ let animatedEmojiStickers: [String: [StickerPackItem]]
let forcedResourceStatus: FileMediaResourceStatus?
- init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool = false, isScheduledMessages: Bool = false, contactsPeerIds: Set = Set(), animatedEmojiStickers: [String: StickerPackItem] = [:], forcedResourceStatus: FileMediaResourceStatus? = nil) {
+ init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool = false, isScheduledMessages: Bool = false, contactsPeerIds: Set = Set(), animatedEmojiStickers: [String: [StickerPackItem]] = [:], forcedResourceStatus: FileMediaResourceStatus? = nil) {
self.automaticDownloadPeerType = automaticDownloadPeerType
self.automaticDownloadNetworkType = automaticDownloadNetworkType
self.isRecentActions = isRecentActions
diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift
index 31b1d33df8..5df3808ac2 100644
--- a/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift
@@ -428,6 +428,8 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
return .hashtag(hashtag.peerName, hashtag.hashtag)
} else if let timecode = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Timecode)] as? TelegramTimecode {
return .timecode(timecode.time, timecode.text)
+ } else if let bankCard = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BankCard)] as? String {
+ return .bankCard(bankCard)
} else {
return .none
}
@@ -451,7 +453,8 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
TelegramTextAttributes.PeerTextMention,
TelegramTextAttributes.BotCommand,
TelegramTextAttributes.Hashtag,
- TelegramTextAttributes.Timecode
+ TelegramTextAttributes.Timecode,
+ TelegramTextAttributes.BankCard
]
for name in possibleNames {
if let _ = attributes[NSAttributedString.Key(rawValue: name)] {
diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift
index cf5344ad57..b4de87c21a 100644
--- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift
@@ -392,6 +392,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
})
])])
strongSelf.presentController(actionSheet, nil)
+ case .bankCard:
+ break
}
}
}, openCheckoutOrReceipt: { _ in
diff --git a/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift
index 4b77d486aa..e69a824772 100644
--- a/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift
+++ b/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift
@@ -352,7 +352,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - buttonHeight - insets.bottom - 10.0 - buttonOffset, width: contentFrame.width, height: buttonHeight))
let onlineSize = self.onlineButton.measure(CGSize(width: width, height: titleHeight))
- let onlineFrame = CGRect(origin: CGPoint(x: ceil((layout.size.width - onlineSize.width) / 2.0), y: contentHeight - 45.0 - insets.bottom), size: onlineSize)
+ let onlineFrame = CGRect(origin: CGPoint(x: ceil((contentFrame.width - onlineSize.width) / 2.0), y: contentHeight - 45.0 - insets.bottom), size: onlineSize)
transition.updateFrame(node: self.onlineButton, frame: onlineFrame)
self.pickerView?.frame = CGRect(origin: CGPoint(x: 0.0, y: 54.0), size: CGSize(width: contentFrame.width, height: pickerHeight))
diff --git a/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift b/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift
index 48c50b6f43..606f2431d9 100644
--- a/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift
+++ b/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift
@@ -28,7 +28,7 @@ func paneGifSearchForQuery(account: Account, query: String, updateActivity: ((Bo
}
|> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> in
if let user = peer as? TelegramUser, let botInfo = user.botInfo, let _ = botInfo.inlinePlaceholder {
- let results = requestContextResults(account: account, botId: user.id, query: query, peerId: account.peerId, limit: 64)
+ let results = requestContextResults(account: account, botId: user.id, query: query, peerId: account.peerId, limit: 15)
|> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
return { _ in
return .contextRequestResult(user, results)
diff --git a/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift b/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift
index 5a3d511455..0e6f49d611 100644
--- a/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift
+++ b/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift
@@ -105,4 +105,3 @@ final class ListMessageDateHeaderNode: ListViewItemHeaderNode {
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size)
}
}
-
diff --git a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping
index 0e740b4a15..97d55f8f57 100644
Binary files a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping and b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping differ
diff --git a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift
index 615d605e19..e3cad1726e 100644
--- a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift
+++ b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift
@@ -209,6 +209,15 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
string.insert(NSAttributedString(string: paragraphBreak), at: paragraphRange.upperBound)
rangeOffset += paragraphBreak.count
+ case .BankCard:
+ string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range)
+ if underlineLinks && underlineAllLinks {
+ string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range)
+ }
+ if nsString == nil {
+ nsString = text as NSString
+ }
+ string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.BankCard), value: nsString!.substring(with: range), range: range)
case let .Custom(type):
if type == ApplicationSpecificEntityType.Timecode {
string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range)
diff --git a/submodules/TextFormat/Sources/TelegramAttributes.swift b/submodules/TextFormat/Sources/TelegramAttributes.swift
index b05f982d82..ab276a41e3 100644
--- a/submodules/TextFormat/Sources/TelegramAttributes.swift
+++ b/submodules/TextFormat/Sources/TelegramAttributes.swift
@@ -37,6 +37,7 @@ public struct TelegramTextAttributes {
public static let PeerTextMention = "TelegramPeerTextMention"
public static let BotCommand = "TelegramBotCommand"
public static let Hashtag = "TelegramHashtag"
+ public static let BankCard = "TelegramBankCard"
public static let Timecode = "TelegramTimecode"
public static let BlockQuote = "TelegramBlockQuote"
}
diff --git a/submodules/UrlHandling/Sources/UrlHandling.swift b/submodules/UrlHandling/Sources/UrlHandling.swift
index bd53d7861c..051053b059 100644
--- a/submodules/UrlHandling/Sources/UrlHandling.swift
+++ b/submodules/UrlHandling/Sources/UrlHandling.swift
@@ -14,6 +14,8 @@ import TelegramUIPreferences
import AccountContext
import WalletUrl
+private let baseTelegramMePaths = ["telegram.me", "t.me", "telegram.dog"]
+
public enum ParsedInternalPeerUrlParameter {
case botStart(String)
case groupBotStart(String)
@@ -346,7 +348,6 @@ private func resolveInternalUrl(account: Account, url: ParsedInternalUrl) -> Sig
public func isTelegramMeLink(_ url: String) -> Bool {
let schemes = ["http://", "https://", ""]
- let baseTelegramMePaths = ["telegram.me", "t.me"]
for basePath in baseTelegramMePaths {
for scheme in schemes {
let basePrefix = scheme + basePath + "/"
@@ -360,7 +361,6 @@ public func isTelegramMeLink(_ url: String) -> Bool {
public func parseProxyUrl(_ url: String) -> (host: String, port: Int32, username: String?, password: String?, secret: Data?)? {
let schemes = ["http://", "https://", ""]
- let baseTelegramMePaths = ["telegram.me", "t.me"]
for basePath in baseTelegramMePaths {
for scheme in schemes {
let basePrefix = scheme + basePath + "/"
@@ -382,7 +382,6 @@ public func parseProxyUrl(_ url: String) -> (host: String, port: Int32, username
public func parseStickerPackUrl(_ url: String) -> String? {
let schemes = ["http://", "https://", ""]
- let baseTelegramMePaths = ["telegram.me", "t.me"]
for basePath in baseTelegramMePaths {
for scheme in schemes {
let basePrefix = scheme + basePath + "/"
@@ -404,7 +403,6 @@ public func parseStickerPackUrl(_ url: String) -> String? {
public func parseWallpaperUrl(_ url: String) -> WallpaperUrlParameter? {
let schemes = ["http://", "https://", ""]
- let baseTelegramMePaths = ["telegram.me", "t.me"]
for basePath in baseTelegramMePaths {
for scheme in schemes {
let basePrefix = scheme + basePath + "/"
@@ -431,7 +429,6 @@ public func resolveUrlImpl(account: Account, url: String) -> Signal()
private let centralItemTitleView = Promise()
private let centralItemNavigationStyle = Promise()
- private let centralItemFooterContentNode = Promise()
+ private let centralItemFooterContentNode = Promise<(GalleryFooterContentNode?, GalleryOverlayContentNode?)>()
private let centralItemAttributesDisposable = DisposableSet();
private let checkedDisposable = MetaDisposable()
@@ -156,7 +156,7 @@ class WebSearchGalleryController: ViewController {
self?.navigationItem.titleView = titleView
}))
- self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode in
+ self.centralItemAttributesDisposable.add(self.centralItemFooterContentNode.get().start(next: { [weak self] footerContentNode, _ in
self?.galleryNode.updatePresentationState({
$0.withUpdatedFooterContentNode(footerContentNode)
}, transition: .immediate)
diff --git a/submodules/WebSearchUI/Sources/WebSearchVideoGalleryItem.swift b/submodules/WebSearchUI/Sources/WebSearchVideoGalleryItem.swift
index 498a758306..1f69d4ec7a 100644
--- a/submodules/WebSearchUI/Sources/WebSearchVideoGalleryItem.swift
+++ b/submodules/WebSearchUI/Sources/WebSearchVideoGalleryItem.swift
@@ -534,7 +534,7 @@ final class WebSearchVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
}
- override func footerContent() -> Signal {
- return .single(self.footerContentNode)
+ override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
+ return .single((self.footerContentNode, nil))
}
}
diff --git a/submodules/ffmpeg/gas-preprocessor.pl b/submodules/ffmpeg/gas-preprocessor.pl
new file mode 100755
index 0000000000..6da37c1f0d
--- /dev/null
+++ b/submodules/ffmpeg/gas-preprocessor.pl
@@ -0,0 +1,1210 @@
+#!/usr/bin/env perl
+# by David Conrad
+# This code is licensed under GPLv2 or later; go to gnu.org to read it
+# (not that it much matters for an asm preprocessor)
+# usage: set your assembler to be something like "perl gas-preprocessor.pl gcc"
+use strict;
+
+# Apple's gas is ancient and doesn't support modern preprocessing features like
+# .rept and has ugly macro syntax, among other things. Thus, this script
+# implements the subset of the gas preprocessor used by x264 and ffmpeg
+# that isn't supported by Apple's gas.
+
+my %canonical_arch = ("aarch64" => "aarch64", "arm64" => "aarch64",
+ "arm" => "arm",
+ "powerpc" => "powerpc", "ppc" => "powerpc");
+
+my %comments = ("aarch64" => '//',
+ "arm" => '@',
+ "powerpc" => '#');
+
+my @gcc_cmd;
+my @preprocess_c_cmd;
+
+my $comm;
+my $arch;
+my $as_type = "apple-gas";
+
+my $fix_unreq = $^O eq "darwin";
+my $force_thumb = 0;
+my $verbose = 0;
+
+my $arm_cond_codes = "eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo";
+
+my $usage_str = "
+$0\n
+Gas-preprocessor.pl converts assembler files using modern GNU as syntax for
+Apple's ancient gas version or clang's incompatible integrated assembler. The
+conversion is regularly tested for Libav, x264 and vlc. Other projects might
+use different features which are not correctly handled.
+
+Options for this program needs to be separated with ' -- ' from the assembler
+command. Following options are currently supported:
+
+ -help - this usage text
+ -arch - target architecture
+ -as-type - one value out of {{,apple-}{gas,clang},armasm}
+ -fix-unreq
+ -no-fix-unreq
+ -force-thumb - assemble as thumb regardless of the input source
+ (note, this is incomplete and only works for sources
+ it explicitly was tested with)
+ -verbose - print executed commands
+";
+
+sub usage() {
+ print $usage_str;
+}
+
+while (@ARGV) {
+ my $opt = shift;
+
+ if ($opt =~ /^-(no-)?fix-unreq$/) {
+ $fix_unreq = $1 ne "no-";
+ } elsif ($opt eq "-force-thumb") {
+ $force_thumb = 1;
+ } elsif ($opt eq "-verbose") {
+ $verbose = 1;
+ } elsif ($opt eq "-arch") {
+ $arch = shift;
+ die "unknown arch: '$arch'\n" if not exists $canonical_arch{$arch};
+ } elsif ($opt eq "-as-type") {
+ $as_type = shift;
+ die "unknown as type: '$as_type'\n" if $as_type !~ /^((apple-)?(gas|clang)|armasm)$/;
+ } elsif ($opt eq "-help") {
+ usage();
+ exit 0;
+ } elsif ($opt eq "--" ) {
+ @gcc_cmd = @ARGV;
+ } elsif ($opt =~ /^-/) {
+ die "option '$opt' is not known. See '$0 -help' for usage information\n";
+ } else {
+ push @gcc_cmd, $opt, @ARGV;
+ }
+ last if (@gcc_cmd);
+}
+
+if (grep /\.c$/, @gcc_cmd) {
+ # C file (inline asm?) - compile
+ @preprocess_c_cmd = (@gcc_cmd, "-S");
+} elsif (grep /\.[sS]$/, @gcc_cmd) {
+ # asm file, just do C preprocessor
+ @preprocess_c_cmd = (@gcc_cmd, "-E");
+} elsif (grep /-(v|h|-version|dumpversion)/, @gcc_cmd) {
+ # pass -v/--version along, used during probing. Matching '-v' might have
+ # uninteded results but it doesn't matter much if gas-preprocessor or
+ # the compiler fails.
+ print STDERR join(" ", @gcc_cmd)."\n" if $verbose;
+ exec(@gcc_cmd);
+} else {
+ die "Unrecognized input filetype";
+}
+if ($as_type eq "armasm") {
+
+ $preprocess_c_cmd[0] = "cpp";
+ push(@preprocess_c_cmd, "-undef");
+ # Normally a preprocessor for windows would predefine _WIN32,
+ # but we're using any generic system-agnostic preprocessor "cpp"
+ # with -undef (to avoid getting predefined variables from the host
+ # system in cross compilation cases), so manually define it here.
+ push(@preprocess_c_cmd, "-D_WIN32");
+
+ @preprocess_c_cmd = grep ! /^-nologo$/, @preprocess_c_cmd;
+ # Remove -ignore XX parameter pairs from preprocess_c_cmd
+ my $index = 1;
+ while ($index < $#preprocess_c_cmd) {
+ if ($preprocess_c_cmd[$index] eq "-ignore" and $index + 1 < $#preprocess_c_cmd) {
+ splice(@preprocess_c_cmd, $index, 2);
+ next;
+ }
+ $index++;
+ }
+ if (grep /^-MM$/, @preprocess_c_cmd) {
+ print STDERR join(" ", @preprocess_c_cmd)."\n" if $verbose;
+ system(@preprocess_c_cmd) == 0 or die "Error running preprocessor";
+ exit 0;
+ }
+}
+
+# if compiling, avoid creating an output file named '-.o'
+if ((grep /^-c$/, @gcc_cmd) && !(grep /^-o/, @gcc_cmd)) {
+ foreach my $i (@gcc_cmd) {
+ if ($i =~ /\.[csS]$/) {
+ my $outputfile = $i;
+ $outputfile =~ s/\.[csS]$/.o/;
+ push(@gcc_cmd, "-o");
+ push(@gcc_cmd, $outputfile);
+ last;
+ }
+ }
+}
+# replace only the '-o' argument with '-', avoids rewriting the make dependency
+# target specified with -MT to '-'
+my $index = 1;
+while ($index < $#preprocess_c_cmd) {
+ if ($preprocess_c_cmd[$index] eq "-o") {
+ $index++;
+ $preprocess_c_cmd[$index] = "-";
+ }
+ $index++;
+}
+
+my $tempfile;
+if ($as_type ne "armasm") {
+ @gcc_cmd = map { /\.[csS]$/ ? qw(-x assembler -) : $_ } @gcc_cmd;
+} else {
+ @preprocess_c_cmd = grep ! /^-c$/, @preprocess_c_cmd;
+ @preprocess_c_cmd = grep ! /^-m/, @preprocess_c_cmd;
+
+ @preprocess_c_cmd = grep ! /^-G/, @preprocess_c_cmd;
+ @preprocess_c_cmd = grep ! /^-W/, @preprocess_c_cmd;
+ @preprocess_c_cmd = grep ! /^-Z/, @preprocess_c_cmd;
+ @preprocess_c_cmd = grep ! /^-fp/, @preprocess_c_cmd;
+ @preprocess_c_cmd = grep ! /^-EHsc$/, @preprocess_c_cmd;
+ @preprocess_c_cmd = grep ! /^-O/, @preprocess_c_cmd;
+
+ @gcc_cmd = grep ! /^-G/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-W/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-Z/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-fp/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-EHsc$/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-O/, @gcc_cmd;
+
+ my @outfiles = grep /\.(o|obj)$/, @gcc_cmd;
+ $tempfile = $outfiles[0].".asm";
+
+ # Remove most parameters from gcc_cmd, which actually is the armasm command,
+ # which doesn't support any of the common compiler/preprocessor options.
+ @gcc_cmd = grep ! /^-D/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-U/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-m/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-M/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-c$/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-I/, @gcc_cmd;
+ @gcc_cmd = map { /\.S$/ ? $tempfile : $_ } @gcc_cmd;
+}
+
+# detect architecture from gcc binary name
+if (!$arch) {
+ if ($gcc_cmd[0] =~ /(arm64|aarch64|arm|powerpc|ppc)/) {
+ $arch = $1;
+ } else {
+ # look for -arch flag
+ foreach my $i (1 .. $#gcc_cmd-1) {
+ if ($gcc_cmd[$i] eq "-arch" and
+ $gcc_cmd[$i+1] =~ /(arm64|aarch64|arm|powerpc|ppc)/) {
+ $arch = $1;
+ }
+ }
+ }
+}
+
+# assume we're not cross-compiling if no -arch or the binary doesn't have the arch name
+$arch = qx/arch/ if (!$arch);
+
+die "Unknown target architecture '$arch'" if not exists $canonical_arch{$arch};
+
+$arch = $canonical_arch{$arch};
+$comm = $comments{$arch};
+my $inputcomm = $comm;
+$comm = ";" if $as_type =~ /armasm/;
+
+my %ppc_spr = (ctr => 9,
+ vrsave => 256);
+
+print STDERR join(" ", @preprocess_c_cmd)."\n" if $verbose;
+open(INPUT, "-|", @preprocess_c_cmd) || die "Error running preprocessor";
+
+if ($ENV{GASPP_DEBUG}) {
+ open(ASMFILE, ">&STDOUT");
+} else {
+ if ($as_type ne "armasm") {
+ print STDERR join(" ", @gcc_cmd)."\n" if $verbose;
+ open(ASMFILE, "|-", @gcc_cmd) or die "Error running assembler";
+ } else {
+ open(ASMFILE, ">", $tempfile);
+ }
+}
+
+my $current_macro = '';
+my $macro_level = 0;
+my $rept_level = 0;
+my %macro_lines;
+my %macro_args;
+my %macro_args_default;
+my $macro_count = 0;
+my $altmacro = 0;
+my $in_irp = 0;
+
+my $num_repts;
+my @rept_lines;
+
+my @irp_args;
+my $irp_param;
+
+my @ifstack;
+
+my %symbols;
+
+my @sections;
+
+my %literal_labels; # for ldr , =
+my $literal_num = 0;
+my $literal_expr = ".word";
+$literal_expr = ".quad" if $arch eq "aarch64";
+
+my $thumb = 0;
+
+my %thumb_labels;
+my %call_targets;
+my %import_symbols;
+
+my %neon_alias_reg;
+my %neon_alias_type;
+
+my $temp_label_next = 0;
+my %last_temp_labels;
+my %next_temp_labels;
+
+my %labels_seen;
+
+my %aarch64_req_alias;
+
+if ($force_thumb) {
+ parse_line(".thumb\n");
+}
+
+# pass 1: parse .macro
+# note that the handling of arguments is probably overly permissive vs. gas
+# but it should be the same for valid cases
+while () {
+ # remove lines starting with '#', preprocessing is done, '#' at start of
+ # the line indicates a comment for all supported archs (aarch64, arm, ppc
+ # and x86). Also strips line number comments but since they are off anyway
+ # it is no loss.
+ s/^\s*#.*$//;
+ # remove all comments (to avoid interfering with evaluating directives)
+ s/(? 0) {
+ $ifstack[-1] = -$ifstack[-1];
+ }
+ return 1;
+ } elsif ($line =~ /\.else/) {
+ $ifstack[-1] = !$ifstack[-1];
+ return 1;
+ } elsif (handle_if($line)) {
+ return 1;
+ }
+ }
+
+ # discard lines in false .if blocks
+ foreach my $i (0 .. $#ifstack) {
+ if ($ifstack[$i] <= 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+sub parse_line {
+ my $line = $_[0];
+
+ return if (parse_if_line($line));
+
+ if (scalar(@rept_lines) == 0) {
+ if ($line =~ /\.macro/) {
+ $macro_level++;
+ if ($macro_level > 1 && !$current_macro) {
+ die "nested macros but we don't have master macro";
+ }
+ } elsif ($line =~ /\.endm/) {
+ $macro_level--;
+ if ($macro_level < 0) {
+ die "unmatched .endm";
+ } elsif ($macro_level == 0) {
+ $current_macro = '';
+ return;
+ }
+ }
+ }
+
+ if ($macro_level == 0) {
+ if ($line =~ /\.(rept|irp)/) {
+ $rept_level++;
+ } elsif ($line =~ /.endr/) {
+ $rept_level--;
+ }
+ }
+
+ if ($macro_level > 1) {
+ push(@{$macro_lines{$current_macro}}, $line);
+ } elsif (scalar(@rept_lines) and $rept_level >= 1) {
+ push(@rept_lines, $line);
+ } elsif ($macro_level == 0) {
+ expand_macros($line);
+ } else {
+ if ($line =~ /\.macro\s+([\d\w\.]+)\s*,?\s*(.*)/) {
+ $current_macro = $1;
+
+ # commas in the argument list are optional, so only use whitespace as the separator
+ my $arglist = $2;
+ $arglist =~ s/,/ /g;
+
+ my @args = split(/\s+/, $arglist);
+ foreach my $i (0 .. $#args) {
+ my @argpair = split(/=/, $args[$i]);
+ $macro_args{$current_macro}[$i] = $argpair[0];
+ $argpair[0] =~ s/:vararg$//;
+ $macro_args_default{$current_macro}{$argpair[0]} = $argpair[1];
+ }
+ # ensure %macro_lines has the macro name added as a key
+ $macro_lines{$current_macro} = [];
+
+ } elsif ($current_macro) {
+ push(@{$macro_lines{$current_macro}}, $line);
+ } else {
+ die "macro level without a macro name";
+ }
+ }
+}
+
+sub handle_set {
+ my $line = $_[0];
+ if ($line =~ /\.(?:set|equ)\s+(\S*)\s*,\s*(.*)/) {
+ $symbols{$1} = eval_expr($2);
+ return 1;
+ }
+ return 0;
+}
+
+sub expand_macros {
+ my $line = $_[0];
+
+ # handle .if directives; apple's assembler doesn't support important non-basic ones
+ # evaluating them is also needed to handle recursive macros
+ if (handle_if($line)) {
+ return;
+ }
+
+ if (/\.purgem\s+([\d\w\.]+)/) {
+ delete $macro_lines{$1};
+ delete $macro_args{$1};
+ delete $macro_args_default{$1};
+ return;
+ }
+
+ if ($line =~ /\.altmacro/) {
+ $altmacro = 1;
+ return;
+ }
+
+ if ($line =~ /\.noaltmacro/) {
+ $altmacro = 0;
+ return;
+ }
+
+ $line =~ s/\%([^,]*)/eval_expr($1)/eg if $altmacro;
+
+ # Strip out the .set lines from the armasm output
+ return if (handle_set($line) and $as_type eq "armasm");
+
+ if ($line =~ /\.rept\s+(.*)/) {
+ $num_repts = $1;
+ @rept_lines = ("\n");
+
+ # handle the possibility of repeating another directive on the same line
+ # .endr on the same line is not valid, I don't know if a non-directive is
+ if ($num_repts =~ s/(\.\w+.*)//) {
+ push(@rept_lines, "$1\n");
+ }
+ $num_repts = eval_expr($num_repts);
+ } elsif ($line =~ /\.irp\s+([\d\w\.]+)\s*(.*)/) {
+ $in_irp = 1;
+ $num_repts = 1;
+ @rept_lines = ("\n");
+ $irp_param = $1;
+
+ # only use whitespace as the separator
+ my $irp_arglist = $2;
+ $irp_arglist =~ s/,/ /g;
+ $irp_arglist =~ s/^\s+//;
+ @irp_args = split(/\s+/, $irp_arglist);
+ } elsif ($line =~ /\.irpc\s+([\d\w\.]+)\s*(.*)/) {
+ $in_irp = 1;
+ $num_repts = 1;
+ @rept_lines = ("\n");
+ $irp_param = $1;
+
+ my $irp_arglist = $2;
+ $irp_arglist =~ s/,/ /g;
+ $irp_arglist =~ s/^\s+//;
+ @irp_args = split(//, $irp_arglist);
+ } elsif ($line =~ /\.endr/) {
+ my @prev_rept_lines = @rept_lines;
+ my $prev_in_irp = $in_irp;
+ my @prev_irp_args = @irp_args;
+ my $prev_irp_param = $irp_param;
+ my $prev_num_repts = $num_repts;
+ @rept_lines = ();
+ $in_irp = 0;
+ @irp_args = '';
+
+ if ($prev_in_irp != 0) {
+ foreach my $i (@prev_irp_args) {
+ foreach my $origline (@prev_rept_lines) {
+ my $line = $origline;
+ $line =~ s/\\$prev_irp_param/$i/g;
+ $line =~ s/\\\(\)//g; # remove \()
+ parse_line($line);
+ }
+ }
+ } else {
+ for (1 .. $prev_num_repts) {
+ foreach my $origline (@prev_rept_lines) {
+ my $line = $origline;
+ parse_line($line);
+ }
+ }
+ }
+ } elsif ($line =~ /(\S+:|)\s*([\w\d\.]+)\s*(.*)/ && exists $macro_lines{$2}) {
+ handle_serialized_line($1);
+ my $macro = $2;
+
+ # commas are optional here too, but are syntactically important because
+ # parameters can be blank
+ my @arglist = split(/,/, $3);
+ my @args;
+ my @args_seperator;
+
+ my $comma_sep_required = 0;
+ foreach (@arglist) {
+ # allow arithmetic/shift operators in macro arguments
+ $_ =~ s/\s*(\+|-|\*|\/|<<|>>|<|>)\s*/$1/g;
+
+ my @whitespace_split = split(/\s+/, $_);
+ if (!@whitespace_split) {
+ push(@args, '');
+ push(@args_seperator, '');
+ } else {
+ foreach (@whitespace_split) {
+ #print ("arglist = \"$_\"\n");
+ if (length($_)) {
+ push(@args, $_);
+ my $sep = $comma_sep_required ? "," : " ";
+ push(@args_seperator, $sep);
+ #print ("sep = \"$sep\", arg = \"$_\"\n");
+ $comma_sep_required = 0;
+ }
+ }
+ }
+
+ $comma_sep_required = 1;
+ }
+
+ my %replacements;
+ if ($macro_args_default{$macro}){
+ %replacements = %{$macro_args_default{$macro}};
+ }
+
+ # construct hashtable of text to replace
+ foreach my $i (0 .. $#args) {
+ my $argname = $macro_args{$macro}[$i];
+ my @macro_args = @{ $macro_args{$macro} };
+ if ($args[$i] =~ m/=/) {
+ # arg=val references the argument name
+ # XXX: I'm not sure what the expected behaviour if a lot of
+ # these are mixed with unnamed args
+ my @named_arg = split(/=/, $args[$i]);
+ $replacements{$named_arg[0]} = $named_arg[1];
+ } elsif ($i > $#{$macro_args{$macro}}) {
+ # more args given than the macro has named args
+ # XXX: is vararg allowed on arguments before the last?
+ $argname = $macro_args{$macro}[-1];
+ if ($argname =~ s/:vararg$//) {
+ #print "macro = $macro, args[$i] = $args[$i], args_seperator=@args_seperator, argname = $argname, arglist[$i] = $arglist[$i], arglist = @arglist, args=@args, macro_args=@macro_args\n";
+ #$replacements{$argname} .= ", $args[$i]";
+ $replacements{$argname} .= "$args_seperator[$i] $args[$i]";
+ } else {
+ die "Too many arguments to macro $macro";
+ }
+ } else {
+ $argname =~ s/:vararg$//;
+ $replacements{$argname} = $args[$i];
+ }
+ }
+
+ my $count = $macro_count++;
+
+ # apply replacements as regex
+ foreach (@{$macro_lines{$macro}}) {
+ my $macro_line = $_;
+ # do replacements by longest first, this avoids wrong replacement
+ # when argument names are subsets of each other
+ foreach (reverse sort {length $a <=> length $b} keys %replacements) {
+ $macro_line =~ s/\\$_/$replacements{$_}/g;
+ }
+ if ($altmacro) {
+ foreach (reverse sort {length $a <=> length $b} keys %replacements) {
+ $macro_line =~ s/\b$_\b/$replacements{$_}/g;
+ }
+ }
+ $macro_line =~ s/\\\@/$count/g;
+ $macro_line =~ s/\\\(\)//g; # remove \()
+ parse_line($macro_line);
+ }
+ } else {
+ handle_serialized_line($line);
+ }
+}
+
+sub is_arm_register {
+ my $name = $_[0];
+ if ($name eq "lr" or
+ $name eq "ip" or
+ $name =~ /^[rav]\d+$/) {
+ return 1;
+ }
+ return 0;
+}
+
+sub is_aarch64_register {
+ my $name = $_[0];
+ if ($name =~ /^[xw]\d+$/) {
+ return 1;
+ }
+ return 0;
+}
+
+sub handle_local_label {
+ my $line = $_[0];
+ my $num = $_[1];
+ my $dir = $_[2];
+ my $target = "$num$dir";
+ if ($dir eq "b") {
+ $line =~ s/\b$target\b/$last_temp_labels{$num}/g;
+ } else {
+ my $name = "temp_label_$temp_label_next";
+ $temp_label_next++;
+ push(@{$next_temp_labels{$num}}, $name);
+ $line =~ s/\b$target\b/$name/g;
+ }
+ return $line;
+}
+
+sub handle_serialized_line {
+ my $line = $_[0];
+
+ # handle .previous (only with regard to .section not .subsection)
+ if ($line =~ /\.(section|text|const_data)/) {
+ push(@sections, $line);
+ } elsif ($line =~ /\.previous/) {
+ if (!$sections[-2]) {
+ die ".previous without a previous section";
+ }
+ $line = $sections[-2];
+ push(@sections, $line);
+ }
+
+ $thumb = 1 if $line =~ /\.code\s+16|\.thumb/;
+ $thumb = 0 if $line =~ /\.code\s+32|\.arm/;
+
+ # handle ldr , =
+ if ($line =~ /(.*)\s*ldr([\w\s\d]+)\s*,\s*=(.*)/ and $as_type ne "armasm") {
+ my $label = $literal_labels{$3};
+ if (!$label) {
+ $label = "Literal_$literal_num";
+ $literal_num++;
+ $literal_labels{$3} = $label;
+ }
+ $line = "$1 ldr$2, $label\n";
+ } elsif ($line =~ /\.ltorg/ and $as_type ne "armasm") {
+ $line .= ".align 2\n";
+ foreach my $literal (keys %literal_labels) {
+ $line .= "$literal_labels{$literal}:\n $literal_expr $literal\n";
+ }
+ %literal_labels = ();
+ }
+
+ # handle GNU as pc-relative relocations for adrp/add
+ if ($line =~ /(.*)\s*adrp([\w\s\d]+)\s*,\s*#?:pg_hi21:([^\s]+)/ and $as_type =~ /^apple-/) {
+ $line = "$1 adrp$2, ${3}\@PAGE\n";
+ } elsif ($line =~ /(.*)\s*add([\w\s\d]+)\s*,([\w\s\d]+)\s*,\s*#?:lo12:([^\s]+)/ and $as_type =~ /^apple-/) {
+ $line = "$1 add$2, $3, ${4}\@PAGEOFF\n";
+ }
+
+ # thumb add with large immediate needs explicit add.w
+ if ($thumb and $line =~ /add\s+.*#([^@]+)/) {
+ $line =~ s/add/add.w/ if eval_expr($1) > 255;
+ }
+
+ # mach-o local symbol names start with L (no dot)
+ $line =~ s/(? with ic as conditional code
+ if ($cond =~ /^(|$arm_cond_codes)$/) {
+ if (exists $thumb_labels{$label}) {
+ print ASMFILE ".thumb_func $label\n";
+ } else {
+ $call_targets{$label}++;
+ }
+ }
+ }
+
+ # @l -> lo16() @ha -> ha16()
+ $line =~ s/,\s+([^,]+)\@l\b/, lo16($1)/g;
+ $line =~ s/,\s+([^,]+)\@ha\b/, ha16($1)/g;
+
+ # move to/from SPR
+ if ($line =~ /(\s+)(m[ft])([a-z]+)\s+(\w+)/ and exists $ppc_spr{$3}) {
+ if ($2 eq 'mt') {
+ $line = "$1${2}spr $ppc_spr{$3}, $4\n";
+ } else {
+ $line = "$1${2}spr $4, $ppc_spr{$3}\n";
+ }
+ }
+
+ if ($line =~ /\.unreq\s+(.*)/) {
+ if (defined $neon_alias_reg{$1}) {
+ delete $neon_alias_reg{$1};
+ delete $neon_alias_type{$1};
+ return;
+ } elsif (defined $aarch64_req_alias{$1}) {
+ delete $aarch64_req_alias{$1};
+ return;
+ }
+ }
+ # old gas versions store upper and lower case names on .req,
+ # but they remove only one on .unreq
+ if ($fix_unreq) {
+ if ($line =~ /\.unreq\s+(.*)/) {
+ $line = ".unreq " . lc($1) . "\n";
+ $line .= ".unreq " . uc($1) . "\n";
+ }
+ }
+
+ if ($line =~ /(\w+)\s+\.(dn|qn)\s+(\w+)(?:\.(\w+))?(\[\d+\])?/) {
+ $neon_alias_reg{$1} = "$3$5";
+ $neon_alias_type{$1} = $4;
+ return;
+ }
+ if (scalar keys %neon_alias_reg > 0 && $line =~ /^\s+v\w+/) {
+ # This line seems to possibly have a neon instruction
+ foreach (keys %neon_alias_reg) {
+ my $alias = $_;
+ # Require the register alias to match as an invididual word, not as a substring
+ # of a larger word-token.
+ if ($line =~ /\b$alias\b/) {
+ $line =~ s/\b$alias\b/$neon_alias_reg{$alias}/g;
+ # Add the type suffix. If multiple aliases match on the same line,
+ # only do this replacement the first time (a vfoo.bar string won't match v\w+).
+ $line =~ s/^(\s+)(v\w+)(\s+)/$1$2.$neon_alias_type{$alias}$3/;
+ }
+ }
+ }
+
+ if ($arch eq "aarch64" or $as_type eq "armasm") {
+ # clang's integrated aarch64 assembler in Xcode 5 does not support .req/.unreq
+ if ($line =~ /\b(\w+)\s+\.req\s+(\w+)\b/) {
+ $aarch64_req_alias{$1} = $2;
+ return;
+ }
+ foreach (keys %aarch64_req_alias) {
+ my $alias = $_;
+ # recursively resolve aliases
+ my $resolved = $aarch64_req_alias{$alias};
+ while (defined $aarch64_req_alias{$resolved}) {
+ $resolved = $aarch64_req_alias{$resolved};
+ }
+ $line =~ s/\b$alias\b/$resolved/g;
+ }
+ }
+ if ($arch eq "aarch64") {
+ # fix missing aarch64 instructions in Xcode 5.1 (beta3)
+ # mov with vector arguments is not supported, use alias orr instead
+ if ($line =~ /^(\d+:)?\s*mov\s+(v\d[\.{}\[\]\w]+),\s*(v\d[\.{}\[\]\w]+)\b\s*$/) {
+ $line = "$1 orr $2, $3, $3\n";
+ }
+ # movi 16, 32 bit shifted variant, shift is optional
+ if ($line =~ /^(\d+:)?\s*movi\s+(v[0-3]?\d\.(?:2|4|8)[hsHS])\s*,\s*(#\w+)\b\s*$/) {
+ $line = "$1 movi $2, $3, lsl #0\n";
+ }
+ # Xcode 5 misses the alias uxtl. Replace it with the more general ushll.
+ # Clang 3.4 misses the alias sxtl too. Replace it with the more general sshll.
+ # armasm64 also misses these instructions.
+ if ($line =~ /^(\d+:)?\s*(s|u)xtl(2)?\s+(v[0-3]?\d\.[248][hsdHSD])\s*,\s*(v[0-3]?\d\.(?:2|4|8|16)[bhsBHS])\b\s*$/) {
+ $line = "$1 $2shll$3 $4, $5, #0\n";
+ }
+ # clang 3.4 and armasm64 do not automatically use shifted immediates in add/sub
+ if (($as_type eq "clang" or $as_type eq "armasm") and
+ $line =~ /^(\d+:)?(\s*(?:add|sub)s?) ([^#l]+)#([\d\+\-\*\/ <>]+)\s*$/) {
+ my $imm = eval $4;
+ if ($imm > 4095 and not ($imm & 4095)) {
+ $line = "$1 $2 $3#" . ($imm >> 12) . ", lsl #12\n";
+ }
+ }
+ if ($ENV{GASPP_FIX_XCODE5}) {
+ if ($line =~ /^\s*bsl\b/) {
+ $line =~ s/\b(bsl)(\s+v[0-3]?\d\.(\w+))\b/$1.$3$2/;
+ $line =~ s/\b(v[0-3]?\d)\.$3\b/$1/g;
+ }
+ if ($line =~ /^\s*saddl2?\b/) {
+ $line =~ s/\b(saddl2?)(\s+v[0-3]?\d\.(\w+))\b/$1.$3$2/;
+ $line =~ s/\b(v[0-3]?\d)\.\w+\b/$1/g;
+ }
+ if ($line =~ /^\s*dup\b.*\]$/) {
+ $line =~ s/\bdup(\s+v[0-3]?\d)\.(\w+)\b/dup.$2$1/g;
+ $line =~ s/\b(v[0-3]?\d)\.[bhsdBHSD](\[\d\])$/$1$2/g;
+ }
+ }
+ }
+
+ if ($as_type eq "armasm") {
+ # Also replace variables set by .set
+ foreach (keys %symbols) {
+ my $sym = $_;
+ $line =~ s/\b$sym\b/$symbols{$sym}/g;
+ }
+
+ # Handle function declarations and keep track of the declared labels
+ if ($line =~ s/^\s*\.func\s+(\w+)/$1 PROC/) {
+ $labels_seen{$1} = 1;
+ }
+
+ if ($line =~ s/^\s*(\d+)://) {
+ # Convert local labels into unique labels. armasm (at least in
+ # RVCT) has something similar, but still different enough.
+ # By converting to unique labels we avoid any possible
+ # incompatibilities.
+
+ my $num = $1;
+ foreach (@{$next_temp_labels{$num}}) {
+ $line = "$_\n" . $line;
+ }
+ @next_temp_labels{$num} = ();
+ my $name = "temp_label_$temp_label_next";
+ $temp_label_next++;
+ # The matching regexp above removes the label from the start of
+ # the line (which might contain an instruction as well), readd
+ # it on a separate line above it.
+ $line = "$name:\n" . $line;
+ $last_temp_labels{$num} = $name;
+ }
+
+ if ($line =~ s/^\s*(\w+):/$1/) {
+ # Skip labels that have already been declared with a PROC,
+ # labels must not be declared multiple times.
+ return if (defined $labels_seen{$1});
+ $labels_seen{$1} = 1;
+ } elsif ($line !~ /(\w+) PROC/) {
+ # If not a label, make sure the line starts with whitespace,
+ # otherwise ms armasm interprets it incorrectly.
+ $line =~ s/^[\.\w]/\t$&/;
+ }
+
+
+ # Check branch instructions
+ if ($line =~ /(?:^|\n)\s*(\w+\s*:\s*)?(bl?x?\.?([^\s]{2})?(\.w)?)\s+(\w+)/) {
+ my $instr = $2;
+ my $cond = $3;
+ my $width = $4;
+ my $target = $5;
+ # Don't interpret e.g. bic as b with ic as conditional code
+ if ($cond !~ /^(|$arm_cond_codes)$/) {
+ # Not actually a branch
+ } elsif ($target =~ /^(\d+)([bf])$/) {
+ # The target is a local label
+ $line = handle_local_label($line, $1, $2);
+ $line =~ s/\b$instr\b/$&.w/ if $width eq "" and $arch eq "arm";
+ } elsif (($arch eq "arm" and !is_arm_register($target)) or
+ ($arch eq "aarch64" and !is_aarch64_register($target))) {
+ $call_targets{$target}++;
+ }
+ } elsif ($line =~ /(?:^|\n)\s*(\w+\s*:\s*)?(cbn?z|adr|tbz)\s+(\w+)\s*,(\s*#\d+\s*,)?\s*(\w+)/) {
+ my $instr = $2;
+ my $reg = $3;
+ my $bit = $4;
+ my $target = $5;
+ if ($target =~ /^(\d+)([bf])$/) {
+ # The target is a local label
+ $line = handle_local_label($line, $1, $2);
+ } else {
+ $call_targets{$target}++;
+ }
+ # Convert tbz with a wX register into an xX register,
+ # due to armasm64 bugs/limitations.
+ if ($instr eq "tbz" and $reg =~ /w\d+/) {
+ my $xreg = $reg;
+ $xreg =~ s/w/x/;
+ $line =~ s/\b$reg\b/$xreg/;
+ }
+ } elsif ($line =~ /^\s*.h?word.*\b\d+[bf]\b/) {
+ while ($line =~ /\b(\d+)([bf])\b/g) {
+ $line = handle_local_label($line, $1, $2);
+ }
+ }
+
+ # ALIGN in armasm syntax is the actual number of bytes
+ if ($line =~ /\.(?:p2)?align\s+(\d+)/) {
+ my $align = 1 << $1;
+ $line =~ s/\.(?:p2)?align\s+(\d+)/ALIGN $align/;
+ }
+ # Convert gas style [r0, :128] into armasm [r0@128] alignment specification
+ $line =~ s/\[([^\[,]+),?\s*:(\d+)\]/[$1\@$2]/g;
+
+ # armasm treats logical values {TRUE} and {FALSE} separately from
+ # numeric values - logical operators and values can't be intermixed
+ # with numerical values. Evaluate ! and (a <> b) into numbers,
+ # let the assembler evaluate the rest of the expressions. This current
+ # only works for cases when ! and <> are used with actual constant numbers,
+ # we don't evaluate subexpressions here.
+
+ # Evaluate !
+ while ($line =~ /!\s*(\d+)/g) {
+ my $val = ($1 != 0) ? 0 : 1;
+ $line =~ s/!(\d+)/$val/;
+ }
+ # Evaluate (a > b)
+ while ($line =~ /\(\s*(\d+)\s*([<>])\s*(\d+)\s*\)/) {
+ my $val;
+ if ($2 eq "<") {
+ $val = ($1 < $3) ? 1 : 0;
+ } else {
+ $val = ($1 > $3) ? 1 : 0;
+ }
+ $line =~ s/\(\s*(\d+)\s*([<>])\s*(\d+)\s*\)/$val/;
+ }
+
+ if ($arch eq "arm") {
+ # Change a movw... #:lower16: into a mov32 pseudoinstruction
+ $line =~ s/^(\s*)movw(\s+\w+\s*,\s*)\#:lower16:(.*)$/$1mov32$2$3/;
+ # and remove the following, matching movt completely
+ $line =~ s/^\s*movt\s+\w+\s*,\s*\#:upper16:.*$//;
+
+ if ($line =~ /^\s*mov32\s+\w+,\s*([a-zA-Z]\w*)/) {
+ $import_symbols{$1}++;
+ }
+
+ # Misc bugs/deficiencies:
+ # armasm seems unable to parse e.g. "vmov s0, s1" without a type
+ # qualifier, thus add .f32.
+ $line =~ s/^(\s+(?:vmov|vadd))(\s+s\d+\s*,\s*s\d+)/$1.f32$2/;
+ } elsif ($arch eq "aarch64") {
+ # Convert ext into ext8; armasm64 seems to require it named as ext8.
+ $line =~ s/^(\s+)ext(\s+)/$1ext8$2/;
+
+ # Pick up targets from ldr x0, =sym+offset
+ if ($line =~ /^\s*ldr\s+(\w+)\s*,\s*=([a-zA-Z]\w*)(.*)$/) {
+ my $reg = $1;
+ my $sym = $2;
+ my $offset = eval_expr($3);
+ if ($offset < 0 and $ENV{GASPP_ARMASM64_SKIP_NEG_OFFSET}) {
+ # armasm64 in VS < 15.6 is buggy with ldr x0, =sym+offset where the
+ # offset is a negative value; it does write a negative
+ # offset into the literal pool as it should, but the
+ # negative offset only covers the lower 32 bit of the 64
+ # bit literal/relocation.
+ # Thus remove the offset and apply it manually with a sub
+ # afterwards.
+ $offset = -$offset;
+ $line = "\tldr $reg, =$sym\n\tsub $reg, $reg, #$offset\n";
+ }
+ $import_symbols{$sym}++;
+ }
+
+ # armasm64 (currently) doesn't support offsets on adrp targets,
+ # even though the COFF format relocations (and the linker)
+ # supports it. Therefore strip out the offsets from adrp and
+ # add :lo12: (in case future armasm64 would start handling it)
+ # and add an extra explicit add instruction for the offset.
+ if ($line =~ s/(adrp\s+\w+\s*,\s*(\w+))([\d\+\-\*\/\(\) <>]+)?/\1/) {
+ $import_symbols{$2}++;
+ }
+ if ($line =~ s/(add\s+(\w+)\s*,\s*\w+\s*,\s*):lo12:(\w+)([\d\+\-\*\/\(\) <>]+)?/\1\3/) {
+ my $reg = $2;
+ my $sym = $3;
+ my $offset = eval_expr($4);
+ $line .= "\tadd $reg, $reg, #$offset\n" if $offset > 0;
+ $import_symbols{$sym}++;
+ }
+
+ # Convert e.g. "add x0, x0, w0, uxtw" into "add x0, x0, w0, uxtw #0",
+ # or "ldr x0, [x0, w0, uxtw]" into "ldr x0, [x0, w0, uxtw #0]".
+ $line =~ s/(uxt[whb]|sxt[whb])(\s*\]?\s*)$/\1 #0\2/i;
+
+ # Convert "mov x0, v0.d[0]" into "umov x0, v0.d[0]"
+ $line =~ s/\bmov\s+[xw]\d+\s*,\s*v\d+\.[ds]/u$&/i;
+
+ # Convert "ccmp w0, #0, #0, ne" into "ccmpne w0, #0, #0",
+ # and "csel w0, w0, w0, ne" into "cselne w0, w0, w0".
+ $line =~ s/(ccmp|csel)\s+([xw]\w+)\s*,\s*([xw#]\w+)\s*,\s*([xw#]\w+)\s*,\s*($arm_cond_codes)/\1\5 \2, \3, \4/;
+
+ # Convert "cinc w0, w0, ne" into "cincne w0, w0".
+ $line =~ s/(cinc)\s+([xw]\w+)\s*,\s*([xw]\w+)\s*,\s*($arm_cond_codes)/\1\4 \2, \3/;
+
+ # Convert "cset w0, lo" into "csetlo w0"
+ $line =~ s/(cset)\s+([xw]\w+)\s*,\s*($arm_cond_codes)/\1\3 \2/;
+
+ if ($ENV{GASPP_ARMASM64_SKIP_PRFUM}) {
+ # Strip out prfum; armasm64 (VS < 15.5) fails to assemble any
+ # variant/combination of prfum tested so far, but since it is
+ # a prefetch instruction it can be skipped without changing
+ # results.
+ $line =~ s/prfum.*\]//;
+ }
+
+ # Convert "ldrb w0, [x0, #-1]" into "ldurb w0, [x0, #-1]".
+ # Don't do this for forms with writeback though.
+ if ($line =~ /(ld|st)(r[bh]?)\s+(\w+)\s*,\s*\[\s*(\w+)\s*,\s*#([^\]]+)\s*\][^!]/) {
+ my $instr = $1;
+ my $suffix = $2;
+ my $target = $3;
+ my $base = $4;
+ my $offset = eval_expr($5);
+ if ($offset < 0) {
+ $line =~ s/$instr$suffix/${instr}u$suffix/;
+ }
+ }
+
+ if ($ENV{GASPP_ARMASM64_INVERT_SCALE}) {
+ # Instructions like fcvtzs and scvtf store the scale value
+ # inverted in the opcode (stored as 64 - scale), but armasm64
+ # in VS < 15.5 stores it as-is. Thus convert from
+ # "fcvtzs w0, s0, #8" into "fcvtzs w0, s0, #56".
+ if ($line =~ /(?:fcvtzs|scvtf)\s+(\w+)\s*,\s*(\w+)\s*,\s*#(\d+)/) {
+ my $scale = $3;
+ my $inverted_scale = 64 - $3;
+ $line =~ s/#$scale/#$inverted_scale/;
+ }
+ }
+
+ # Convert "ld1 {v0.4h-v3.4h}" into "ld1 {v0.4h,v1.4h,v2.4h,v3.4h}"
+ if ($line =~ /(?:ld|st)\d\s+({\s*v(\d+)\.(\d[bhsdBHSD])\s*-\s*v(\d+)\.(\d[bhsdBHSD])\s*})/) {
+ my $regspec = $1;
+ my $reg1 = $2;
+ my $layout1 = $3;
+ my $reg2 = $4;
+ my $layout2 = $5;
+ if ($layout1 eq $layout2) {
+ my $new_regspec = "{";
+ foreach my $i ($reg1 .. $reg2) {
+ $new_regspec .= "," if ($i > $reg1);
+ $new_regspec .= "v$i.$layout1";
+ }
+ $new_regspec .= "}";
+ $line =~ s/$regspec/$new_regspec/;
+ }
+ }
+ }
+ # armasm is unable to parse &0x - add spacing
+ $line =~ s/&0x/& 0x/g;
+ }
+
+ if ($force_thumb) {
+ # Convert register post indexing to a separate add instruction.
+ # This converts e.g. "ldr r0, [r1], r2" into "ldr r0, [r1]",
+ # "add r1, r1, r2".
+ $line =~ s/((?:ldr|str)[bh]?)\s+(\w+),\s*\[(\w+)\],\s*(\w+)/$1 $2, [$3]\n\tadd $3, $3, $4/g;
+
+ # Convert "mov pc, lr" into "bx lr", since the former only works
+ # for switching from arm to thumb (and only in armv7), but not
+ # from thumb to arm.
+ $line =~ s/mov\s*pc\s*,\s*lr/bx lr/g;
+
+ # Convert stmdb/ldmia/stmfd/ldmfd/ldm with only one register into a plain str/ldr with post-increment/decrement.
+ # Wide thumb2 encoding requires at least two registers in register list while all other encodings support one register too.
+ $line =~ s/stm(?:db|fd)\s+sp!\s*,\s*\{([^,-]+)\}/str $1, [sp, #-4]!/g;
+ $line =~ s/ldm(?:ia|fd)?\s+sp!\s*,\s*\{([^,-]+)\}/ldr $1, [sp], #4/g;
+
+ # Convert muls into mul+cmp
+ $line =~ s/muls\s+(\w+),\s*(\w+)\,\s*(\w+)/mul $1, $2, $3\n\tcmp $1, #0/g;
+
+ # Convert "and r0, sp, #xx" into "mov r0, sp", "and r0, r0, #xx"
+ $line =~ s/and\s+(\w+),\s*(sp|r13)\,\s*#(\w+)/mov $1, $2\n\tand $1, $1, #$3/g;
+
+ # Convert "ldr r0, [r0, r1, lsl #6]" where the shift is >3 (which
+ # can't be handled in thumb) into "add r0, r0, r1, lsl #6",
+ # "ldr r0, [r0]", for the special case where the same address is
+ # used as base and target for the ldr.
+ if ($line =~ /(ldr[bh]?)\s+(\w+),\s*\[\2,\s*(\w+),\s*lsl\s*#(\w+)\]/ and $4 > 3) {
+ $line =~ s/(ldr[bh]?)\s+(\w+),\s*\[\2,\s*(\w+),\s*lsl\s*#(\w+)\]/add $2, $2, $3, lsl #$4\n\t$1 $2, [$2]/;
+ }
+
+ $line =~ s/\.arm/.thumb/x;
+ }
+
+ # comment out unsupported directives
+ $line =~ s/\.type/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+ $line =~ s/\.func/$comm$&/x if $as_type =~ /^(apple-|clang)/;
+ $line =~ s/\.endfunc/$comm$&/x if $as_type =~ /^(apple-|clang)/;
+ $line =~ s/\.endfunc/ENDP/x if $as_type =~ /armasm/;
+ $line =~ s/\.ltorg/$comm$&/x if $as_type =~ /^(apple-|clang)/;
+ $line =~ s/\.ltorg/LTORG/x if $as_type eq "armasm";
+ $line =~ s/\.size/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+ $line =~ s/\.fpu/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+ $line =~ s/\.arch/$comm$&/x if $as_type =~ /^(apple-|clang|armasm)/;
+ $line =~ s/\.object_arch/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+ $line =~ s/.section\s+.note.GNU-stack.*/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+
+ $line =~ s/\.syntax/$comm$&/x if $as_type =~ /armasm/;
+
+ $line =~ s/\.hword/.short/x;
+
+ if ($as_type =~ /^apple-/) {
+ # the syntax for these is a little different
+ $line =~ s/\.global/.globl/x;
+ # also catch .section .rodata since the equivalent to .const_data is .section __DATA,__const
+ $line =~ s/(.*)\.rodata/.const_data/x;
+ $line =~ s/\.int/.long/x;
+ $line =~ s/\.float/.single/x;
+ }
+ if ($as_type eq "apple-gas") {
+ $line =~ s/vmrs\s+APSR_nzcv/fmrx r15/x;
+ }
+ if ($as_type eq "armasm") {
+ $line =~ s/\.global/EXPORT/x;
+ $line =~ s/\.extern/IMPORT/x;
+ $line =~ s/\.int/dcd/x;
+ $line =~ s/\.long/dcd/x;
+ $line =~ s/\.float/dcfs/x;
+ $line =~ s/\.word/dcd/x;
+ $line =~ s/\.short/dcw/x;
+ $line =~ s/\.byte/dcb/x;
+ $line =~ s/\.quad/dcq/x;
+ $line =~ s/\.ascii/dcb/x;
+ $line =~ s/\.asciz(.*)$/dcb\1,0/x;
+ $line =~ s/\.thumb/THUMB/x;
+ $line =~ s/\.arm/ARM/x;
+ # The alignment in AREA is the power of two, just as .align in gas
+ $line =~ s/\.text/AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN/;
+ $line =~ s/(\s*)(.*)\.ro?data/$1AREA |.rdata|, DATA, READONLY, ALIGN=5/;
+ $line =~ s/\.data/AREA |.data|, DATA, ALIGN=5/;
+ }
+ if ($as_type eq "armasm" and $arch eq "arm") {
+ $line =~ s/fmxr/vmsr/;
+ $line =~ s/fmrx/vmrs/;
+ $line =~ s/fadds/vadd.f32/;
+ }
+ if ($as_type eq "armasm" and $arch eq "aarch64") {
+ # Convert "b.eq" into "beq"
+ $line =~ s/\bb\.($arm_cond_codes)\b/b\1/;
+ }
+
+ # catch unknown section names that aren't mach-o style (with a comma)
+ if ($as_type =~ /apple-/ and $line =~ /.section ([^,]*)$/) {
+ die ".section $1 unsupported; figure out the mach-o section name and add it";
+ }
+
+ print ASMFILE $line;
+}
+
+if ($as_type ne "armasm") {
+ print ASMFILE ".text\n";
+ print ASMFILE ".align 2\n";
+ foreach my $literal (keys %literal_labels) {
+ print ASMFILE "$literal_labels{$literal}:\n $literal_expr $literal\n";
+ }
+
+ map print(ASMFILE ".thumb_func $_\n"),
+ grep exists $thumb_labels{$_}, keys %call_targets;
+} else {
+ map print(ASMFILE "\tIMPORT $_\n"),
+ grep ! exists $labels_seen{$_}, (keys %call_targets, keys %import_symbols);
+
+ print ASMFILE "\tEND\n";
+}
+
+close(INPUT) or exit 1;
+close(ASMFILE) or exit 1;
+if ($as_type eq "armasm" and ! defined $ENV{GASPP_DEBUG}) {
+ print STDERR join(" ", @gcc_cmd)."\n" if $verbose;
+ system(@gcc_cmd) == 0 or die "Error running assembler";
+}
+
+END {
+ unlink($tempfile) if defined $tempfile;
+}
+#exit 1