// This is a generated file (see the discoveryapis_generator project).

// ignore_for_file: camel_case_types
// ignore_for_file: comment_references
// ignore_for_file: file_names
// ignore_for_file: library_names
// ignore_for_file: lines_longer_than_80_chars
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: prefer_expression_function_bodies
// ignore_for_file: prefer_final_locals
// ignore_for_file: prefer_interpolation_to_compose_strings
// ignore_for_file: unnecessary_brace_in_string_interps
// ignore_for_file: unnecessary_cast
// ignore_for_file: unnecessary_lambdas
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: unnecessary_string_interpolations

/// Ad Exchange Buyer API - v1.3
///
/// Accesses your bidding-account information, submits creatives for validation,
/// finds available direct deals, and retrieves performance reports.
///
/// For more information, see
/// <https://developers.google.com/ad-exchange/buyer-rest>
library adexchangebuyer.v1_3;

import 'dart:async' as async;
import 'dart:convert' as convert;
import 'dart:core' as core;

import 'package:_discoveryapis_commons/_discoveryapis_commons.dart' as commons;
import 'package:http/http.dart' as http;

import '../src/user_agent.dart';

export 'package:_discoveryapis_commons/_discoveryapis_commons.dart'
    show ApiRequestError, DetailedApiRequestError;

/// Accesses your bidding-account information, submits creatives for validation,
/// finds available direct deals, and retrieves performance reports.
class AdExchangeBuyerApi {
  /// Manage your Ad Exchange buyer account configuration
  static const adexchangeBuyerScope =
      'https://www.googleapis.com/auth/adexchange.buyer';

  final commons.ApiRequester _requester;

  AccountsResourceApi get accounts => AccountsResourceApi(_requester);
  BillingInfoResourceApi get billingInfo => BillingInfoResourceApi(_requester);
  BudgetResourceApi get budget => BudgetResourceApi(_requester);
  CreativesResourceApi get creatives => CreativesResourceApi(_requester);
  DirectDealsResourceApi get directDeals => DirectDealsResourceApi(_requester);
  PerformanceReportResourceApi get performanceReport =>
      PerformanceReportResourceApi(_requester);
  PretargetingConfigResourceApi get pretargetingConfig =>
      PretargetingConfigResourceApi(_requester);

  AdExchangeBuyerApi(http.Client client,
      {core.String rootUrl = 'https://www.googleapis.com/',
      core.String servicePath = 'adexchangebuyer/v1.3/'})
      : _requester =
            commons.ApiRequester(client, rootUrl, servicePath, userAgent);
}

class AccountsResourceApi {
  final commons.ApiRequester _requester;

  AccountsResourceApi(commons.ApiRequester client) : _requester = client;

