import Foundation
import SwiftUI
import WidgetKit
struct ConfigureQuickActionsWidgetEntry: TimelineEntry {
  let date: Date
  let useLens: Bool
}
struct ConfigureQuickActionsWidgetEntryProvider: TimelineProvider {
  func placeholder(in context: Context) -> ConfigureQuickActionsWidgetEntry {
    ConfigureQuickActionsWidgetEntry(date: Date(), useLens: false)
  }
  func shouldUseLens() -> Bool {
    let sharedDefaults: UserDefaults = AppGroupHelper.groupUserDefaults()
    let useLens: Bool =
      sharedDefaults.bool(
        forKey: WidgetConstants.QuickActionsWidget.isGoogleDefaultSearchEngineKey)
      && sharedDefaults.bool(
        forKey: WidgetConstants.QuickActionsWidget.enableLensInWidgetKey)
    return useLens
  }
  func getSnapshot(
    in context: Context,
  ) {
    let entry = ConfigureQuickActionsWidgetEntry(
      date: Date(),
      useLens: shouldUseLens()
    )
    let entries: [ConfigureQuickActionsWidgetEntry] = [entry]
    let timeline: Timeline = Timeline(entries: entries, policy: .never)
    completion(timeline)
  }
}
struct QuickActionsWidget: Widget {
  // Changing |kind| or deleting this widget will cause all installed instances of this widget to
  // stop updating and show the placeholder state.
  let kind: String = "QuickActionsWidget"
  var body: some WidgetConfiguration {
    StaticConfiguration(
      kind: kind,
      provider: ConfigureQuickActionsWidgetEntryProvider()
    ) { entry in
      QuickActionsWidgetEntryView(entry: entry)
    }
    .configurationDisplayName(
      Text("IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_DISPLAY_NAME")
    )
    .description(Text("IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_DESCRIPTION"))
    .supportedFamilies([.systemMedium])
  }
}
struct QuickActionsWidgetEntryView: View {
  var entry: ConfigureQuickActionsWidgetEntry
  private let searchAreaHeight: CGFloat = 92
  private let separatorHeight: CGFloat = 32
  private let incognitoA11yLabel: LocalizedStringKey =
    "IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_INCOGNITO_A11Y_LABEL"
  private let voiceSearchA11yLabel: LocalizedStringKey =
    "IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_VOICE_SEARCH_A11Y_LABEL"
  private let lensA11yLabel: LocalizedStringKey =
    "IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_LENS_A11Y_LABEL"
  private let qrA11yLabel: LocalizedStringKey =
    "IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_QR_SCAN_A11Y_LABEL"
  func symbolWithName(symbolName: String, system: Bool) -> some View {
    let image = system ? Image(systemName: symbolName) : Image(symbolName)
    return image.foregroundColor(Color("widget_actions_icon_color")).font(
      .system(size: 20, weight: .medium)
    ).imageScale(.medium)
  }
  var body: some View {
    VStack(spacing: 0) {
      ZStack {
        Color("widget_background_color")
          .unredacted()
        VStack {
          Spacer()
          Link(destination: WidgetConstants.QuickActionsWidget.searchUrl) {
            ZStack {
              RoundedRectangle(cornerRadius: 26)
                .frame(height: 52)
                .foregroundColor(Color("widget_search_bar_color"))
              HStack(spacing: 12) {
                Image("widget_chrome_logo")
                  .clipShape(Circle())
                  // Without .clipShape(Circle()), in the redacted/placeholder
                  // state the Widget shows an rectangle placeholder instead of
                  // a circular one.
                  .padding(.leading, 8)
                  .unredacted()
                Text("IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_TITLE")
                  .font(.subheadline)
                  .foregroundColor(Color("widget_text_color"))
                Spacer()
              }
            }
            .frame(minWidth: 0, maxWidth: .infinity)
            .padding([.leading, .trailing], 11)
          }
          .accessibility(
            label:
              Text(
                "IDS_IOS_WIDGET_KIT_EXTENSION_QUICK_ACTIONS_SEARCH_A11Y_LABEL"
              )
          )
          Spacer()
        }
        .frame(height: searchAreaHeight)
      }
      ZStack {
        Rectangle()
          .foregroundColor(Color("widget_actions_row_background_color"))
          .frame(minWidth: 0, maxWidth: .infinity)
        HStack {
          // Show interactive buttons if the widget is fully loaded, and show
          // the custom placeholder otherwise.
          if redactionReasons.isEmpty {
            Link(destination: WidgetConstants.QuickActionsWidget.incognitoUrl) {
              symbolWithName(symbolName: "widget_incognito_icon", system: false)
                .frame(minWidth: 0, maxWidth: .infinity)
            }
            .accessibility(label: Text(incognitoA11yLabel))
            Separator(height: separatorHeight)
            Link(
              destination: WidgetConstants.QuickActionsWidget.voiceSearchUrl
            ) {
              symbolWithName(symbolName: "mic", system: true)
                .frame(minWidth: 0, maxWidth: .infinity)
            }
            .accessibility(label: Text(voiceSearchA11yLabel))
            Separator(height: separatorHeight)
            if entry.useLens {
              Link(destination: WidgetConstants.QuickActionsWidget.lensUrl) {
                symbolWithName(symbolName: "widget_lens_icon", system: false)
                  .frame(minWidth: 0, maxWidth: .infinity)
              }
              .accessibility(label: Text(lensA11yLabel))
            } else {
              Link(destination: WidgetConstants.QuickActionsWidget.qrCodeUrl) {
                symbolWithName(symbolName: "qrcode", system: true)
                  .frame(minWidth: 0, maxWidth: .infinity)
              }
              .accessibility(label: Text(qrA11yLabel))
            }
          } else {
            ButtonPlaceholder()
            Separator(height: separatorHeight)
            ButtonPlaceholder()
            Separator(height: separatorHeight)
            ButtonPlaceholder()
          }
        }
        .frame(minWidth: 0, maxWidth: .infinity)
        .padding([.leading, .trailing], 11)
      }
    }
  }
}
struct Separator: View {
  let height: CGFloat
  var body: some View {
    RoundedRectangle(cornerRadius: 1)
      .foregroundColor(Color("widget_separator_color"))
      .frame(width: 2, height: height)
  }
}
struct ButtonPlaceholder: View {
  private let widthOfPlaceholder: CGFloat = 28
  var body: some View {
    Group {
      RoundedRectangle(cornerRadius: 4, style: .continuous)
        .frame(width: widthOfPlaceholder, height: widthOfPlaceholder)
        .foregroundColor(Color("widget_text_color"))
        .opacity(0.3)
    }.frame(minWidth: 0, maxWidth: .infinity)
  }
}


main

  ) {
    let entry = SimpleEntry(date: Date())
    completion(entry)
  }
  func getTimeline(
    in context: Context,
struct ChromeWidgets: WidgetBundle {
  init() {
    CrashHelper.configure()
  }
  var body: some Widget {
    QuickActionsWidget()
    SearchWidget()
    DinoGameWidget()
    #if IOS_ENABLE_SHORTCUTS_WIDGET
      ShortcutsWidget()
    #endif
    #if IOS_ENABLE_LOCKSCREEN_WIDGET
      #if IOS_AVAILABLE_LOCKSCREEN_WIDGET
        LockscreenLauncherSearchWidget()
        LockscreenLauncherIncognitoWidget()
        LockscreenLauncherVoiceSearchWidget()
        LockscreenLauncherGameWidget()
      #endif
    #endif
  }
}


import Foundation
import SwiftUI
import WidgetKit
struct DinoGameWidget: Widget {
  // Changing |kind| or deleting this widget will cause all installed instances of this widget to
  // stop updating and show the placeholder state.
  let kind: String = "DinoGameWidget"
  var body: some WidgetConfiguration {
    StaticConfiguration(kind: kind, provider: Provider()) { entry in
      DinoGameWidgetEntryView(entry: entry)
    }
    .configurationDisplayName(
      Text("IDS_IOS_WIDGET_KIT_EXTENSION_GAME_DISPLAY_NAME")
    )
    .description(Text("IDS_IOS_WIDGET_KIT_EXTENSION_GAME_DESCRIPTION"))
    .supportedFamilies([.systemSmall])
  }
}
struct DinoGameWidgetEntryView: View {
  let background = "widget_dino_background"
  let backgroundPlaceholder = "widget_dino_background_placeholder"
  var entry: Provider.Entry
  var body: some View {
    // We wrap this widget in a link on top of using `widgetUrl` so that the voice over will treat
    // the widget as one tap target. Without the wrapping, voice over treats the content within
    // the widget as multiple tap targets.
    Link(destination: WidgetConstants.DinoGameWidget.url) {
      ZStack {
        Image(redactionReasons.isEmpty ? background : backgroundPlaceholder)
          .resizable()
          .unredacted()
        VStack(alignment: .leading, spacing: 0) {
          Spacer()
            .frame(minWidth: 0, maxWidth: .infinity)
          HStack {
            Text("IDS_IOS_WIDGET_KIT_EXTENSION_GAME_TITLE")
              .foregroundColor(Color("widget_text_color"))
              .fontWeight(.semibold)
              .font(.subheadline)
              .lineLimit(1)
            Spacer()
          }
          .padding([.leading, .bottom], 16)
        }
      }
    }
    .widgetURL(WidgetConstants.DinoGameWidget.url)
    .accessibility(
      label: Text("IDS_IOS_WIDGET_KIT_EXTENSION_GAME_A11Y_LABEL"))
  }
}


import Foundation
struct WidgetConstants {
  struct SearchWidget {
    static let url = URL(string: "chromewidgetkit://search-widget/search")!
  }
  struct QuickActionsWidget {
    static let searchUrl =
      URL(string: "chromewidgetkit://quick-actions-widget/search")!
    static let incognitoUrl =
      URL(string: "chromewidgetkit://quick-actions-widget/incognito")!
    static let voiceSearchUrl =
      URL(string: "chromewidgetkit://quick-actions-widget/voicesearch")!
    static let qrCodeUrl =
      URL(string: "chromewidgetkit://quick-actions-widget/qrreader")!
    static let lensUrl =
      URL(string: "chromewidgetkit://quick-actions-widget/lens")!
    static let isGoogleDefaultSearchEngineKey = "isGoogleDefaultSearchEngine"
    static let enableLensInWidgetKey = "enableLensInWidget"
  }
  struct DinoGameWidget {
    static let url = URL(string: "chromewidgetkit://dino-game-widget/game")!
  }
  struct LockscreenLauncherWidget {
    static let searchUrl =
      URL(string: "chromewidgetkit://lockscreen-launcher-widget/search")!
    static let incognitoUrl =
      URL(string: "chromewidgetkit://lockscreen-launcher-widget/incognito")!
    static let voiceSearchUrl =
      URL(string: "chromewidgetkit://lockscreen-launcher-widget/voicesearch")!
    static let gameUrl = URL(string: "chromewidgetkit://lockscreen-launcher-widget/game")!
  }
}


file

import Foundation

public class GypSwiftTest {
  let myProperty = false

  init() {
    self.myProperty = true
  }
}


Package

// swift-tools-version:5.2
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription

let package = Package(
  name: "gRPC",
  products: [
    .library(
      name: "gRPC-Core",
      targets: [
        "gRPC-Core",
      ]
    ),
    .library(
      name: "gRPC-cpp",
      targets: [
        "gRPC-cpp",
      ]
    )
  ],

  dependencies: [
    .package(
      name: "abseil",
      url: "https://github.com/firebase/abseil-cpp-SwiftPM.git",
      "0.20220203.0"..<"0.20220204.0"
    ),
    .package(
      name: "BoringSSL-GRPC",
      url: "https://github.com/firebase/boringssl-SwiftPM.git",
      "0.9.0"..<"0.10.0"
    ),
  ],

  targets: [
    .target(
      name: "gRPC-Core",
      dependencies: [
        .product(name:"abseil", package: "abseil"),
        .product(name:"openssl_grpc", package: "BoringSSL-GRPC"),
      ],
      path: ".",
      exclude: [
        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc",
        "src/core/ext/filters/load_reporting/",
        "src/core/ext/transport/cronet/",
        "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h",
        "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc",
        "src/core/lib/surface/init_unsecure.cc",
        "src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc",
        "src/core/plugin_registry/grpc_unsecure_plugin_registry.cc",
        "third_party/re2/re2/testing/",
        "third_party/re2/re2/fuzzing/",
        "third_party/re2/util/benchmark.cc",
        "third_party/re2/util/test.cc",
        "third_party/re2/util/fuzz.cc",
        "third_party/upb/upb/bindings/",
        "third_party/upb/upb/msg_test.cc",
      ],
      sources: [
        "src/core/ext/filters/",
        "src/core/ext/transport/",
        "src/core/ext/upb-generated/",
        "src/core/ext/upbdefs-generated/",
        "src/core/ext/xds/",
        "src/core/lib/",
        "src/core/plugin_registry/grpc_plugin_registry.cc",
        "src/core/tsi/",
        "third_party/re2/re2/",
        "third_party/re2/util/",
        "third_party/upb/upb/",
        "third_party/xxhash/xxhash.h",
      ],
      publicHeadersPath: "spm-core-include",
      cSettings: [
        .headerSearchPath("./"),
        .headerSearchPath("include/"),
        .headerSearchPath("third_party/re2/"),
        .headerSearchPath("third_party/upb/"),
        .headerSearchPath("third_party/xxhash/"),
        .headerSearchPath("src/core/ext/upb-generated/"),
        .headerSearchPath("src/core/ext/upbdefs-generated/"),
        .define("GRPC_ARES", to: "0"),
      ],
      linkerSettings: [
        .linkedFramework("CoreFoundation"),
        .linkedLibrary("z"),
      ]
    ),
    .target(
      name: "gRPC-cpp",
      dependencies: [
        .product(name:"abseil", package: "abseil"),
        "gRPC-Core",
      ],
      path: ".",
      exclude: [
        "src/cpp/client/cronet_credentials.cc",
        "src/cpp/client/channel_test_peer.cc",
        "src/cpp/common/alts_util.cc",
        "src/cpp/common/alts_context.cc",
        "src/cpp/common/insecure_create_auth_context.cc",
        "src/cpp/server/admin/",
        "src/cpp/server/channelz/",
        "src/cpp/server/csds/",
        "src/cpp/server/load_reporter/",
        "src/cpp/ext/",
        "src/cpp/util/core_stats.cc",
        "src/cpp/util/core_stats.h",
        "src/cpp/util/error_details.cc",
      ],
      sources: [
        "src/cpp/",
      ],
      publicHeadersPath: "spm-cpp-include",
      cSettings: [
        .headerSearchPath("./"),
        .headerSearchPath("include/"),
        .headerSearchPath("third_party/upb/"),
        .headerSearchPath("src/core/ext/upb-generated"),
      ]
    ),
    .testTarget(
      name: "build-test",
      dependencies: [
        "gRPC-cpp",
      ],
      path: "test/spm_build"
    ),
  ],
  cLanguageStandard: .gnu11,
  cxxLanguageStandard: .cxx14
)


AppDelegate

/*
 *
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
}


ViewController

/*
 *
 *
 */
import UIKit
import RemoteTest
import RxLibrary
class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    let RemoteHost = "grpc-test.sandbox.googleapis.com"
    let request = RMTSimpleRequest()
    request.responseSize = 10
    request.fillUsername = true
    request.fillOauthScope = true
    // Example gRPC call using a generated proto client library:
    let service = RMTTestService(host: RemoteHost)
    service.unaryCall(with: request) { response, error in
      if let response = response {
        NSLog("1. Finished successfully with response:\n\(response)")
      } else {
        NSLog("1. Finished with error: \(error!)")
      }
    }
    // Same but manipulating headers:
    var RPC : GRPCProtoCall! // Needed to convince Swift to capture by reference (__block)
    RPC = service.rpcToUnaryCall(with: request) { response, error in
      if let response = response {
        NSLog("2. Finished successfully with response:\n\(response)")
      } else {
        NSLog("2. Finished with error: \(error!)")
      }
      NSLog("2. Response headers: \(String(describing: RPC.responseHeaders))")
      NSLog("2. Response trailers: \(String(describing: RPC.responseTrailers))")
    }
    // TODO(jcanizales): Revert to using subscript syntax once XCode 8 is released.
    RPC.requestHeaders["My-Header"] = "My value"
    RPC.start()
    // Same example call using the generic gRPC client library:
    let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")!
    let requestsWriter = GRXWriter(value: request.data())!
    let call = GRPCCall(host: RemoteHost, path: method.httpPath, requestsWriter: requestsWriter)!
    call.requestHeaders["My-Header"] = "My value"
    call.start(with: GRXWriteable { response, error in
      if let response = response as? Data {
        NSLog("3. Received response:\n\(try! RMTSimpleResponse(data: response))")
      } else {
        NSLog("3. Finished with error: \(error!)")
      }
      NSLog("3. Response headers: \(String(describing: call.responseHeaders))")
      NSLog("3. Response trailers: \(String(describing: call.responseTrailers))")
    })
  }
}


AppDelegate

/*
 */
import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
}


ViewController

/*
 */
import GCDWebServers
import UIKit
class ViewController: UIViewController {
  var webServer: GCDWebUploader!
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
    webServer = GCDWebUploader(uploadDirectory: documentsPath)
    webServer.delegate = self
    webServer.allowHiddenItems = true
    if webServer.start() {
      label?.text = "GCDWebServer running locally on port \(webServer.port)"
    } else {
      label?.text = "GCDWebServer not running!"
    }
  }
  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    webServer.stop()
    webServer = nil
  }
}
extension ViewController: GCDWebUploaderDelegate {
  func webUploader(_: GCDWebUploader, didUploadFileAtPath path: String) {
    print("[UPLOAD] \(path)")
  }
  func webUploader(_: GCDWebUploader, didDownloadFileAtPath path: String) {
    print("[DOWNLOAD] \(path)")
  }
  func webUploader(_: GCDWebUploader, didMoveItemFromPath fromPath: String, toPath: String) {
    print("[MOVE] \(fromPath) -> \(toPath)")
  }
  func webUploader(_: GCDWebUploader, didCreateDirectoryAtPath path: String) {
    print("[CREATE] \(path)")
  }
  func webUploader(_: GCDWebUploader, didDeleteItemAtPath path: String) {
    print("[DELETE] \(path)")
  }
}


LinuxMain

import XCTest

XCTMain([
    testCase(SomeIntegTest.allTests), testCase(SomeOtherTest.allTests)
])


SomeOtherTest

import XCTest

class SomeOtherTest: XCTestCase {
    public static var allTests = [
        ("testQuickUiCheck", testQuickUiCheck),
        ("testQuickServerCheck", testQuickServerCheck)
    ]
    func testQuickUiCheck() {}
    func testQuickServerCheck() {}
}


SomeIntegTest

import XCTest

class SomeIntegTest: XCTestCase {
    public static var allTests = [
        ("test1", test1),
        ("test2", test2)
    ]
    func test1() {}
    func test2() {}
}


LinuxMain

import XCTest

XCTMain([
    testCase(UtilTest.allTests)
])


UtilTest

import XCTest

class UtilTest: XCTestCase {
    public static var allTests = [
        ("testOk", testOk)
    ]
    func testOk() {
        print("hello from UtilTest.")
    }
}


LinuxMain

import XCTest

XCTMain([
    testCase(CoreTest.allTests)
])


CoreTest

import XCTest

class CoreTest: XCTestCase {
    public static var allTests = [
        ("testOk", testOk)
    ]

    func testOk() {
        print("hello from CoreTest.")
    }
}


Tensor

import Foundation
import TensorFlowLiteC
/// An input or output tensor in a TensorFlow Lite graph.
public struct Tensor: Equatable, Hashable {
  /// The name of the `Tensor`.
  public let name: String
  /// The data type of the `Tensor`.
  public let dataType: DataType
  /// The shape of the `Tensor`.
  public let shape: Shape
  /// The data of the `Tensor`. The data is created with copied memory content. See creating data
  /// from raw memory at https://developer.apple.com/documentation/foundation/data.
  public let data: Data
  /// The quantization parameters for the `Tensor` if using a quantized model.
  public let quantizationParameters: QuantizationParameters?
  /// Creates a new input or output `Tensor` instance.
  ///
  /// - Parameters:
  ///   - name: The name of the `Tensor`.
  ///   - dataType: The data type of the `Tensor`.
  ///   - shape: The shape of the `Tensor`.
  ///   - data: The data in the input `Tensor`.
  ///   - quantizationParameters Parameters for the `Tensor` if using a quantized model. The default
  ///       is `nil`.
  init(
    name: String,
    dataType: DataType,
    shape: Shape,
    data: Data,
    quantizationParameters: QuantizationParameters? = nil
  ) {
    self.name = name
    self.dataType = dataType
    self.shape = shape
    self.data = data
    self.quantizationParameters = quantizationParameters
  }
}
extension Tensor {
  /// The supported `Tensor` data types.
  public enum DataType: Equatable, Hashable {
    /// A boolean.
    case bool
    /// An 8-bit unsigned integer.
    case uInt8
    /// A 16-bit signed integer.
    case int16
    /// A 32-bit signed integer.
    case int32
    /// A 64-bit signed integer.
    case int64
    /// A 16-bit half precision floating point.
    case float16
    /// A 32-bit single precision floating point.
    case float32
    /// A 64-bit double precision floating point.
    case float64
    /// Creates a new instance from the given `TfLiteType` or `nil` if the data type is unsupported
    /// or could not be determined because there was an error.
    ///
    /// - Parameter type: A data type for a tensor.
    init?(type: TfLiteType) {
      switch type {
      case kTfLiteBool:
        self = .bool
      case kTfLiteUInt8:
        self = .uInt8
      case kTfLiteInt16:
        self = .int16
      case kTfLiteInt32:
        self = .int32
      case kTfLiteInt64:
        self = .int64
      case kTfLiteFloat16:
        self = .float16
      case kTfLiteFloat32:
        self = .float32
      case kTfLiteFloat64:
        self = .float64
      case kTfLiteNoType:
        fallthrough
      default:
        return nil
      }
    }
  }
}
extension Tensor {
  /// The shape of a `Tensor`.
  public struct Shape: Equatable, Hashable {
    /// The number of dimensions of the `Tensor`.
    public let rank: Int
    /// An array of dimensions for the `Tensor`.
    public let dimensions: [Int]
    /// An array of `Int32` dimensions for the `Tensor`.
    var int32Dimensions: [Int32] { return dimensions.map(Int32.init) }
    /// Creates a new instance with the given array of dimensions.
    ///
    /// - Parameters:
    ///   - dimensions: Dimensions for the `Tensor`.
    public init(_ dimensions: [Int]) {
      self.rank = dimensions.count
      self.dimensions = dimensions
    }
    /// Creates a new instance with the given elements representing the dimensions.
    ///
    /// - Parameters:
    ///   - elements: Dimensions for the `Tensor`.
    public init(_ elements: Int...) {
      self.init(elements)
    }
  }
}
extension Tensor.Shape: ExpressibleByArrayLiteral {
  /// Creates a new instance with the given array literal representing the dimensions.
  ///
  /// - Parameters:
  ///   - arrayLiteral: Dimensions for the `Tensor`.
  public init(arrayLiteral: Int...) {
    self.init(arrayLiteral)
  }
}
/// A tensor's function level purpose: input or output.
internal enum TensorType: String {
  case input
  case output
}