  /// Gets one account by ID.
  ///
  /// Request parameters:
  ///
  /// [id] - The account id
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Account].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Account> get(
    core.int id, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (id == null) {
      throw core.ArgumentError('Parameter id is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'accounts/' + commons.Escaper.ecapeVariable('$id');

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Account.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Retrieves the authenticated user's list of accounts.
  ///
  /// Request parameters:
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [AccountsList].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<AccountsList> list({
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'accounts';

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) =>
          AccountsList.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Updates an existing account. This method supports patch semantics.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [id] - The account id
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Account].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Account> patch(
    Account request,
    core.int id, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (id == null) {
      throw core.ArgumentError('Parameter id is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'accounts/' + commons.Escaper.ecapeVariable('$id');

    final _response = _requester.request(
      _url,
      'PATCH',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Account.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Updates an existing account.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [id] - The account id
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Account].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Account> update(
    Account request,
    core.int id, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (id == null) {
      throw core.ArgumentError('Parameter id is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'accounts/' + commons.Escaper.ecapeVariable('$id');

    final _response = _requester.request(
      _url,
      'PUT',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Account.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }
}

class BillingInfoResourceApi {
  final commons.ApiRequester _requester;

  BillingInfoResourceApi(commons.ApiRequester client) : _requester = client;

  /// Returns the billing information for one account specified by account ID.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [BillingInfo].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<BillingInfo> get(
    core.int accountId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'billinginfo/' + commons.Escaper.ecapeVariable('$accountId');

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) =>
          BillingInfo.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Retrieves a list of billing information for all accounts of the
  /// authenticated user.
  ///
  /// Request parameters:
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [BillingInfoList].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<BillingInfoList> list({
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'billinginfo';

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) =>
          BillingInfoList.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }
}

class BudgetResourceApi {
  final commons.ApiRequester _requester;

  BudgetResourceApi(commons.ApiRequester client) : _requester = client;

  /// Returns the budget information for the adgroup specified by the accountId
  /// and billingId.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to get the budget information for.
  ///
  /// [billingId] - The billing id to get the budget information for.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Budget].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Budget> get(
    core.String accountId,
    core.String billingId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (billingId == null) {
      throw core.ArgumentError('Parameter billingId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'billinginfo/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$billingId');

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Budget.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Updates the budget amount for the budget of the adgroup specified by the
  /// accountId and billingId, with the budget amount in the request. This
  /// method supports patch semantics.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id associated with the budget being updated.
  ///
  /// [billingId] - The billing id associated with the budget being updated.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Budget].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Budget> patch(
    Budget request,
    core.String accountId,
    core.String billingId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (billingId == null) {
      throw core.ArgumentError('Parameter billingId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'billinginfo/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$billingId');

    final _response = _requester.request(
      _url,
      'PATCH',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Budget.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Updates the budget amount for the budget of the adgroup specified by the
  /// accountId and billingId, with the budget amount in the request.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id associated with the budget being updated.
  ///
  /// [billingId] - The billing id associated with the budget being updated.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Budget].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Budget> update(
    Budget request,
    core.String accountId,
    core.String billingId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (billingId == null) {
      throw core.ArgumentError('Parameter billingId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'billinginfo/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$billingId');

    final _response = _requester.request(
      _url,
      'PUT',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Budget.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }
}

class CreativesResourceApi {
  final commons.ApiRequester _requester;

  CreativesResourceApi(commons.ApiRequester client) : _requester = client;

  /// Gets the status for a single creative. A creative will be available 30-40
  /// minutes after submission.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The id for the account that will serve this creative.
  ///
  /// [buyerCreativeId] - The buyer-specific id for this creative.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Creative].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Creative> get(
    core.int accountId,
    core.String buyerCreativeId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (buyerCreativeId == null) {
      throw core.ArgumentError('Parameter buyerCreativeId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'creatives/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$buyerCreativeId');

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Creative.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Submit a new creative.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Creative].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Creative> insert(
    Creative request, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'creatives';

    final _response = _requester.request(
      _url,
      'POST',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => Creative.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Retrieves a list of the authenticated user's active creatives. A creative
  /// will be available 30-40 minutes after submission.
  ///
  /// Request parameters:
  ///
  /// [accountId] - When specified, only creatives for the given account ids are
  /// returned.
  ///
  /// [buyerCreativeId] - When specified, only creatives for the given buyer
  /// creative ids are returned.
  ///
  /// [maxResults] - Maximum number of entries returned on one result page. If
  /// not set, the default is 100. Optional.
  /// Value must be between "1" and "1000".
  ///
  /// [pageToken] - A continuation token, used to page through ad clients. To
  /// retrieve the next page, set this parameter to the value of "nextPageToken"
  /// from the previous response. Optional.
  ///
  /// [statusFilter] - When specified, only creatives having the given status
  /// are returned.
  /// Possible string values are:
  /// - "approved" : Creatives which have been approved.
  /// - "disapproved" : Creatives which have been disapproved.
  /// - "not_checked" : Creatives whose status is not yet checked.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [CreativesList].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<CreativesList> list({
    core.List<core.int> accountId,
    core.List<core.String> buyerCreativeId,
    core.int maxResults,
    core.String pageToken,
    core.String statusFilter,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId != null) {
      _queryParams['accountId'] = accountId.map((item) => '${item}').toList();
    }
    if (buyerCreativeId != null) {
      _queryParams['buyerCreativeId'] = buyerCreativeId;
    }
    if (maxResults != null) {
      _queryParams['maxResults'] = ['${maxResults}'];
    }
    if (pageToken != null) {
      _queryParams['pageToken'] = [pageToken];
    }
    if (statusFilter != null) {
      _queryParams['statusFilter'] = [statusFilter];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'creatives';

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) =>
          CreativesList.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }
}

class DirectDealsResourceApi {
  final commons.ApiRequester _requester;

  DirectDealsResourceApi(commons.ApiRequester client) : _requester = client;

  /// Gets one direct deal by ID.
  ///
  /// Request parameters:
  ///
  /// [id] - The direct deal id
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [DirectDeal].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<DirectDeal> get(
    core.String id, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (id == null) {
      throw core.ArgumentError('Parameter id is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'directdeals/' + commons.Escaper.ecapeVariable('$id');

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) =>
          DirectDeal.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Retrieves the authenticated user's list of direct deals.
  ///
  /// Request parameters:
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [DirectDealsList].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<DirectDealsList> list({
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'directdeals';

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) =>
          DirectDealsList.fromJson(data as core.Map<core.String, core.dynamic>),
    );
  }
}

class PerformanceReportResourceApi {
  final commons.ApiRequester _requester;

  PerformanceReportResourceApi(commons.ApiRequester client)
      : _requester = client;

  /// Retrieves the authenticated user's list of performance metrics.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to get the reports.
  ///
  /// [endDateTime] - The end time of the report in ISO 8601 timestamp format
  /// using UTC.
  ///
  /// [startDateTime] - The start time of the report in ISO 8601 timestamp
  /// format using UTC.
  ///
  /// [maxResults] - Maximum number of entries returned on one result page. If
  /// not set, the default is 100. Optional.
  /// Value must be between "1" and "1000".
  ///
  /// [pageToken] - A continuation token, used to page through performance
  /// reports. To retrieve the next page, set this parameter to the value of
  /// "nextPageToken" from the previous response. Optional.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [PerformanceReportList].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<PerformanceReportList> list(
    core.String accountId,
    core.String endDateTime,
    core.String startDateTime, {
    core.int maxResults,
    core.String pageToken,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    _queryParams['accountId'] = [accountId];
    if (endDateTime == null) {
      throw core.ArgumentError('Parameter endDateTime is required.');
    }
    _queryParams['endDateTime'] = [endDateTime];
    if (startDateTime == null) {
      throw core.ArgumentError('Parameter startDateTime is required.');
    }
    _queryParams['startDateTime'] = [startDateTime];
    if (maxResults != null) {
      _queryParams['maxResults'] = ['${maxResults}'];
    }
    if (pageToken != null) {
      _queryParams['pageToken'] = [pageToken];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'performancereport';

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => PerformanceReportList.fromJson(
          data as core.Map<core.String, core.dynamic>),
    );
  }
}

class PretargetingConfigResourceApi {
  final commons.ApiRequester _requester;

  PretargetingConfigResourceApi(commons.ApiRequester client)
      : _requester = client;

  /// Deletes an existing pretargeting config.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to delete the pretargeting config for.
  ///
  /// [configId] - The specific id of the configuration to delete.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future delete(
    core.String accountId,
    core.String configId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (configId == null) {
      throw core.ArgumentError('Parameter configId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _downloadOptions = null;

    _url = 'pretargetingconfigs/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$configId');

    final _response = _requester.request(
      _url,
      'DELETE',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => null,
    );
  }

  /// Gets a specific pretargeting configuration
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to get the pretargeting config for.
  ///
  /// [configId] - The specific id of the configuration to retrieve.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [PretargetingConfig].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<PretargetingConfig> get(
    core.String accountId,
    core.String configId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (configId == null) {
      throw core.ArgumentError('Parameter configId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'pretargetingconfigs/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$configId');

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => PretargetingConfig.fromJson(
          data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Inserts a new pretargeting configuration.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to insert the pretargeting config for.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [PretargetingConfig].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<PretargetingConfig> insert(
    PretargetingConfig request,
    core.String accountId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'pretargetingconfigs/' + commons.Escaper.ecapeVariable('$accountId');

    final _response = _requester.request(
      _url,
      'POST',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => PretargetingConfig.fromJson(
          data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Retrieves a list of the authenticated user's pretargeting configurations.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to get the pretargeting configs for.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [PretargetingConfigList].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<PretargetingConfigList> list(
    core.String accountId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'pretargetingconfigs/' + commons.Escaper.ecapeVariable('$accountId');

    final _response = _requester.request(
      _url,
      'GET',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => PretargetingConfigList.fromJson(
          data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Updates an existing pretargeting config. This method supports patch
  /// semantics.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to update the pretargeting config for.
  ///
  /// [configId] - The specific id of the configuration to update.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [PretargetingConfig].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<PretargetingConfig> patch(
    PretargetingConfig request,
    core.String accountId,
    core.String configId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (configId == null) {
      throw core.ArgumentError('Parameter configId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'pretargetingconfigs/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$configId');

    final _response = _requester.request(
      _url,
      'PATCH',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => PretargetingConfig.fromJson(
          data as core.Map<core.String, core.dynamic>),
    );
  }

  /// Updates an existing pretargeting config.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [accountId] - The account id to update the pretargeting config for.
  ///
  /// [configId] - The specific id of the configuration to update.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [PretargetingConfig].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<PretargetingConfig> update(
    PretargetingConfig request,
    core.String accountId,
    core.String configId, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (accountId == null) {
      throw core.ArgumentError('Parameter accountId is required.');
    }
    if (configId == null) {
      throw core.ArgumentError('Parameter configId is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'pretargetingconfigs/' +
        commons.Escaper.ecapeVariable('$accountId') +
        '/' +
        commons.Escaper.ecapeVariable('$configId');

    final _response = _requester.request(
      _url,
      'PUT',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response.then(
      (data) => PretargetingConfig.fromJson(
          data as core.Map<core.String, core.dynamic>),
    );
  }
}

class AccountBidderLocation {
  /// The maximum queries per second the Ad Exchange will send.
  core.int maximumQps;

  /// The geographical region the Ad Exchange should send requests from. Only
  /// used by some quota systems, but always setting the value is recommended.
  /// Allowed values:
  /// - ASIA
  /// - EUROPE
  /// - US_EAST
  /// - US_WEST
  core.String region;

  /// The URL to which the Ad Exchange will send bid requests.
  core.String url;

  AccountBidderLocation();

  AccountBidderLocation.fromJson(core.Map _json) {
    if (_json.containsKey('maximumQps')) {
      maximumQps = _json['maximumQps'] as core.int;
    }
    if (_json.containsKey('region')) {
      region = _json['region'] as core.String;
    }
    if (_json.containsKey('url')) {
      url = _json['url'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (maximumQps != null) {
      _json['maximumQps'] = maximumQps;
    }
    if (region != null) {
      _json['region'] = region;
    }
    if (url != null) {
      _json['url'] = url;
    }
    return _json;
  }
}

/// Configuration data for an Ad Exchange buyer account.
class Account {
  /// Your bidder locations that have distinct URLs.
  core.List<AccountBidderLocation> bidderLocation;

  /// The nid parameter value used in cookie match requests. Please contact your
  /// technical account manager if you need to change this.
  core.String cookieMatchingNid;

  /// The base URL used in cookie match requests.
  core.String cookieMatchingUrl;

  /// Account id.
  core.int id;

  /// Resource type.
  core.String kind;

  /// The maximum number of active creatives that an account can have, where a
  /// creative is active if it was inserted or bid with in the last 30 days.
  /// Please contact your technical account manager if you need to change this.
  core.int maximumActiveCreatives;

  /// The sum of all bidderLocation.maximumQps values cannot exceed this. Please
  /// contact your technical account manager if you need to change this.
  core.int maximumTotalQps;

  /// The number of creatives that this account inserted or bid with in the last
  /// 30 days.
  core.int numberActiveCreatives;

  Account();

  Account.fromJson(core.Map _json) {
    if (_json.containsKey('bidderLocation')) {
      bidderLocation = (_json['bidderLocation'] as core.List)
          .map<AccountBidderLocation>((value) => AccountBidderLocation.fromJson(
              value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('cookieMatchingNid')) {
      cookieMatchingNid = _json['cookieMatchingNid'] as core.String;
    }
    if (_json.containsKey('cookieMatchingUrl')) {
      cookieMatchingUrl = _json['cookieMatchingUrl'] as core.String;
    }
    if (_json.containsKey('id')) {
      id = _json['id'] as core.int;
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
    if (_json.containsKey('maximumActiveCreatives')) {
      maximumActiveCreatives = _json['maximumActiveCreatives'] as core.int;
    }
    if (_json.containsKey('maximumTotalQps')) {
      maximumTotalQps = _json['maximumTotalQps'] as core.int;
    }
    if (_json.containsKey('numberActiveCreatives')) {
      numberActiveCreatives = _json['numberActiveCreatives'] as core.int;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (bidderLocation != null) {
      _json['bidderLocation'] =
          bidderLocation.map((value) => value.toJson()).toList();
    }
    if (cookieMatchingNid != null) {
      _json['cookieMatchingNid'] = cookieMatchingNid;
    }
    if (cookieMatchingUrl != null) {
      _json['cookieMatchingUrl'] = cookieMatchingUrl;
    }
    if (id != null) {
      _json['id'] = id;
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    if (maximumActiveCreatives != null) {
      _json['maximumActiveCreatives'] = maximumActiveCreatives;
    }
    if (maximumTotalQps != null) {
      _json['maximumTotalQps'] = maximumTotalQps;
    }
    if (numberActiveCreatives != null) {
      _json['numberActiveCreatives'] = numberActiveCreatives;
    }
    return _json;
  }
}

/// An account feed lists Ad Exchange buyer accounts that the user has access
/// to. Each entry in the feed corresponds to a single buyer account.
class AccountsList {
  /// A list of accounts.
  core.List<Account> items;

  /// Resource type.
  core.String kind;

  AccountsList();

  AccountsList.fromJson(core.Map _json) {
    if (_json.containsKey('items')) {
      items = (_json['items'] as core.List)
          .map<Account>((value) =>
              Account.fromJson(value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (items != null) {
      _json['items'] = items.map((value) => value.toJson()).toList();
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    return _json;
  }
}

/// The configuration data for an Ad Exchange billing info.
class BillingInfo {
  /// Account id.
  core.int accountId;

  /// Account name.
  core.String accountName;

  /// A list of adgroup IDs associated with this particular account. These IDs
  /// may show up as part of a realtime bidding BidRequest, which indicates a
  /// bid request for this account.
  core.List<core.String> billingId;

  /// Resource type.
  core.String kind;

  BillingInfo();

  BillingInfo.fromJson(core.Map _json) {
    if (_json.containsKey('accountId')) {
      accountId = _json['accountId'] as core.int;
    }
    if (_json.containsKey('accountName')) {
      accountName = _json['accountName'] as core.String;
    }
    if (_json.containsKey('billingId')) {
      billingId = (_json['billingId'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (accountId != null) {
      _json['accountId'] = accountId;
    }
    if (accountName != null) {
      _json['accountName'] = accountName;
    }
    if (billingId != null) {
      _json['billingId'] = billingId;
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    return _json;
  }
}

/// A billing info feed lists Billing Info the Ad Exchange buyer account has
/// access to. Each entry in the feed corresponds to a single billing info.
class BillingInfoList {
  /// A list of billing info relevant for your account.
  core.List<BillingInfo> items;

  /// Resource type.
  core.String kind;

  BillingInfoList();

  BillingInfoList.fromJson(core.Map _json) {
    if (_json.containsKey('items')) {
      items = (_json['items'] as core.List)
          .map<BillingInfo>((value) => BillingInfo.fromJson(
              value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (items != null) {
      _json['items'] = items.map((value) => value.toJson()).toList();
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    return _json;
  }
}

/// The configuration data for Ad Exchange RTB - Budget API.
class Budget {
  /// The id of the account. This is required for get and update requests.
  core.String accountId;

  /// The billing id to determine which adgroup to provide budget information
  /// for. This is required for get and update requests.
  core.String billingId;

  /// The daily budget amount in unit amount of the account currency to apply
  /// for the billingId provided. This is required for update requests.
  core.String budgetAmount;

  /// The currency code for the buyer. This cannot be altered here.
  core.String currencyCode;

  /// The unique id that describes this item.
  core.String id;

  /// The kind of the resource, i.e. "adexchangebuyer#budget".
  core.String kind;

  Budget();

  Budget.fromJson(core.Map _json) {
    if (_json.containsKey('accountId')) {
      accountId = _json['accountId'] as core.String;
    }
    if (_json.containsKey('billingId')) {
      billingId = _json['billingId'] as core.String;
    }
    if (_json.containsKey('budgetAmount')) {
      budgetAmount = _json['budgetAmount'] as core.String;
    }
    if (_json.containsKey('currencyCode')) {
      currencyCode = _json['currencyCode'] as core.String;
    }
    if (_json.containsKey('id')) {
      id = _json['id'] as core.String;
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (accountId != null) {
      _json['accountId'] = accountId;
    }
    if (billingId != null) {
      _json['billingId'] = billingId;
    }
    if (budgetAmount != null) {
      _json['budgetAmount'] = budgetAmount;
    }
    if (currencyCode != null) {
      _json['currencyCode'] = currencyCode;
    }
    if (id != null) {
      _json['id'] = id;
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    return _json;
  }
}

class CreativeAdTechnologyProviders {
  /// The detected ad technology provider IDs for this creative. See
  /// https://storage.googleapis.com/adx-rtb-dictionaries/providers.csv for
  /// mapping of provider ID to provided name, a privacy policy URL, and a list
  /// of domains which can be attributed to the provider. If this creative
  /// contains provider IDs that are outside of those listed in the
  /// `BidRequest.adslot.consented_providers_settings.consented_providers` field
  /// on the  Authorized Buyers Real-Time Bidding protocol or the
  /// `BidRequest.user.ext.consented_providers_settings.consented_providers`
  /// field on the OpenRTB protocol, a bid submitted for a European Economic
  /// Area (EEA) user with this creative is not compliant with the GDPR policies
  /// as mentioned in the "Third-party Ad Technology Vendors" section of
  /// Authorized Buyers Program Guidelines.
  core.List<core.String> detectedProviderIds;

  /// Whether the creative contains an unidentified ad technology provider. If
  /// true, a bid submitted for a European Economic Area (EEA) user with this
  /// creative is not compliant with the GDPR policies as mentioned in the
  /// "Third-party Ad Technology Vendors" section of Authorized Buyers Program
  /// Guidelines.
  core.bool hasUnidentifiedProvider;

  CreativeAdTechnologyProviders();

  CreativeAdTechnologyProviders.fromJson(core.Map _json) {
    if (_json.containsKey('detectedProviderIds')) {
      detectedProviderIds = (_json['detectedProviderIds'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('hasUnidentifiedProvider')) {
      hasUnidentifiedProvider = _json['hasUnidentifiedProvider'] as core.bool;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (detectedProviderIds != null) {
      _json['detectedProviderIds'] = detectedProviderIds;
    }
    if (hasUnidentifiedProvider != null) {
      _json['hasUnidentifiedProvider'] = hasUnidentifiedProvider;
    }
    return _json;
  }
}

class CreativeCorrections {
  /// Additional details about the correction.
  core.List<core.String> details;

  /// The type of correction that was applied to the creative.
  core.String reason;

  CreativeCorrections();

  CreativeCorrections.fromJson(core.Map _json) {
    if (_json.containsKey('details')) {
      details = (_json['details'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('reason')) {
      reason = _json['reason'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (details != null) {
      _json['details'] = details;
    }
    if (reason != null) {
      _json['reason'] = reason;
    }
    return _json;
  }
}

class CreativeDisapprovalReasons {
  /// Additional details about the reason for disapproval.
  core.List<core.String> details;

  /// The categorized reason for disapproval.
  core.String reason;

  CreativeDisapprovalReasons();

  CreativeDisapprovalReasons.fromJson(core.Map _json) {
    if (_json.containsKey('details')) {
      details = (_json['details'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('reason')) {
      reason = _json['reason'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (details != null) {
      _json['details'] = details;
    }
    if (reason != null) {
      _json['reason'] = reason;
    }
    return _json;
  }
}

class CreativeFilteringReasonsReasons {
  /// The number of times the creative was filtered for the status. The count is
  /// aggregated across all publishers on the exchange.
  core.String filteringCount;

  /// The filtering status code. Please refer to the creative-status-codes.txt
  /// file for different statuses.
  core.int filteringStatus;

  CreativeFilteringReasonsReasons();

  CreativeFilteringReasonsReasons.fromJson(core.Map _json) {
    if (_json.containsKey('filteringCount')) {
      filteringCount = _json['filteringCount'] as core.String;
    }
    if (_json.containsKey('filteringStatus')) {
      filteringStatus = _json['filteringStatus'] as core.int;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (filteringCount != null) {
      _json['filteringCount'] = filteringCount;
    }
    if (filteringStatus != null) {
      _json['filteringStatus'] = filteringStatus;
    }
    return _json;
  }
}

/// The filtering reasons for the creative. Read-only. This field should not be
/// set in requests.
class CreativeFilteringReasons {
  /// The date in ISO 8601 format for the data. The data is collected from
  /// 00:00:00 to 23:59:59 in PST.
  core.String date;

  /// The filtering reasons.
  core.List<CreativeFilteringReasonsReasons> reasons;

  CreativeFilteringReasons();

  CreativeFilteringReasons.fromJson(core.Map _json) {
    if (_json.containsKey('date')) {
      date = _json['date'] as core.String;
    }
    if (_json.containsKey('reasons')) {
      reasons = (_json['reasons'] as core.List)
          .map<CreativeFilteringReasonsReasons>((value) =>
              CreativeFilteringReasonsReasons.fromJson(
                  value as core.Map<core.String, core.dynamic>))
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (date != null) {
      _json['date'] = date;
    }
    if (reasons != null) {
      _json['reasons'] = reasons.map((value) => value.toJson()).toList();
    }
    return _json;
  }
}

/// The app icon, for app download ads.
class CreativeNativeAdAppIcon {
  core.int height;
  core.String url;
  core.int width;

  CreativeNativeAdAppIcon();

  CreativeNativeAdAppIcon.fromJson(core.Map _json) {
    if (_json.containsKey('height')) {
      height = _json['height'] as core.int;
    }
    if (_json.containsKey('url')) {
      url = _json['url'] as core.String;
    }
    if (_json.containsKey('width')) {
      width = _json['width'] as core.int;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (height != null) {
      _json['height'] = height;
    }
    if (url != null) {
      _json['url'] = url;
    }
    if (width != null) {
      _json['width'] = width;
    }
    return _json;
  }
}

/// A large image.
class CreativeNativeAdImage {
  core.int height;
  core.String url;
  core.int width;

  CreativeNativeAdImage();

  CreativeNativeAdImage.fromJson(core.Map _json) {
    if (_json.containsKey('height')) {
      height = _json['height'] as core.int;
    }
    if (_json.containsKey('url')) {
      url = _json['url'] as core.String;
    }
    if (_json.containsKey('width')) {
      width = _json['width'] as core.int;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (height != null) {
      _json['height'] = height;
    }
    if (url != null) {
      _json['url'] = url;
    }
    if (width != null) {
      _json['width'] = width;
    }
    return _json;
  }
}

/// A smaller image, for the advertiser logo.
class CreativeNativeAdLogo {
  core.int height;
  core.String url;
  core.int width;

  CreativeNativeAdLogo();

  CreativeNativeAdLogo.fromJson(core.Map _json) {
    if (_json.containsKey('height')) {
      height = _json['height'] as core.int;
    }
    if (_json.containsKey('url')) {
      url = _json['url'] as core.String;
    }
    if (_json.containsKey('width')) {
      width = _json['width'] as core.int;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (height != null) {
      _json['height'] = height;
    }
    if (url != null) {
      _json['url'] = url;
    }
    if (width != null) {
      _json['width'] = width;
    }
    return _json;
  }
}

/// If nativeAd is set, HTMLSnippet and videoURL should not be set.
class CreativeNativeAd {
  core.String advertiser;

  /// The app icon, for app download ads.
  CreativeNativeAdAppIcon appIcon;

  /// A long description of the ad.
  core.String body;

  /// A label for the button that the user is supposed to click.
  core.String callToAction;

  /// The URL to use for click tracking.
  core.String clickTrackingUrl;

  /// A short title for the ad.
  core.String headline;

  /// A large image.
  CreativeNativeAdImage image;

  /// The URLs are called when the impression is rendered.
  core.List<core.String> impressionTrackingUrl;

  /// A smaller image, for the advertiser logo.
  CreativeNativeAdLogo logo;

  /// The price of the promoted app including the currency info.
  core.String price;

  /// The app rating in the app store. Must be in the range [0-5].
  core.double starRating;

  CreativeNativeAd();

  CreativeNativeAd.fromJson(core.Map _json) {
    if (_json.containsKey('advertiser')) {
      advertiser = _json['advertiser'] as core.String;
    }
    if (_json.containsKey('appIcon')) {
      appIcon = CreativeNativeAdAppIcon.fromJson(
          _json['appIcon'] as core.Map<core.String, core.dynamic>);
    }
    if (_json.containsKey('body')) {
      body = _json['body'] as core.String;
    }
    if (_json.containsKey('callToAction')) {
      callToAction = _json['callToAction'] as core.String;
    }
    if (_json.containsKey('clickTrackingUrl')) {
      clickTrackingUrl = _json['clickTrackingUrl'] as core.String;
    }
    if (_json.containsKey('headline')) {
      headline = _json['headline'] as core.String;
    }
    if (_json.containsKey('image')) {
      image = CreativeNativeAdImage.fromJson(
          _json['image'] as core.Map<core.String, core.dynamic>);
    }
    if (_json.containsKey('impressionTrackingUrl')) {
      impressionTrackingUrl = (_json['impressionTrackingUrl'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('logo')) {
      logo = CreativeNativeAdLogo.fromJson(
          _json['logo'] as core.Map<core.String, core.dynamic>);
    }
    if (_json.containsKey('price')) {
      price = _json['price'] as core.String;
    }
    if (_json.containsKey('starRating')) {
      starRating = (_json['starRating'] as core.num).toDouble();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (advertiser != null) {
      _json['advertiser'] = advertiser;
    }
    if (appIcon != null) {
      _json['appIcon'] = appIcon.toJson();
    }
    if (body != null) {
      _json['body'] = body;
    }
    if (callToAction != null) {
      _json['callToAction'] = callToAction;
    }
    if (clickTrackingUrl != null) {
      _json['clickTrackingUrl'] = clickTrackingUrl;
    }
    if (headline != null) {
      _json['headline'] = headline;
    }
    if (image != null) {
      _json['image'] = image.toJson();
    }
    if (impressionTrackingUrl != null) {
      _json['impressionTrackingUrl'] = impressionTrackingUrl;
    }
    if (logo != null) {
      _json['logo'] = logo.toJson();
    }
    if (price != null) {
      _json['price'] = price;
    }
    if (starRating != null) {
      _json['starRating'] = starRating;
    }
    return _json;
  }
}

/// A creative and its classification data.
class Creative {
  /// The HTML snippet that displays the ad when inserted in the web page. If
  /// set, videoURL should not be set.
  core.String HTMLSnippet;

  /// Account id.
  core.int accountId;
  CreativeAdTechnologyProviders adTechnologyProviders;

  /// Detected advertiser id, if any. Read-only. This field should not be set in
  /// requests.
  core.List<core.String> advertiserId;

  /// The name of the company being advertised in the creative.
  core.String advertiserName;

  /// The agency id for this creative.
  core.String agencyId;

  /// The last upload timestamp of this creative if it was uploaded via API.
  /// Read-only. The value of this field is generated, and will be ignored for
  /// uploads. (formatted RFC 3339 timestamp).
  core.DateTime apiUploadTimestamp;

  /// All attributes for the ads that may be shown from this snippet.
  core.List<core.int> attribute;

  /// A buyer-specific id identifying the creative in this ad.
  core.String buyerCreativeId;

  /// The set of destination urls for the snippet.
  core.List<core.String> clickThroughUrl;

  /// Shows any corrections that were applied to this creative. Read-only. This
  /// field should not be set in requests.
  core.List<CreativeCorrections> corrections;

  /// The reasons for disapproval, if any. Note that not all disapproval reasons
  /// may be categorized, so it is possible for the creative to have a status of
  /// DISAPPROVED with an empty list for disapproval_reasons. In this case,
  /// please reach out to your TAM to help debug the issue. Read-only. This
  /// field should not be set in requests.
  core.List<CreativeDisapprovalReasons> disapprovalReasons;

  /// The filtering reasons for the creative. Read-only. This field should not
  /// be set in requests.
  CreativeFilteringReasons filteringReasons;

  /// Ad height.
  core.int height;

  /// The set of urls to be called to record an impression.
  core.List<core.String> impressionTrackingUrl;

  /// Resource type.
  core.String kind;

  /// If nativeAd is set, HTMLSnippet and videoURL should not be set.
  CreativeNativeAd nativeAd;

  /// Detected product categories, if any. Read-only. This field should not be
  /// set in requests.
  core.List<core.int> productCategories;

  /// All restricted categories for the ads that may be shown from this snippet.
  core.List<core.int> restrictedCategories;

  /// Detected sensitive categories, if any. Read-only. This field should not be
  /// set in requests.
  core.List<core.int> sensitiveCategories;

  /// Creative serving status. Read-only. This field should not be set in
  /// requests.
  core.String status;

  /// All vendor types for the ads that may be shown from this snippet.
  core.List<core.int> vendorType;

  /// The version for this creative. Read-only. This field should not be set in
  /// requests.
  core.int version;

  /// The URL to fetch a video ad. If set, HTMLSnippet and the nativeAd should
  /// not be set.
  core.String videoURL;

  /// Ad width.
  core.int width;

  Creative();

  Creative.fromJson(core.Map _json) {
    if (_json.containsKey('HTMLSnippet')) {
      HTMLSnippet = _json['HTMLSnippet'] as core.String;
    }
    if (_json.containsKey('accountId')) {
      accountId = _json['accountId'] as core.int;
    }
    if (_json.containsKey('adTechnologyProviders')) {
      adTechnologyProviders = CreativeAdTechnologyProviders.fromJson(
          _json['adTechnologyProviders']
              as core.Map<core.String, core.dynamic>);
    }
    if (_json.containsKey('advertiserId')) {
      advertiserId = (_json['advertiserId'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('advertiserName')) {
      advertiserName = _json['advertiserName'] as core.String;
    }
    if (_json.containsKey('agencyId')) {
      agencyId = _json['agencyId'] as core.String;
    }
    if (_json.containsKey('apiUploadTimestamp')) {
      apiUploadTimestamp =
          core.DateTime.parse(_json['apiUploadTimestamp'] as core.String);
    }
    if (_json.containsKey('attribute')) {
      attribute = (_json['attribute'] as core.List)
          .map<core.int>((value) => value as core.int)
          .toList();
    }
    if (_json.containsKey('buyerCreativeId')) {
      buyerCreativeId = _json['buyerCreativeId'] as core.String;
    }
    if (_json.containsKey('clickThroughUrl')) {
      clickThroughUrl = (_json['clickThroughUrl'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('corrections')) {
      corrections = (_json['corrections'] as core.List)
          .map<CreativeCorrections>((value) => CreativeCorrections.fromJson(
              value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('disapprovalReasons')) {
      disapprovalReasons = (_json['disapprovalReasons'] as core.List)
          .map<CreativeDisapprovalReasons>((value) =>
              CreativeDisapprovalReasons.fromJson(
                  value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('filteringReasons')) {
      filteringReasons = CreativeFilteringReasons.fromJson(
          _json['filteringReasons'] as core.Map<core.String, core.dynamic>);
    }
    if (_json.containsKey('height')) {
      height = _json['height'] as core.int;
    }
    if (_json.containsKey('impressionTrackingUrl')) {
      impressionTrackingUrl = (_json['impressionTrackingUrl'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
    if (_json.containsKey('nativeAd')) {
      nativeAd = CreativeNativeAd.fromJson(
          _json['nativeAd'] as core.Map<core.String, core.dynamic>);
    }
    if (_json.containsKey('productCategories')) {
      productCategories = (_json['productCategories'] as core.List)
          .map<core.int>((value) => value as core.int)
          .toList();
    }
    if (_json.containsKey('restrictedCategories')) {
      restrictedCategories = (_json['restrictedCategories'] as core.List)
          .map<core.int>((value) => value as core.int)
          .toList();
    }
    if (_json.containsKey('sensitiveCategories')) {
      sensitiveCategories = (_json['sensitiveCategories'] as core.List)
          .map<core.int>((value) => value as core.int)
          .toList();
    }
    if (_json.containsKey('status')) {
      status = _json['status'] as core.String;
    }
    if (_json.containsKey('vendorType')) {
      vendorType = (_json['vendorType'] as core.List)
          .map<core.int>((value) => value as core.int)
          .toList();
    }
    if (_json.containsKey('version')) {
      version = _json['version'] as core.int;
    }
    if (_json.containsKey('videoURL')) {
      videoURL = _json['videoURL'] as core.String;
    }
    if (_json.containsKey('width')) {
      width = _json['width'] as core.int;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (HTMLSnippet != null) {
      _json['HTMLSnippet'] = HTMLSnippet;
    }
    if (accountId != null) {
      _json['accountId'] = accountId;
    }
    if (adTechnologyProviders != null) {
      _json['adTechnologyProviders'] = adTechnologyProviders.toJson();
    }
    if (advertiserId != null) {
      _json['advertiserId'] = advertiserId;
    }
    if (advertiserName != null) {
      _json['advertiserName'] = advertiserName;
    }
    if (agencyId != null) {
      _json['agencyId'] = agencyId;
    }
    if (apiUploadTimestamp != null) {
      _json['apiUploadTimestamp'] = (apiUploadTimestamp).toIso8601String();
    }
    if (attribute != null) {
      _json['attribute'] = attribute;
    }
    if (buyerCreativeId != null) {
      _json['buyerCreativeId'] = buyerCreativeId;
    }
    if (clickThroughUrl != null) {
      _json['clickThroughUrl'] = clickThroughUrl;
    }
    if (corrections != null) {
      _json['corrections'] =
          corrections.map((value) => value.toJson()).toList();
    }
    if (disapprovalReasons != null) {
      _json['disapprovalReasons'] =
          disapprovalReasons.map((value) => value.toJson()).toList();
    }
    if (filteringReasons != null) {
      _json['filteringReasons'] = filteringReasons.toJson();
    }
    if (height != null) {
      _json['height'] = height;
    }
    if (impressionTrackingUrl != null) {
      _json['impressionTrackingUrl'] = impressionTrackingUrl;
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    if (nativeAd != null) {
      _json['nativeAd'] = nativeAd.toJson();
    }
    if (productCategories != null) {
      _json['productCategories'] = productCategories;
    }
    if (restrictedCategories != null) {
      _json['restrictedCategories'] = restrictedCategories;
    }
    if (sensitiveCategories != null) {
      _json['sensitiveCategories'] = sensitiveCategories;
    }
    if (status != null) {
      _json['status'] = status;
    }
    if (vendorType != null) {
      _json['vendorType'] = vendorType;
    }
    if (version != null) {
      _json['version'] = version;
    }
    if (videoURL != null) {
      _json['videoURL'] = videoURL;
    }
    if (width != null) {
      _json['width'] = width;
    }
    return _json;
  }
}

/// The creatives feed lists the active creatives for the Ad Exchange buyer
/// accounts that the user has access to. Each entry in the feed corresponds to
/// a single creative.
class CreativesList {
  /// A list of creatives.
  core.List<Creative> items;

  /// Resource type.
  core.String kind;

  /// Continuation token used to page through creatives. To retrieve the next
  /// page of results, set the next request's "pageToken" value to this.
  core.String nextPageToken;

  CreativesList();

  CreativesList.fromJson(core.Map _json) {
    if (_json.containsKey('items')) {
      items = (_json['items'] as core.List)
          .map<Creative>((value) =>
              Creative.fromJson(value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
    if (_json.containsKey('nextPageToken')) {
      nextPageToken = _json['nextPageToken'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (items != null) {
      _json['items'] = items.map((value) => value.toJson()).toList();
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    if (nextPageToken != null) {
      _json['nextPageToken'] = nextPageToken;
    }
    return _json;
  }
}

/// The configuration data for an Ad Exchange direct deal.
class DirectDeal {
  /// The account id of the buyer this deal is for.
  core.int accountId;

  /// The name of the advertiser this deal is for.
  core.String advertiser;

  /// Whether the publisher for this deal is eligible for alcohol ads.
  core.bool allowsAlcohol;

  /// The account id that this deal was negotiated for. It is either the buyer
  /// or the client that this deal was negotiated on behalf of.
  core.String buyerAccountId;

  /// The currency code that applies to the fixed_cpm value. If not set then
  /// assumed to be USD.
  core.String currencyCode;

  /// The deal type such as programmatic reservation or fixed price and so on.
  core.String dealTier;

  /// End time for when this deal stops being active. If not set then this deal
  /// is valid until manually disabled by the publisher. In seconds since the
  /// epoch.
  core.String endTime;

  /// The fixed price for this direct deal. In cpm micros of currency according
  /// to currency_code. If set, then this deal is eligible for the fixed price
  /// tier of buying (highest priority, pay exactly the configured fixed price).
  core.String fixedCpm;

  /// Deal id.
  core.String id;

  /// Resource type.
  core.String kind;

  /// Deal name.
  core.String name;

  /// The minimum price for this direct deal. In cpm micros of currency
  /// according to currency_code. If set, then this deal is eligible for the
  /// private exchange tier of buying (below fixed price priority, run as a
  /// second price auction).
  core.String privateExchangeMinCpm;

  /// If true, the publisher has opted to have their blocks ignored when a
  /// creative is bid with for this deal.
  core.bool publisherBlocksOverriden;

  /// The name of the publisher offering this direct deal.
  core.String sellerNetwork;

  /// Start time for when this deal becomes active. If not set then this deal is
  /// active immediately upon creation. In seconds since the epoch.
  core.String startTime;

  DirectDeal();

  DirectDeal.fromJson(core.Map _json) {
    if (_json.containsKey('accountId')) {
      accountId = _json['accountId'] as core.int;
    }
    if (_json.containsKey('advertiser')) {
      advertiser = _json['advertiser'] as core.String;
    }
    if (_json.containsKey('allowsAlcohol')) {
      allowsAlcohol = _json['allowsAlcohol'] as core.bool;
    }
    if (_json.containsKey('buyerAccountId')) {
      buyerAccountId = _json['buyerAccountId'] as core.String;
    }
    if (_json.containsKey('currencyCode')) {
      currencyCode = _json['currencyCode'] as core.String;
    }
    if (_json.containsKey('dealTier')) {
      dealTier = _json['dealTier'] as core.String;
    }
    if (_json.containsKey('endTime')) {
      endTime = _json['endTime'] as core.String;
    }
    if (_json.containsKey('fixedCpm')) {
      fixedCpm = _json['fixedCpm'] as core.String;
    }
    if (_json.containsKey('id')) {
      id = _json['id'] as core.String;
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
    if (_json.containsKey('name')) {
      name = _json['name'] as core.String;
    }
    if (_json.containsKey('privateExchangeMinCpm')) {
      privateExchangeMinCpm = _json['privateExchangeMinCpm'] as core.String;
    }
    if (_json.containsKey('publisherBlocksOverriden')) {
      publisherBlocksOverriden = _json['publisherBlocksOverriden'] as core.bool;
    }
    if (_json.containsKey('sellerNetwork')) {
      sellerNetwork = _json['sellerNetwork'] as core.String;
    }
    if (_json.containsKey('startTime')) {
      startTime = _json['startTime'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (accountId != null) {
      _json['accountId'] = accountId;
    }
    if (advertiser != null) {
      _json['advertiser'] = advertiser;
    }
    if (allowsAlcohol != null) {
      _json['allowsAlcohol'] = allowsAlcohol;
    }
    if (buyerAccountId != null) {
      _json['buyerAccountId'] = buyerAccountId;
    }
    if (currencyCode != null) {
      _json['currencyCode'] = currencyCode;
    }
    if (dealTier != null) {
      _json['dealTier'] = dealTier;
    }
    if (endTime != null) {
      _json['endTime'] = endTime;
    }
    if (fixedCpm != null) {
      _json['fixedCpm'] = fixedCpm;
    }
    if (id != null) {
      _json['id'] = id;
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    if (name != null) {
      _json['name'] = name;
    }
    if (privateExchangeMinCpm != null) {
      _json['privateExchangeMinCpm'] = privateExchangeMinCpm;
    }
    if (publisherBlocksOverriden != null) {
      _json['publisherBlocksOverriden'] = publisherBlocksOverriden;
    }
    if (sellerNetwork != null) {
      _json['sellerNetwork'] = sellerNetwork;
    }
    if (startTime != null) {
      _json['startTime'] = startTime;
    }
    return _json;
  }
}

/// A direct deals feed lists Direct Deals the Ad Exchange buyer account has
/// access to. This includes direct deals set up for the buyer account as well
/// as its merged stream seats.
class DirectDealsList {
  /// A list of direct deals relevant for your account.
  core.List<DirectDeal> directDeals;

  /// Resource type.
  core.String kind;

  DirectDealsList();

  DirectDealsList.fromJson(core.Map _json) {
    if (_json.containsKey('directDeals')) {
      directDeals = (_json['directDeals'] as core.List)
          .map<DirectDeal>((value) =>
              DirectDeal.fromJson(value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (directDeals != null) {
      _json['directDeals'] =
          directDeals.map((value) => value.toJson()).toList();
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    return _json;
  }
}

/// The configuration data for an Ad Exchange performance report list.
class PerformanceReport {
  /// The number of bid responses with an ad.
  core.double bidRate;

  /// The number of bid requests sent to your bidder.
  core.double bidRequestRate;

  /// Rate of various prefiltering statuses per match. Please refer to the
  /// callout-status-codes.txt file for different statuses.
  ///
  /// The values for Object must be JSON objects. It can consist of `num`,
  /// `String`, `bool` and `null` as well as `Map` and `List` values.
  core.List<core.Object> calloutStatusRate;

  /// Average QPS for cookie matcher operations.
  ///
  /// The values for Object must be JSON objects. It can consist of `num`,
  /// `String`, `bool` and `null` as well as `Map` and `List` values.
  core.List<core.Object> cookieMatcherStatusRate;

  /// Rate of ads with a given status. Please refer to the
  /// creative-status-codes.txt file for different statuses.
  ///
  /// The values for Object must be JSON objects. It can consist of `num`,
  /// `String`, `bool` and `null` as well as `Map` and `List` values.
  core.List<core.Object> creativeStatusRate;

  /// The number of bid responses that were filtered due to a policy violation
  /// or other errors.
  core.double filteredBidRate;

  /// Average QPS for hosted match operations.
  ///
  /// The values for Object must be JSON objects. It can consist of `num`,
  /// `String`, `bool` and `null` as well as `Map` and `List` values.
  core.List<core.Object> hostedMatchStatusRate;

  /// The number of potential queries based on your pretargeting settings.
  core.double inventoryMatchRate;

  /// Resource type.
  core.String kind;

  /// The 50th percentile round trip latency(ms) as perceived from Google
  /// servers for the duration period covered by the report.
  core.double latency50thPercentile;

  /// The 85th percentile round trip latency(ms) as perceived from Google
  /// servers for the duration period covered by the report.
  core.double latency85thPercentile;

  /// The 95th percentile round trip latency(ms) as perceived from Google
  /// servers for the duration period covered by the report.
  core.double latency95thPercentile;

  /// Rate of various quota account statuses per quota check.
  core.double noQuotaInRegion;

  /// Rate of various quota account statuses per quota check.
  core.double outOfQuota;

  /// Average QPS for pixel match requests from clients.
  core.double pixelMatchRequests;

  /// Average QPS for pixel match responses from clients.
  core.double pixelMatchResponses;

  /// The configured quota limits for this account.
  core.double quotaConfiguredLimit;

  /// The throttled quota limits for this account.
  core.double quotaThrottledLimit;

  /// The trading location of this data.
  core.String region;

  /// The number of properly formed bid responses received by our servers within
  /// the deadline.
  core.double successfulRequestRate;

  /// The unix timestamp of the starting time of this performance data.
  core.String timestamp;

  /// The number of bid responses that were unsuccessful due to timeouts,
  /// incorrect formatting, etc.
  core.double unsuccessfulRequestRate;

  PerformanceReport();

  PerformanceReport.fromJson(core.Map _json) {
    if (_json.containsKey('bidRate')) {
      bidRate = (_json['bidRate'] as core.num).toDouble();
    }
    if (_json.containsKey('bidRequestRate')) {
      bidRequestRate = (_json['bidRequestRate'] as core.num).toDouble();
    }
    if (_json.containsKey('calloutStatusRate')) {
      calloutStatusRate = (_json['calloutStatusRate'] as core.List)
          .map<core.Object>((value) => value as core.Object)
          .toList();
    }
    if (_json.containsKey('cookieMatcherStatusRate')) {
      cookieMatcherStatusRate = (_json['cookieMatcherStatusRate'] as core.List)
          .map<core.Object>((value) => value as core.Object)
          .toList();
    }
    if (_json.containsKey('creativeStatusRate')) {
      creativeStatusRate = (_json['creativeStatusRate'] as core.List)
          .map<core.Object>((value) => value as core.Object)
          .toList();
    }
    if (_json.containsKey('filteredBidRate')) {
      filteredBidRate = (_json['filteredBidRate'] as core.num).toDouble();
    }
    if (_json.containsKey('hostedMatchStatusRate')) {
      hostedMatchStatusRate = (_json['hostedMatchStatusRate'] as core.List)
          .map<core.Object>((value) => value as core.Object)
          .toList();
    }
    if (_json.containsKey('inventoryMatchRate')) {
      inventoryMatchRate = (_json['inventoryMatchRate'] as core.num).toDouble();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
    if (_json.containsKey('latency50thPercentile')) {
      latency50thPercentile =
          (_json['latency50thPercentile'] as core.num).toDouble();
    }
    if (_json.containsKey('latency85thPercentile')) {
      latency85thPercentile =
          (_json['latency85thPercentile'] as core.num).toDouble();
    }
    if (_json.containsKey('latency95thPercentile')) {
      latency95thPercentile =
          (_json['latency95thPercentile'] as core.num).toDouble();
    }
    if (_json.containsKey('noQuotaInRegion')) {
      noQuotaInRegion = (_json['noQuotaInRegion'] as core.num).toDouble();
    }
    if (_json.containsKey('outOfQuota')) {
      outOfQuota = (_json['outOfQuota'] as core.num).toDouble();
    }
    if (_json.containsKey('pixelMatchRequests')) {
      pixelMatchRequests = (_json['pixelMatchRequests'] as core.num).toDouble();
    }
    if (_json.containsKey('pixelMatchResponses')) {
      pixelMatchResponses =
          (_json['pixelMatchResponses'] as core.num).toDouble();
    }
    if (_json.containsKey('quotaConfiguredLimit')) {
      quotaConfiguredLimit =
          (_json['quotaConfiguredLimit'] as core.num).toDouble();
    }
    if (_json.containsKey('quotaThrottledLimit')) {
      quotaThrottledLimit =
          (_json['quotaThrottledLimit'] as core.num).toDouble();
    }
    if (_json.containsKey('region')) {
      region = _json['region'] as core.String;
    }
    if (_json.containsKey('successfulRequestRate')) {
      successfulRequestRate =
          (_json['successfulRequestRate'] as core.num).toDouble();
    }
    if (_json.containsKey('timestamp')) {
      timestamp = _json['timestamp'] as core.String;
    }
    if (_json.containsKey('unsuccessfulRequestRate')) {
      unsuccessfulRequestRate =
          (_json['unsuccessfulRequestRate'] as core.num).toDouble();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (bidRate != null) {
      _json['bidRate'] = bidRate;
    }
    if (bidRequestRate != null) {
      _json['bidRequestRate'] = bidRequestRate;
    }
    if (calloutStatusRate != null) {
      _json['calloutStatusRate'] = calloutStatusRate;
    }
    if (cookieMatcherStatusRate != null) {
      _json['cookieMatcherStatusRate'] = cookieMatcherStatusRate;
    }
    if (creativeStatusRate != null) {
      _json['creativeStatusRate'] = creativeStatusRate;
    }
    if (filteredBidRate != null) {
      _json['filteredBidRate'] = filteredBidRate;
    }
    if (hostedMatchStatusRate != null) {
      _json['hostedMatchStatusRate'] = hostedMatchStatusRate;
    }
    if (inventoryMatchRate != null) {
      _json['inventoryMatchRate'] = inventoryMatchRate;
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    if (latency50thPercentile != null) {
      _json['latency50thPercentile'] = latency50thPercentile;
    }
    if (latency85thPercentile != null) {
      _json['latency85thPercentile'] = latency85thPercentile;
    }
    if (latency95thPercentile != null) {
      _json['latency95thPercentile'] = latency95thPercentile;
    }
    if (noQuotaInRegion != null) {
      _json['noQuotaInRegion'] = noQuotaInRegion;
    }
    if (outOfQuota != null) {
      _json['outOfQuota'] = outOfQuota;
    }
    if (pixelMatchRequests != null) {
      _json['pixelMatchRequests'] = pixelMatchRequests;
    }
    if (pixelMatchResponses != null) {
      _json['pixelMatchResponses'] = pixelMatchResponses;
    }
    if (quotaConfiguredLimit != null) {
      _json['quotaConfiguredLimit'] = quotaConfiguredLimit;
    }
    if (quotaThrottledLimit != null) {
      _json['quotaThrottledLimit'] = quotaThrottledLimit;
    }
    if (region != null) {
      _json['region'] = region;
    }
    if (successfulRequestRate != null) {
      _json['successfulRequestRate'] = successfulRequestRate;
    }
    if (timestamp != null) {
      _json['timestamp'] = timestamp;
    }
    if (unsuccessfulRequestRate != null) {
      _json['unsuccessfulRequestRate'] = unsuccessfulRequestRate;
    }
    return _json;
  }
}

/// The configuration data for an Ad Exchange performance report list.
class PerformanceReportList {
  /// Resource type.
  core.String kind;

  /// A list of performance reports relevant for the account.
  core.List<PerformanceReport> performanceReport;

  PerformanceReportList();

  PerformanceReportList.fromJson(core.Map _json) {
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
    if (_json.containsKey('performanceReport')) {
      performanceReport = (_json['performanceReport'] as core.List)
          .map<PerformanceReport>((value) => PerformanceReport.fromJson(
              value as core.Map<core.String, core.dynamic>))
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (kind != null) {
      _json['kind'] = kind;
    }
    if (performanceReport != null) {
      _json['performanceReport'] =
          performanceReport.map((value) => value.toJson()).toList();
    }
    return _json;
  }
}

class PretargetingConfigDimensions {
  /// Height in pixels.
  core.String height;

  /// Width in pixels.
  core.String width;

  PretargetingConfigDimensions();

  PretargetingConfigDimensions.fromJson(core.Map _json) {
    if (_json.containsKey('height')) {
      height = _json['height'] as core.String;
    }
    if (_json.containsKey('width')) {
      width = _json['width'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (height != null) {
      _json['height'] = height;
    }
    if (width != null) {
      _json['width'] = width;
    }
    return _json;
  }
}

class PretargetingConfigExcludedPlacements {
  /// The value of the placement. Interpretation depends on the placement type,
  /// e.g. URL for a site placement, channel name for a channel placement, app
  /// id for a mobile app placement.
  core.String token;

  /// The type of the placement.
  core.String type;

  PretargetingConfigExcludedPlacements();

  PretargetingConfigExcludedPlacements.fromJson(core.Map _json) {
    if (_json.containsKey('token')) {
      token = _json['token'] as core.String;
    }
    if (_json.containsKey('type')) {
      type = _json['type'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (token != null) {
      _json['token'] = token;
    }
    if (type != null) {
      _json['type'] = type;
    }
    return _json;
  }
}

class PretargetingConfigPlacements {
  /// The value of the placement. Interpretation depends on the placement type,
  /// e.g. URL for a site placement, channel name for a channel placement, app
  /// id for a mobile app placement.
  core.String token;

  /// The type of the placement.
  core.String type;

  PretargetingConfigPlacements();

  PretargetingConfigPlacements.fromJson(core.Map _json) {
    if (_json.containsKey('token')) {
      token = _json['token'] as core.String;
    }
    if (_json.containsKey('type')) {
      type = _json['type'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (token != null) {
      _json['token'] = token;
    }
    if (type != null) {
      _json['type'] = type;
    }
    return _json;
  }
}

class PretargetingConfig {
  /// The id for billing purposes, provided for reference. Leave this field
  /// blank for insert requests; the id will be generated automatically.
  core.String billingId;

  /// The config id; generated automatically. Leave this field blank for insert
  /// requests.
  core.String configId;

  /// The name of the config. Must be unique. Required for all requests.
  core.String configName;

  /// List must contain exactly one of PRETARGETING_CREATIVE_TYPE_HTML or
  /// PRETARGETING_CREATIVE_TYPE_VIDEO.
  core.List<core.String> creativeType;

  /// Requests which allow one of these (width, height) pairs will match. All
  /// pairs must be supported ad dimensions.
  core.List<PretargetingConfigDimensions> dimensions;

  /// Requests with any of these content labels will not match. Values are from
  /// content-labels.txt in the downloadable files section.
  core.List<core.String> excludedContentLabels;

  /// Requests containing any of these geo criteria ids will not match.
  core.List<core.String> excludedGeoCriteriaIds;

  /// Requests containing any of these placements will not match.
  core.List<PretargetingConfigExcludedPlacements> excludedPlacements;

  /// Requests containing any of these users list ids will not match.
  core.List<core.String> excludedUserLists;

  /// Requests containing any of these vertical ids will not match. Values are
  /// from the publisher-verticals.txt file in the downloadable files section.
  core.List<core.String> excludedVerticals;

  /// Requests containing any of these geo criteria ids will match.
  core.List<core.String> geoCriteriaIds;

  /// Whether this config is active. Required for all requests.
  core.bool isActive;

  /// The kind of the resource, i.e. "adexchangebuyer#pretargetingConfig".
  core.String kind;

  /// Request containing any of these language codes will match.
  core.List<core.String> languages;

  /// The maximum QPS allocated to this pretargeting configuration, used for
  /// pretargeting-level QPS limits. By default, this is not set, which
  /// indicates that there is no QPS limit at the configuration level (a global
  /// or account-level limit may still be imposed).
  core.String maximumQps;

  /// Requests containing any of these mobile carrier ids will match. Values are
  /// from mobile-carriers.csv in the downloadable files section.
  core.List<core.String> mobileCarriers;

  /// Requests containing any of these mobile device ids will match. Values are
  /// from mobile-devices.csv in the downloadable files section.
  core.List<core.String> mobileDevices;

  /// Requests containing any of these mobile operating system version ids will
  /// match. Values are from mobile-os.csv in the downloadable files section.
  core.List<core.String> mobileOperatingSystemVersions;

  /// Requests containing any of these placements will match.
  core.List<PretargetingConfigPlacements> placements;

  /// Requests matching any of these platforms will match. Possible values are
  /// PRETARGETING_PLATFORM_MOBILE, PRETARGETING_PLATFORM_DESKTOP, and
  /// PRETARGETING_PLATFORM_TABLET.
  core.List<core.String> platforms;

  /// Creative attributes should be declared here if all creatives corresponding
  /// to this pretargeting configuration have that creative attribute. Values
  /// are from pretargetable-creative-attributes.txt in the downloadable files
  /// section.
  core.List<core.String> supportedCreativeAttributes;

  /// Requests containing any of these user list ids will match.
  core.List<core.String> userLists;

  /// Requests that allow any of these vendor ids will match. Values are from
  /// vendors.txt in the downloadable files section.
  core.List<core.String> vendorTypes;

  /// Requests containing any of these vertical ids will match.
  core.List<core.String> verticals;

  PretargetingConfig();

  PretargetingConfig.fromJson(core.Map _json) {
    if (_json.containsKey('billingId')) {
      billingId = _json['billingId'] as core.String;
    }
    if (_json.containsKey('configId')) {
      configId = _json['configId'] as core.String;
    }
    if (_json.containsKey('configName')) {
      configName = _json['configName'] as core.String;
    }
    if (_json.containsKey('creativeType')) {
      creativeType = (_json['creativeType'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('dimensions')) {
      dimensions = (_json['dimensions'] as core.List)
          .map<PretargetingConfigDimensions>((value) =>
              PretargetingConfigDimensions.fromJson(
                  value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('excludedContentLabels')) {
      excludedContentLabels = (_json['excludedContentLabels'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('excludedGeoCriteriaIds')) {
      excludedGeoCriteriaIds = (_json['excludedGeoCriteriaIds'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('excludedPlacements')) {
      excludedPlacements = (_json['excludedPlacements'] as core.List)
          .map<PretargetingConfigExcludedPlacements>((value) =>
              PretargetingConfigExcludedPlacements.fromJson(
                  value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('excludedUserLists')) {
      excludedUserLists = (_json['excludedUserLists'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('excludedVerticals')) {
      excludedVerticals = (_json['excludedVerticals'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('geoCriteriaIds')) {
      geoCriteriaIds = (_json['geoCriteriaIds'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('isActive')) {
      isActive = _json['isActive'] as core.bool;
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
    if (_json.containsKey('languages')) {
      languages = (_json['languages'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('maximumQps')) {
      maximumQps = _json['maximumQps'] as core.String;
    }
    if (_json.containsKey('mobileCarriers')) {
      mobileCarriers = (_json['mobileCarriers'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('mobileDevices')) {
      mobileDevices = (_json['mobileDevices'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('mobileOperatingSystemVersions')) {
      mobileOperatingSystemVersions =
          (_json['mobileOperatingSystemVersions'] as core.List)
              .map<core.String>((value) => value as core.String)
              .toList();
    }
    if (_json.containsKey('placements')) {
      placements = (_json['placements'] as core.List)
          .map<PretargetingConfigPlacements>((value) =>
              PretargetingConfigPlacements.fromJson(
                  value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('platforms')) {
      platforms = (_json['platforms'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('supportedCreativeAttributes')) {
      supportedCreativeAttributes =
          (_json['supportedCreativeAttributes'] as core.List)
              .map<core.String>((value) => value as core.String)
              .toList();
    }
    if (_json.containsKey('userLists')) {
      userLists = (_json['userLists'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('vendorTypes')) {
      vendorTypes = (_json['vendorTypes'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
    if (_json.containsKey('verticals')) {
      verticals = (_json['verticals'] as core.List)
          .map<core.String>((value) => value as core.String)
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (billingId != null) {
      _json['billingId'] = billingId;
    }
    if (configId != null) {
      _json['configId'] = configId;
    }
    if (configName != null) {
      _json['configName'] = configName;
    }
    if (creativeType != null) {
      _json['creativeType'] = creativeType;
    }
    if (dimensions != null) {
      _json['dimensions'] = dimensions.map((value) => value.toJson()).toList();
    }
    if (excludedContentLabels != null) {
      _json['excludedContentLabels'] = excludedContentLabels;
    }
    if (excludedGeoCriteriaIds != null) {
      _json['excludedGeoCriteriaIds'] = excludedGeoCriteriaIds;
    }
    if (excludedPlacements != null) {
      _json['excludedPlacements'] =
          excludedPlacements.map((value) => value.toJson()).toList();
    }
    if (excludedUserLists != null) {
      _json['excludedUserLists'] = excludedUserLists;
    }
    if (excludedVerticals != null) {
      _json['excludedVerticals'] = excludedVerticals;
    }
    if (geoCriteriaIds != null) {
      _json['geoCriteriaIds'] = geoCriteriaIds;
    }
    if (isActive != null) {
      _json['isActive'] = isActive;
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    if (languages != null) {
      _json['languages'] = languages;
    }
    if (maximumQps != null) {
      _json['maximumQps'] = maximumQps;
    }
    if (mobileCarriers != null) {
      _json['mobileCarriers'] = mobileCarriers;
    }
    if (mobileDevices != null) {
      _json['mobileDevices'] = mobileDevices;
    }
    if (mobileOperatingSystemVersions != null) {
      _json['mobileOperatingSystemVersions'] = mobileOperatingSystemVersions;
    }
    if (placements != null) {
      _json['placements'] = placements.map((value) => value.toJson()).toList();
    }
    if (platforms != null) {
      _json['platforms'] = platforms;
    }
    if (supportedCreativeAttributes != null) {
      _json['supportedCreativeAttributes'] = supportedCreativeAttributes;
    }
    if (userLists != null) {
      _json['userLists'] = userLists;
    }
    if (vendorTypes != null) {
      _json['vendorTypes'] = vendorTypes;
    }
    if (verticals != null) {
      _json['verticals'] = verticals;
    }
    return _json;
  }
}

class PretargetingConfigList {
  /// A list of pretargeting configs
  core.List<PretargetingConfig> items;

  /// Resource type.
  core.String kind;

  PretargetingConfigList();

  PretargetingConfigList.fromJson(core.Map _json) {
    if (_json.containsKey('items')) {
      items = (_json['items'] as core.List)
          .map<PretargetingConfig>((value) => PretargetingConfig.fromJson(
              value as core.Map<core.String, core.dynamic>))
          .toList();
    }
    if (_json.containsKey('kind')) {
      kind = _json['kind'] as core.String;
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (items != null) {
      _json['items'] = items.map((value) => value.toJson()).toList();
    }
    if (kind != null) {
      _json['kind'] = kind;
    }
    return _json;
  }
}