Interpreter

import Foundation
import TensorFlowLiteC
#if os(Linux)
  import SwiftGlibc
#else
  import Darwin
#endif
/// A TensorFlow Lite interpreter that performs inference from a given model.
///
/// - Note: Interpreter instances are *not* thread-safe.
public final class Interpreter {
  /// The configuration options for the `Interpreter`.
  public let options: Options?
  /// An `Array` of `Delegate`s for the `Interpreter` to use to perform graph operations.
  public let delegates: [Delegate]?
  /// The total number of input `Tensor`s associated with the model.
  public var inputTensorCount: Int {
    return Int(TfLiteInterpreterGetInputTensorCount(cInterpreter))
  }
  /// The total number of output `Tensor`s associated with the model.
  public var outputTensorCount: Int {
    return Int(TfLiteInterpreterGetOutputTensorCount(cInterpreter))
  }
  /// An ordered list of SignatureDef exported method names available in the model.
  public var signatureKeys: [String] {
    guard let signatureKeys = _signatureKeys else {
      let signatureCount = Int(TfLiteInterpreterGetSignatureCount(self.cInterpreter))
      let keys: [String] = (0..<signatureCount).map {
        guard
          let signatureNameCString = TfLiteInterpreterGetSignatureKey(
            self.cInterpreter, Int32($0))
        else {
          return ""
        }
        return String(cString: signatureNameCString)
      }
      _signatureKeys = keys
      return keys
    }
    return signatureKeys
  }
  /// The `TfLiteInterpreter` C pointer type represented as an `UnsafePointer<TfLiteInterpreter>`.
  internal typealias CInterpreter = OpaquePointer
  /// The underlying `TfLiteInterpreter` C pointer.
  internal var cInterpreter: CInterpreter?
  /// The underlying `TfLiteDelegate` C pointer for XNNPACK delegate.
  private var cXNNPackDelegate: Delegate.CDelegate?
  /// An ordered list of SignatureDef exported method names available in the model.
  private var _signatureKeys: [String]? = nil
  /// Creates a new instance with the given values.
  ///
  /// - Parameters:
  ///   - modelPath: The local file path to a TensorFlow Lite model.
  ///   - options: Configurations for the `Interpreter`. The default is `nil` indicating that the
  ///       `Interpreter` will determine the configuration options.
  ///   - delegate: `Array` of `Delegate`s for the `Interpreter` to use to peform graph operations.
  ///       The default is `nil`.
  /// - Throws: An error if the model could not be loaded or the interpreter could not be created.
  public convenience init(modelPath: String, options: Options? = nil, delegates: [Delegate]? = nil)
    throws
  {
    guard let model = Model(filePath: modelPath) else { throw InterpreterError.failedToLoadModel }
    try self.init(model: model, options: options, delegates: delegates)
  }
  /// Creates a new instance with the given values.
  ///
  /// - Parameters:
  ///   - modelData: Binary data representing a TensorFlow Lite model.
  ///   - options: Configurations for the `Interpreter`. The default is `nil` indicating that the
  ///       `Interpreter` will determine the configuration options.
  ///   - delegate: `Array` of `Delegate`s for the `Interpreter` to use to peform graph operations.
  ///       The default is `nil`.
  /// - Throws: An error if the model could not be loaded or the interpreter could not be created.
  public convenience init(modelData: Data, options: Options? = nil, delegates: [Delegate]? = nil)
    throws
  {
    guard let model = Model(modelData: modelData) else { throw InterpreterError.failedToLoadModel }
    try self.init(model: model, options: options, delegates: delegates)
  }
  /// Create a new instance with the given values.
  ///
  /// - Parameters:
  ///   - model: An instantiated TensorFlow Lite model.
  ///   - options: Configurations for the `Interpreter`. The default is `nil` indicating that the
  ///       `Interpreter` will determine the configuration options.
  ///   - delegate: `Array` of `Delegate`s for the `Interpreter` to use to peform graph operations.
  ///       The default is `nil`.
  /// - Throws: An error if the model could not be loaded or the interpreter could not be created.
  private init(model: Model, options: Options? = nil, delegates: [Delegate]? = nil) throws {
    guard let cInterpreterOptions = TfLiteInterpreterOptionsCreate() else {
      throw InterpreterError.failedToCreateInterpreter
    }
    defer { TfLiteInterpreterOptionsDelete(cInterpreterOptions) }
    self.options = options
    self.delegates = delegates
    options.map {
      if let threadCount = $0.threadCount, threadCount > 0 {
        TfLiteInterpreterOptionsSetNumThreads(cInterpreterOptions, Int32(threadCount))
      }
      TfLiteInterpreterOptionsSetErrorReporter(
        cInterpreterOptions,
        { (_, format, args) -> Void in
          // Workaround for optionality differences for x86_64 (non-optional) and arm64 (optional).
          let optionalArgs: CVaListPointer? = args
          guard let cFormat = format,
            let arguments = optionalArgs,
            let message = String(cFormat: cFormat, arguments: arguments)
          else {
            return
          }
          print(String(describing: InterpreterError.tensorFlowLiteError(message)))
        },
        nil
      )
    }
    delegates?.forEach { TfLiteInterpreterOptionsAddDelegate(cInterpreterOptions, $0.cDelegate) }
    // Configure the XNNPack delegate after the other delegates explicitly added by the user.
    options.map {
      if $0.isXNNPackEnabled {
        configureXNNPack(options: $0, cInterpreterOptions: cInterpreterOptions)
      }
    }
    guard let cInterpreter = TfLiteInterpreterCreate(model.cModel, cInterpreterOptions) else {
      throw InterpreterError.failedToCreateInterpreter
    }
    self.cInterpreter = cInterpreter
  }
  deinit {
    TfLiteInterpreterDelete(cInterpreter)
    TfLiteXNNPackDelegateDelete(cXNNPackDelegate)
  }
  /// Invokes the interpreter to perform inference from the loaded graph.
  ///
  /// - Throws: An error if the model was not ready because the tensors were not allocated.
  public func invoke() throws {
    guard TfLiteInterpreterInvoke(cInterpreter) == kTfLiteOk else {
      throw InterpreterError.allocateTensorsRequired
    }
  }
  /// Returns the input `Tensor` at the given index.
  ///
  /// - Parameters:
  ///   - index: The index for the input `Tensor`.
  /// - Throws: An error if the index is invalid or the tensors have not been allocated.
  /// - Returns: The input `Tensor` at the given index.
  public func input(at index: Int) throws -> Tensor {
    let maxIndex = inputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard let cTensor = TfLiteInterpreterGetInputTensor(cInterpreter, Int32(index)),
      let bytes = TfLiteTensorData(cTensor),
      let nameCString = TfLiteTensorName(cTensor)
    else {
      throw InterpreterError.allocateTensorsRequired
    }
    guard let dataType = Tensor.DataType(type: TfLiteTensorType(cTensor)) else {
      throw InterpreterError.invalidTensorDataType
    }
    let name = String(cString: nameCString)
    let rank = TfLiteTensorNumDims(cTensor)
    let dimensions = (0..<rank).map { Int(TfLiteTensorDim(cTensor, $0)) }
    let shape = Tensor.Shape(dimensions)
    let byteCount = TfLiteTensorByteSize(cTensor)
    let data = Data(bytes: bytes, count: byteCount)
    let cQuantizationParams = TfLiteTensorQuantizationParams(cTensor)
    let scale = cQuantizationParams.scale
    let zeroPoint = Int(cQuantizationParams.zero_point)
    var quantizationParameters: QuantizationParameters? = nil
    if scale != 0.0 {
      quantizationParameters = QuantizationParameters(scale: scale, zeroPoint: zeroPoint)
    }
    let tensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    return tensor
  }
  /// Returns the output `Tensor` at the given index.
  ///
  /// - Parameters:
  ///   - index: The index for the output `Tensor`.
  /// - Throws: An error if the index is invalid, tensors haven't been allocated, or interpreter
  ///     has not been invoked for models that dynamically compute output tensors based on the
  ///     values of its input tensors.
  /// - Returns: The output `Tensor` at the given index.
  public func output(at index: Int) throws -> Tensor {
    let maxIndex = outputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard let cTensor = TfLiteInterpreterGetOutputTensor(cInterpreter, Int32(index)),
      let bytes = TfLiteTensorData(cTensor),
      let nameCString = TfLiteTensorName(cTensor)
    else {
      throw InterpreterError.invokeInterpreterRequired
    }
    guard let dataType = Tensor.DataType(type: TfLiteTensorType(cTensor)) else {
      throw InterpreterError.invalidTensorDataType
    }
    let name = String(cString: nameCString)
    let rank = TfLiteTensorNumDims(cTensor)
    let dimensions = (0..<rank).map { Int(TfLiteTensorDim(cTensor, $0)) }
    let shape = Tensor.Shape(dimensions)
    let byteCount = TfLiteTensorByteSize(cTensor)
    let data = Data(bytes: bytes, count: byteCount)
    let cQuantizationParams = TfLiteTensorQuantizationParams(cTensor)
    let scale = cQuantizationParams.scale
    let zeroPoint = Int(cQuantizationParams.zero_point)
    var quantizationParameters: QuantizationParameters? = nil
    if scale != 0.0 {
      quantizationParameters = QuantizationParameters(scale: scale, zeroPoint: zeroPoint)
    }
    let tensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    return tensor
  }
  /// Resizes the input `Tensor` at the given index to the specified `Tensor.Shape`.
  ///
  /// - Note: After resizing an input tensor, the client **must** explicitly call
  ///     `allocateTensors()` before attempting to access the resized tensor data or invoking the
  ///     interpreter to perform inference.
  /// - Parameters:
  ///   - index: The index for the input `Tensor`.
  ///   - shape: The shape to resize the input `Tensor` to.
  /// - Throws: An error if the input tensor at the given index could not be resized.
  public func resizeInput(at index: Int, to shape: Tensor.Shape) throws {
    let maxIndex = inputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard
      TfLiteInterpreterResizeInputTensor(
        cInterpreter,
        Int32(index),
        shape.int32Dimensions,
        Int32(shape.rank)
      ) == kTfLiteOk
    else {
      throw InterpreterError.failedToResizeInputTensor(index: index)
    }
  }
  public func copy(_ data: Data, toInputAt index: Int) throws -> Tensor {
    let maxIndex = inputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard let cTensor = TfLiteInterpreterGetInputTensor(cInterpreter, Int32(index)) else {
      throw InterpreterError.allocateTensorsRequired
    }
    let byteCount = TfLiteTensorByteSize(cTensor)
    guard data.count == byteCount else {
      throw InterpreterError.invalidTensorDataCount(provided: data.count, required: byteCount)
    }
    #if swift(>=5.0)
      let status = data.withUnsafeBytes {
        TfLiteTensorCopyFromBuffer(cTensor, $0.baseAddress, data.count)
      }
    #else
      let status = data.withUnsafeBytes { TfLiteTensorCopyFromBuffer(cTensor, $0, data.count) }
    #endif  // swift(>=5.0)
    guard status == kTfLiteOk else { throw InterpreterError.failedToCopyDataToInputTensor }
    return try input(at: index)
  }
  /// Allocates memory for all input `Tensor`s based on their `Tensor.Shape`s.
  ///
  /// - Note: This is a relatively expensive operation and should only be called after creating the
  ///     interpreter and resizing any input tensors.
  /// - Throws: An error if memory could not be allocated for the input tensors.
  public func allocateTensors() throws {
    guard TfLiteInterpreterAllocateTensors(cInterpreter) == kTfLiteOk else {
      throw InterpreterError.failedToAllocateTensors
    }
  }
  /// Returns a new signature runner instance for the signature with the given key in the model.
  ///
  /// - Parameters:
  ///   - key: The signature key.
  /// - Throws: `SignatureRunnerError` if signature runner creation fails.
  /// - Returns: A new signature runner instance for the signature with the given key.
  public func signatureRunner(with key: String) throws -> SignatureRunner {
    guard signatureKeys.contains(key) else {
      throw SignatureRunnerError.failedToCreateSignatureRunner(signatureKey: key)
    }
    return try SignatureRunner.init(interpreter: self, signatureKey: key)
  }
  // MARK: - Private
  private func configureXNNPack(options: Options, cInterpreterOptions: OpaquePointer) {
    var cXNNPackOptions = TfLiteXNNPackDelegateOptionsDefault()
    if let threadCount = options.threadCount, threadCount > 0 {
      cXNNPackOptions.num_threads = Int32(threadCount)
    }
    cXNNPackDelegate = TfLiteXNNPackDelegateCreate(&cXNNPackOptions)
    TfLiteInterpreterOptionsAddDelegate(cInterpreterOptions, cXNNPackDelegate)
  }
}
extension Interpreter {
  /// Options for configuring the `Interpreter`.
  public struct Options: Equatable, Hashable {
    /// The maximum number of CPU threads that the interpreter should run on. The default is `nil`
    /// indicating that the `Interpreter` will decide the number of threads to use.
    public var threadCount: Int? = nil
    /// Indicates whether an optimized set of floating point CPU kernels, provided by XNNPACK, is
    /// enabled.
    ///
    /// - Experiment:
    /// Enabling this flag will enable use of a new, highly optimized set of CPU kernels provided
    /// via the XNNPACK delegate. Currently, this is restricted to a subset of floating point
    /// operations. Eventually, we plan to enable this by default, as it can provide significant
    /// performance benefits for many classes of floating point models. See
    /// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/delegates/xnnpack/README.md
    /// for more details.
    ///
    /// - Important:
    /// Things to keep in mind when enabling this flag:
    ///
    ///     * Startup time and resize time may increase.
    ///     * Baseline memory consumption may increase.
    ///     * Compatibility with other delegates (e.g., GPU) has not been fully validated.
    ///     * Quantized models will not see any benefit.
    ///
    /// - Warning: This is an experimental interface that is subject to change.
    public var isXNNPackEnabled: Bool = false
    /// Creates a new instance with the default values.
    public init() {}
  }
}
/// A type alias for `Interpreter.Options` to support backwards compatibility with the deprecated
/// `InterpreterOptions` struct.
public typealias InterpreterOptions = Interpreter.Options
extension String {
  /// Returns a new `String` initialized by using the given format C array as a template into which
  /// the remaining argument values are substituted according to the user’s default locale.
  ///
  /// - Note: Returns `nil` if a new `String` could not be constructed from the given values.
  /// - Parameters:
  ///   - cFormat: The format C array as a template for substituting values.
  ///   - arguments: A C pointer to a `va_list` of arguments to substitute into `cFormat`.
  init?(cFormat: UnsafePointer<CChar>, arguments: CVaListPointer) {
    #if os(Linux)
      let length = Int(vsnprintf(nil, 0, cFormat, arguments) + 1)  // null terminator
      guard length > 0 else { return nil }
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: length)
      defer {
        buffer.deallocate()
      }
      guard vsnprintf(buffer, length, cFormat, arguments) == length - 1 else { return nil }
      self.init(validatingUTF8: buffer)
    #else
      var buffer: UnsafeMutablePointer<CChar>?
      guard vasprintf(&buffer, cFormat, arguments) != 0, let cString = buffer else { return nil }
      self.init(validatingUTF8: cString)
    #endif
  }
}


Delegate

import TensorFlowLiteC
/// A delegate that the `Interpreter` uses to perform TensorFlow Lite model computations.
public protocol Delegate: AnyObject {
  /// The `TfLiteDelegate` C pointer type.
  typealias CDelegate = UnsafeMutablePointer<TfLiteDelegate>
  /// The delegate that performs model computations.
  var cDelegate: CDelegate { get }
}


TensorFlowLite

import TensorFlowLiteC
/// TensorFlow Lite runtime values.
public enum Runtime {
  /// A string describing the semantic versioning information for the runtime. Is an empty string if
  /// the version could not be determined.
  public static var version: String { return TfLiteVersion().map(String.init) ?? "" }
}


InterpreterError

import Foundation
/// Errors thrown by the TensorFlow Lite `Interpreter`.
public enum InterpreterError: Error, Equatable, Hashable {
  case invalidTensorIndex(index: Int, maxIndex: Int)
  case invalidTensorDataCount(provided: Int, required: Int)
  case invalidTensorDataType
  case failedToLoadModel
  case failedToCreateInterpreter
  case failedToResizeInputTensor(index: Int)
  case failedToCopyDataToInputTensor
  case failedToAllocateTensors
  case allocateTensorsRequired
  case invokeInterpreterRequired
  case tensorFlowLiteError(String)
}
extension InterpreterError: LocalizedError {
  /// A localized description of the interpreter error.
  public var errorDescription: String? {
    switch self {
    case .invalidTensorIndex(let index, let maxIndex):
      return "Invalid tensor index \(index), max index is \(maxIndex)."
    case .invalidTensorDataCount(let provided, let required):
      return "Provided data count \(provided) must match the required count \(required)."
    case .invalidTensorDataType:
      return "Tensor data type is unsupported or could not be determined due to a model error."
    case .failedToLoadModel:
      return "Failed to load the given model."
    case .failedToCreateInterpreter:
      return "Failed to create the interpreter."
    case .failedToResizeInputTensor(let index):
      return "Failed to resize input tensor at index \(index)."
    case .failedToCopyDataToInputTensor:
      return "Failed to copy data to input tensor."
    case .failedToAllocateTensors:
      return "Failed to allocate memory for input tensors."
    case .allocateTensorsRequired:
      return "Must call allocateTensors()."
    case .invokeInterpreterRequired:
      return "Must call invoke()."
    case .tensorFlowLiteError(let message):
      return "TensorFlow Lite Error: \(message)"
    }
  }
}
extension InterpreterError: CustomStringConvertible {
  /// A textual representation of the TensorFlow Lite interpreter error.
  public var description: String { return errorDescription ?? "Unknown error." }
}


SignatureRunner

import Foundation
import TensorFlowLiteC
#if os(Linux)
  import SwiftGlibc
#else
  import Darwin
#endif
/// A TensorFlow Lite model signature runner. You can get a `SignatureRunner` instance for a
/// signature from an `Interpreter` and then use the SignatureRunner APIs.
///
/// - Note: `SignatureRunner` instances are *not* thread-safe.
/// - Note: Each `SignatureRunner` instance is associated with an `Interpreter` instance. As long
///     as a `SignatureRunner` instance is still in use, its associated `Interpreter` instance
///     will not be deallocated.
public final class SignatureRunner {
  /// The signature key.
  public let signatureKey: String
  /// The SignatureDefs input names.
  public var inputs: [String] {
    guard let inputs = _inputs else {
      let inputCount = Int(TfLiteSignatureRunnerGetInputCount(self.cSignatureRunner))
      let ins: [String] = (0..<inputCount).map {
        guard
          let inputNameCString = TfLiteSignatureRunnerGetInputName(
            self.cSignatureRunner, Int32($0))
        else {
          return ""
        }
        return String(cString: inputNameCString)
      }
      _inputs = ins
      return ins
    }
    return inputs
  }
  /// The SignatureDefs output names.
  public var outputs: [String] {
    guard let outputs = _outputs else {
      let outputCount = Int(TfLiteSignatureRunnerGetOutputCount(self.cSignatureRunner))
      let outs: [String] = (0..<outputCount).map {
        guard
          let outputNameCString = TfLiteSignatureRunnerGetOutputName(
            self.cSignatureRunner, Int32($0))
        else {
          return ""
        }
        return String(cString: outputNameCString)
      }
      _outputs = outs
      return outs
    }
    return outputs
  }
  /// The backing interpreter. It's a strong reference to ensure that the interpreter is never
  /// released before this signature runner is released.
  ///
  /// - Warning: Never let the interpreter hold a strong reference to the signature runner to avoid
  ///     retain cycles.
  private var interpreter: Interpreter
  /// The `TfLiteSignatureRunner` C pointer type represented as an
  /// `UnsafePointer<TfLiteSignatureRunner>`.
  private typealias CSignatureRunner = OpaquePointer
  /// The `TfLiteTensor` C pointer type represented as an
  /// `UnsafePointer<TfLiteTensor>`.
  private typealias CTensor = UnsafePointer<TfLiteTensor>?
  /// The underlying `TfLiteSignatureRunner` C pointer.
  private var cSignatureRunner: CSignatureRunner
  /// Whether we need to allocate tensors memory.
  private var isTensorsAllocationNeeded: Bool = true
  /// The SignatureDefs input names.
  private var _inputs: [String]?
  /// The SignatureDefs output names.
  private var _outputs: [String]?
  // MARK: Initializers
  /// Initializes a new TensorFlow Lite signature runner instance with the given interpreter and
  /// signature key.
  ///
  /// - Parameters:
  ///   - interpreter: The TensorFlow Lite model interpreter.
  ///   - signatureKey: The signature key.
  /// - Throws: An error if fail to create the signature runner with given key.
  internal init(interpreter: Interpreter, signatureKey: String) throws {
    guard let signatureKeyCString = signatureKey.cString(using: String.Encoding.utf8),
      let cSignatureRunner = TfLiteInterpreterGetSignatureRunner(
        interpreter.cInterpreter, signatureKeyCString)
    else {
      throw SignatureRunnerError.failedToCreateSignatureRunner(signatureKey: signatureKey)
    }
    self.cSignatureRunner = cSignatureRunner
    self.signatureKey = signatureKey
    self.interpreter = interpreter
    try allocateTensors()
  }
  deinit {
    TfLiteSignatureRunnerDelete(cSignatureRunner)
  }
  // MARK: Public
  /// Invokes the signature with given input data.
  ///
  /// - Parameters:
  ///   - inputs: A map from input name to the input data. The input data will be copied into the
  ///       input tensor.
  public func invoke(with inputs: [String: Data]) throws {
    try allocateTensors()
    for (inputName, inputData) in inputs {
      try copy(inputData, toInputNamed: inputName)
    }
    guard TfLiteSignatureRunnerInvoke(self.cSignatureRunner) == kTfLiteOk else {
      throw SignatureRunnerError.failedToInvokeSignature(signatureKey: signatureKey)
    }
  }
  /// Returns the input tensor with the given input name in the signature.
  ///
  /// - Parameters:
  ///   - name: The input name in the signature.
  /// - Throws: An error if fail to get the input `Tensor` or the `Tensor` is invalid.
  /// - Returns: The input `Tensor` with the given input name.
  public func input(named name: String) throws -> Tensor {
    return try tensor(named: name, withType: TensorType.input)
  }
  /// Returns the output tensor with the given output name in the signature.
  ///
  /// - Parameters:
  ///   - name: The output name in the signature.
  /// - Throws: An error if fail to get the output `Tensor` or the `Tensor` is invalid.
  /// - Returns: The output `Tensor` with the given output name.
  public func output(named name: String) throws -> Tensor {
    return try tensor(named: name, withType: TensorType.output)
  }
  /// Resizes the input `Tensor` with the given input name to the specified `Tensor.Shape`.
  ///
  /// - Note: After resizing an input tensor, the client **must** explicitly call
  ///     `allocateTensors()` before attempting to access the resized tensor data.
  /// - Parameters:
  ///   - name: The input name of the `Tensor`.
  ///   - shape: The shape to resize the input `Tensor` to.
  /// - Throws: An error if the input tensor with given input name could not be resized.
  public func resizeInput(named name: String, toShape shape: Tensor.Shape) throws {
    guard let inputNameCString = name.cString(using: String.Encoding.utf8),
      TfLiteSignatureRunnerResizeInputTensor(
        self.cSignatureRunner,
        inputNameCString,
        shape.int32Dimensions,
        Int32(shape.rank)
      ) == kTfLiteOk
    else {
      throw SignatureRunnerError.failedToResizeInputTensor(inputName: name)
    }
    isTensorsAllocationNeeded = true
  }
  ///
  /// - Parameters:
  ///   - data: The data to be copied to the input `Tensor`'s data buffer.
  ///   - name: The input name of the `Tensor`.
  /// - Throws: An error if fail to get the input `Tensor` or if the `data.count` does not match the
  ///     input tensor's `data.count`.
  /// - Returns: The input `Tensor` with the copied data.
  public func copy(_ data: Data, toInputNamed name: String) throws {
    guard let inputNameCString = name.cString(using: String.Encoding.utf8),
      let cTensor = TfLiteSignatureRunnerGetInputTensor(self.cSignatureRunner, inputNameCString)
    else {
      throw SignatureRunnerError.failedToGetTensor(tensorType: "input", nameInSignature: name)
    }
    let byteCount = TfLiteTensorByteSize(cTensor)
    guard data.count == byteCount else {
      throw SignatureRunnerError.invalidTensorDataCount(provided: data.count, required: byteCount)
    }
    #if swift(>=5.0)
      let status = data.withUnsafeBytes {
        TfLiteTensorCopyFromBuffer(cTensor, $0.baseAddress, data.count)
      }
    #else
      let status = data.withUnsafeBytes { TfLiteTensorCopyFromBuffer(cTensor, $0, data.count) }
    #endif  // swift(>=5.0)
    guard status == kTfLiteOk else { throw SignatureRunnerError.failedToCopyDataToInputTensor }
  }
  /// Allocates memory for tensors.
  /// - Note: This is a relatively expensive operation and this call is *purely optional*.
  ///     Tensor allocation will occur automatically during execution.
  /// - Throws: An error if memory could not be allocated for the tensors.
  public func allocateTensors() throws {
    if !isTensorsAllocationNeeded { return }
    guard TfLiteSignatureRunnerAllocateTensors(self.cSignatureRunner) == kTfLiteOk else {
      throw SignatureRunnerError.failedToAllocateTensors
    }
    isTensorsAllocationNeeded = false
  }
  // MARK: - Private
  /// Returns the I/O tensor with the given name in the signature.
  ///
  /// - Parameters:
  ///   - nameInSignature: The input or output name in the signature.
  ///   - type: The tensor type.
  /// - Throws: An error if fail to get the `Tensor` or the `Tensor` is invalid.
  /// - Returns: The `Tensor` with the given name in the signature.
  private func tensor(named nameInSignature: String, withType type: TensorType) throws -> Tensor {
    guard let nameInSignatureCString = nameInSignature.cString(using: String.Encoding.utf8)
    else {
      throw SignatureRunnerError.failedToGetTensor(
        tensorType: type.rawValue, nameInSignature: nameInSignature)
    }
    var cTensorPointer: CTensor
    switch type {
    case .input:
      cTensorPointer = UnsafePointer(
        TfLiteSignatureRunnerGetInputTensor(self.cSignatureRunner, nameInSignatureCString))
    case .output:
      cTensorPointer = TfLiteSignatureRunnerGetOutputTensor(
        self.cSignatureRunner, nameInSignatureCString)
    }
    guard let cTensor = cTensorPointer else {
      throw SignatureRunnerError.failedToGetTensor(
        tensorType: type.rawValue, nameInSignature: nameInSignature)
    }
    guard let bytes = TfLiteTensorData(cTensor) else {
      throw SignatureRunnerError.allocateTensorsRequired
    }
    guard let dataType = Tensor.DataType(type: TfLiteTensorType(cTensor)) else {
      throw SignatureRunnerError.invalidTensorDataType
    }
    let nameCString = TfLiteTensorName(cTensor)
    let name = nameCString == nil ? "" : String(cString: nameCString!)
    let byteCount = TfLiteTensorByteSize(cTensor)
    let data = Data(bytes: bytes, count: byteCount)
    let rank = TfLiteTensorNumDims(cTensor)
    let dimensions = (0..<rank).map { Int(TfLiteTensorDim(cTensor, $0)) }
    let shape = Tensor.Shape(dimensions)
    let cQuantizationParams = TfLiteTensorQuantizationParams(cTensor)
    let scale = cQuantizationParams.scale
    let zeroPoint = Int(cQuantizationParams.zero_point)
    var quantizationParameters: QuantizationParameters? = nil
    if scale != 0.0 {
      quantizationParameters = QuantizationParameters(scale: scale, zeroPoint: zeroPoint)
    }
    let tensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    return tensor
  }
}


Model

import Foundation
import TensorFlowLiteC
/// A TensorFlow Lite model used by the `Interpreter` to perform inference.
final class Model {
  /// The `TfLiteModel` C pointer type represented as an `UnsafePointer<TfLiteModel>`.
  typealias CModel = OpaquePointer
  /// The underlying `TfLiteModel` C pointer.
  let cModel: CModel?
  /// The underlying data if data init is used
  /// From c_api.h: The caller retains ownership of the `model_data` and should ensure that
  // the lifetime of the `model_data` must be at least as long as the lifetime
  // of the `TfLiteModel`.
  let data: Data?
  /// Creates a new instance with the given `filePath`.
  ///
  /// - Precondition: Initialization can fail if the given `filePath` is invalid.
  /// - Parameters:
  ///   - filePath: The local file path to a TensorFlow Lite model.
  init?(filePath: String) {
    guard !filePath.isEmpty, let cModel = TfLiteModelCreateFromFile(filePath) else { return nil }
    self.cModel = cModel
    self.data = nil
  }
  /// Creates a new instance with the given `modelData`.
  ///
  /// - Precondition: Initialization can fail if the given `modelData` is invalid.
  /// - Parameters:
  ///   - modelData: Binary data representing a TensorFlow Lite model.
  init?(modelData: Data) {
    self.data = modelData
    self.cModel = modelData.withUnsafeBytes { TfLiteModelCreate($0, modelData.count) }
  }
  deinit {
    TfLiteModelDelete(cModel)
  }
}


SignatureRunnerError

import Foundation
/// Errors thrown by the TensorFlow Lite `SignatureRunner`.
public enum SignatureRunnerError: Error, Equatable, Hashable {
  case invalidTensorDataCount(provided: Int, required: Int)
  case invalidTensorDataType
  case failedToCreateSignatureRunner(signatureKey: String)
  case failedToGetTensor(tensorType: String, nameInSignature: String)
  case failedToResizeInputTensor(inputName: String)
  case failedToCopyDataToInputTensor
  case failedToAllocateTensors
  case failedToInvokeSignature(signatureKey: String)
  case allocateTensorsRequired
}
extension SignatureRunnerError: LocalizedError {
  /// A localized description of the signature runner error.
  public var errorDescription: String? {
    switch self {
    case .invalidTensorDataCount(let provided, let required):
      return "Provided data count \(provided) must match the required count \(required)."
    case .invalidTensorDataType:
      return "Tensor data type is unsupported or could not be determined due to a model error."
    case .failedToCreateSignatureRunner(let signatureKey):
      return "Failed to create a signature runner. Signature with key (\(signatureKey)) not found."
    case .failedToGetTensor(let tensorType, let nameInSignature):
      return "Failed to get \(tensorType) tensor with \(tensorType) name (\(nameInSignature))."
    case .failedToResizeInputTensor(let inputName):
      return "Failed to resize input tensor with input name (\(inputName))."
    case .failedToCopyDataToInputTensor:
      return "Failed to copy data to input tensor."
    case .failedToAllocateTensors:
      return "Failed to allocate memory for input tensors."
    case .failedToInvokeSignature(let signatureKey):
      return "Failed to invoke the signature runner with key (\(signatureKey))."
    case .allocateTensorsRequired:
      return "Must call allocateTensors()."
    }
  }
}
extension SignatureRunnerError: CustomStringConvertible {
  /// A textual representation of the TensorFlow Lite signature runner error.
  public var description: String { return errorDescription ?? "Unknown error." }
}


MetalDelegate

import TensorFlowLiteCMetal
/// A delegate that uses the `Metal` framework for performing TensorFlow Lite graph operations with
/// GPU acceleration.
///
/// - Important: This is an experimental interface that is subject to change.
public final class MetalDelegate: Delegate {
  /// The configuration options for the `MetalDelegate`.
  public let options: Options
  // Conformance to the `Delegate` protocol.
  public private(set) var cDelegate: CDelegate
  /// Creates a new instance configured with the given `options`.
  ///
  /// - Parameters:
  ///   - options: Configurations for the delegate. The default is a new instance of
  ///       `MetalDelegate.Options` with the default configuration values.
  public init(options: Options = Options()) {
    self.options = options
    var delegateOptions = TFLGpuDelegateOptions()
    delegateOptions.allow_precision_loss = options.isPrecisionLossAllowed
    delegateOptions.wait_type = options.waitType.cWaitType
    delegateOptions.enable_quantization = options.isQuantizationEnabled
    cDelegate = TFLGpuDelegateCreate(&delegateOptions)
  }
  deinit {
    TFLGpuDelegateDelete(cDelegate)
  }
}
extension MetalDelegate {
  /// Options for configuring the `MetalDelegate`.
  public struct Options: Equatable, Hashable {
    /// Indicates whether the GPU delegate allows precision loss, such as allowing `Float16`
    /// precision for a `Float32` computation. The default is `false`.
    public var isPrecisionLossAllowed = false
      *, deprecated, message: "Deprecated since TensorFlow Lite 2.4",
      renamed: "isPrecisionLossAllowed"
    )
    public var allowsPrecisionLoss: Bool {
      get { return isPrecisionLossAllowed }
      set(value) { isPrecisionLossAllowed = value }
    }
    /// A type indicating how the current thread should wait for work on the GPU to complete. The
    /// default is `passive`.
    public var waitType: ThreadWaitType = .passive
    /// Indicates whether the GPU delegate allows execution of an 8-bit quantized model. The default
    /// is `true`.
    public var isQuantizationEnabled = true
    /// Creates a new instance with the default values.
    public init() {}
  }
}
/// A type indicating how the current thread should wait for work scheduled on the GPU to complete.
public enum ThreadWaitType: Equatable, Hashable {
  /// The thread does not wait for the work to complete. Useful when the output of the work is used
  /// with the GPU pipeline.
  case none
  /// The thread waits until the work is complete.
  case passive
  /// The thread waits for the work to complete with minimal latency, which may require additional
  /// CPU resources.
  case active
  /// The thread waits for the work while trying to prevent the GPU from going into sleep mode.
  case aggressive
  /// The C `TFLGpuDelegateWaitType` for the current `ThreadWaitType`.
  var cWaitType: TFLGpuDelegateWaitType {
    switch self {
    case .none:
      return TFLGpuDelegateWaitTypeDoNotWait
    case .passive:
      return TFLGpuDelegateWaitTypePassive
    case .active:
      return TFLGpuDelegateWaitTypeActive
    case .aggressive:
      return TFLGpuDelegateWaitTypeAggressive
    }
  }
}


CoreMLDelegate

import TensorFlowLiteCCoreML
/// A delegate that uses the `Core ML` framework for performing TensorFlow Lite graph operations.
///
/// - Important: This is an experimental interface that is subject to change.
public final class CoreMLDelegate: Delegate {
  /// The configuration options for the `CoreMLDelegate`.
  public let options: Options
  // Conformance to the `Delegate` protocol.
  public private(set) var cDelegate: CDelegate
  /// Creates a new instance configured with the given `options`. Returns `nil` if the underlying
  /// Core ML delegate could not be created because `Options.enabledDevices` was set to
  /// `neuralEngine` but the device does not have the Neural Engine.
  ///
  /// - Parameters:
  ///   - options: Configurations for the delegate. The default is a new instance of
  ///       `CoreMLDelegate.Options` with the default configuration values.
  public init?(options: Options = Options()) {
    self.options = options
    var delegateOptions = TfLiteCoreMlDelegateOptions()
    delegateOptions.enabled_devices = options.enabledDevices.cEnabledDevices
    delegateOptions.coreml_version = Int32(options.coreMLVersion)
    delegateOptions.max_delegated_partitions = Int32(options.maxDelegatedPartitions)
    delegateOptions.min_nodes_per_partition = Int32(options.minNodesPerPartition)
    guard let delegate = TfLiteCoreMlDelegateCreate(&delegateOptions) else { return nil }
    cDelegate = delegate
  }
  deinit {
    TfLiteCoreMlDelegateDelete(cDelegate)
  }
}
extension CoreMLDelegate {
  /// A type indicating which devices the Core ML delegate should be enabled for.
  public enum EnabledDevices: Equatable, Hashable {
    /// Enables the delegate for devices with Neural Engine only.
    case neuralEngine
    /// Enables the delegate for all devices.
    case all
    /// The C `TfLiteCoreMlDelegateEnabledDevices` for the current `EnabledDevices`.
    var cEnabledDevices: TfLiteCoreMlDelegateEnabledDevices {
      switch self {
      case .neuralEngine:
        return TfLiteCoreMlDelegateDevicesWithNeuralEngine
      case .all:
        return TfLiteCoreMlDelegateAllDevices
      }
    }
  }
  /// Options for configuring the `CoreMLDelegate`.
  // TODO(b/143931022): Add preferred device support.
  public struct Options: Equatable, Hashable {
    /// A type indicating which devices the Core ML delegate should be enabled for. The default
    /// value is `.neuralEngine` indicating that the delegate is enabled for Neural Engine devices
    /// only.
    public var enabledDevices: EnabledDevices = .neuralEngine
    /// Target Core ML version for the model conversion. When it's not set, Core ML version will
    /// be set to highest available version for the platform.
    public var coreMLVersion = 0
    /// The maximum number of Core ML delegate partitions created. Each graph corresponds to one
    /// delegated node subset in the TFLite model. The default value is `0` indicating that all
    /// possible partitions are delegated.
    public var maxDelegatedPartitions = 0
    /// The minimum number of nodes per partition to be delegated by the Core ML delegate. The
    /// default value is `2`.
    public var minNodesPerPartition = 2
    /// Creates a new instance with the default values.
    public init() {}
  }
}


QuantizationParameters

/// Parameters that determine the mapping of quantized values to real values. Quantized values can
/// be mapped to float values using the following conversion:
/// `realValue = scale * (quantizedValue - zeroPoint)`.
public struct QuantizationParameters: Equatable, Hashable {
  /// The difference between real values corresponding to consecutive quantized values differing by
  /// 1. For example, the range of quantized values for `UInt8` data type is [0, 255].
  public let scale: Float
  /// The quantized value that corresponds to the real 0 value.
  public let zeroPoint: Int
  /// Creates a new instance with the given values.
  ///
  /// - Parameters:
  ///   - scale: The scale value for asymmetric quantization.
  ///   - zeroPoint: The zero point for asymmetric quantization.
  init(scale: Float, zeroPoint: Int) {
    self.scale = scale
    self.zeroPoint = zeroPoint
  }
}


InterpreterTests

class InterpreterTests: XCTestCase {
  var interpreter: Interpreter!
  override func setUp() {
    super.setUp()
    interpreter = try! Interpreter(modelPath: AddModel.path)
  }
  override func tearDown() {
    interpreter = nil
    super.tearDown()
  }
  func testInit_ValidModelPath() {
    XCTAssertNoThrow(try Interpreter(modelPath: AddModel.path))
  }
  func testInit_InvalidModelPath_ThrowsFailedToLoadModel() {
    XCTAssertThrowsError(try Interpreter(modelPath: "/invalid/path")) { error in
      self.assertEqualErrors(actual: error, expected: .failedToLoadModel)
    }
  }
  func testInitWithOptions() throws {
    var options = Interpreter.Options()
    options.threadCount = 2
    let interpreter = try Interpreter(modelPath: AddQuantizedModel.path, options: options)
    XCTAssertNotNil(interpreter.options)
    XCTAssertNil(interpreter.delegates)
  }
  func testInit_WithData_ValidModelPath() {
    XCTAssertNoThrow(
      try Interpreter(modelData: try Data(contentsOf: URL(fileURLWithPath: AddModel.path))))
  }
  func testInitWithDataWithOptions() throws {
    var options = Interpreter.Options()
    options.threadCount = 2
    let interpreter = try Interpreter(
      modelData: try Data(contentsOf: URL(fileURLWithPath: AddQuantizedModel.path)),
      options: options
    )
    XCTAssertNotNil(interpreter.options)
    XCTAssertNil(interpreter.delegates)
  }
  func testInputTensorCount() {
    XCTAssertEqual(interpreter.inputTensorCount, AddModel.inputTensorCount)
  }
  func testOutputTensorCount() {
    XCTAssertEqual(interpreter.outputTensorCount, AddModel.outputTensorCount)
  }
  func testInvoke() throws {
    try interpreter.allocateTensors()
    XCTAssertNoThrow(try interpreter.invoke())
  }
  func testInvoke_ThrowsAllocateTensorsRequired_ModelNotReady() {
    XCTAssertThrowsError(try interpreter.invoke()) { error in
      self.assertEqualErrors(actual: error, expected: .allocateTensorsRequired)
    }
  }
  func testInputTensorAtIndex() throws {
    try setUpAddModelInputTensor()
    let inputTensor = try interpreter.input(at: AddModel.validIndex)
    XCTAssertEqual(inputTensor, AddModel.inputTensor)
  }
  func testInputTensorAtIndex_QuantizedModel() throws {
    interpreter = try Interpreter(modelPath: AddQuantizedModel.path)
    try setUpAddQuantizedModelInputTensor()
    let inputTensor = try interpreter.input(at: AddQuantizedModel.inputOutputIndex)
    XCTAssertEqual(inputTensor, AddQuantizedModel.inputTensor)
  }
  func testInputTensorAtIndex_ThrowsInvalidIndex() throws {
    try interpreter.allocateTensors()
    XCTAssertThrowsError(try interpreter.input(at: AddModel.invalidIndex)) { error in
      let maxIndex = AddModel.inputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testInputTensorAtIndex_ThrowsAllocateTensorsRequired() {
    XCTAssertThrowsError(try interpreter.input(at: AddModel.validIndex)) { error in
      self.assertEqualErrors(actual: error, expected: .allocateTensorsRequired)
    }
  }
  func testOutputTensorAtIndex() throws {
    try setUpAddModelInputTensor()
    try interpreter.invoke()
    let outputTensor = try interpreter.output(at: AddModel.validIndex)
    XCTAssertEqual(outputTensor, AddModel.outputTensor)
    let expectedResults = [Float32](unsafeData: outputTensor.data)
    XCTAssertEqual(expectedResults, AddModel.results)
  }
  func testOutputTensorAtIndex_QuantizedModel() throws {
    interpreter = try Interpreter(modelPath: AddQuantizedModel.path)
    try setUpAddQuantizedModelInputTensor()
    try interpreter.invoke()
    let outputTensor = try interpreter.output(at: AddQuantizedModel.inputOutputIndex)
    XCTAssertEqual(outputTensor, AddQuantizedModel.outputTensor)
    let expectedResults = [UInt8](outputTensor.data)
    XCTAssertEqual(expectedResults, AddQuantizedModel.results)
  }
  func testOutputTensorAtIndex_ThrowsInvalidIndex() throws {
    try interpreter.allocateTensors()
    try interpreter.invoke()
    XCTAssertThrowsError(try interpreter.output(at: AddModel.invalidIndex)) { error in
      let maxIndex = AddModel.outputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testOutputTensorAtIndex_ThrowsInvokeInterpreterRequired() {
    XCTAssertThrowsError(try interpreter.output(at: AddModel.validIndex)) { error in
      self.assertEqualErrors(actual: error, expected: .invokeInterpreterRequired)
    }
  }
  func testResizeInputTensorAtIndexToShape() {
    XCTAssertNoThrow(try interpreter.resizeInput(at: AddModel.validIndex, to: [2, 2, 3]))
    XCTAssertNoThrow(try interpreter.allocateTensors())
  }
  func testResizeInputTensorAtIndexToShape_ThrowsInvalidIndex() {
    XCTAssertThrowsError(
      try interpreter.resizeInput(
        at: AddModel.invalidIndex,
        to: [2, 2, 3]
      )
    ) { error in
      let maxIndex = AddModel.inputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testCopyDataToInputTensorAtIndex() throws {
    try interpreter.resizeInput(at: AddModel.validIndex, to: AddModel.shape)
    try interpreter.allocateTensors()
    let inputTensor = try interpreter.copy(AddModel.inputData, toInputAt: AddModel.validIndex)
    XCTAssertEqual(inputTensor.data, AddModel.inputData)
  }
  func testCopyDataToInputTensorAtIndex_ThrowsInvalidIndex() {
    XCTAssertThrowsError(
      try interpreter.copy(
        AddModel.inputData,
        toInputAt: AddModel.invalidIndex
      )
    ) { error in
      let maxIndex = AddModel.inputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testCopyDataToInputTensorAtIndex_ThrowsInvalidDataCount() throws {
    try interpreter.resizeInput(at: AddModel.validIndex, to: AddModel.shape)
    try interpreter.allocateTensors()
    let invalidData = Data(count: AddModel.dataCount - 1)
    XCTAssertThrowsError(
      try interpreter.copy(
        invalidData,
        toInputAt: AddModel.validIndex
      )
    ) { error in
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorDataCount(provided: invalidData.count, required: AddModel.dataCount)
      )
    }
  }
  func testAllocateTensors() {
    XCTAssertNoThrow(try interpreter.allocateTensors())
  }
  // MARK: - Private
  private func setUpAddModelInputTensor() throws {
    precondition(interpreter != nil)
    try interpreter.resizeInput(at: AddModel.validIndex, to: AddModel.shape)
    try interpreter.allocateTensors()
    try interpreter.copy(AddModel.inputData, toInputAt: AddModel.validIndex)
  }
  private func setUpAddQuantizedModelInputTensor() throws {
    precondition(interpreter != nil)
    try interpreter.resizeInput(at: AddQuantizedModel.inputOutputIndex, to: AddQuantizedModel.shape)
    try interpreter.allocateTensors()
    try interpreter.copy(AddQuantizedModel.inputData, toInputAt: AddQuantizedModel.inputOutputIndex)
  }
  private func assertEqualErrors(actual: Error, expected: InterpreterError) {
    guard let actual = actual as? InterpreterError else {
      XCTFail("Actual error should be of type InterpreterError.")
      return
    }
    XCTAssertEqual(actual, expected)
  }
}
class InterpreterOptionsTests: XCTestCase {
  func testInitWithDefaultValues() {
    let options = Interpreter.Options()
    XCTAssertNil(options.threadCount)
    XCTAssertFalse(options.isXNNPackEnabled)
  }
  func testInitWithCustomValues() {
    var options = Interpreter.Options()
    options.threadCount = 2
    XCTAssertEqual(options.threadCount, 2)
    options.isXNNPackEnabled = false
    XCTAssertFalse(options.isXNNPackEnabled)
    options.isXNNPackEnabled = true
    XCTAssertTrue(options.isXNNPackEnabled)
  }
  func testEquatable() {
    var options1 = Interpreter.Options()
    var options2 = Interpreter.Options()
    XCTAssertEqual(options1, options2)
    options1.threadCount = 2
    options2.threadCount = 2
    XCTAssertEqual(options1, options2)
    options2.threadCount = 3
    XCTAssertNotEqual(options1, options2)
    options2.threadCount = 2
    XCTAssertEqual(options1, options2)
    options2.isXNNPackEnabled = true
    XCTAssertNotEqual(options1, options2)
    options1.isXNNPackEnabled = true
    XCTAssertEqual(options1, options2)
  }
}
// MARK: - Constants
/// Values for the `add.bin` model.
enum AddModel {
  static let info = (name: "add", extension: "bin")
  static let inputTensorCount = 1
  static let outputTensorCount = 1
  static let invalidIndex = 1
  static let validIndex = 0
  static let shape: Tensor.Shape = [2]
  static let dataCount = inputData.count
  static let results = [Float32(3.0), Float32(9.0)]
  static let inputTensor = Tensor(
    name: "input",
    dataType: .float32,
    shape: shape,
    data: inputData
  )
  static let outputTensor = Tensor(
    name: "output",
    dataType: .float32,
    shape: shape,
    data: outputData
  )
  static var path: String = {
    let bundle = Bundle(for: InterpreterTests.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
}
/// Values for the `add_quantized.bin` model.
enum AddQuantizedModel {
  static let info = (name: "add_quantized", extension: "bin")
  static let inputOutputIndex = 0
  static let shape: Tensor.Shape = [2]
  static let inputData = Data([1, 3])
  static let outputData = Data([3, 9])
  static let quantizationParameters = QuantizationParameters(scale: 0.003922, zeroPoint: 0)
  static let results: [UInt8] = [3, 9]
  static let inputTensor = Tensor(
    name: "input",
    dataType: .uInt8,
    shape: shape,
    data: inputData,
    quantizationParameters: quantizationParameters
  )
  static let outputTensor = Tensor(
    name: "output",
    dataType: .uInt8,
    shape: shape,
    data: outputData,
    quantizationParameters: quantizationParameters
  )
  static var path: String = {
    let bundle = Bundle(for: InterpreterTests.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
}
// MARK: - Extensions
extension Array {
  /// Creates a new array from the bytes of the given unsafe data.
  ///
  /// - Warning: The array's `Element` type must be trivial in that it can be copied bit for bit
  ///     the `unsafeData`'s buffer to a new array returns an unsafe copy.
  /// - Note: Returns `nil` if `unsafeData.count` is not a multiple of
  ///     `MemoryLayout<Element>.stride`.
  /// - Parameter unsafeData: The data containing the bytes to turn into an array.
  init?(unsafeData: Data) {
    guard unsafeData.count % MemoryLayout<Element>.stride == 0 else { return nil }
    #if swift(>=5.0)
      self = unsafeData.withUnsafeBytes { .init($0.bindMemory(to: Element.self)) }
    #else
      self = unsafeData.withUnsafeBytes {
        .init(
          UnsafeBufferPointer<Element>(
            start: $0,
            count: unsafeData.count / MemoryLayout<Element>.stride
          ))
      }
    #endif  // swift(>=5.0)
  }
}
extension Data {
    self = array.withUnsafeBufferPointer(Data.init)
  }
}


MetalDelegateTests

class MetalDelegateTests: XCTestCase {
  func testInitDefaultGPUDelegateOptions() {
    let delegate = MetalDelegate()
    XCTAssertFalse(delegate.options.isPrecisionLossAllowed)
    XCTAssertEqual(delegate.options.waitType, .passive)
  }
  func testInitWithCustomGPUDelegateOptions() {
    var options = MetalDelegate.Options()
    options.isPrecisionLossAllowed = true
    options.waitType = .active
    let delegate = MetalDelegate(options: options)
    XCTAssertTrue(delegate.options.isPrecisionLossAllowed)
    XCTAssertEqual(delegate.options.waitType, .active)
  }
  func testInitInterpreterWithDelegate() throws {
    // If metal device is not available, skip.
    if MTLCreateSystemDefaultDevice() == nil {
      return
    }
    let metalDelegate = MetalDelegate()
    let interpreter = try Interpreter(modelPath: MultiAddModel.path, delegates: [metalDelegate])
    XCTAssertEqual(interpreter.delegates?.count, 1)
    XCTAssertNil(interpreter.options)
  }
  func testInitInterpreterWithOptionsAndDelegate() throws {
    // If metal device is not available, skip.
    if MTLCreateSystemDefaultDevice() == nil {
      return
    }
    var options = Interpreter.Options()
    options.threadCount = 1
    let metalDelegate = MetalDelegate()
    let interpreter = try Interpreter(
      modelPath: MultiAddModel.path,
      options: options,
      delegates: [metalDelegate]
    )
    XCTAssertNotNil(interpreter.options)
    XCTAssertEqual(interpreter.delegates?.count, 1)
  }
}
class MetalDelegateOptionsTests: XCTestCase {
  func testInitWithDefaultValues() {
    let options = MetalDelegate.Options()
    XCTAssertFalse(options.isPrecisionLossAllowed)
    XCTAssertEqual(options.waitType, .passive)
  }
  func testInitWithCustomValues() {
    var options = MetalDelegate.Options()
    options.isPrecisionLossAllowed = true
    options.waitType = .active
    XCTAssertTrue(options.isPrecisionLossAllowed)
    XCTAssertEqual(options.waitType, .active)
  }
  func testEquatable() {
    var options1 = MetalDelegate.Options()
    var options2 = MetalDelegate.Options()
    XCTAssertEqual(options1, options2)
    options1.isPrecisionLossAllowed = true
    options2.isPrecisionLossAllowed = true
    XCTAssertEqual(options1, options2)
    options1.waitType = .none
    options2.waitType = .none
    XCTAssertEqual(options1, options2)
    options2.isPrecisionLossAllowed = false
    XCTAssertNotEqual(options1, options2)
    options1.isPrecisionLossAllowed = false
    options1.waitType = .aggressive
    XCTAssertNotEqual(options1, options2)
  }
}
/// Values for the `multi_add.bin` model.
enum MultiAddModel {
  static let info = (name: "multi_add", extension: "bin")
  static var path: String = {
    let bundle = Bundle(for: MetalDelegateTests.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
}


ModelTests

class ModelTests: XCTestCase {
  var modelPath: String!
  override func setUp() {
    super.setUp()
    let bundle = Bundle(for: type(of: self))
    guard
      let modelPath = bundle.path(
        forResource: Constant.modelInfo.name,
        ofType: Constant.modelInfo.extension
      )
    else {
      XCTFail("Failed to get the model file path.")
      return
    }
    self.modelPath = modelPath
  }
  override func tearDown() {
    modelPath = nil
    super.tearDown()
  }
  func testInitWithFilePath() {
    let model = Model(filePath: modelPath)
    XCTAssertNotNil(model)
    XCTAssertNotNil(model?.cModel)
    XCTAssertNil(model?.data)
  }
  func testInitWithEmptyFilePath_FailsInitialization() {
    XCTAssertNil(Model(filePath: ""))
  }
  func testInitWithInvalidFilePath_FailsInitialization() {
    XCTAssertNil(Model(filePath: "invalid/path"))
  }
  func testInitWithData() throws {
    let model = Model(modelData: try Data(contentsOf: URL(fileURLWithPath: modelPath)))
    XCTAssertNotNil(model)
    XCTAssertNotNil(model?.cModel)
    XCTAssertNotNil(model?.data)
  }
}
// MARK: - Constants
private enum Constant {
  static let modelInfo = (name: "add", extension: "bin")
}


TensorFlowLiteTests

class TensorFlowLiteTests: XCTestCase {
  func testRuntime_Version() {
    #if swift(>=5.0)
    let pattern = #"^(\d+)\.(\d+)\.(\d+)([+-][-.0-9A-Za-z]+)?$"#
    #else
    let pattern = "^(\\d+)\\.(\\d+)\\.(\\d+)([+-][-.0-9A-Za-z]+)?$"
    #endif  // swift(>=5.0)
    XCTAssertNotNil(TensorFlowLite.Runtime.version.range(of: pattern, options: .regularExpression))
  }
}


QuantizationParametersTests

class QuantizationParametersTests: XCTestCase {
  func testInitWithCustomValues() {
    let parameters = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    XCTAssertEqual(parameters.scale, 0.5)
    XCTAssertEqual(parameters.zeroPoint, 1)
  }
  func testEquatable() {
    let parameters1 = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    let parameters2 = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    XCTAssertEqual(parameters1, parameters2)
    let parameters3 = QuantizationParameters(scale: 0.4, zeroPoint: 1)
    XCTAssertNotEqual(parameters1, parameters3)
    XCTAssertNotEqual(parameters2, parameters3)
  }
}


SignatureRunnerTest

class SignatureRunnerTest: XCTestCase {
  func testSignatureKeys() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    XCTAssertEqual(interpreter.signatureKeys, MultiSignaturesModel.signatureKeys)
    XCTAssertNotNil(try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key))
    XCTAssertThrowsError(try interpreter.signatureRunner(with: "dummy")) { error in
      self.assertEqualErrors(
        actual: error, expected: .failedToCreateSignatureRunner(signatureKey: "dummy"))
    }
  }
  func testResizeInputTensor() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    let addRunner = try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key)
    XCTAssertEqual(addRunner.inputs, MultiSignaturesModel.AddSignature.inputs)
    let inputTensor = try addRunner.input(named: "x")
    // Validate signature "add" input tensor "x" before resizing.
    XCTAssertEqual(inputTensor.name, MultiSignaturesModel.AddSignature.inputTensor.name)
    XCTAssertEqual(inputTensor.dataType, MultiSignaturesModel.AddSignature.inputTensor.dataType)
    XCTAssertEqual(inputTensor.shape, [1])
    // Test fail to copy data before resizing the tensor
    XCTAssertThrowsError(
      try addRunner.copy(MultiSignaturesModel.AddSignature.inputData, toInputNamed: "x")
    ) { error in
      self.assertEqualErrors(
        actual: error, expected: .invalidTensorDataCount(provided: 8, required: 4))
    }
    // Resize signature "add" input tensor "x"
    try addRunner.resizeInput(named: "x", toShape: MultiSignaturesModel.AddSignature.shape)
    try addRunner.allocateTensors()
    // Copy data to input tensor "x"
    try addRunner.copy(MultiSignaturesModel.AddSignature.inputData, toInputNamed: "x")
    XCTAssertEqual(
      try addRunner.input(named: "x"), MultiSignaturesModel.AddSignature.inputTensor)
  }
  func testResizeInputTensor_invalidTensor() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    let addRunner = try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key)
    // Test fail to get input tensor for a dummy input name.
    XCTAssertThrowsError(
      try addRunner.input(named: "dummy")
    ) { error in
      self.assertEqualErrors(
        actual: error, expected: .failedToGetTensor(tensorType: "input", nameInSignature: "dummy"))
    }
    // Test fail to resize dummy input tensor
    XCTAssertThrowsError(
      try addRunner.resizeInput(named: "dummy", toShape: [2])
    ) { error in
      self.assertEqualErrors(
        actual: error, expected: .failedToResizeInputTensor(inputName: "dummy"))
    }
  }
  func testInvokeWithInputs() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    let addRunner = try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key)
    XCTAssertEqual(addRunner.outputs, MultiSignaturesModel.AddSignature.outputs)
    // Validate signature "add" output tensor "output_0" before inference
    let outputTensor = try addRunner.output(named: "output_0")
    XCTAssertEqual(outputTensor.name, MultiSignaturesModel.AddSignature.outputTensor.name)
    XCTAssertEqual(outputTensor.dataType, MultiSignaturesModel.AddSignature.outputTensor.dataType)
    XCTAssertEqual(outputTensor.shape, [1])
    // Resize signature "add" input tensor "x"
    try addRunner.resizeInput(named: "x", toShape: MultiSignaturesModel.AddSignature.shape)
    // Invoke signature "add" with inputs.
    try addRunner.invoke(with: ["x": MultiSignaturesModel.AddSignature.inputData])
    // Validate signature "add" output tensor "output_0" after inference
    XCTAssertEqual(
      try addRunner.output(named: "output_0"), MultiSignaturesModel.AddSignature.outputTensor)
  }
  // MARK: - Private
  private func assertEqualErrors(actual: Error, expected: SignatureRunnerError) {
    guard let actual = actual as? SignatureRunnerError else {
      XCTFail("Actual error should be of type SignatureRunnerError.")
      return
    }
    XCTAssertEqual(actual, expected)
  }
}
// MARK: - Constants
/// Values for the `multi_signatures.bin` model.
enum MultiSignaturesModel {
  static let info = (name: "multi_signatures", extension: "bin")
  static let signatureKeys = [AddSignature.key, SubSignature.key]
  static var path: String = {
    let bundle = Bundle(for: SignatureRunnerTest.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
  enum AddSignature {
    static let key = "add"
    static let inputs = ["x"]
    static let outputs = ["output_0"]
    static let shape: Tensor.Shape = [2]
    static let inputTensor = Tensor(
      name: "add_x:0",
      dataType: .float32,
      shape: shape,
      data: inputData
    )
    static let outputTensor = Tensor(
      name: "StatefulPartitionedCall:0",
      dataType: .float32,
      shape: shape,
      data: outputData
    )
  }
  enum SubSignature {
    static let key = "sub"
  }
}


TensorTests

class TensorTests: XCTestCase {
  func testInit() {
    let name = "InputTensor"
    let dataType: Tensor.DataType = .uInt8
    let shape = Tensor.Shape(Constant.dimensions)
    guard let data = name.data(using: .utf8) else { XCTFail("Data should not be nil."); return }
    let quantizationParameters = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    let inputTensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    XCTAssertEqual(inputTensor.name, name)
    XCTAssertEqual(inputTensor.dataType, dataType)
    XCTAssertEqual(inputTensor.shape, shape)
    XCTAssertEqual(inputTensor.data, data)
    XCTAssertEqual(inputTensor.quantizationParameters, quantizationParameters)
  }
  func testEquatable() {
    let name = "Tensor"
    let dataType: Tensor.DataType = .uInt8
    let shape = Tensor.Shape(Constant.dimensions)
    guard let data = name.data(using: .utf8) else { XCTFail("Data should not be nil."); return }
    let quantizationParameters = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    let tensor1 = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    var tensor2 = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    XCTAssertEqual(tensor1, tensor2)
    tensor2 = Tensor(
      name: "Tensor2",
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    XCTAssertNotEqual(tensor1, tensor2)
  }
}
class TensorShapeTests: XCTestCase {
  func testInitWithArray() {
    let shape = Tensor.Shape(Constant.dimensions)
    XCTAssertEqual(shape.rank, Constant.dimensions.count)
    XCTAssertEqual(shape.dimensions, Constant.dimensions)
  }
  func testInitWithElements() {
    let shape = Tensor.Shape(2, 2, 3)
    XCTAssertEqual(shape.rank, Constant.dimensions.count)
    XCTAssertEqual(shape.dimensions, Constant.dimensions)
  }
  func testInitWithArrayLiteral() {
    let shape: Tensor.Shape = [2, 2, 3]
    XCTAssertEqual(shape.rank, Constant.dimensions.count)
    XCTAssertEqual(shape.dimensions, Constant.dimensions)
  }
  func testEquatable() {
    let shape1 = Tensor.Shape(2, 2, 3)
    var shape2: Tensor.Shape = [2, 2, 3]
    XCTAssertEqual(shape1, shape2)
    shape2 = [2, 2, 4]
    XCTAssertNotEqual(shape1, shape2)
  }
}
// MARK: - Constants
private enum Constant {
  /// Array of 2 arrays of 2 arrays of 3 numbers: [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]].
  static let dimensions = [2, 2, 3]
}


AppDelegate

class AppDelegate: FlutterAppDelegate {
  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    return true
  }
}


MainFlutterWindow

import Cocoa
import FlutterMacOS
class MainFlutterWindow: NSWindow {
  override func awakeFromNib() {
    let flutterViewController = FlutterViewController.init()
    let windowFrame = self.frame
    self.contentViewController = flutterViewController
    self.setFrame(windowFrame, display: true)
    RegisterGeneratedPlugins(registry: flutterViewController)
    super.awakeFromNib()
  }
}


PathProviderPlugin

import Foundation
#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#endif
public class PathProviderPlugin: NSObject, FlutterPlugin, PathProviderApi {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let instance = PathProviderPlugin()
    // Workaround for https://github.com/flutter/flutter/issues/118103.
#if os(iOS)
    let messenger = registrar.messenger()
#else
    let messenger = registrar.messenger
#endif
    PathProviderApiSetup.setUp(binaryMessenger: messenger, api: instance)
  }
  func getDirectoryPath(type: DirectoryType) -> String? {
    var path = getDirectory(ofType: fileManagerDirectoryForType(type))
  #if os(macOS)
    // In a non-sandboxed app, this is a shared directory where applications are
    // expected to use its bundle ID as a subdirectory. (For non-sandboxed apps,
    // adding the extra path is harmless).
    // This is not done for iOS, for compatibility with older versions of the
    // plugin.
    if type == .applicationSupport {
      if let basePath = path {
        let basePathURL = URL.init(fileURLWithPath: basePath)
        path = basePathURL.appendingPathComponent(Bundle.main.bundleIdentifier!).path
      }
    }
  #endif
    return path
  }
  // Returns the path for the container of the specified app group.
  func getContainerPath(appGroupIdentifier: String) -> String? {
      return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)?.path
  }
}
/// Returns the FileManager constant corresponding to the given type.
private func fileManagerDirectoryForType(_ type: DirectoryType) -> FileManager.SearchPathDirectory {
  switch type {
    case .applicationDocuments:
      return FileManager.SearchPathDirectory.documentDirectory
    case .applicationSupport:
      return FileManager.SearchPathDirectory.applicationSupportDirectory
    case .downloads:
      return FileManager.SearchPathDirectory.downloadsDirectory
    case .library:
      return FileManager.SearchPathDirectory.libraryDirectory
    case .temp:
      return FileManager.SearchPathDirectory.cachesDirectory
  }
}
/// Returns the user-domain directory of the given type.
private func getDirectory(ofType directory: FileManager.SearchPathDirectory) -> String? {
  let paths = NSSearchPathForDirectoriesInDomains(
    directory,
    FileManager.SearchPathDomainMask.userDomainMask,
    true)
  return paths.first
}


messages.g

// Autogenerated from Pigeon (v9.2.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon
import Foundation
#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#else
#error("Unsupported platform.")
#endif
private func wrapResult(_ result: Any?) -> [Any?] {
  return [result]
}
private func wrapError(_ error: Any) -> [Any?] {
  if let flutterError = error as? FlutterError {
    return [
      flutterError.code,
      flutterError.message,
      flutterError.details
    ]
  }
  return [
    "\(error)",
    "\(type(of: error))",
    "Stacktrace: \(Thread.callStackSymbols)"
  ]
}
private func nilOrValue<T>(_ value: Any?) -> T? {
  if value is NSNull { return nil }
  return (value as Any) as! T?
}
enum DirectoryType: Int {
  case applicationDocuments = 0
  case applicationSupport = 1
  case downloads = 2
  case library = 3
  case temp = 4
}
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol PathProviderApi {
  func getDirectoryPath(type: DirectoryType) throws -> String?
  func getContainerPath(appGroupIdentifier: String) throws -> String?
}
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class PathProviderApiSetup {
  /// The codec used by PathProviderApi.
  /// Sets up an instance of `PathProviderApi` to handle messages through the `binaryMessenger`.
  static func setUp(binaryMessenger: FlutterBinaryMessenger, api: PathProviderApi?) {
    let getDirectoryPathChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.PathProviderApi.getDirectoryPath", binaryMessenger: binaryMessenger)
    if let api = api {
      getDirectoryPathChannel.setMessageHandler { message, reply in
        let args = message as! [Any]
        let typeArg = DirectoryType(rawValue: args[0] as! Int)!
        do {
          let result = try api.getDirectoryPath(type: typeArg)
          reply(wrapResult(result))
        } catch {
          reply(wrapError(error))
        }
      }
    } else {
      getDirectoryPathChannel.setMessageHandler(nil)
    }
    let getContainerPathChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.PathProviderApi.getContainerPath", binaryMessenger: binaryMessenger)
    if let api = api {
      getContainerPathChannel.setMessageHandler { message, reply in
        let args = message as! [Any]
        let appGroupIdentifierArg = args[0] as! String
        do {
          let result = try api.getContainerPath(appGroupIdentifier: appGroupIdentifierArg)
          reply(wrapResult(result))
        } catch {
          reply(wrapError(error))
        }
      }
    } else {
      getContainerPathChannel.setMessageHandler(nil)
    }
  }
}


RunnerTests

#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#endif
class RunnerTests: XCTestCase {
  func testGetTemporaryDirectory() throws {
    let plugin = PathProviderPlugin()
    let path = plugin.getDirectoryPath(type: .temp)
    XCTAssertEqual(
      path,
      NSSearchPathForDirectoriesInDomains(
        FileManager.SearchPathDirectory.cachesDirectory,
        FileManager.SearchPathDomainMask.userDomainMask,
        true
      ).first)
  }
  func testGetApplicationDocumentsDirectory() throws {
    let plugin = PathProviderPlugin()
    let path = plugin.getDirectoryPath(type: .applicationDocuments)
    XCTAssertEqual(
      path,
      NSSearchPathForDirectoriesInDomains(
        FileManager.SearchPathDirectory.documentDirectory,
        FileManager.SearchPathDomainMask.userDomainMask,
        true
      ).first)
  }
  func testGetApplicationSupportDirectory() throws {
    let plugin = PathProviderPlugin()
    let path = plugin.getDirectoryPath(type: .applicationSupport)
#if os(iOS)
    // On iOS, the application support directory path should be just the system application
    // support path.
    XCTAssertEqual(
      path,
      NSSearchPathForDirectoriesInDomains(
        FileManager.SearchPathDirectory.applicationSupportDirectory,
        FileManager.SearchPathDomainMask.userDomainMask,
        true
      ).first)
#else
    // On macOS, the application support directory path should be the system application
    // support path with an added subdirectory based on the app name.
    XCTAssert(
      path!.hasPrefix(
        NSSearchPathForDirectoriesInDomains(
          FileManager.SearchPathDirectory.applicationSupportDirectory,
          FileManager.SearchPathDomainMask.userDomainMask,
          true
        ).first!))
    XCTAssert(path!.hasSuffix("Example"))
#endif
  }
  func testGetLibraryDirectory() throws {
    let plugin = PathProviderPlugin()
    let path = plugin.getDirectoryPath(type: .library)
    XCTAssertEqual(
      path,
      NSSearchPathForDirectoriesInDomains(
        FileManager.SearchPathDirectory.libraryDirectory,
        FileManager.SearchPathDomainMask.userDomainMask,
        true
      ).first)
  }
  func testGetDownloadsDirectory() throws {
    let plugin = PathProviderPlugin()
    let path = plugin.getDirectoryPath(type: .downloads)
    XCTAssertEqual(
      path,
      NSSearchPathForDirectoriesInDomains(
        FileManager.SearchPathDirectory.downloadsDirectory,
        FileManager.SearchPathDomainMask.userDomainMask,
        true
      ).first)
  }
}


AppDelegate

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}