// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package slides provides access to the Google Slides API.
//
// For product documentation, see: https://developers.google.com/slides/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/slides/v1"
//   ...
//   ctx := context.Background()
//   slidesService, err := slides.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   slidesService, err := slides.NewService(ctx, option.WithScopes(slides.SpreadsheetsReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   slidesService, err := slides.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   slidesService, err := slides.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package slides // import "google.golang.org/api/slides/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "slides:v1"
const apiName = "slides"
const apiVersion = "v1"
const basePath = "https://slides.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, edit, create, and delete all of your Google Drive files
	DriveScope = "https://www.googleapis.com/auth/drive"

	// View and manage Google Drive files and folders that you have opened
	// or created with this app
	DriveFileScope = "https://www.googleapis.com/auth/drive.file"

	// See and download all your Google Drive files
	DriveReadonlyScope = "https://www.googleapis.com/auth/drive.readonly"

	// View and manage your Google Slides presentations
	PresentationsScope = "https://www.googleapis.com/auth/presentations"

	// View your Google Slides presentations
	PresentationsReadonlyScope = "https://www.googleapis.com/auth/presentations.readonly"

	// See, edit, create, and delete your spreadsheets in Google Drive
	SpreadsheetsScope = "https://www.googleapis.com/auth/spreadsheets"

	// View your Google Spreadsheets
	SpreadsheetsReadonlyScope = "https://www.googleapis.com/auth/spreadsheets.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/drive",
		"https://www.googleapis.com/auth/drive.file",
		"https://www.googleapis.com/auth/drive.readonly",
		"https://www.googleapis.com/auth/presentations",
		"https://www.googleapis.com/auth/presentations.readonly",
		"https://www.googleapis.com/auth/spreadsheets",
		"https://www.googleapis.com/auth/spreadsheets.readonly",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Presentations = NewPresentationsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Presentations *PresentationsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewPresentationsService(s *Service) *PresentationsService {
	rs := &PresentationsService{s: s}
	rs.Pages = NewPresentationsPagesService(s)
	return rs
}

type PresentationsService struct {
	s *Service

	Pages *PresentationsPagesService
}

func NewPresentationsPagesService(s *Service) *PresentationsPagesService {
	rs := &PresentationsPagesService{s: s}
	return rs
}

type PresentationsPagesService struct {
	s *Service
}

// AffineTransform: AffineTransform uses a 3x3 matrix with an implied
// last row of [ 0 0 1 ]
// to transform source coordinates (x,y) into destination coordinates
// (x', y')
// according to:
//
//       x'  x  =   shear_y  scale_y  translate_y
//       1  [ 1 ]
//
// After transformation,
//
//      x' = scale_x * x + shear_x * y + translate_x;
//      y' = scale_y * y + shear_y * x + translate_y;
//
// This message is therefore composed of these six matrix elements.
type AffineTransform struct {
	// ScaleX: The X coordinate scaling element.
	ScaleX float64 `json:"scaleX,omitempty"`

	// ScaleY: The Y coordinate scaling element.
	ScaleY float64 `json:"scaleY,omitempty"`

	// ShearX: The X coordinate shearing element.
	ShearX float64 `json:"shearX,omitempty"`

	// ShearY: The Y coordinate shearing element.
	ShearY float64 `json:"shearY,omitempty"`

	// TranslateX: The X coordinate translation element.
	TranslateX float64 `json:"translateX,omitempty"`

	// TranslateY: The Y coordinate translation element.
	TranslateY float64 `json:"translateY,omitempty"`

	// Unit: The units for translate elements.
	//
	// Possible values:
	//   "UNIT_UNSPECIFIED" - The units are unknown.
	//   "EMU" - An English Metric Unit (EMU) is defined as 1/360,000 of a
	// centimeter
	// and thus there are 914,400 EMUs per inch, and 12,700 EMUs per point.
	//   "PT" - A point, 1/72 of an inch.
	Unit string `json:"unit,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ScaleX") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ScaleX") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AffineTransform) MarshalJSON() ([]byte, error) {
	type NoMethod AffineTransform
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *AffineTransform) UnmarshalJSON(data []byte) error {
	type NoMethod AffineTransform
	var s1 struct {
		ScaleX     gensupport.JSONFloat64 `json:"scaleX"`
		ScaleY     gensupport.JSONFloat64 `json:"scaleY"`
		ShearX     gensupport.JSONFloat64 `json:"shearX"`
		ShearY     gensupport.JSONFloat64 `json:"shearY"`
		TranslateX gensupport.JSONFloat64 `json:"translateX"`
		TranslateY gensupport.JSONFloat64 `json:"translateY"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ScaleX = float64(s1.ScaleX)
	s.ScaleY = float64(s1.ScaleY)
	s.ShearX = float64(s1.ShearX)
	s.ShearY = float64(s1.ShearY)
	s.TranslateX = float64(s1.TranslateX)
	s.TranslateY = float64(s1.TranslateY)
	return nil
}

// AutoText: A TextElement kind that represents auto text.
type AutoText struct {
	// Content: The rendered content of this auto text, if available.
	Content string `json:"content,omitempty"`

	// Style: The styling applied to this auto text.
	Style *TextStyle `json:"style,omitempty"`

	// Type: The type of this auto text.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - An unspecified autotext type.
	//   "SLIDE_NUMBER" - Type for autotext that represents the current
	// slide number.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Content") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Content") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoText) MarshalJSON() ([]byte, error) {
	type NoMethod AutoText
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BatchUpdatePresentationRequest: Request message for
// PresentationsService.BatchUpdatePresentation.
type BatchUpdatePresentationRequest struct {
	// Requests: A list of updates to apply to the presentation.
	Requests []*Request `json:"requests,omitempty"`

	// WriteControl: Provides control over how write requests are executed.
	WriteControl *WriteControl `json:"writeControl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Requests") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Requests") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BatchUpdatePresentationRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BatchUpdatePresentationRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BatchUpdatePresentationResponse: Response message from a batch
// update.
type BatchUpdatePresentationResponse struct {
	// PresentationId: The presentation the updates were applied to.
	PresentationId string `json:"presentationId,omitempty"`

	// Replies: The reply of the updates.  This maps 1:1 with the updates,
	// although
	// replies to some requests may be empty.
	Replies []*Response `json:"replies,omitempty"`

	// WriteControl: The updated write control after applying the request.
	WriteControl *WriteControl `json:"writeControl,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "PresentationId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PresentationId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *BatchUpdatePresentationResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BatchUpdatePresentationResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Bullet: Describes the bullet of a paragraph.
type Bullet struct {
	// BulletStyle: The paragraph specific text style applied to this
	// bullet.
	BulletStyle *TextStyle `json:"bulletStyle,omitempty"`

	// Glyph: The rendered bullet glyph for this paragraph.
	Glyph string `json:"glyph,omitempty"`

	// ListId: The ID of the list this paragraph belongs to.
	ListId string `json:"listId,omitempty"`

	// NestingLevel: The nesting level of this paragraph in the list.
	NestingLevel int64 `json:"nestingLevel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BulletStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BulletStyle") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Bullet) MarshalJSON() ([]byte, error) {
	type NoMethod Bullet
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ColorScheme: The palette of predefined colors for a page.
type ColorScheme struct {
	// Colors: The ThemeColorType and corresponding concrete color pairs.
	Colors []*ThemeColorPair `json:"colors,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Colors") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Colors") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ColorScheme) MarshalJSON() ([]byte, error) {
	type NoMethod ColorScheme
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ColorStop: A color and position in a gradient band.
type ColorStop struct {
	// Alpha: The alpha value of this color in the gradient band. Defaults
	// to 1.0,
	// fully opaque.
	Alpha float64 `json:"alpha,omitempty"`

	// Color: The color of the gradient stop.
	Color *OpaqueColor `json:"color,omitempty"`

	// Position: The relative position of the color stop in the gradient
	// band measured
	// in percentage. The value should be in the interval [0.0, 1.0].
	Position float64 `json:"position,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alpha") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alpha") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ColorStop) MarshalJSON() ([]byte, error) {
	type NoMethod ColorStop
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ColorStop) UnmarshalJSON(data []byte) error {
	type NoMethod ColorStop
	var s1 struct {
		Alpha    gensupport.JSONFloat64 `json:"alpha"`
		Position gensupport.JSONFloat64 `json:"position"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	s.Position = float64(s1.Position)
	return nil
}

// CreateImageRequest: Creates an image.
type CreateImageRequest struct {
	// ElementProperties: The element properties for the image.
	//
	// When the aspect ratio of the provided size does not match the image
	// aspect
	// ratio, the image is scaled and centered with respect to the size in
	// order
	// to maintain aspect ratio. The provided transform is applied after
	// this
	// operation.
	//
	// The PageElementProperties.size property is
	// optional. If you don't specify the size, the default size of the
	// image is
	// used.
	//
	// The PageElementProperties.transform property is
	// optional. If you don't specify a transform, the image will be placed
	// at the
	// top left corner of the page.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// Url: The image URL.
	//
	// The image is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Images must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length. The URL itself is
	// saved
	// with the image, and exposed via the Image.source_url field.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ElementProperties")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ElementProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateImageRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateImageRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateImageResponse: The result of creating an image.
type CreateImageResponse struct {
	// ObjectId: The object ID of the created image.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateImageResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateImageResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateLineRequest: Creates a line.
type CreateLineRequest struct {
	// Category: The category of the line to be created.
	//
	// The exact line type created is
	// determined based on the category and how it's routed to connect to
	// other
	// page elements.
	//
	// If you specify both a `category` and a `line_category`, the
	// `category`
	// takes precedence.
	//
	// If you do not specify a value for `category`, but specify a value
	// for
	// `line_category`, then the specified `line_category` value is
	// used.
	//
	// If you do not specify either, then STRAIGHT is used.
	//
	// Possible values:
	//   "LINE_CATEGORY_UNSPECIFIED" - Unspecified line category.
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	Category string `json:"category,omitempty"`

	// ElementProperties: The element properties for the line.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// LineCategory: The category of the line to be
	// created.
	//
	// <b>Deprecated</b>: use `category` instead.
	//
	// The exact line type created is
	// determined based on the category and how it's routed to connect to
	// other
	// page elements.
	//
	// If you specify both a `category` and a `line_category`, the
	// `category`
	// takes precedence.
	//
	// Possible values:
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	// The is the default
	// category when one is not specified.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	LineCategory string `json:"lineCategory,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Category") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Category") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateLineRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateLineRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateLineResponse: The result of creating a line.
type CreateLineResponse struct {
	// ObjectId: The object ID of the created line.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateLineResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateLineResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateParagraphBulletsRequest: Creates bullets for all of the
// paragraphs that overlap with the given
// text index range.
//
// The nesting level of each paragraph will be determined by counting
// leading
// tabs in front of each paragraph. To avoid excess space between the
// bullet and
// the corresponding paragraph, these leading tabs are removed by this
// request.
// This may change the indices of parts of the text.
//
// If the paragraph immediately before paragraphs being updated is in a
// list
// with a matching preset, the paragraphs being updated are added to
// that
// preceding list.
type CreateParagraphBulletsRequest struct {
	// BulletPreset: The kinds of bullet glyphs to be used. Defaults to
	// the
	// `BULLET_DISC_CIRCLE_SQUARE` preset.
	//
	// Possible values:
	//   "BULLET_DISC_CIRCLE_SQUARE" - A bulleted list with a `DISC`,
	// `CIRCLE` and `SQUARE` bullet glyph for the
	// first 3 list nesting levels.
	//   "BULLET_DIAMONDX_ARROW3D_SQUARE" - A bulleted list with a
	// `DIAMONDX`, `ARROW3D` and `SQUARE` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_CHECKBOX" - A bulleted list with `CHECKBOX` bullet glyphs
	// for all list nesting levels.
	//   "BULLET_ARROW_DIAMOND_DISC" - A bulleted list with a `ARROW`,
	// `DIAMOND` and `DISC` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_STAR_CIRCLE_SQUARE" - A bulleted list with a `STAR`,
	// `CIRCLE` and `SQUARE` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_ARROW3D_CIRCLE_SQUARE" - A bulleted list with a `ARROW3D`,
	// `CIRCLE` and `SQUARE` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_LEFTTRIANGLE_DIAMOND_DISC" - A bulleted list with a
	// `LEFTTRIANGLE`, `DIAMOND` and `DISC` bullet glyph
	// for the first 3 list nesting levels.
	//   "BULLET_DIAMONDX_HOLLOWDIAMOND_SQUARE" - A bulleted list with a
	// `DIAMONDX`, `HOLLOWDIAMOND` and `SQUARE` bullet
	// glyph for the first 3 list nesting levels.
	//   "BULLET_DIAMOND_CIRCLE_SQUARE" - A bulleted list with a `DIAMOND`,
	// `CIRCLE` and `SQUARE` bullet glyph
	// for the first 3 list nesting levels.
	//   "NUMBERED_DIGIT_ALPHA_ROMAN" - A numbered list with `DIGIT`,
	// `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by periods.
	//   "NUMBERED_DIGIT_ALPHA_ROMAN_PARENS" - A numbered list with `DIGIT`,
	// `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by parenthesis.
	//   "NUMBERED_DIGIT_NESTED" - A numbered list with `DIGIT` numeric
	// glyphs separated by periods, where
	// each nesting level uses the previous nesting level's glyph as a
	// prefix.
	// For example: '1.', '1.1.', '2.', '2.2.'.
	//   "NUMBERED_UPPERALPHA_ALPHA_ROMAN" - A numbered list with
	// `UPPERALPHA`, `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by periods.
	//   "NUMBERED_UPPERROMAN_UPPERALPHA_DIGIT" - A numbered list with
	// `UPPERROMAN`, `UPPERALPHA` and `DIGIT` numeric glyphs
	// for the first 3 list nesting levels, followed by periods.
	//   "NUMBERED_ZERODIGIT_ALPHA_ROMAN" - A numbered list with
	// `ZERODIGIT`, `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by periods.
	BulletPreset string `json:"bulletPreset,omitempty"`

	// CellLocation: The optional table cell location if the text to be
	// modified is in a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// ObjectId: The object ID of the shape or table containing the text to
	// add bullets to.
	ObjectId string `json:"objectId,omitempty"`

	// TextRange: The range of text to apply the bullet presets to, based on
	// TextElement indexes.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BulletPreset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BulletPreset") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateParagraphBulletsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateParagraphBulletsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateShapeRequest: Creates a new shape.
type CreateShapeRequest struct {
	// ElementProperties: The element properties for the shape.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	// If empty, a unique identifier will be generated.
	ObjectId string `json:"objectId,omitempty"`

	// ShapeType: The shape type.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The shape type that is not predefined.
	//   "TEXT_BOX" - Text box shape.
	//   "RECTANGLE" - Rectangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'rect'.
	//   "ROUND_RECTANGLE" - Round corner rectangle shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'roundRect'
	//   "ELLIPSE" - Ellipse shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ellipse'
	//   "ARC" - Curved arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'arc'
	//   "BENT_ARROW" - Bent arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentArrow'
	//   "BENT_UP_ARROW" - Bent up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentUpArrow'
	//   "BEVEL" - Bevel shape. Corresponds to ECMA-376 ST_ShapeType 'bevel'
	//   "BLOCK_ARC" - Block arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'blockArc'
	//   "BRACE_PAIR" - Brace pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracePair'
	//   "BRACKET_PAIR" - Bracket pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracketPair'
	//   "CAN" - Can shape. Corresponds to ECMA-376 ST_ShapeType 'can'
	//   "CHEVRON" - Chevron shape. Corresponds to ECMA-376 ST_ShapeType
	// 'chevron'
	//   "CHORD" - Chord shape. Corresponds to ECMA-376 ST_ShapeType 'chord'
	//   "CLOUD" - Cloud shape. Corresponds to ECMA-376 ST_ShapeType 'cloud'
	//   "CORNER" - Corner shape. Corresponds to ECMA-376 ST_ShapeType
	// 'corner'
	//   "CUBE" - Cube shape. Corresponds to ECMA-376 ST_ShapeType 'cube'
	//   "CURVED_DOWN_ARROW" - Curved down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedDownArrow'
	//   "CURVED_LEFT_ARROW" - Curved left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedLeftArrow'
	//   "CURVED_RIGHT_ARROW" - Curved right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedRightArrow'
	//   "CURVED_UP_ARROW" - Curved up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'curvedUpArrow'
	//   "DECAGON" - Decagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'decagon'
	//   "DIAGONAL_STRIPE" - Diagonal stripe shape. Corresponds to ECMA-376
	// ST_ShapeType 'diagStripe'
	//   "DIAMOND" - Diamond shape. Corresponds to ECMA-376 ST_ShapeType
	// 'diamond'
	//   "DODECAGON" - Dodecagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'dodecagon'
	//   "DONUT" - Donut shape. Corresponds to ECMA-376 ST_ShapeType 'donut'
	//   "DOUBLE_WAVE" - Double wave shape. Corresponds to ECMA-376
	// ST_ShapeType 'doubleWave'
	//   "DOWN_ARROW" - Down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'downArrow'
	//   "DOWN_ARROW_CALLOUT" - Callout down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'downArrowCallout'
	//   "FOLDED_CORNER" - Folded corner shape. Corresponds to ECMA-376
	// ST_ShapeType 'foldedCorner'
	//   "FRAME" - Frame shape. Corresponds to ECMA-376 ST_ShapeType 'frame'
	//   "HALF_FRAME" - Half frame shape. Corresponds to ECMA-376
	// ST_ShapeType 'halfFrame'
	//   "HEART" - Heart shape. Corresponds to ECMA-376 ST_ShapeType 'heart'
	//   "HEPTAGON" - Heptagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'heptagon'
	//   "HEXAGON" - Hexagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'hexagon'
	//   "HOME_PLATE" - Home plate shape. Corresponds to ECMA-376
	// ST_ShapeType 'homePlate'
	//   "HORIZONTAL_SCROLL" - Horizontal scroll shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'horizontalScroll'
	//   "IRREGULAR_SEAL_1" - Irregular seal 1 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal1'
	//   "IRREGULAR_SEAL_2" - Irregular seal 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal2'
	//   "LEFT_ARROW" - Left arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftArrow'
	//   "LEFT_ARROW_CALLOUT" - Callout left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftArrowCallout'
	//   "LEFT_BRACE" - Left brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBrace'
	//   "LEFT_BRACKET" - Left bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBracket'
	//   "LEFT_RIGHT_ARROW" - Left right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightArrow'
	//   "LEFT_RIGHT_ARROW_CALLOUT" - Callout left right arrow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'leftRightArrowCallout'
	//   "LEFT_RIGHT_UP_ARROW" - Left right up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightUpArrow'
	//   "LEFT_UP_ARROW" - Left up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftUpArrow'
	//   "LIGHTNING_BOLT" - Lightning bolt shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'lightningBolt'
	//   "MATH_DIVIDE" - Divide math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathDivide'
	//   "MATH_EQUAL" - Equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathEqual'
	//   "MATH_MINUS" - Minus math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMinus'
	//   "MATH_MULTIPLY" - Multiply math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMultiply'
	//   "MATH_NOT_EQUAL" - Not equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathNotEqual'
	//   "MATH_PLUS" - Plus math shape. Corresponds to ECMA-376 ST_ShapeType
	// 'mathPlus'
	//   "MOON" - Moon shape. Corresponds to ECMA-376 ST_ShapeType 'moon'
	//   "NO_SMOKING" - No smoking shape. Corresponds to ECMA-376
	// ST_ShapeType 'noSmoking'
	//   "NOTCHED_RIGHT_ARROW" - Notched right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'notchedRightArrow'
	//   "OCTAGON" - Octagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'octagon'
	//   "PARALLELOGRAM" - Parallelogram shape. Corresponds to ECMA-376
	// ST_ShapeType 'parallelogram'
	//   "PENTAGON" - Pentagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'pentagon'
	//   "PIE" - Pie shape. Corresponds to ECMA-376 ST_ShapeType 'pie'
	//   "PLAQUE" - Plaque shape. Corresponds to ECMA-376 ST_ShapeType
	// 'plaque'
	//   "PLUS" - Plus shape. Corresponds to ECMA-376 ST_ShapeType 'plus'
	//   "QUAD_ARROW" - Quad-arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'quadArrow'
	//   "QUAD_ARROW_CALLOUT" - Callout quad-arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'quadArrowCallout'
	//   "RIBBON" - Ribbon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon'
	//   "RIBBON_2" - Ribbon 2 shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon2'
	//   "RIGHT_ARROW" - Right arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightArrow'
	//   "RIGHT_ARROW_CALLOUT" - Callout right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'rightArrowCallout'
	//   "RIGHT_BRACE" - Right brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBrace'
	//   "RIGHT_BRACKET" - Right bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBracket'
	//   "ROUND_1_RECTANGLE" - One round corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'round1Rect'
	//   "ROUND_2_DIAGONAL_RECTANGLE" - Two diagonal round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2DiagRect'
	//   "ROUND_2_SAME_RECTANGLE" - Two same-side round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2SameRect'
	//   "RIGHT_TRIANGLE" - Right triangle shape. Corresponds to ECMA-376
	// ST_ShapeType 'rtTriangle'
	//   "SMILEY_FACE" - Smiley face shape. Corresponds to ECMA-376
	// ST_ShapeType 'smileyFace'
	//   "SNIP_1_RECTANGLE" - One snip corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'snip1Rect'
	//   "SNIP_2_DIAGONAL_RECTANGLE" - Two diagonal snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2DiagRect'
	//   "SNIP_2_SAME_RECTANGLE" - Two same-side snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2SameRect'
	//   "SNIP_ROUND_RECTANGLE" - One snip one round corner rectangle shape.
	// Corresponds to ECMA-376
	// ST_ShapeType 'snipRoundRect'
	//   "STAR_10" - Ten pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star10'
	//   "STAR_12" - Twelve pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star12'
	//   "STAR_16" - Sixteen pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star16'
	//   "STAR_24" - Twenty four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star24'
	//   "STAR_32" - Thirty two pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star32'
	//   "STAR_4" - Four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star4'
	//   "STAR_5" - Five pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star5'
	//   "STAR_6" - Six pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star6'
	//   "STAR_7" - Seven pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star7'
	//   "STAR_8" - Eight pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star8'
	//   "STRIPED_RIGHT_ARROW" - Striped right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'stripedRightArrow'
	//   "SUN" - Sun shape. Corresponds to ECMA-376 ST_ShapeType 'sun'
	//   "TRAPEZOID" - Trapezoid shape. Corresponds to ECMA-376 ST_ShapeType
	// 'trapezoid'
	//   "TRIANGLE" - Triangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'triangle'
	//   "UP_ARROW" - Up arrow shape. Corresponds to ECMA-376 ST_ShapeType
	// 'upArrow'
	//   "UP_ARROW_CALLOUT" - Callout up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'upArrowCallout'
	//   "UP_DOWN_ARROW" - Up down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'upDownArrow'
	//   "UTURN_ARROW" - U-turn arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'uturnArrow'
	//   "VERTICAL_SCROLL" - Vertical scroll shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'verticalScroll'
	//   "WAVE" - Wave shape. Corresponds to ECMA-376 ST_ShapeType 'wave'
	//   "WEDGE_ELLIPSE_CALLOUT" - Callout wedge ellipse shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'wedgeEllipseCallout'
	//   "WEDGE_RECTANGLE_CALLOUT" - Callout wedge rectangle shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRectCallout'
	//   "WEDGE_ROUND_RECTANGLE_CALLOUT" - Callout wedge round rectangle
	// shape. Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRoundRectCallout'
	//   "FLOW_CHART_ALTERNATE_PROCESS" - Alternate process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartAlternateProcess'
	//   "FLOW_CHART_COLLATE" - Collate flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartCollate'
	//   "FLOW_CHART_CONNECTOR" - Connector flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartConnector'
	//   "FLOW_CHART_DECISION" - Decision flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDecision'
	//   "FLOW_CHART_DELAY" - Delay flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartDelay'
	//   "FLOW_CHART_DISPLAY" - Display flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartDisplay'
	//   "FLOW_CHART_DOCUMENT" - Document flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDocument'
	//   "FLOW_CHART_EXTRACT" - Extract flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartExtract'
	//   "FLOW_CHART_INPUT_OUTPUT" - Input output flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartInputOutput'
	//   "FLOW_CHART_INTERNAL_STORAGE" - Internal storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartInternalStorage'
	//   "FLOW_CHART_MAGNETIC_DISK" - Magnetic disk flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDisk'
	//   "FLOW_CHART_MAGNETIC_DRUM" - Magnetic drum flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDrum'
	//   "FLOW_CHART_MAGNETIC_TAPE" - Magnetic tape flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticTape'
	//   "FLOW_CHART_MANUAL_INPUT" - Manual input flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartManualInput'
	//   "FLOW_CHART_MANUAL_OPERATION" - Manual operation flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartManualOperation'
	//   "FLOW_CHART_MERGE" - Merge flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartMerge'
	//   "FLOW_CHART_MULTIDOCUMENT" - Multi-document flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMultidocument'
	//   "FLOW_CHART_OFFLINE_STORAGE" - Offline storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOfflineStorage'
	//   "FLOW_CHART_OFFPAGE_CONNECTOR" - Off-page connector flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOffpageConnector'
	//   "FLOW_CHART_ONLINE_STORAGE" - Online storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOnlineStorage'
	//   "FLOW_CHART_OR" - Or flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartOr'
	//   "FLOW_CHART_PREDEFINED_PROCESS" - Predefined process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartPredefinedProcess'
	//   "FLOW_CHART_PREPARATION" - Preparation flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPreparation'
	//   "FLOW_CHART_PROCESS" - Process flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartProcess'
	//   "FLOW_CHART_PUNCHED_CARD" - Punched card flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedCard'
	//   "FLOW_CHART_PUNCHED_TAPE" - Punched tape flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedTape'
	//   "FLOW_CHART_SORT" - Sort flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartSort'
	//   "FLOW_CHART_SUMMING_JUNCTION" - Summing junction flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartSummingJunction'
	//   "FLOW_CHART_TERMINATOR" - Terminator flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartTerminator'
	//   "ARROW_EAST" - East arrow shape.
	//   "ARROW_NORTH_EAST" - Northeast arrow shape.
	//   "ARROW_NORTH" - North arrow shape.
	//   "SPEECH" - Speech shape.
	//   "STARBURST" - Star burst shape.
	//   "TEARDROP" - Teardrop shape. Corresponds to ECMA-376 ST_ShapeType
	// 'teardrop'
	//   "ELLIPSE_RIBBON" - Ellipse ribbon shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'ellipseRibbon'
	//   "ELLIPSE_RIBBON_2" - Ellipse ribbon 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'ellipseRibbon2'
	//   "CLOUD_CALLOUT" - Callout cloud shape. Corresponds to ECMA-376
	// ST_ShapeType 'cloudCallout'
	//   "CUSTOM" - Custom shape.
	ShapeType string `json:"shapeType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ElementProperties")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ElementProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateShapeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateShapeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateShapeResponse: The result of creating a shape.
type CreateShapeResponse struct {
	// ObjectId: The object ID of the created shape.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateShapeResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateShapeResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSheetsChartRequest: Creates an embedded Google Sheets
// chart.
//
// NOTE: Chart creation requires at least one of the
// spreadsheets.readonly,
// spreadsheets, drive.readonly, drive.file, or drive OAuth scopes.
type CreateSheetsChartRequest struct {
	// ChartId: The ID of the specific chart in the Google Sheets
	// spreadsheet.
	ChartId int64 `json:"chartId,omitempty"`

	// ElementProperties: The element properties for the chart.
	//
	// When the aspect ratio of the provided size does not match the chart
	// aspect
	// ratio, the chart is scaled and centered with respect to the size in
	// order
	// to maintain aspect ratio. The provided transform is applied after
	// this
	// operation.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// LinkingMode: The mode with which the chart is linked to the source
	// spreadsheet. When
	// not specified, the chart will be an image that is not linked.
	//
	// Possible values:
	//   "NOT_LINKED_IMAGE" - The chart is not associated with the source
	// spreadsheet and cannot be
	// updated. A chart that is not linked will be inserted as an image.
	//   "LINKED" - Linking the chart allows it to be updated, and other
	// collaborators will
	// see a link to the spreadsheet.
	LinkingMode string `json:"linkingMode,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If specified, the ID must be unique among all pages and page elements
	// in
	// the presentation. The ID should start with a word character
	// [a-zA-Z0-9_]
	// and then followed by any number of the following characters
	// [a-zA-Z0-9_-:].
	// The length of the ID should not be less than 5 or greater than 50.
	// If empty, a unique identifier will be generated.
	ObjectId string `json:"objectId,omitempty"`

	// SpreadsheetId: The ID of the Google Sheets spreadsheet that contains
	// the chart.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChartId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateSheetsChartRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSheetsChartRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSheetsChartResponse: The result of creating an embedded Google
// Sheets chart.
type CreateSheetsChartResponse struct {
	// ObjectId: The object ID of the created chart.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateSheetsChartResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSheetsChartResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSlideRequest: Creates a new slide.
type CreateSlideRequest struct {
	// InsertionIndex: The optional zero-based index indicating where to
	// insert the slides.
	//
	// If you don't specify an index, the new slide is created at the end.
	InsertionIndex int64 `json:"insertionIndex,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// PlaceholderIdMappings: An optional list of object ID mappings from
	// the placeholder(s) on the layout to the placeholder(s)
	// that will be created on the new slide from that specified layout. Can
	// only
	// be used when `slide_layout_reference` is specified.
	PlaceholderIdMappings []*LayoutPlaceholderIdMapping `json:"placeholderIdMappings,omitempty"`

	// SlideLayoutReference: Layout reference of the slide to be inserted,
	// based on the *current
	// master*, which is one of the following:
	//
	// - The master of the previous slide index.
	// - The master of the first slide, if the insertion_index is zero.
	// - The first master in the presentation, if there are no slides.
	//
	// If the LayoutReference is not found in the current master, a 400
	// bad
	// request error is returned.
	//
	// If you don't specify a layout reference, then the new slide will use
	// the
	// predefined layout `BLANK`.
	SlideLayoutReference *LayoutReference `json:"slideLayoutReference,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InsertionIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InsertionIndex") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateSlideRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSlideRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSlideResponse: The result of creating a slide.
type CreateSlideResponse struct {
	// ObjectId: The object ID of the created slide.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateSlideResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSlideResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateTableRequest: Creates a new table.
type CreateTableRequest struct {
	// Columns: Number of columns in the table.
	Columns int64 `json:"columns,omitempty"`

	// ElementProperties: The element properties for the table.
	//
	// The table will be created at the provided size, subject to a minimum
	// size.
	// If no size is provided, the table will be automatically sized.
	//
	// Table transforms must have a scale of 1 and no shear components. If
	// no
	// transform is provided, the table will be centered on the page.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// Rows: Number of rows in the table.
	Rows int64 `json:"rows,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Columns") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Columns") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateTableRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateTableRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateTableResponse: The result of creating a table.
type CreateTableResponse struct {
	// ObjectId: The object ID of the created table.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateTableResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateTableResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateVideoRequest: Creates a video.
//
// NOTE: Creating a video from Google Drive requires that the requesting
// app
// have at least one of the drive, drive.readonly, or drive.file OAuth
// scopes.
type CreateVideoRequest struct {
	// ElementProperties: The element properties for the video.
	//
	// The PageElementProperties.size property is
	// optional. If you don't specify a size, a default size is chosen by
	// the
	// server.
	//
	// The PageElementProperties.transform property is
	// optional. The transform must not have shear components.
	// If you don't specify a transform, the video will be placed at the top
	// left
	// corner of the page.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// Id: The video source's unique identifier for this video.
	//
	// e.g. For YouTube video
	// https://www.youtube.com/watch?v=7U3axjORYZ0,
	// the ID is 7U3axjORYZ0. For a Google Drive
	// video
	// https://drive.google.com/file/d/1xCgQLFTJi5_Xl8DgW_lcUYq5e-q6Hi5
	// Q the ID
	// is 1xCgQLFTJi5_Xl8DgW_lcUYq5e-q6Hi5Q.
	Id string `json:"id,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// Source: The video source.
	//
	// Possible values:
	//   "SOURCE_UNSPECIFIED" - The video source is unspecified.
	//   "YOUTUBE" - The video source is YouTube.
	//   "DRIVE" - The video source is Google Drive.
	Source string `json:"source,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ElementProperties")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ElementProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateVideoRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateVideoRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateVideoResponse: The result of creating a video.
type CreateVideoResponse struct {
	// ObjectId: The object ID of the created video.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CropProperties: The crop properties of an object enclosed in a
// container. For example, an
// Image.
//
// The crop properties is represented by the offsets of four edges which
// define
// a crop rectangle. The offsets are measured in percentage from
// the
// corresponding edges of the object's original bounding rectangle
// towards
// inside, relative to the object's original dimensions.
//
// - If the offset is in the interval (0, 1), the corresponding edge of
// crop
// rectangle is positioned inside of the object's original bounding
// rectangle.
// - If the offset is negative or greater than 1, the corresponding edge
// of crop
// rectangle is positioned outside of the object's original bounding
// rectangle.
// - If the left edge of the crop rectangle is on the right side of its
// right
// edge, the object will be flipped horizontally.
// - If the top edge of the crop rectangle is below its bottom edge, the
// object
// will be flipped vertically.
// - If all offsets and rotation angle is 0, the object is not
// cropped.
//
// After cropping, the content in the crop rectangle will be stretched
// to fit
// its container.
type CropProperties struct {
	// Angle: The rotation angle of the crop window around its center, in
	// radians.
	// Rotation angle is applied after the offset.
	Angle float64 `json:"angle,omitempty"`

	// BottomOffset: The offset specifies the bottom edge of the crop
	// rectangle that is located
	// above the original bounding rectangle bottom edge, relative to the
	// object's
	// original height.
	BottomOffset float64 `json:"bottomOffset,omitempty"`

	// LeftOffset: The offset specifies the left edge of the crop rectangle
	// that is located to
	// the right of the original bounding rectangle left edge, relative to
	// the
	// object's original width.
	LeftOffset float64 `json:"leftOffset,omitempty"`

	// RightOffset: The offset specifies the right edge of the crop
	// rectangle that is located
	// to the left of the original bounding rectangle right edge, relative
	// to the
	// object's original width.
	RightOffset float64 `json:"rightOffset,omitempty"`

	// TopOffset: The offset specifies the top edge of the crop rectangle
	// that is located
	// below the original bounding rectangle top edge, relative to the
	// object's
	// original height.
	TopOffset float64 `json:"topOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Angle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Angle") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CropProperties) MarshalJSON() ([]byte, error) {
	type NoMethod CropProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *CropProperties) UnmarshalJSON(data []byte) error {
	type NoMethod CropProperties
	var s1 struct {
		Angle        gensupport.JSONFloat64 `json:"angle"`
		BottomOffset gensupport.JSONFloat64 `json:"bottomOffset"`
		LeftOffset   gensupport.JSONFloat64 `json:"leftOffset"`
		RightOffset  gensupport.JSONFloat64 `json:"rightOffset"`
		TopOffset    gensupport.JSONFloat64 `json:"topOffset"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Angle = float64(s1.Angle)
	s.BottomOffset = float64(s1.BottomOffset)
	s.LeftOffset = float64(s1.LeftOffset)
	s.RightOffset = float64(s1.RightOffset)
	s.TopOffset = float64(s1.TopOffset)
	return nil
}

// DeleteObjectRequest: Deletes an object, either pages or
// page elements, from the
// presentation.
type DeleteObjectRequest struct {
	// ObjectId: The object ID of the page or page element to delete.
	//
	// If after a delete operation a group contains
	// only 1 or no page elements, the group is also deleted.
	//
	// If a placeholder is deleted on a layout, any empty inheriting shapes
	// are
	// also deleted.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteObjectRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteObjectRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteParagraphBulletsRequest: Deletes bullets from all of the
// paragraphs that overlap with the given text
// index range.
//
// The nesting level of each paragraph will be visually preserved by
// adding
// indent to the start of the corresponding paragraph.
type DeleteParagraphBulletsRequest struct {
	// CellLocation: The optional table cell location if the text to be
	// modified is in a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// ObjectId: The object ID of the shape or table containing the text to
	// delete bullets
	// from.
	ObjectId string `json:"objectId,omitempty"`

	// TextRange: The range of text to delete bullets from, based on
	// TextElement indexes.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteParagraphBulletsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteParagraphBulletsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteTableColumnRequest: Deletes a column from a table.
type DeleteTableColumnRequest struct {
	// CellLocation: The reference table cell location from which a column
	// will be deleted.
	//
	// The column this cell spans will be deleted. If this is a merged
	// cell,
	// multiple columns will be deleted. If no columns remain in the table
	// after
	// this deletion, the whole table is deleted.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// TableObjectId: The table to delete columns from.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteTableColumnRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteTableColumnRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteTableRowRequest: Deletes a row from a table.
type DeleteTableRowRequest struct {
	// CellLocation: The reference table cell location from which a row will
	// be deleted.
	//
	// The row this cell spans will be deleted. If this is a merged cell,
	// multiple
	// rows will be deleted. If no rows remain in the table after this
	// deletion,
	// the whole table is deleted.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// TableObjectId: The table to delete rows from.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteTableRowRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteTableRowRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteTextRequest: Deletes text from a shape or a table cell.
type DeleteTextRequest struct {
	// CellLocation: The optional table cell location if the text is to be
	// deleted from a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// ObjectId: The object ID of the shape or table from which the text
	// will be deleted.
	ObjectId string `json:"objectId,omitempty"`

	// TextRange: The range of text to delete, based on TextElement
	// indexes.
	//
	// There is always an implicit newline character at the end of a shape's
	// or
	// table cell's text that cannot be deleted. `Range.Type.ALL` will use
	// the
	// correct bounds, but care must be taken when specifying explicit
	// bounds for
	// range types `FROM_START_INDEX` and `FIXED_RANGE`. For example, if the
	// text
	// is "ABC", followed by an implicit newline, then the maximum value is
	// 2 for
	// `text_range.start_index` and 3 for `text_range.end_index`.
	//
	// Deleting text that crosses a paragraph boundary may result in
	// changes
	// to paragraph styles and lists as the two paragraphs are
	// merged.
	//
	// Ranges that include only one code unit of a surrogate pair are
	// expanded to
	// include both code units.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Dimension: A magnitude in a single direction in the specified units.
type Dimension struct {
	// Magnitude: The magnitude.
	Magnitude float64 `json:"magnitude,omitempty"`

	// Unit: The units for magnitude.
	//
	// Possible values:
	//   "UNIT_UNSPECIFIED" - The units are unknown.
	//   "EMU" - An English Metric Unit (EMU) is defined as 1/360,000 of a
	// centimeter
	// and thus there are 914,400 EMUs per inch, and 12,700 EMUs per point.
	//   "PT" - A point, 1/72 of an inch.
	Unit string `json:"unit,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Magnitude") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Magnitude") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Dimension) MarshalJSON() ([]byte, error) {
	type NoMethod Dimension
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Dimension) UnmarshalJSON(data []byte) error {
	type NoMethod Dimension
	var s1 struct {
		Magnitude gensupport.JSONFloat64 `json:"magnitude"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Magnitude = float64(s1.Magnitude)
	return nil
}

// DuplicateObjectRequest: Duplicates a slide or page element.
//
// When duplicating a slide, the duplicate slide will be created
// immediately
// following the specified slide. When duplicating a page element, the
// duplicate
// will be placed on the same page at the same position as the original.
type DuplicateObjectRequest struct {
	// ObjectId: The ID of the object to duplicate.
	ObjectId string `json:"objectId,omitempty"`

	// ObjectIds: The object being duplicated may contain other objects, for
	// example when
	// duplicating a slide or a group page element. This map defines how the
	// IDs
	// of duplicated objects are generated: the keys are the IDs of the
	// original
	// objects and its values are the IDs that will be assigned to
	// the
	// corresponding duplicate object. The ID of the source object's
	// duplicate
	// may be specified in this map as well, using the same value of
	// the
	// `object_id` field as a key and the newly desired ID as the
	// value.
	//
	// All keys must correspond to existing IDs in the presentation. All
	// values
	// must be unique in the presentation and must start with an
	// alphanumeric
	// character or an underscore (matches regex `[a-zA-Z0-9_]`);
	// remaining
	// characters may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`). The length of the new ID must not be less than 5
	// or
	// greater than 50.
	//
	// If any IDs of source objects are omitted from the map, a new random
	// ID will
	// be assigned. If the map is empty or unset, all duplicate objects
	// will
	// receive a new random ID.
	ObjectIds map[string]string `json:"objectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DuplicateObjectRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DuplicateObjectRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DuplicateObjectResponse: The response of duplicating an object.
type DuplicateObjectResponse struct {
	// ObjectId: The ID of the new duplicate object.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DuplicateObjectResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DuplicateObjectResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Group: A PageElement kind representing a
// joined collection of PageElements.
type Group struct {
	// Children: The collection of elements in the group. The minimum size
	// of a group is 2.
	Children []*PageElement `json:"children,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Children") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Children") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Group) MarshalJSON() ([]byte, error) {
	type NoMethod Group
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupObjectsRequest: Groups objects to create an object group. For
// example, groups PageElements to create a Group on the same page as
// all the children.
type GroupObjectsRequest struct {
	// ChildrenObjectIds: The object IDs of the objects to group.
	//
	// Only page elements can be grouped. There should be at least two
	// page
	// elements on the same page that are not already in another group. Some
	// page
	// elements, such as videos, tables and placeholder shapes cannot be
	// grouped.
	ChildrenObjectIds []string `json:"childrenObjectIds,omitempty"`

	// GroupObjectId: A user-supplied object ID for the group to be
	// created.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	GroupObjectId string `json:"groupObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChildrenObjectIds")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChildrenObjectIds") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GroupObjectsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GroupObjectsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupObjectsResponse: The result of grouping objects.
type GroupObjectsResponse struct {
	// ObjectId: The object ID of the created group.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GroupObjectsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GroupObjectsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Image: A PageElement kind representing an
// image.
type Image struct {
	// ContentUrl: An URL to an image with a default lifetime of 30
	// minutes.
	// This URL is tagged with the account of the requester. Anyone with the
	// URL
	// effectively accesses the image as the original requester. Access to
	// the
	// image may be lost if the presentation's sharing settings change.
	ContentUrl string `json:"contentUrl,omitempty"`

	// ImageProperties: The properties of the image.
	ImageProperties *ImageProperties `json:"imageProperties,omitempty"`

	// SourceUrl: The source URL is the URL used to insert the image. The
	// source URL can be
	// empty.
	SourceUrl string `json:"sourceUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentUrl") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Image) MarshalJSON() ([]byte, error) {
	type NoMethod Image
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ImageProperties: The properties of the Image.
type ImageProperties struct {
	// Brightness: The brightness effect of the image. The value should be
	// in the interval
	// [-1.0, 1.0], where 0 means no effect. This property is read-only.
	Brightness float64 `json:"brightness,omitempty"`

	// Contrast: The contrast effect of the image. The value should be in
	// the interval
	// [-1.0, 1.0], where 0 means no effect. This property is read-only.
	Contrast float64 `json:"contrast,omitempty"`

	// CropProperties: The crop properties of the image. If not set, the
	// image is not cropped.
	// This property is read-only.
	CropProperties *CropProperties `json:"cropProperties,omitempty"`

	// Link: The hyperlink destination of the image. If unset, there is no
	// link.
	Link *Link `json:"link,omitempty"`

	// Outline: The outline of the image. If not set, the image has no
	// outline.
	Outline *Outline `json:"outline,omitempty"`

	// Recolor: The recolor effect of the image. If not set, the image is
	// not recolored.
	// This property is read-only.
	Recolor *Recolor `json:"recolor,omitempty"`

	// Shadow: The shadow of the image. If not set, the image has no shadow.
	// This property
	// is read-only.
	Shadow *Shadow `json:"shadow,omitempty"`

	// Transparency: The transparency effect of the image. The value should
	// be in the interval
	// [0.0, 1.0], where 0 means no effect and 1 means completely
	// transparent.
	// This property is read-only.
	Transparency float64 `json:"transparency,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Brightness") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Brightness") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ImageProperties) MarshalJSON() ([]byte, error) {
	type NoMethod ImageProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ImageProperties) UnmarshalJSON(data []byte) error {
	type NoMethod ImageProperties
	var s1 struct {
		Brightness   gensupport.JSONFloat64 `json:"brightness"`
		Contrast     gensupport.JSONFloat64 `json:"contrast"`
		Transparency gensupport.JSONFloat64 `json:"transparency"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Brightness = float64(s1.Brightness)
	s.Contrast = float64(s1.Contrast)
	s.Transparency = float64(s1.Transparency)
	return nil
}

// InsertTableColumnsRequest: Inserts columns into a table.
//
// Other columns in the table will be resized to fit the new column.
type InsertTableColumnsRequest struct {
	// CellLocation: The reference table cell location from which columns
	// will be inserted.
	//
	// A new column will be inserted to the left (or right) of the column
	// where
	// the reference cell is. If the reference cell is a merged cell, a
	// new
	// column will be inserted to the left (or right) of the merged cell.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// InsertRight: Whether to insert new columns to the right of the
	// reference cell location.
	//
	// - `True`: insert to the right.
	// - `False`: insert to the left.
	InsertRight bool `json:"insertRight,omitempty"`

	// Number: The number of columns to be inserted. Maximum 20 per request.
	Number int64 `json:"number,omitempty"`

	// TableObjectId: The table to insert columns into.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InsertTableColumnsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InsertTableColumnsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertTableRowsRequest: Inserts rows into a table.
type InsertTableRowsRequest struct {
	// CellLocation: The reference table cell location from which rows will
	// be inserted.
	//
	// A new row will be inserted above (or below) the row where the
	// reference
	// cell is. If the reference cell is a merged cell, a new row will
	// be
	// inserted above (or below) the merged cell.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// InsertBelow: Whether to insert new rows below the reference cell
	// location.
	//
	// - `True`: insert below the cell.
	// - `False`: insert above the cell.
	InsertBelow bool `json:"insertBelow,omitempty"`

	// Number: The number of rows to be inserted. Maximum 20 per request.
	Number int64 `json:"number,omitempty"`

	// TableObjectId: The table to insert rows into.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InsertTableRowsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InsertTableRowsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertTextRequest: Inserts text into a shape or a table cell.
type InsertTextRequest struct {
	// CellLocation: The optional table cell location if the text is to be
	// inserted into a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// InsertionIndex: The index where the text will be inserted, in Unicode
	// code units, based
	// on TextElement indexes.
	//
	// The index is zero-based and is computed from the start of the
	// string.
	// The index may be adjusted to prevent insertions inside Unicode
	// grapheme
	// clusters. In these cases, the text will be inserted immediately after
	// the
	// grapheme cluster.
	InsertionIndex int64 `json:"insertionIndex,omitempty"`

	// ObjectId: The object ID of the shape or table where the text will be
	// inserted.
	ObjectId string `json:"objectId,omitempty"`

	// Text: The text to be inserted.
	//
	// Inserting a newline character will implicitly create a
	// new
	// ParagraphMarker at that index.
	// The paragraph style of the new paragraph will be copied from the
	// paragraph
	// at the current insertion index, including lists and bullets.
	//
	// Text styles for inserted text will be determined automatically,
	// generally
	// preserving the styling of neighboring text. In most cases, the text
	// will be
	// added to the TextRun that exists at the
	// insertion index.
	//
	// Some control characters (U+0000-U+0008, U+000C-U+001F) and
	// characters
	// from the Unicode Basic Multilingual Plane Private Use Area
	// (U+E000-U+F8FF)
	// will be stripped out of the inserted text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InsertTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InsertTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LayoutPlaceholderIdMapping: The user-specified ID mapping for a
// placeholder that will be created on a
// slide from a specified layout.
type LayoutPlaceholderIdMapping struct {
	// LayoutPlaceholder: The placeholder on a layout that will be applied
	// to a slide. Only type and index are needed. For example, a
	// predefined `TITLE_AND_BODY` layout may usually have a TITLE
	// placeholder
	// with index 0 and a BODY placeholder with index 0.
	LayoutPlaceholder *Placeholder `json:"layoutPlaceholder,omitempty"`

	// LayoutPlaceholderObjectId: The object ID of the placeholder on a
	// layout that will be applied
	// to a slide.
	LayoutPlaceholderObjectId string `json:"layoutPlaceholderObjectId,omitempty"`

	// ObjectId: A user-supplied object ID for the placeholder identified
	// above that to be
	// created onto a slide.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LayoutPlaceholder")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutPlaceholder") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *LayoutPlaceholderIdMapping) MarshalJSON() ([]byte, error) {
	type NoMethod LayoutPlaceholderIdMapping
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LayoutProperties: The properties of Page are only
// relevant for pages with page_type LAYOUT.
type LayoutProperties struct {
	// DisplayName: The human-readable name of the layout.
	DisplayName string `json:"displayName,omitempty"`

	// MasterObjectId: The object ID of the master that this layout is based
	// on.
	MasterObjectId string `json:"masterObjectId,omitempty"`

	// Name: The name of the layout.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DisplayName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LayoutProperties) MarshalJSON() ([]byte, error) {
	type NoMethod LayoutProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LayoutReference: Slide layout reference. This may reference
// either:
//
// - A predefined layout
// - One of the layouts in the presentation.
type LayoutReference struct {
	// LayoutId: Layout ID: the object ID of one of the layouts in the
	// presentation.
	LayoutId string `json:"layoutId,omitempty"`

	// PredefinedLayout: Predefined layout.
	//
	// Possible values:
	//   "PREDEFINED_LAYOUT_UNSPECIFIED" - Unspecified layout.
	//   "BLANK" - Blank layout, with no placeholders.
	//   "CAPTION_ONLY" - Layout with a caption at the bottom.
	//   "TITLE" - Layout with a title and a subtitle.
	//   "TITLE_AND_BODY" - Layout with a title and body.
	//   "TITLE_AND_TWO_COLUMNS" - Layout with a title and two columns.
	//   "TITLE_ONLY" - Layout with only a title.
	//   "SECTION_HEADER" - Layout with a section title.
	//   "SECTION_TITLE_AND_DESCRIPTION" - Layout with a title and subtitle
	// on one side and description on the other.
	//   "ONE_COLUMN_TEXT" - Layout with one title and one body, arranged in
	// a single column.
	//   "MAIN_POINT" - Layout with a main point.
	//   "BIG_NUMBER" - Layout with a big number heading.
	PredefinedLayout string `json:"predefinedLayout,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LayoutId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LayoutReference) MarshalJSON() ([]byte, error) {
	type NoMethod LayoutReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Line: A PageElement kind representing a
// non-connector line, straight connector, curved connector, or bent
// connector.
type Line struct {
	// LineCategory: The category of the line.
	//
	// It matches the `category` specified in CreateLineRequest, and can be
	// updated with
	// UpdateLineCategoryRequest.
	//
	// Possible values:
	//   "LINE_CATEGORY_UNSPECIFIED" - Unspecified line category.
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	LineCategory string `json:"lineCategory,omitempty"`

	// LineProperties: The properties of the line.
	LineProperties *LineProperties `json:"lineProperties,omitempty"`

	// LineType: The type of the line.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - An unspecified line type.
	//   "STRAIGHT_CONNECTOR_1" - Straight connector 1 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'straightConnector1'.
	//   "BENT_CONNECTOR_2" - Bent connector 2 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector2'.
	//   "BENT_CONNECTOR_3" - Bent connector 3 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector3'.
	//   "BENT_CONNECTOR_4" - Bent connector 4 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector4'.
	//   "BENT_CONNECTOR_5" - Bent connector 5 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector5'.
	//   "CURVED_CONNECTOR_2" - Curved connector 2 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector2'.
	//   "CURVED_CONNECTOR_3" - Curved connector 3 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector3'.
	//   "CURVED_CONNECTOR_4" - Curved connector 4 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector4'.
	//   "CURVED_CONNECTOR_5" - Curved connector 5 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector5'.
	//   "STRAIGHT_LINE" - Straight line. Corresponds to ECMA-376
	// ST_ShapeType 'line'. This line
	// type is not a connector.
	LineType string `json:"lineType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LineCategory") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LineCategory") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Line) MarshalJSON() ([]byte, error) {
	type NoMethod Line
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineConnection: The properties for one end of a Line
// connection.
type LineConnection struct {
	// ConnectedObjectId: The object ID of the connected page element.
	//
	// Some page elements, such as groups, tables, and lines
	// do not have connection sites and therefore cannot be connected to
	// a
	// connector line.
	ConnectedObjectId string `json:"connectedObjectId,omitempty"`

	// ConnectionSiteIndex: The index of the connection site on the
	// connected page element.
	//
	// In most cases, it corresponds to the predefined connection site index
	// from
	// the ECMA-376 standard. More information on those connection sites can
	// be
	// found in the description of the "cnx" attribute in section 20.1.9.9
	// and
	// Annex H. "Predefined DrawingML Shape and Text Geometries" of "Office
	// Open
	// XML File Formats-Fundamentals and Markup Language Reference", part 1
	// of
	// [ECMA-376 5th
	// edition]
	// (http://www.ecma-international.org/publications/standards/Ecm
	// a-376.htm).
	//
	// The position of each connection site can also be viewed from Slides
	// editor.
	ConnectionSiteIndex int64 `json:"connectionSiteIndex,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ConnectedObjectId")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ConnectedObjectId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *LineConnection) MarshalJSON() ([]byte, error) {
	type NoMethod LineConnection
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineFill: The fill of the line.
type LineFill struct {
	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SolidFill") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SolidFill") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LineFill) MarshalJSON() ([]byte, error) {
	type NoMethod LineFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineProperties: The properties of the Line.
//
// When unset, these fields default to values that match the appearance
// of
// new lines created in the Slides editor.
type LineProperties struct {
	// DashStyle: The dash style of the line.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'.
	// This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	//   "DASH_DOT" - Alternating dashes and dots. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'dashDot'.
	//   "LONG_DASH" - Line with large dashes. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'lgDash'.
	//   "LONG_DASH_DOT" - Alternating large dashes and dots. Corresponds to
	// ECMA-376
	// ST_PresetLineDashVal value 'lgDashDot'.
	DashStyle string `json:"dashStyle,omitempty"`

	// EndArrow: The style of the arrow at the end of the line.
	//
	// Possible values:
	//   "ARROW_STYLE_UNSPECIFIED" - An unspecified arrow style.
	//   "NONE" - No arrow.
	//   "STEALTH_ARROW" - Arrow with notched back. Corresponds to ECMA-376
	// ST_LineEndType value
	// 'stealth'.
	//   "FILL_ARROW" - Filled arrow. Corresponds to ECMA-376 ST_LineEndType
	// value 'triangle'.
	//   "FILL_CIRCLE" - Filled circle. Corresponds to ECMA-376
	// ST_LineEndType value 'oval'.
	//   "FILL_SQUARE" - Filled square.
	//   "FILL_DIAMOND" - Filled diamond. Corresponds to ECMA-376
	// ST_LineEndType value 'diamond'.
	//   "OPEN_ARROW" - Hollow arrow.
	//   "OPEN_CIRCLE" - Hollow circle.
	//   "OPEN_SQUARE" - Hollow square.
	//   "OPEN_DIAMOND" - Hollow diamond.
	EndArrow string `json:"endArrow,omitempty"`

	// EndConnection: The connection at the end of the line. If unset, there
	// is no connection.
	//
	// Only lines with a Type indicating it is
	// a "connector" can have an `end_connection`.
	EndConnection *LineConnection `json:"endConnection,omitempty"`

	// LineFill: The fill of the line. The default line fill matches the
	// defaults for new
	// lines created in the Slides editor.
	LineFill *LineFill `json:"lineFill,omitempty"`

	// Link: The hyperlink destination of the line. If unset, there is no
	// link.
	Link *Link `json:"link,omitempty"`

	// StartArrow: The style of the arrow at the beginning of the line.
	//
	// Possible values:
	//   "ARROW_STYLE_UNSPECIFIED" - An unspecified arrow style.
	//   "NONE" - No arrow.
	//   "STEALTH_ARROW" - Arrow with notched back. Corresponds to ECMA-376
	// ST_LineEndType value
	// 'stealth'.
	//   "FILL_ARROW" - Filled arrow. Corresponds to ECMA-376 ST_LineEndType
	// value 'triangle'.
	//   "FILL_CIRCLE" - Filled circle. Corresponds to ECMA-376
	// ST_LineEndType value 'oval'.
	//   "FILL_SQUARE" - Filled square.
	//   "FILL_DIAMOND" - Filled diamond. Corresponds to ECMA-376
	// ST_LineEndType value 'diamond'.
	//   "OPEN_ARROW" - Hollow arrow.
	//   "OPEN_CIRCLE" - Hollow circle.
	//   "OPEN_SQUARE" - Hollow square.
	//   "OPEN_DIAMOND" - Hollow diamond.
	StartArrow string `json:"startArrow,omitempty"`

	// StartConnection: The connection at the beginning of the line. If
	// unset, there is no
	// connection.
	//
	// Only lines with a Type indicating it is
	// a "connector" can have a `start_connection`.
	StartConnection *LineConnection `json:"startConnection,omitempty"`

	// Weight: The thickness of the line.
	Weight *Dimension `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DashStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DashStyle") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LineProperties) MarshalJSON() ([]byte, error) {
	type NoMethod LineProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Link: A hypertext link.
type Link struct {
	// PageObjectId: If set, indicates this is a link to the specific page
	// in this
	// presentation with this ID. A page with this ID may not exist.
	PageObjectId string `json:"pageObjectId,omitempty"`

	// RelativeLink: If set, indicates this is a link to a slide in this
	// presentation,
	// addressed by its position.
	//
	// Possible values:
	//   "RELATIVE_SLIDE_LINK_UNSPECIFIED" - An unspecified relative slide
	// link.
	//   "NEXT_SLIDE" - A link to the next slide.
	//   "PREVIOUS_SLIDE" - A link to the previous slide.
	//   "FIRST_SLIDE" - A link to the first slide in the presentation.
	//   "LAST_SLIDE" - A link to the last slide in the presentation.
	RelativeLink string `json:"relativeLink,omitempty"`

	// SlideIndex: If set, indicates this is a link to the slide at this
	// zero-based index
	// in the presentation. There may not be a slide at this index.
	SlideIndex int64 `json:"slideIndex,omitempty"`

	// Url: If set, indicates this is a link to the external web page at
	// this URL.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PageObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PageObjectId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Link) MarshalJSON() ([]byte, error) {
	type NoMethod Link
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// List: A List describes the look and feel of bullets belonging to
// paragraphs
// associated with a list. A paragraph that is part of a list has an
// implicit
// reference to that list's ID.
type List struct {
	// ListId: The ID of the list.
	ListId string `json:"listId,omitempty"`

	// NestingLevel: A map of nesting levels to the properties of bullets at
	// the associated
	// level. A list has at most nine levels of nesting, so the possible
	// values
	// for the keys of this map are 0 through 8, inclusive.
	NestingLevel map[string]NestingLevel `json:"nestingLevel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ListId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ListId") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *List) MarshalJSON() ([]byte, error) {
	type NoMethod List
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MasterProperties: The properties of Page that are only
// relevant for pages with page_type MASTER.
type MasterProperties struct {
	// DisplayName: The human-readable name of the master.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DisplayName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MasterProperties) MarshalJSON() ([]byte, error) {
	type NoMethod MasterProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MergeTableCellsRequest: Merges cells in a Table.
type MergeTableCellsRequest struct {
	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableRange: The table range specifying which cells of the table to
	// merge.
	//
	// Any text in the cells being merged will be concatenated and stored in
	// the
	// upper-left ("head") cell of the range. If the range is
	// non-rectangular
	// (which can occur in some cases where the range covers cells that
	// are
	// already merged), a 400 bad request error is returned.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MergeTableCellsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod MergeTableCellsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NestingLevel: Contains properties describing the look and feel of a
// list bullet at a given
// level of nesting.
type NestingLevel struct {
	// BulletStyle: The style of a bullet at this level of nesting.
	BulletStyle *TextStyle `json:"bulletStyle,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BulletStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BulletStyle") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NestingLevel) MarshalJSON() ([]byte, error) {
	type NoMethod NestingLevel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotesProperties: The properties of Page that are only
// relevant for pages with page_type NOTES.
type NotesProperties struct {
	// SpeakerNotesObjectId: The object ID of the shape on this notes page
	// that contains the speaker
	// notes for the corresponding slide.
	// The actual shape may not always exist on the notes page. Inserting
	// text
	// using this object ID will automatically create the shape. In this
	// case, the
	// actual shape may have different object ID. The `GetPresentation`
	// or
	// `GetPage` action will always return the latest object ID.
	SpeakerNotesObjectId string `json:"speakerNotesObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "SpeakerNotesObjectId") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SpeakerNotesObjectId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NotesProperties) MarshalJSON() ([]byte, error) {
	type NoMethod NotesProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OpaqueColor: A themeable solid color value.
type OpaqueColor struct {
	// RgbColor: An opaque RGB color.
	RgbColor *RgbColor `json:"rgbColor,omitempty"`

	// ThemeColor: An opaque theme color.
	//
	// Possible values:
	//   "THEME_COLOR_TYPE_UNSPECIFIED" - Unspecified theme color. This
	// value should not be used.
	//   "DARK1" - Represents the first dark color.
	//   "LIGHT1" - Represents the first light color.
	//   "DARK2" - Represents the second dark color.
	//   "LIGHT2" - Represents the second light color.
	//   "ACCENT1" - Represents the first accent color.
	//   "ACCENT2" - Represents the second accent color.
	//   "ACCENT3" - Represents the third accent color.
	//   "ACCENT4" - Represents the fourth accent color.
	//   "ACCENT5" - Represents the fifth accent color.
	//   "ACCENT6" - Represents the sixth accent color.
	//   "HYPERLINK" - Represents the color to use for hyperlinks.
	//   "FOLLOWED_HYPERLINK" - Represents the color to use for visited
	// hyperlinks.
	//   "TEXT1" - Represents the first text color.
	//   "BACKGROUND1" - Represents the first background color.
	//   "TEXT2" - Represents the second text color.
	//   "BACKGROUND2" - Represents the second background color.
	ThemeColor string `json:"themeColor,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RgbColor") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RgbColor") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OpaqueColor) MarshalJSON() ([]byte, error) {
	type NoMethod OpaqueColor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OptionalColor: A color that can either be fully opaque or fully
// transparent.
type OptionalColor struct {
	// OpaqueColor: If set, this will be used as an opaque color. If unset,
	// this represents
	// a transparent color.
	OpaqueColor *OpaqueColor `json:"opaqueColor,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OpaqueColor") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OpaqueColor") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OptionalColor) MarshalJSON() ([]byte, error) {
	type NoMethod OptionalColor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Outline: The outline of a PageElement.
//
// If these fields are unset, they may be inherited from a parent
// placeholder
// if it exists. If there is no parent, the fields will default to the
// value
// used for new page elements created in the Slides editor, which may
// depend on
// the page element kind.
type Outline struct {
	// DashStyle: The dash style of the outline.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'.
	// This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	//   "DASH_DOT" - Alternating dashes and dots. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'dashDot'.
	//   "LONG_DASH" - Line with large dashes. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'lgDash'.
	//   "LONG_DASH_DOT" - Alternating large dashes and dots. Corresponds to
	// ECMA-376
	// ST_PresetLineDashVal value 'lgDashDot'.
	DashStyle string `json:"dashStyle,omitempty"`

	// OutlineFill: The fill of the outline.
	OutlineFill *OutlineFill `json:"outlineFill,omitempty"`

	// PropertyState: The outline property state.
	//
	// Updating the outline on a page element will implicitly update this
	// field
	// to `RENDERED`, unless another value is specified in the same request.
	// To
	// have no outline on a page element, set this field to `NOT_RENDERED`.
	// In
	// this case, any other outline fields set in the same request will
	// be
	// ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// Weight: The thickness of the outline.
	Weight *Dimension `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DashStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DashStyle") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Outline) MarshalJSON() ([]byte, error) {
	type NoMethod Outline
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OutlineFill: The fill of the outline.
type OutlineFill struct {
	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SolidFill") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SolidFill") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OutlineFill) MarshalJSON() ([]byte, error) {
	type NoMethod OutlineFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Page: A page in a presentation.
type Page struct {
	// LayoutProperties: Layout specific properties. Only set if page_type =
	// LAYOUT.
	LayoutProperties *LayoutProperties `json:"layoutProperties,omitempty"`

	// MasterProperties: Master specific properties. Only set if page_type =
	// MASTER.
	MasterProperties *MasterProperties `json:"masterProperties,omitempty"`

	// NotesProperties: Notes specific properties. Only set if page_type =
	// NOTES.
	NotesProperties *NotesProperties `json:"notesProperties,omitempty"`

	// ObjectId: The object ID for this page. Object IDs used by
	// Page and
	// PageElement share the same namespace.
	ObjectId string `json:"objectId,omitempty"`

	// PageElements: The page elements rendered on the page.
	PageElements []*PageElement `json:"pageElements,omitempty"`

	// PageProperties: The properties of the page.
	PageProperties *PageProperties `json:"pageProperties,omitempty"`

	// PageType: The type of the page.
	//
	// Possible values:
	//   "SLIDE" - A slide page.
	//   "MASTER" - A master slide page.
	//   "LAYOUT" - A layout page.
	//   "NOTES" - A notes page.
	//   "NOTES_MASTER" - A notes master page.
	PageType string `json:"pageType,omitempty"`

	// RevisionId: The revision ID of the presentation containing this page.
	// Can be used in
	// update requests to assert that the presentation revision hasn't
	// changed
	// since the last read operation. Only populated if the user has edit
	// access
	// to the presentation.
	//
	// The format of the revision ID may change over time, so it should be
	// treated
	// opaquely. A returned revision ID is only guaranteed to be valid for
	// 24
	// hours after it has been returned and cannot be shared across users.
	// If the
	// revision ID is unchanged between calls, then the presentation has
	// not
	// changed. Conversely, a changed ID (for the same presentation and
	// user)
	// usually means the presentation has been updated; however, a changed
	// ID can
	// also be due to internal factors such as ID format changes.
	RevisionId string `json:"revisionId,omitempty"`

	// SlideProperties: Slide specific properties. Only set if page_type =
	// SLIDE.
	SlideProperties *SlideProperties `json:"slideProperties,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "LayoutProperties") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Page) MarshalJSON() ([]byte, error) {
	type NoMethod Page
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageBackgroundFill: The page background fill.
type PageBackgroundFill struct {
	// PropertyState: The background fill property state.
	//
	// Updating the fill on a page will implicitly update this field
	// to
	// `RENDERED`, unless another value is specified in the same request.
	// To
	// have no fill on a page, set this field to `NOT_RENDERED`. In this
	// case,
	// any other fill fields set in the same request will be ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// StretchedPictureFill: Stretched picture fill.
	StretchedPictureFill *StretchedPictureFill `json:"stretchedPictureFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PropertyState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PropertyState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageBackgroundFill) MarshalJSON() ([]byte, error) {
	type NoMethod PageBackgroundFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageElement: A visual element rendered on a page.
type PageElement struct {
	// Description: The description of the page element. Combined with title
	// to display alt
	// text.
	Description string `json:"description,omitempty"`

	// ElementGroup: A collection of page elements joined as a single unit.
	ElementGroup *Group `json:"elementGroup,omitempty"`

	// Image: An image page element.
	Image *Image `json:"image,omitempty"`

	// Line: A line page element.
	Line *Line `json:"line,omitempty"`

	// ObjectId: The object ID for this page element. Object IDs used
	// by
	// google.apps.slides.v1.Page and
	// google.apps.slides.v1.PageElement share the same namespace.
	ObjectId string `json:"objectId,omitempty"`

	// Shape: A generic shape.
	Shape *Shape `json:"shape,omitempty"`

	// SheetsChart: A linked chart embedded from Google Sheets. Unlinked
	// charts are
	// represented as images.
	SheetsChart *SheetsChart `json:"sheetsChart,omitempty"`

	// Size: The size of the page element.
	Size *Size `json:"size,omitempty"`

	// Table: A table page element.
	Table *Table `json:"table,omitempty"`

	// Title: The title of the page element. Combined with description to
	// display alt
	// text.
	Title string `json:"title,omitempty"`

	// Transform: The transform of the page element.
	//
	// The visual appearance of the page element is determined by its
	// absolute
	// transform. To compute the absolute transform, preconcatenate a
	// page
	// element's transform with the transforms of all of its parent groups.
	// If the
	// page element is not in a group, its absolute transform is the same as
	// the
	// value in this field.
	//
	// The initial transform for the newly created Group is always the
	// identity transform.
	Transform *AffineTransform `json:"transform,omitempty"`

	// Video: A video page element.
	Video *Video `json:"video,omitempty"`

	// WordArt: A word art page element.
	WordArt *WordArt `json:"wordArt,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageElement) MarshalJSON() ([]byte, error) {
	type NoMethod PageElement
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageElementProperties: Common properties for a page element.
//
// Note: When you initially create a
// PageElement, the API may modify
// the values of both `size` and `transform`, but the
// visual size will be unchanged.
type PageElementProperties struct {
	// PageObjectId: The object ID of the page where the element is located.
	PageObjectId string `json:"pageObjectId,omitempty"`

	// Size: The size of the element.
	Size *Size `json:"size,omitempty"`

	// Transform: The transform for the element.
	Transform *AffineTransform `json:"transform,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PageObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PageObjectId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageElementProperties) MarshalJSON() ([]byte, error) {
	type NoMethod PageElementProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageProperties: The properties of the Page.
//
// The page will inherit properties from the parent page. Depending on
// the page
// type the hierarchy is defined in either
// SlideProperties or
// LayoutProperties.
type PageProperties struct {
	// ColorScheme: The color scheme of the page. If unset, the color scheme
	// is inherited from
	// a parent page. If the page has no parent, the color scheme uses a
	// default
	// Slides color scheme, matching the defaults in the Slides
	// editor.
	//
	// Only the concrete colors of the first 12 ThemeColorTypes are
	// editable. In addition, only
	// the color scheme on `Master` pages can be updated. To update the
	// field, a
	// color scheme containing mappings from all the first 12
	// ThemeColorTypes to
	// their concrete colors must be provided. Colors for the
	// remaining
	// ThemeColorTypes will be ignored.
	ColorScheme *ColorScheme `json:"colorScheme,omitempty"`

	// PageBackgroundFill: The background fill of the page. If unset, the
	// background fill is inherited
	// from a parent page if it exists. If the page has no parent, then
	// the
	// background fill defaults to the corresponding fill in the Slides
	// editor.
	PageBackgroundFill *PageBackgroundFill `json:"pageBackgroundFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColorScheme") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColorScheme") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageProperties) MarshalJSON() ([]byte, error) {
	type NoMethod PageProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParagraphMarker: A TextElement kind that represents the beginning of
// a new paragraph.
type ParagraphMarker struct {
	// Bullet: The bullet for this paragraph. If not present, the paragraph
	// does not
	// belong to a list.
	Bullet *Bullet `json:"bullet,omitempty"`

	// Style: The paragraph's style
	Style *ParagraphStyle `json:"style,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bullet") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bullet") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ParagraphMarker) MarshalJSON() ([]byte, error) {
	type NoMethod ParagraphMarker
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParagraphStyle: Styles that apply to a whole paragraph.
//
// If this text is contained in a shape with a parent placeholder, then
// these paragraph styles may be
// inherited from the parent. Which paragraph styles are inherited
// depend on the
// nesting level of lists:
//
// * A paragraph not in a list will inherit its paragraph style from
// the
//   paragraph at the 0 nesting level of the list inside the parent
// placeholder.
// * A paragraph in a list will inherit its paragraph style from the
// paragraph
//   at its corresponding nesting level of the list inside the parent
//   placeholder.
//
// Inherited paragraph styles are represented as unset fields in this
// message.
type ParagraphStyle struct {
	// Alignment: The text alignment for this paragraph.
	//
	// Possible values:
	//   "ALIGNMENT_UNSPECIFIED" - The paragraph alignment is inherited from
	// the parent.
	//   "START" - The paragraph is aligned to the start of the line.
	// Left-aligned for
	// LTR text, right-aligned otherwise.
	//   "CENTER" - The paragraph is centered.
	//   "END" - The paragraph is aligned to the end of the line.
	// Right-aligned for
	// LTR text, left-aligned otherwise.
	//   "JUSTIFIED" - The paragraph is justified.
	Alignment string `json:"alignment,omitempty"`

	// Direction: The text direction of this paragraph. If unset, the value
	// defaults to
	// LEFT_TO_RIGHT since
	// text direction is not inherited.
	//
	// Possible values:
	//   "TEXT_DIRECTION_UNSPECIFIED" - The text direction is inherited from
	// the parent.
	//   "LEFT_TO_RIGHT" - The text goes from left to right.
	//   "RIGHT_TO_LEFT" - The text goes from right to left.
	Direction string `json:"direction,omitempty"`

	// IndentEnd: The amount indentation for the paragraph on the side that
	// corresponds to
	// the end of the text, based on the current text direction. If unset,
	// the
	// value is inherited from the parent.
	IndentEnd *Dimension `json:"indentEnd,omitempty"`

	// IndentFirstLine: The amount of indentation for the start of the first
	// line of the paragraph.
	// If unset, the value is inherited from the parent.
	IndentFirstLine *Dimension `json:"indentFirstLine,omitempty"`

	// IndentStart: The amount indentation for the paragraph on the side
	// that corresponds to
	// the start of the text, based on the current text direction. If unset,
	// the
	// value is inherited from the parent.
	IndentStart *Dimension `json:"indentStart,omitempty"`

	// LineSpacing: The amount of space between lines, as a percentage of
	// normal, where normal
	// is represented as 100.0. If unset, the value is inherited from the
	// parent.
	LineSpacing float64 `json:"lineSpacing,omitempty"`

	// SpaceAbove: The amount of extra space above the paragraph. If unset,
	// the value is
	// inherited from the parent.
	SpaceAbove *Dimension `json:"spaceAbove,omitempty"`

	// SpaceBelow: The amount of extra space below the paragraph. If unset,
	// the value is
	// inherited from the parent.
	SpaceBelow *Dimension `json:"spaceBelow,omitempty"`

	// SpacingMode: The spacing mode for the paragraph.
	//
	// Possible values:
	//   "SPACING_MODE_UNSPECIFIED" - The spacing mode is inherited from the
	// parent.
	//   "NEVER_COLLAPSE" - Paragraph spacing is always rendered.
	//   "COLLAPSE_LISTS" - Paragraph spacing is skipped between list
	// elements.
	SpacingMode string `json:"spacingMode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alignment") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ParagraphStyle) MarshalJSON() ([]byte, error) {
	type NoMethod ParagraphStyle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ParagraphStyle) UnmarshalJSON(data []byte) error {
	type NoMethod ParagraphStyle
	var s1 struct {
		LineSpacing gensupport.JSONFloat64 `json:"lineSpacing"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.LineSpacing = float64(s1.LineSpacing)
	return nil
}

// Placeholder: The placeholder information that uniquely identifies a
// placeholder shape.
type Placeholder struct {
	// Index: The index of the placeholder. If the same placeholder types
	// are present in
	// the same page, they would have different index values.
	Index int64 `json:"index,omitempty"`

	// ParentObjectId: The object ID of this shape's parent placeholder.
	// If unset, the parent placeholder shape does not exist, so the shape
	// does
	// not inherit properties from any other shape.
	ParentObjectId string `json:"parentObjectId,omitempty"`

	// Type: The type of the placeholder.
	//
	// Possible values:
	//   "NONE" - Default value, signifies it is not a placeholder.
	//   "BODY" - Body text.
	//   "CHART" - Chart or graph.
	//   "CLIP_ART" - Clip art image.
	//   "CENTERED_TITLE" - Title centered.
	//   "DIAGRAM" - Diagram.
	//   "DATE_AND_TIME" - Date and time.
	//   "FOOTER" - Footer text.
	//   "HEADER" - Header text.
	//   "MEDIA" - Multimedia.
	//   "OBJECT" - Any content type.
	//   "PICTURE" - Picture.
	//   "SLIDE_NUMBER" - Number of a slide.
	//   "SUBTITLE" - Subtitle.
	//   "TABLE" - Table.
	//   "TITLE" - Slide title.
	//   "SLIDE_IMAGE" - Slide image.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Index") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Index") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Placeholder) MarshalJSON() ([]byte, error) {
	type NoMethod Placeholder
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Presentation: A Google Slides presentation.
type Presentation struct {
	// Layouts: The layouts in the presentation. A layout is a template that
	// determines
	// how content is arranged and styled on the slides that inherit from
	// that
	// layout.
	Layouts []*Page `json:"layouts,omitempty"`

	// Locale: The locale of the presentation, as an IETF BCP 47 language
	// tag.
	Locale string `json:"locale,omitempty"`

	// Masters: The slide masters in the presentation. A slide master
	// contains all common
	// page elements and the common properties for a set of layouts. They
	// serve
	// three purposes:
	//
	// - Placeholder shapes on a master contain the default text styles and
	// shape
	//   properties of all placeholder shapes on pages that use that
	// master.
	// - The master page properties define the common page properties
	// inherited by
	//   its layouts.
	// - Any other shapes on the master slide will appear on all slides
	// using that
	//   master, regardless of their layout.
	Masters []*Page `json:"masters,omitempty"`

	// NotesMaster: The notes master in the presentation. It serves three
	// purposes:
	//
	// - Placeholder shapes on a notes master contain the default text
	// styles and
	//   shape properties of all placeholder shapes on notes pages.
	// Specifically,
	//   a `SLIDE_IMAGE` placeholder shape contains the slide thumbnail, and
	// a
	//   `BODY` placeholder shape contains the speaker notes.
	// - The notes master page properties define the common page properties
	//   inherited by all notes pages.
	// - Any other shapes on the notes master will appear on all notes
	// pages.
	//
	// The notes master is read-only.
	NotesMaster *Page `json:"notesMaster,omitempty"`

	// PageSize: The size of pages in the presentation.
	PageSize *Size `json:"pageSize,omitempty"`

	// PresentationId: The ID of the presentation.
	PresentationId string `json:"presentationId,omitempty"`

	// RevisionId: The revision ID of the presentation. Can be used in
	// update requests
	// to assert that the presentation revision hasn't changed since the
	// last
	// read operation. Only populated if the user has edit access to
	// the
	// presentation.
	//
	// The format of the revision ID may change over time, so it should be
	// treated
	// opaquely. A returned revision ID is only guaranteed to be valid for
	// 24
	// hours after it has been returned and cannot be shared across users.
	// If the
	// revision ID is unchanged between calls, then the presentation has
	// not
	// changed. Conversely, a changed ID (for the same presentation and
	// user)
	// usually means the presentation has been updated; however, a changed
	// ID can
	// also be due to internal factors such as ID format changes.
	RevisionId string `json:"revisionId,omitempty"`

	// Slides: The slides in the presentation.
	// A slide inherits properties from a slide layout.
	Slides []*Page `json:"slides,omitempty"`

	// Title: The title of the presentation.
	Title string `json:"title,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Layouts") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Layouts") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Presentation) MarshalJSON() ([]byte, error) {
	type NoMethod Presentation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Range: Specifies a contiguous range of an indexed collection, such as
// characters in
// text.
type Range struct {
	// EndIndex: The optional zero-based index of the end of the
	// collection.
	// Required for `FIXED_RANGE` ranges.
	EndIndex int64 `json:"endIndex,omitempty"`

	// StartIndex: The optional zero-based index of the beginning of the
	// collection.
	// Required for `FIXED_RANGE` and `FROM_START_INDEX` ranges.
	StartIndex int64 `json:"startIndex,omitempty"`

	// Type: The type of range.
	//
	// Possible values:
	//   "RANGE_TYPE_UNSPECIFIED" - Unspecified range type. This value must
	// not be used.
	//   "FIXED_RANGE" - A fixed range. Both the `start_index`
	// and
	// `end_index` must be specified.
	//   "FROM_START_INDEX" - Starts the range at `start_index` and
	// continues until the
	// end of the collection. The `end_index` must not be specified.
	//   "ALL" - Sets the range to be the whole length of the collection.
	// Both the
	// `start_index` and the `end_index` must not be
	// specified.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EndIndex") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Range) MarshalJSON() ([]byte, error) {
	type NoMethod Range
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Recolor: A recolor effect applied on an image.
type Recolor struct {
	// Name: The name of the recolor effect.
	//
	// The name is determined from the `recolor_stops` by matching the
	// gradient
	// against the colors in the page's current color scheme. This property
	// is
	// read-only.
	//
	// Possible values:
	//   "NONE" - No recolor effect. The default value.
	//   "LIGHT1" - A recolor effect that lightens the image using the
	// page's first available
	// color from its color scheme.
	//   "LIGHT2" - A recolor effect that lightens the image using the
	// page's second
	// available color from its color scheme.
	//   "LIGHT3" - A recolor effect that lightens the image using the
	// page's third available
	// color from its color scheme.
	//   "LIGHT4" - A recolor effect that lightens the image using the
	// page's forth available
	// color from its color scheme.
	//   "LIGHT5" - A recolor effect that lightens the image using the
	// page's fifth available
	// color from its color scheme.
	//   "LIGHT6" - A recolor effect that lightens the image using the
	// page's sixth available
	// color from its color scheme.
	//   "LIGHT7" - A recolor effect that lightens the image using the
	// page's seventh
	// available color from its color scheme.
	//   "LIGHT8" - A recolor effect that lightens the image using the
	// page's eighth
	// available color from its color scheme.
	//   "LIGHT9" - A recolor effect that lightens the image using the
	// page's ninth available
	// color from its color scheme.
	//   "LIGHT10" - A recolor effect that lightens the image using the
	// page's tenth available
	// color from its color scheme.
	//   "DARK1" - A recolor effect that darkens the image using the page's
	// first available
	// color from its color scheme.
	//   "DARK2" - A recolor effect that darkens the image using the page's
	// second available
	// color from its color scheme.
	//   "DARK3" - A recolor effect that darkens the image using the page's
	// third available
	// color from its color scheme.
	//   "DARK4" - A recolor effect that darkens the image using the page's
	// fourth available
	// color from its color scheme.
	//   "DARK5" - A recolor effect that darkens the image using the page's
	// fifth available
	// color from its color scheme.
	//   "DARK6" - A recolor effect that darkens the image using the page's
	// sixth available
	// color from its color scheme.
	//   "DARK7" - A recolor effect that darkens the image using the page's
	// seventh
	// available color from its color scheme.
	//   "DARK8" - A recolor effect that darkens the image using the page's
	// eighth available
	// color from its color scheme.
	//   "DARK9" - A recolor effect that darkens the image using the page's
	// ninth available
	// color from its color scheme.
	//   "DARK10" - A recolor effect that darkens the image using the page's
	// tenth available
	// color from its color scheme.
	//   "GRAYSCALE" - A recolor effect that recolors the image to
	// grayscale.
	//   "NEGATIVE" - A recolor effect that recolors the image to negative
	// grayscale.
	//   "SEPIA" - A recolor effect that recolors the image using the sepia
	// color.
	//   "CUSTOM" - Custom recolor effect. Refer to `recolor_stops` for the
	// concrete
	// gradient.
	Name string `json:"name,omitempty"`

	// RecolorStops: The recolor effect is represented by a gradient, which
	// is a list of color
	// stops.
	//
	// The colors in the gradient will replace the corresponding colors
	// at
	// the same position in the color palette and apply to the image.
	// This
	// property is read-only.
	RecolorStops []*ColorStop `json:"recolorStops,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Recolor) MarshalJSON() ([]byte, error) {
	type NoMethod Recolor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RefreshSheetsChartRequest: Refreshes an embedded Google Sheets chart
// by replacing it with the latest
// version of the chart from Google Sheets.
//
// NOTE: Refreshing charts requires  at least one of the
// spreadsheets.readonly,
// spreadsheets, drive.readonly, or drive OAuth scopes.
type RefreshSheetsChartRequest struct {
	// ObjectId: The object ID of the chart to refresh.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RefreshSheetsChartRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RefreshSheetsChartRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithImageRequest: Replaces all shapes that match the
// given criteria with the provided image.
//
// The images replacing the shapes are rectangular after being inserted
// into
// the presentation and do not take on the forms of the shapes.
type ReplaceAllShapesWithImageRequest struct {
	// ContainsText: If set, this request will replace all of the shapes
	// that contain the
	// given text.
	ContainsText *SubstringMatchCriteria `json:"containsText,omitempty"`

	// ImageReplaceMethod: The image replace method.
	//
	// If you specify both a `replace_method` and an `image_replace_method`,
	// the
	// `image_replace_method` takes precedence.
	//
	// If you do not specify a value for `image_replace_method`, but specify
	// a
	// value for `replace_method`, then the specified `replace_method` value
	// is
	// used.
	//
	// If you do not specify either, then CENTER_INSIDE is used.
	//
	// Possible values:
	//   "IMAGE_REPLACE_METHOD_UNSPECIFIED" - Unspecified image replace
	// method. This value must not be used.
	//   "CENTER_INSIDE" - Scales and centers the image to fit within the
	// bounds of the original
	// shape and maintains the image's aspect ratio. The rendered size of
	// the
	// image may be smaller than the size of the shape. This is the
	// default
	// method when one is not specified.
	//   "CENTER_CROP" - Scales and centers the image to fill the bounds of
	// the original shape.
	// The image may be cropped in order to fill the shape. The rendered
	// size of
	// the image will be the same as that of the original shape.
	ImageReplaceMethod string `json:"imageReplaceMethod,omitempty"`

	// ImageUrl: The image URL.
	//
	// The image is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Images must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length. The URL itself is
	// saved
	// with the image, and exposed via the Image.source_url field.
	ImageUrl string `json:"imageUrl,omitempty"`

	// PageObjectIds: If non-empty, limits the matches to page elements only
	// on the given pages.
	//
	// Returns a 400 bad request error if given the page object ID of
	// a
	// notes page or a
	// notes master, or if a
	// page with that object ID doesn't exist in the presentation.
	PageObjectIds []string `json:"pageObjectIds,omitempty"`

	// ReplaceMethod: The replace method.
	//
	// <b>Deprecated</b>: use `image_replace_method` instead.
	//
	// If you specify both a `replace_method` and an `image_replace_method`,
	// the
	// `image_replace_method` takes precedence.
	//
	// Possible values:
	//   "CENTER_INSIDE" - Scales and centers the image to fit within the
	// bounds of the original
	// shape and maintains the image's aspect ratio. The rendered size of
	// the
	// image may be smaller than the size of the shape. This is the
	// default
	// method when one is not specified.
	//   "CENTER_CROP" - Scales and centers the image to fill the bounds of
	// the original shape.
	// The image may be cropped in order to fill the shape. The rendered
	// size of
	// the image will be the same as that of the original shape.
	ReplaceMethod string `json:"replaceMethod,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContainsText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContainsText") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithImageRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithImageRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithImageResponse: The result of replacing shapes
// with an image.
type ReplaceAllShapesWithImageResponse struct {
	// OccurrencesChanged: The number of shapes replaced with images.
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OccurrencesChanged")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OccurrencesChanged") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithImageResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithImageResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithSheetsChartRequest: Replaces all shapes that
// match the given criteria with the provided Google
// Sheets chart. The chart will be scaled and centered to fit within the
// bounds
// of the original shape.
//
// NOTE: Replacing shapes with a chart requires at least one of
// the
// spreadsheets.readonly, spreadsheets, drive.readonly, or drive OAuth
// scopes.
type ReplaceAllShapesWithSheetsChartRequest struct {
	// ChartId: The ID of the specific chart in the Google Sheets
	// spreadsheet.
	ChartId int64 `json:"chartId,omitempty"`

	// ContainsText: The criteria that the shapes must match in order to be
	// replaced. The
	// request will replace all of the shapes that contain the given text.
	ContainsText *SubstringMatchCriteria `json:"containsText,omitempty"`

	// LinkingMode: The mode with which the chart is linked to the source
	// spreadsheet. When
	// not specified, the chart will be an image that is not linked.
	//
	// Possible values:
	//   "NOT_LINKED_IMAGE" - The chart is not associated with the source
	// spreadsheet and cannot be
	// updated. A chart that is not linked will be inserted as an image.
	//   "LINKED" - Linking the chart allows it to be updated, and other
	// collaborators will
	// see a link to the spreadsheet.
	LinkingMode string `json:"linkingMode,omitempty"`

	// PageObjectIds: If non-empty, limits the matches to page elements only
	// on the given pages.
	//
	// Returns a 400 bad request error if given the page object ID of
	// a
	// notes page or a
	// notes master, or if a
	// page with that object ID doesn't exist in the presentation.
	PageObjectIds []string `json:"pageObjectIds,omitempty"`

	// SpreadsheetId: The ID of the Google Sheets spreadsheet that contains
	// the chart.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChartId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithSheetsChartRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithSheetsChartRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithSheetsChartResponse: The result of replacing
// shapes with a Google Sheets chart.
type ReplaceAllShapesWithSheetsChartResponse struct {
	// OccurrencesChanged: The number of shapes replaced with charts.
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OccurrencesChanged")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OccurrencesChanged") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithSheetsChartResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithSheetsChartResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllTextRequest: Replaces all instances of text matching a
// criteria with replace text.
type ReplaceAllTextRequest struct {
	// ContainsText: Finds text in a shape matching this substring.
	ContainsText *SubstringMatchCriteria `json:"containsText,omitempty"`

	// PageObjectIds: If non-empty, limits the matches to page elements only
	// on the given pages.
	//
	// Returns a 400 bad request error if given the page object ID of
	// a
	// notes master,
	// or if a page with that object ID doesn't exist in the presentation.
	PageObjectIds []string `json:"pageObjectIds,omitempty"`

	// ReplaceText: The text that will replace the matched text.
	ReplaceText string `json:"replaceText,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContainsText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContainsText") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllTextResponse: The result of replacing text.
type ReplaceAllTextResponse struct {
	// OccurrencesChanged: The number of occurrences changed by replacing
	// all text.
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OccurrencesChanged")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OccurrencesChanged") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllTextResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllTextResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceImageRequest: Replaces an existing image with a new
// image.
//
// Replacing an image removes some image effects from the existing
// image.
type ReplaceImageRequest struct {
	// ImageObjectId: The ID of the existing image that will be replaced.
	ImageObjectId string `json:"imageObjectId,omitempty"`

	// ImageReplaceMethod: The replacement method.
	//
	// Possible values:
	//   "IMAGE_REPLACE_METHOD_UNSPECIFIED" - Unspecified image replace
	// method. This value must not be used.
	//   "CENTER_INSIDE" - Scales and centers the image to fit within the
	// bounds of the original
	// shape and maintains the image's aspect ratio. The rendered size of
	// the
	// image may be smaller than the size of the shape. This is the
	// default
	// method when one is not specified.
	//   "CENTER_CROP" - Scales and centers the image to fill the bounds of
	// the original shape.
	// The image may be cropped in order to fill the shape. The rendered
	// size of
	// the image will be the same as that of the original shape.
	ImageReplaceMethod string `json:"imageReplaceMethod,omitempty"`

	// Url: The URL of the new image.
	//
	// The image is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Images must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length. The URL itself is
	// saved
	// with the image, and exposed via the Image.source_url field.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ImageObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ImageObjectId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceImageRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceImageRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Request: A single kind of update to apply to a presentation.
type Request struct {
	// CreateImage: Creates an image.
	CreateImage *CreateImageRequest `json:"createImage,omitempty"`

	// CreateLine: Creates a line.
	CreateLine *CreateLineRequest `json:"createLine,omitempty"`

	// CreateParagraphBullets: Creates bullets for paragraphs.
	CreateParagraphBullets *CreateParagraphBulletsRequest `json:"createParagraphBullets,omitempty"`

	// CreateShape: Creates a new shape.
	CreateShape *CreateShapeRequest `json:"createShape,omitempty"`

	// CreateSheetsChart: Creates an embedded Google Sheets chart.
	CreateSheetsChart *CreateSheetsChartRequest `json:"createSheetsChart,omitempty"`

	// CreateSlide: Creates a new slide.
	CreateSlide *CreateSlideRequest `json:"createSlide,omitempty"`

	// CreateTable: Creates a new table.
	CreateTable *CreateTableRequest `json:"createTable,omitempty"`

	// CreateVideo: Creates a video.
	CreateVideo *CreateVideoRequest `json:"createVideo,omitempty"`

	// DeleteObject: Deletes a page or page element from the presentation.
	DeleteObject *DeleteObjectRequest `json:"deleteObject,omitempty"`

	// DeleteParagraphBullets: Deletes bullets from paragraphs.
	DeleteParagraphBullets *DeleteParagraphBulletsRequest `json:"deleteParagraphBullets,omitempty"`

	// DeleteTableColumn: Deletes a column from a table.
	DeleteTableColumn *DeleteTableColumnRequest `json:"deleteTableColumn,omitempty"`

	// DeleteTableRow: Deletes a row from a table.
	DeleteTableRow *DeleteTableRowRequest `json:"deleteTableRow,omitempty"`

	// DeleteText: Deletes text from a shape or a table cell.
	DeleteText *DeleteTextRequest `json:"deleteText,omitempty"`

	// DuplicateObject: Duplicates a slide or page element.
	DuplicateObject *DuplicateObjectRequest `json:"duplicateObject,omitempty"`

	// GroupObjects: Groups objects, such as page elements.
	GroupObjects *GroupObjectsRequest `json:"groupObjects,omitempty"`

	// InsertTableColumns: Inserts columns into a table.
	InsertTableColumns *InsertTableColumnsRequest `json:"insertTableColumns,omitempty"`

	// InsertTableRows: Inserts rows into a table.
	InsertTableRows *InsertTableRowsRequest `json:"insertTableRows,omitempty"`

	// InsertText: Inserts text into a shape or table cell.
	InsertText *InsertTextRequest `json:"insertText,omitempty"`

	// MergeTableCells: Merges cells in a Table.
	MergeTableCells *MergeTableCellsRequest `json:"mergeTableCells,omitempty"`

	// RefreshSheetsChart: Refreshes a Google Sheets chart.
	RefreshSheetsChart *RefreshSheetsChartRequest `json:"refreshSheetsChart,omitempty"`

	// ReplaceAllShapesWithImage: Replaces all shapes matching some criteria
	// with an image.
	ReplaceAllShapesWithImage *ReplaceAllShapesWithImageRequest `json:"replaceAllShapesWithImage,omitempty"`

	// ReplaceAllShapesWithSheetsChart: Replaces all shapes matching some
	// criteria with a Google Sheets chart.
	ReplaceAllShapesWithSheetsChart *ReplaceAllShapesWithSheetsChartRequest `json:"replaceAllShapesWithSheetsChart,omitempty"`

	// ReplaceAllText: Replaces all instances of specified text.
	ReplaceAllText *ReplaceAllTextRequest `json:"replaceAllText,omitempty"`

	// ReplaceImage: Replaces an existing image with a new image.
	ReplaceImage *ReplaceImageRequest `json:"replaceImage,omitempty"`

	// RerouteLine: Reroutes a line such that it's connected
	// at the two closest connection sites on the connected page elements.
	RerouteLine *RerouteLineRequest `json:"rerouteLine,omitempty"`

	// UngroupObjects: Ungroups objects, such as groups.
	UngroupObjects *UngroupObjectsRequest `json:"ungroupObjects,omitempty"`

	// UnmergeTableCells: Unmerges cells in a Table.
	UnmergeTableCells *UnmergeTableCellsRequest `json:"unmergeTableCells,omitempty"`

	// UpdateImageProperties: Updates the properties of an Image.
	UpdateImageProperties *UpdateImagePropertiesRequest `json:"updateImageProperties,omitempty"`

	// UpdateLineCategory: Updates the category of a line.
	UpdateLineCategory *UpdateLineCategoryRequest `json:"updateLineCategory,omitempty"`

	// UpdateLineProperties: Updates the properties of a Line.
	UpdateLineProperties *UpdateLinePropertiesRequest `json:"updateLineProperties,omitempty"`

	// UpdatePageElementAltText: Updates the alt text title and/or
	// description of a
	// page element.
	UpdatePageElementAltText *UpdatePageElementAltTextRequest `json:"updatePageElementAltText,omitempty"`

	// UpdatePageElementTransform: Updates the transform of a page element.
	UpdatePageElementTransform *UpdatePageElementTransformRequest `json:"updatePageElementTransform,omitempty"`

	// UpdatePageElementsZOrder: Updates the Z-order of page elements.
	UpdatePageElementsZOrder *UpdatePageElementsZOrderRequest `json:"updatePageElementsZOrder,omitempty"`

	// UpdatePageProperties: Updates the properties of a Page.
	UpdatePageProperties *UpdatePagePropertiesRequest `json:"updatePageProperties,omitempty"`

	// UpdateParagraphStyle: Updates the styling of paragraphs within a
	// Shape or Table.
	UpdateParagraphStyle *UpdateParagraphStyleRequest `json:"updateParagraphStyle,omitempty"`

	// UpdateShapeProperties: Updates the properties of a Shape.
	UpdateShapeProperties *UpdateShapePropertiesRequest `json:"updateShapeProperties,omitempty"`

	// UpdateSlidesPosition: Updates the position of a set of slides in the
	// presentation.
	UpdateSlidesPosition *UpdateSlidesPositionRequest `json:"updateSlidesPosition,omitempty"`

	// UpdateTableBorderProperties: Updates the properties of the table
	// borders in a Table.
	UpdateTableBorderProperties *UpdateTableBorderPropertiesRequest `json:"updateTableBorderProperties,omitempty"`

	// UpdateTableCellProperties: Updates the properties of a TableCell.
	UpdateTableCellProperties *UpdateTableCellPropertiesRequest `json:"updateTableCellProperties,omitempty"`

	// UpdateTableColumnProperties: Updates the properties of a
	// Table
	// column.
	UpdateTableColumnProperties *UpdateTableColumnPropertiesRequest `json:"updateTableColumnProperties,omitempty"`

	// UpdateTableRowProperties: Updates the properties of a Table row.
	UpdateTableRowProperties *UpdateTableRowPropertiesRequest `json:"updateTableRowProperties,omitempty"`

	// UpdateTextStyle: Updates the styling of text within a Shape or Table.
	UpdateTextStyle *UpdateTextStyleRequest `json:"updateTextStyle,omitempty"`

	// UpdateVideoProperties: Updates the properties of a Video.
	UpdateVideoProperties *UpdateVideoPropertiesRequest `json:"updateVideoProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateImage") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreateImage") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Request) MarshalJSON() ([]byte, error) {
	type NoMethod Request
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RerouteLineRequest: Reroutes a line such that it's connected at
// the
// two closest connection sites on the connected page elements.
type RerouteLineRequest struct {
	// ObjectId: The object ID of the line to reroute.
	//
	// Only a line with a category
	// indicating it is a "connector" can be rerouted. The start and
	// end
	// connections of the line must be on different page elements.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RerouteLineRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RerouteLineRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Response: A single response from an update.
type Response struct {
	// CreateImage: The result of creating an image.
	CreateImage *CreateImageResponse `json:"createImage,omitempty"`

	// CreateLine: The result of creating a line.
	CreateLine *CreateLineResponse `json:"createLine,omitempty"`

	// CreateShape: The result of creating a shape.
	CreateShape *CreateShapeResponse `json:"createShape,omitempty"`

	// CreateSheetsChart: The result of creating a Google Sheets chart.
	CreateSheetsChart *CreateSheetsChartResponse `json:"createSheetsChart,omitempty"`

	// CreateSlide: The result of creating a slide.
	CreateSlide *CreateSlideResponse `json:"createSlide,omitempty"`

	// CreateTable: The result of creating a table.
	CreateTable *CreateTableResponse `json:"createTable,omitempty"`

	// CreateVideo: The result of creating a video.
	CreateVideo *CreateVideoResponse `json:"createVideo,omitempty"`

	// DuplicateObject: The result of duplicating an object.
	DuplicateObject *DuplicateObjectResponse `json:"duplicateObject,omitempty"`

	// GroupObjects: The result of grouping objects.
	GroupObjects *GroupObjectsResponse `json:"groupObjects,omitempty"`

	// ReplaceAllShapesWithImage: The result of replacing all shapes
	// matching some criteria with an
	// image.
	ReplaceAllShapesWithImage *ReplaceAllShapesWithImageResponse `json:"replaceAllShapesWithImage,omitempty"`

	// ReplaceAllShapesWithSheetsChart: The result of replacing all shapes
	// matching some criteria with a Google
	// Sheets chart.
	ReplaceAllShapesWithSheetsChart *ReplaceAllShapesWithSheetsChartResponse `json:"replaceAllShapesWithSheetsChart,omitempty"`

	// ReplaceAllText: The result of replacing text.
	ReplaceAllText *ReplaceAllTextResponse `json:"replaceAllText,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateImage") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreateImage") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Response) MarshalJSON() ([]byte, error) {
	type NoMethod Response
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RgbColor: An RGB color.
type RgbColor struct {
	// Blue: The blue component of the color, from 0.0 to 1.0.
	Blue float64 `json:"blue,omitempty"`

	// Green: The green component of the color, from 0.0 to 1.0.
	Green float64 `json:"green,omitempty"`

	// Red: The red component of the color, from 0.0 to 1.0.
	Red float64 `json:"red,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Blue") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Blue") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RgbColor) MarshalJSON() ([]byte, error) {
	type NoMethod RgbColor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *RgbColor) UnmarshalJSON(data []byte) error {
	type NoMethod RgbColor
	var s1 struct {
		Blue  gensupport.JSONFloat64 `json:"blue"`
		Green gensupport.JSONFloat64 `json:"green"`
		Red   gensupport.JSONFloat64 `json:"red"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Blue = float64(s1.Blue)
	s.Green = float64(s1.Green)
	s.Red = float64(s1.Red)
	return nil
}

// Shadow: The shadow properties of a page element.
//
// If these fields are unset, they may be inherited from a parent
// placeholder
// if it exists. If there is no parent, the fields will default to the
// value
// used for new page elements created in the Slides editor, which may
// depend on
// the page element kind.
type Shadow struct {
	// Alignment: The alignment point of the shadow, that sets the origin
	// for translate,
	// scale and skew of the shadow. This property is read-only.
	//
	// Possible values:
	//   "RECTANGLE_POSITION_UNSPECIFIED" - Unspecified.
	//   "TOP_LEFT" - Top left.
	//   "TOP_CENTER" - Top center.
	//   "TOP_RIGHT" - Top right.
	//   "LEFT_CENTER" - Left center.
	//   "CENTER" - Center.
	//   "RIGHT_CENTER" - Right center.
	//   "BOTTOM_LEFT" - Bottom left.
	//   "BOTTOM_CENTER" - Bottom center.
	//   "BOTTOM_RIGHT" - Bottom right.
	Alignment string `json:"alignment,omitempty"`

	// Alpha: The alpha of the shadow's color, from 0.0 to 1.0.
	Alpha float64 `json:"alpha,omitempty"`

	// BlurRadius: The radius of the shadow blur. The larger the radius, the
	// more diffuse the
	// shadow becomes.
	BlurRadius *Dimension `json:"blurRadius,omitempty"`

	// Color: The shadow color value.
	Color *OpaqueColor `json:"color,omitempty"`

	// PropertyState: The shadow property state.
	//
	// Updating the shadow on a page element will implicitly update this
	// field to
	// `RENDERED`, unless another value is specified in the same request. To
	// have
	// no shadow on a page element, set this field to `NOT_RENDERED`. In
	// this
	// case, any other shadow fields set in the same request will be
	// ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// RotateWithShape: Whether the shadow should rotate with the shape.
	// This property is
	// read-only.
	RotateWithShape bool `json:"rotateWithShape,omitempty"`

	// Transform: Transform that encodes the translate, scale, and skew of
	// the shadow,
	// relative to the alignment position.
	Transform *AffineTransform `json:"transform,omitempty"`

	// Type: The type of the shadow. This property is read-only.
	//
	// Possible values:
	//   "SHADOW_TYPE_UNSPECIFIED" - Unspecified shadow type.
	//   "OUTER" - Outer shadow.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alignment") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Shadow) MarshalJSON() ([]byte, error) {
	type NoMethod Shadow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Shadow) UnmarshalJSON(data []byte) error {
	type NoMethod Shadow
	var s1 struct {
		Alpha gensupport.JSONFloat64 `json:"alpha"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	return nil
}

// Shape: A PageElement kind representing a
// generic shape that does not have a more specific classification.
type Shape struct {
	// Placeholder: Placeholders are shapes that are inherit from
	// corresponding placeholders on
	// layouts and masters.
	//
	// If set, the shape is a placeholder shape and any inherited
	// properties
	// can be resolved by looking at the parent placeholder identified by
	// the
	// Placeholder.parent_object_id field.
	Placeholder *Placeholder `json:"placeholder,omitempty"`

	// ShapeProperties: The properties of the shape.
	ShapeProperties *ShapeProperties `json:"shapeProperties,omitempty"`

	// ShapeType: The type of the shape.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The shape type that is not predefined.
	//   "TEXT_BOX" - Text box shape.
	//   "RECTANGLE" - Rectangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'rect'.
	//   "ROUND_RECTANGLE" - Round corner rectangle shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'roundRect'
	//   "ELLIPSE" - Ellipse shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ellipse'
	//   "ARC" - Curved arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'arc'
	//   "BENT_ARROW" - Bent arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentArrow'
	//   "BENT_UP_ARROW" - Bent up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentUpArrow'
	//   "BEVEL" - Bevel shape. Corresponds to ECMA-376 ST_ShapeType 'bevel'
	//   "BLOCK_ARC" - Block arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'blockArc'
	//   "BRACE_PAIR" - Brace pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracePair'
	//   "BRACKET_PAIR" - Bracket pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracketPair'
	//   "CAN" - Can shape. Corresponds to ECMA-376 ST_ShapeType 'can'
	//   "CHEVRON" - Chevron shape. Corresponds to ECMA-376 ST_ShapeType
	// 'chevron'
	//   "CHORD" - Chord shape. Corresponds to ECMA-376 ST_ShapeType 'chord'
	//   "CLOUD" - Cloud shape. Corresponds to ECMA-376 ST_ShapeType 'cloud'
	//   "CORNER" - Corner shape. Corresponds to ECMA-376 ST_ShapeType
	// 'corner'
	//   "CUBE" - Cube shape. Corresponds to ECMA-376 ST_ShapeType 'cube'
	//   "CURVED_DOWN_ARROW" - Curved down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedDownArrow'
	//   "CURVED_LEFT_ARROW" - Curved left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedLeftArrow'
	//   "CURVED_RIGHT_ARROW" - Curved right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedRightArrow'
	//   "CURVED_UP_ARROW" - Curved up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'curvedUpArrow'
	//   "DECAGON" - Decagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'decagon'
	//   "DIAGONAL_STRIPE" - Diagonal stripe shape. Corresponds to ECMA-376
	// ST_ShapeType 'diagStripe'
	//   "DIAMOND" - Diamond shape. Corresponds to ECMA-376 ST_ShapeType
	// 'diamond'
	//   "DODECAGON" - Dodecagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'dodecagon'
	//   "DONUT" - Donut shape. Corresponds to ECMA-376 ST_ShapeType 'donut'
	//   "DOUBLE_WAVE" - Double wave shape. Corresponds to ECMA-376
	// ST_ShapeType 'doubleWave'
	//   "DOWN_ARROW" - Down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'downArrow'
	//   "DOWN_ARROW_CALLOUT" - Callout down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'downArrowCallout'
	//   "FOLDED_CORNER" - Folded corner shape. Corresponds to ECMA-376
	// ST_ShapeType 'foldedCorner'
	//   "FRAME" - Frame shape. Corresponds to ECMA-376 ST_ShapeType 'frame'
	//   "HALF_FRAME" - Half frame shape. Corresponds to ECMA-376
	// ST_ShapeType 'halfFrame'
	//   "HEART" - Heart shape. Corresponds to ECMA-376 ST_ShapeType 'heart'
	//   "HEPTAGON" - Heptagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'heptagon'
	//   "HEXAGON" - Hexagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'hexagon'
	//   "HOME_PLATE" - Home plate shape. Corresponds to ECMA-376
	// ST_ShapeType 'homePlate'
	//   "HORIZONTAL_SCROLL" - Horizontal scroll shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'horizontalScroll'
	//   "IRREGULAR_SEAL_1" - Irregular seal 1 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal1'
	//   "IRREGULAR_SEAL_2" - Irregular seal 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal2'
	//   "LEFT_ARROW" - Left arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftArrow'
	//   "LEFT_ARROW_CALLOUT" - Callout left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftArrowCallout'
	//   "LEFT_BRACE" - Left brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBrace'
	//   "LEFT_BRACKET" - Left bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBracket'
	//   "LEFT_RIGHT_ARROW" - Left right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightArrow'
	//   "LEFT_RIGHT_ARROW_CALLOUT" - Callout left right arrow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'leftRightArrowCallout'
	//   "LEFT_RIGHT_UP_ARROW" - Left right up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightUpArrow'
	//   "LEFT_UP_ARROW" - Left up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftUpArrow'
	//   "LIGHTNING_BOLT" - Lightning bolt shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'lightningBolt'
	//   "MATH_DIVIDE" - Divide math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathDivide'
	//   "MATH_EQUAL" - Equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathEqual'
	//   "MATH_MINUS" - Minus math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMinus'
	//   "MATH_MULTIPLY" - Multiply math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMultiply'
	//   "MATH_NOT_EQUAL" - Not equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathNotEqual'
	//   "MATH_PLUS" - Plus math shape. Corresponds to ECMA-376 ST_ShapeType
	// 'mathPlus'
	//   "MOON" - Moon shape. Corresponds to ECMA-376 ST_ShapeType 'moon'
	//   "NO_SMOKING" - No smoking shape. Corresponds to ECMA-376
	// ST_ShapeType 'noSmoking'
	//   "NOTCHED_RIGHT_ARROW" - Notched right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'notchedRightArrow'
	//   "OCTAGON" - Octagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'octagon'
	//   "PARALLELOGRAM" - Parallelogram shape. Corresponds to ECMA-376
	// ST_ShapeType 'parallelogram'
	//   "PENTAGON" - Pentagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'pentagon'
	//   "PIE" - Pie shape. Corresponds to ECMA-376 ST_ShapeType 'pie'
	//   "PLAQUE" - Plaque shape. Corresponds to ECMA-376 ST_ShapeType
	// 'plaque'
	//   "PLUS" - Plus shape. Corresponds to ECMA-376 ST_ShapeType 'plus'
	//   "QUAD_ARROW" - Quad-arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'quadArrow'
	//   "QUAD_ARROW_CALLOUT" - Callout quad-arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'quadArrowCallout'
	//   "RIBBON" - Ribbon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon'
	//   "RIBBON_2" - Ribbon 2 shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon2'
	//   "RIGHT_ARROW" - Right arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightArrow'
	//   "RIGHT_ARROW_CALLOUT" - Callout right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'rightArrowCallout'
	//   "RIGHT_BRACE" - Right brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBrace'
	//   "RIGHT_BRACKET" - Right bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBracket'
	//   "ROUND_1_RECTANGLE" - One round corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'round1Rect'
	//   "ROUND_2_DIAGONAL_RECTANGLE" - Two diagonal round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2DiagRect'
	//   "ROUND_2_SAME_RECTANGLE" - Two same-side round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2SameRect'
	//   "RIGHT_TRIANGLE" - Right triangle shape. Corresponds to ECMA-376
	// ST_ShapeType 'rtTriangle'
	//   "SMILEY_FACE" - Smiley face shape. Corresponds to ECMA-376
	// ST_ShapeType 'smileyFace'
	//   "SNIP_1_RECTANGLE" - One snip corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'snip1Rect'
	//   "SNIP_2_DIAGONAL_RECTANGLE" - Two diagonal snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2DiagRect'
	//   "SNIP_2_SAME_RECTANGLE" - Two same-side snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2SameRect'
	//   "SNIP_ROUND_RECTANGLE" - One snip one round corner rectangle shape.
	// Corresponds to ECMA-376
	// ST_ShapeType 'snipRoundRect'
	//   "STAR_10" - Ten pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star10'
	//   "STAR_12" - Twelve pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star12'
	//   "STAR_16" - Sixteen pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star16'
	//   "STAR_24" - Twenty four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star24'
	//   "STAR_32" - Thirty two pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star32'
	//   "STAR_4" - Four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star4'
	//   "STAR_5" - Five pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star5'
	//   "STAR_6" - Six pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star6'
	//   "STAR_7" - Seven pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star7'
	//   "STAR_8" - Eight pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star8'
	//   "STRIPED_RIGHT_ARROW" - Striped right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'stripedRightArrow'
	//   "SUN" - Sun shape. Corresponds to ECMA-376 ST_ShapeType 'sun'
	//   "TRAPEZOID" - Trapezoid shape. Corresponds to ECMA-376 ST_ShapeType
	// 'trapezoid'
	//   "TRIANGLE" - Triangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'triangle'
	//   "UP_ARROW" - Up arrow shape. Corresponds to ECMA-376 ST_ShapeType
	// 'upArrow'
	//   "UP_ARROW_CALLOUT" - Callout up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'upArrowCallout'
	//   "UP_DOWN_ARROW" - Up down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'upDownArrow'
	//   "UTURN_ARROW" - U-turn arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'uturnArrow'
	//   "VERTICAL_SCROLL" - Vertical scroll shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'verticalScroll'
	//   "WAVE" - Wave shape. Corresponds to ECMA-376 ST_ShapeType 'wave'
	//   "WEDGE_ELLIPSE_CALLOUT" - Callout wedge ellipse shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'wedgeEllipseCallout'
	//   "WEDGE_RECTANGLE_CALLOUT" - Callout wedge rectangle shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRectCallout'
	//   "WEDGE_ROUND_RECTANGLE_CALLOUT" - Callout wedge round rectangle
	// shape. Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRoundRectCallout'
	//   "FLOW_CHART_ALTERNATE_PROCESS" - Alternate process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartAlternateProcess'
	//   "FLOW_CHART_COLLATE" - Collate flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartCollate'
	//   "FLOW_CHART_CONNECTOR" - Connector flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartConnector'
	//   "FLOW_CHART_DECISION" - Decision flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDecision'
	//   "FLOW_CHART_DELAY" - Delay flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartDelay'
	//   "FLOW_CHART_DISPLAY" - Display flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartDisplay'
	//   "FLOW_CHART_DOCUMENT" - Document flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDocument'
	//   "FLOW_CHART_EXTRACT" - Extract flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartExtract'
	//   "FLOW_CHART_INPUT_OUTPUT" - Input output flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartInputOutput'
	//   "FLOW_CHART_INTERNAL_STORAGE" - Internal storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartInternalStorage'
	//   "FLOW_CHART_MAGNETIC_DISK" - Magnetic disk flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDisk'
	//   "FLOW_CHART_MAGNETIC_DRUM" - Magnetic drum flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDrum'
	//   "FLOW_CHART_MAGNETIC_TAPE" - Magnetic tape flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticTape'
	//   "FLOW_CHART_MANUAL_INPUT" - Manual input flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartManualInput'
	//   "FLOW_CHART_MANUAL_OPERATION" - Manual operation flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartManualOperation'
	//   "FLOW_CHART_MERGE" - Merge flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartMerge'
	//   "FLOW_CHART_MULTIDOCUMENT" - Multi-document flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMultidocument'
	//   "FLOW_CHART_OFFLINE_STORAGE" - Offline storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOfflineStorage'
	//   "FLOW_CHART_OFFPAGE_CONNECTOR" - Off-page connector flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOffpageConnector'
	//   "FLOW_CHART_ONLINE_STORAGE" - Online storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOnlineStorage'
	//   "FLOW_CHART_OR" - Or flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartOr'
	//   "FLOW_CHART_PREDEFINED_PROCESS" - Predefined process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartPredefinedProcess'
	//   "FLOW_CHART_PREPARATION" - Preparation flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPreparation'
	//   "FLOW_CHART_PROCESS" - Process flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartProcess'
	//   "FLOW_CHART_PUNCHED_CARD" - Punched card flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedCard'
	//   "FLOW_CHART_PUNCHED_TAPE" - Punched tape flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedTape'
	//   "FLOW_CHART_SORT" - Sort flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartSort'
	//   "FLOW_CHART_SUMMING_JUNCTION" - Summing junction flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartSummingJunction'
	//   "FLOW_CHART_TERMINATOR" - Terminator flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartTerminator'
	//   "ARROW_EAST" - East arrow shape.
	//   "ARROW_NORTH_EAST" - Northeast arrow shape.
	//   "ARROW_NORTH" - North arrow shape.
	//   "SPEECH" - Speech shape.
	//   "STARBURST" - Star burst shape.
	//   "TEARDROP" - Teardrop shape. Corresponds to ECMA-376 ST_ShapeType
	// 'teardrop'
	//   "ELLIPSE_RIBBON" - Ellipse ribbon shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'ellipseRibbon'
	//   "ELLIPSE_RIBBON_2" - Ellipse ribbon 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'ellipseRibbon2'
	//   "CLOUD_CALLOUT" - Callout cloud shape. Corresponds to ECMA-376
	// ST_ShapeType 'cloudCallout'
	//   "CUSTOM" - Custom shape.
	ShapeType string `json:"shapeType,omitempty"`

	// Text: The text content of the shape.
	Text *TextContent `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Placeholder") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Placeholder") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Shape) MarshalJSON() ([]byte, error) {
	type NoMethod Shape
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShapeBackgroundFill: The shape background fill.
type ShapeBackgroundFill struct {
	// PropertyState: The background fill property state.
	//
	// Updating the fill on a shape will implicitly update this field
	// to
	// `RENDERED`, unless another value is specified in the same request.
	// To
	// have no fill on a shape, set this field to `NOT_RENDERED`. In this
	// case,
	// any other fill fields set in the same request will be ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PropertyState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PropertyState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ShapeBackgroundFill) MarshalJSON() ([]byte, error) {
	type NoMethod ShapeBackgroundFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShapeProperties: The properties of a Shape.
//
// If the shape is a placeholder shape as determined by the
// placeholder field, then these
// properties may be inherited from a parent placeholder
// shape.
// Determining the rendered value of the property depends on the
// corresponding
// property_state field value.
type ShapeProperties struct {
	// ContentAlignment: The alignment of the content in the shape. If
	// unspecified,
	// the alignment is inherited from a parent placeholder if it exists. If
	// the
	// shape has no parent, the default alignment matches the alignment for
	// new
	// shapes created in the Slides editor.
	//
	// Possible values:
	//   "CONTENT_ALIGNMENT_UNSPECIFIED" - An unspecified content alignment.
	// The content alignment is inherited from
	// the parent if it exists.
	//   "CONTENT_ALIGNMENT_UNSUPPORTED" - An unsupported content alignment.
	//   "TOP" - An alignment that aligns the content to the top of the
	// content holder.
	// Corresponds to ECMA-376 ST_TextAnchoringType 't'.
	//   "MIDDLE" - An alignment that aligns the content to the middle of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'ctr'.
	//   "BOTTOM" - An alignment that aligns the content to the bottom of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'b'.
	ContentAlignment string `json:"contentAlignment,omitempty"`

	// Link: The hyperlink destination of the shape. If unset, there is no
	// link. Links
	// are not inherited from parent placeholders.
	Link *Link `json:"link,omitempty"`

	// Outline: The outline of the shape. If unset, the outline is inherited
	// from a
	// parent placeholder if it exists. If the shape has no parent, then
	// the
	// default outline depends on the shape type, matching the defaults
	// for
	// new shapes created in the Slides editor.
	Outline *Outline `json:"outline,omitempty"`

	// Shadow: The shadow properties of the shape. If unset, the shadow is
	// inherited from
	// a parent placeholder if it exists. If the shape has no parent, then
	// the
	// default shadow matches the defaults for new shapes created in the
	// Slides
	// editor. This property is read-only.
	Shadow *Shadow `json:"shadow,omitempty"`

	// ShapeBackgroundFill: The background fill of the shape. If unset, the
	// background fill is
	// inherited from a parent placeholder if it exists. If the shape has
	// no
	// parent, then the default background fill depends on the shape
	// type,
	// matching the defaults for new shapes created in the Slides editor.
	ShapeBackgroundFill *ShapeBackgroundFill `json:"shapeBackgroundFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentAlignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentAlignment") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ShapeProperties) MarshalJSON() ([]byte, error) {
	type NoMethod ShapeProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SheetsChart: A PageElement kind representing
// a linked chart embedded from Google Sheets.
type SheetsChart struct {
	// ChartId: The ID of the specific chart in the Google Sheets
	// spreadsheet that is
	// embedded.
	ChartId int64 `json:"chartId,omitempty"`

	// ContentUrl: The URL of an image of the embedded chart, with a default
	// lifetime of 30
	// minutes. This URL is tagged with the account of the requester. Anyone
	// with
	// the URL effectively accesses the image as the original requester.
	// Access to
	// the image may be lost if the presentation's sharing settings change.
	ContentUrl string `json:"contentUrl,omitempty"`

	// SheetsChartProperties: The properties of the Sheets chart.
	SheetsChartProperties *SheetsChartProperties `json:"sheetsChartProperties,omitempty"`

	// SpreadsheetId: The ID of the Google Sheets spreadsheet that contains
	// the source chart.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChartId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SheetsChart) MarshalJSON() ([]byte, error) {
	type NoMethod SheetsChart
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SheetsChartProperties: The properties of the SheetsChart.
type SheetsChartProperties struct {
	// ChartImageProperties: The properties of the embedded chart image.
	ChartImageProperties *ImageProperties `json:"chartImageProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ChartImageProperties") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartImageProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SheetsChartProperties) MarshalJSON() ([]byte, error) {
	type NoMethod SheetsChartProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Size: A width and height.
type Size struct {
	// Height: The height of the object.
	Height *Dimension `json:"height,omitempty"`

	// Width: The width of the object.
	Width *Dimension `json:"width,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Height") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Height") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Size) MarshalJSON() ([]byte, error) {
	type NoMethod Size
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SlideProperties: The properties of Page that are only
// relevant for pages with page_type SLIDE.
type SlideProperties struct {
	// LayoutObjectId: The object ID of the layout that this slide is based
	// on. This property is
	// read-only.
	LayoutObjectId string `json:"layoutObjectId,omitempty"`

	// MasterObjectId: The object ID of the master that this slide is based
	// on. This property is
	// read-only.
	MasterObjectId string `json:"masterObjectId,omitempty"`

	// NotesPage: The notes page that this slide is associated with. It
	// defines the visual
	// appearance of a notes page when printing or exporting slides with
	// speaker
	// notes. A notes page inherits properties from the
	// notes master.
	// The placeholder shape with type BODY on the notes page contains the
	// speaker
	// notes for this slide. The ID of this shape is identified by
	// the
	// speakerNotesObjectId field.
	// The notes page is read-only except for the text content and styles of
	// the
	// speaker notes shape. This property is read-only.
	NotesPage *Page `json:"notesPage,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LayoutObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutObjectId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SlideProperties) MarshalJSON() ([]byte, error) {
	type NoMethod SlideProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SolidFill: A solid color fill. The page or page element is filled
// entirely with the
// specified color value.
//
// If any field is unset, its value may be inherited from a parent
// placeholder
// if it exists.
type SolidFill struct {
	// Alpha: The fraction of this `color` that should be applied to the
	// pixel.
	// That is, the final pixel color is defined by the equation:
	//
	//   pixel color = alpha * (color) + (1.0 - alpha) * (background
	// color)
	//
	// This means that a value of 1.0 corresponds to a solid color,
	// whereas
	// a value of 0.0 corresponds to a completely transparent color.
	Alpha float64 `json:"alpha,omitempty"`

	// Color: The color value of the solid fill.
	Color *OpaqueColor `json:"color,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alpha") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alpha") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SolidFill) MarshalJSON() ([]byte, error) {
	type NoMethod SolidFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *SolidFill) UnmarshalJSON(data []byte) error {
	type NoMethod SolidFill
	var s1 struct {
		Alpha gensupport.JSONFloat64 `json:"alpha"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	return nil
}

// StretchedPictureFill: The stretched picture fill. The page or page
// element is filled entirely with
// the specified picture. The picture is stretched to fit its container.
type StretchedPictureFill struct {
	// ContentUrl: Reading the content_url:
	//
	// An URL to a picture with a default lifetime of 30 minutes.
	// This URL is tagged with the account of the requester. Anyone with the
	// URL
	// effectively accesses the picture as the original requester. Access to
	// the
	// picture may be lost if the presentation's sharing settings
	// change.
	//
	// Writing the content_url:
	//
	// The picture is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Pictures must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length.
	ContentUrl string `json:"contentUrl,omitempty"`

	// Size: The original size of the picture fill. This field is read-only.
	Size *Size `json:"size,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentUrl") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *StretchedPictureFill) MarshalJSON() ([]byte, error) {
	type NoMethod StretchedPictureFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubstringMatchCriteria: A criteria that matches a specific string of
// text in a shape or table.
type SubstringMatchCriteria struct {
	// MatchCase: Indicates whether the search should respect case:
	//
	// - `True`: the search is case sensitive.
	// - `False`: the search is case insensitive.
	MatchCase bool `json:"matchCase,omitempty"`

	// Text: The text to search for in the shape or table.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MatchCase") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MatchCase") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubstringMatchCriteria) MarshalJSON() ([]byte, error) {
	type NoMethod SubstringMatchCriteria
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Table: A PageElement kind representing a
// table.
type Table struct {
	// Columns: Number of columns in the table.
	Columns int64 `json:"columns,omitempty"`

	// HorizontalBorderRows: Properties of horizontal cell borders.
	//
	// A table's horizontal cell borders are represented as a grid. The grid
	// has
	// one more row than the number of rows in the table and the same number
	// of
	// columns as the table. For example, if the table is 3 x 3, its
	// horizontal
	// borders will be represented as a grid with 4 rows and 3 columns.
	HorizontalBorderRows []*TableBorderRow `json:"horizontalBorderRows,omitempty"`

	// Rows: Number of rows in the table.
	Rows int64 `json:"rows,omitempty"`

	// TableColumns: Properties of each column.
	TableColumns []*TableColumnProperties `json:"tableColumns,omitempty"`

	// TableRows: Properties and contents of each row.
	//
	// Cells that span multiple rows are contained in only one of these rows
	// and
	// have a row_span greater
	// than 1.
	TableRows []*TableRow `json:"tableRows,omitempty"`

	// VerticalBorderRows: Properties of vertical cell borders.
	//
	// A table's vertical cell borders are represented as a grid. The grid
	// has the
	// same number of rows as the table and one more column than the number
	// of
	// columns in the table. For example, if the table is 3 x 3, its
	// vertical
	// borders will be represented as a grid with 3 rows and 4 columns.
	VerticalBorderRows []*TableBorderRow `json:"verticalBorderRows,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Columns") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Columns") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Table) MarshalJSON() ([]byte, error) {
	type NoMethod Table
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderCell: The properties of each border cell.
type TableBorderCell struct {
	// Location: The location of the border within the border table.
	Location *TableCellLocation `json:"location,omitempty"`

	// TableBorderProperties: The border properties.
	TableBorderProperties *TableBorderProperties `json:"tableBorderProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Location") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Location") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderCell) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderCell
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderFill: The fill of the border.
type TableBorderFill struct {
	// SolidFill: Solid fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SolidFill") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SolidFill") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderFill) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderProperties: The border styling properties of
// the
// TableBorderCell.
type TableBorderProperties struct {
	// DashStyle: The dash style of the border.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'.
	// This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	//   "DASH_DOT" - Alternating dashes and dots. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'dashDot'.
	//   "LONG_DASH" - Line with large dashes. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'lgDash'.
	//   "LONG_DASH_DOT" - Alternating large dashes and dots. Corresponds to
	// ECMA-376
	// ST_PresetLineDashVal value 'lgDashDot'.
	DashStyle string `json:"dashStyle,omitempty"`

	// TableBorderFill: The fill of the table border.
	TableBorderFill *TableBorderFill `json:"tableBorderFill,omitempty"`

	// Weight: The thickness of the border.
	Weight *Dimension `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DashStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DashStyle") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderRow: Contents of each border row in a table.
type TableBorderRow struct {
	// TableBorderCells: Properties of each border cell. When a border's
	// adjacent table cells are
	// merged, it is not included in the response.
	TableBorderCells []*TableBorderCell `json:"tableBorderCells,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TableBorderCells") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TableBorderCells") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderRow) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderRow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCell: Properties and contents of each table cell.
type TableCell struct {
	// ColumnSpan: Column span of the cell.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// Location: The location of the cell within the table.
	Location *TableCellLocation `json:"location,omitempty"`

	// RowSpan: Row span of the cell.
	RowSpan int64 `json:"rowSpan,omitempty"`

	// TableCellProperties: The properties of the table cell.
	TableCellProperties *TableCellProperties `json:"tableCellProperties,omitempty"`

	// Text: The text content of the cell.
	Text *TextContent `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnSpan") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnSpan") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableCell) MarshalJSON() ([]byte, error) {
	type NoMethod TableCell
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellBackgroundFill: The table cell background fill.
type TableCellBackgroundFill struct {
	// PropertyState: The background fill property state.
	//
	// Updating the fill on a table cell will implicitly update this
	// field
	// to `RENDERED`, unless another value is specified in the same request.
	// To
	// have no fill on a table cell, set this field to `NOT_RENDERED`. In
	// this
	// case, any other fill fields set in the same request will be ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PropertyState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PropertyState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableCellBackgroundFill) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellBackgroundFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellLocation: A location of a single table cell within a table.
type TableCellLocation struct {
	// ColumnIndex: The 0-based column index.
	ColumnIndex int64 `json:"columnIndex,omitempty"`

	// RowIndex: The 0-based row index.
	RowIndex int64 `json:"rowIndex,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnIndex") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableCellLocation) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellLocation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellProperties: The properties of the TableCell.
type TableCellProperties struct {
	// ContentAlignment: The alignment of the content in the table cell. The
	// default alignment
	// matches the alignment for newly created table cells in the Slides
	// editor.
	//
	// Possible values:
	//   "CONTENT_ALIGNMENT_UNSPECIFIED" - An unspecified content alignment.
	// The content alignment is inherited from
	// the parent if it exists.
	//   "CONTENT_ALIGNMENT_UNSUPPORTED" - An unsupported content alignment.
	//   "TOP" - An alignment that aligns the content to the top of the
	// content holder.
	// Corresponds to ECMA-376 ST_TextAnchoringType 't'.
	//   "MIDDLE" - An alignment that aligns the content to the middle of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'ctr'.
	//   "BOTTOM" - An alignment that aligns the content to the bottom of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'b'.
	ContentAlignment string `json:"contentAlignment,omitempty"`

	// TableCellBackgroundFill: The background fill of the table cell. The
	// default fill matches the fill
	// for newly created table cells in the Slides editor.
	TableCellBackgroundFill *TableCellBackgroundFill `json:"tableCellBackgroundFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentAlignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentAlignment") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TableCellProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableColumnProperties: Properties of each column in a table.
type TableColumnProperties struct {
	// ColumnWidth: Width of a column.
	ColumnWidth *Dimension `json:"columnWidth,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnWidth") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnWidth") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableColumnProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableColumnProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableRange: A table range represents a reference to a subset of a
// table.
//
// It's important to note that the cells specified by a table range do
// not
// necessarily form a rectangle. For example, let's say we have a 3 x 3
// table
// where all the cells of the last row are merged together. The table
// looks
// like this:
//
//
//      [             ]
//
// A table range with location = (0, 0), row span = 3 and column span =
// 2
// specifies the following cells:
//
//       x     x
//      [ x    x    x ]
type TableRange struct {
	// ColumnSpan: The column span of the table range.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// Location: The starting location of the table range.
	Location *TableCellLocation `json:"location,omitempty"`

	// RowSpan: The row span of the table range.
	RowSpan int64 `json:"rowSpan,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnSpan") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnSpan") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableRange) MarshalJSON() ([]byte, error) {
	type NoMethod TableRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableRow: Properties and contents of each row in a table.
type TableRow struct {
	// RowHeight: Height of a row.
	RowHeight *Dimension `json:"rowHeight,omitempty"`

	// TableCells: Properties and contents of each cell.
	//
	// Cells that span multiple columns are represented only once with
	// a
	// column_span greater
	// than 1. As a result, the length of this collection does not always
	// match
	// the number of columns of the entire table.
	TableCells []*TableCell `json:"tableCells,omitempty"`

	// TableRowProperties: Properties of the row.
	TableRowProperties *TableRowProperties `json:"tableRowProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RowHeight") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RowHeight") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableRow) MarshalJSON() ([]byte, error) {
	type NoMethod TableRow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableRowProperties: Properties of each row in a table.
type TableRowProperties struct {
	// MinRowHeight: Minimum height of the row. The row will be rendered in
	// the Slides editor at
	// a height equal to or greater than this value in order to show all the
	// text
	// in the row's cell(s).
	MinRowHeight *Dimension `json:"minRowHeight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MinRowHeight") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MinRowHeight") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableRowProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableRowProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextContent: The general text content. The text must reside in a
// compatible shape (e.g.
// text box or rectangle) or a table cell in a page.
type TextContent struct {
	// Lists: The bulleted lists contained in this text, keyed by list ID.
	Lists map[string]List `json:"lists,omitempty"`

	// TextElements: The text contents broken down into its component parts,
	// including styling
	// information. This property is read-only.
	TextElements []*TextElement `json:"textElements,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Lists") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Lists") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TextContent) MarshalJSON() ([]byte, error) {
	type NoMethod TextContent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextElement: A TextElement describes the content of a range of
// indices in the text content
// of a Shape or TableCell.
type TextElement struct {
	// AutoText: A TextElement representing a spot in the text that is
	// dynamically
	// replaced with content that can change over time.
	AutoText *AutoText `json:"autoText,omitempty"`

	// EndIndex: The zero-based end index of this text element, exclusive,
	// in Unicode code
	// units.
	EndIndex int64 `json:"endIndex,omitempty"`

	// ParagraphMarker: A marker representing the beginning of a new
	// paragraph.
	//
	// The `start_index` and `end_index` of this TextElement represent
	// the
	// range of the paragraph. Other TextElements with an index range
	// contained
	// inside this paragraph's range are considered to be part of
	// this
	// paragraph. The range of indices of two separate paragraphs will
	// never
	// overlap.
	ParagraphMarker *ParagraphMarker `json:"paragraphMarker,omitempty"`

	// StartIndex: The zero-based start index of this text element, in
	// Unicode code units.
	StartIndex int64 `json:"startIndex,omitempty"`

	// TextRun: A TextElement representing a run of text where all of the
	// characters
	// in the run have the same TextStyle.
	//
	// The `start_index` and `end_index` of TextRuns will always be
	// fully
	// contained in the index range of a single `paragraph_marker`
	// TextElement.
	// In other words, a TextRun will never span multiple paragraphs.
	TextRun *TextRun `json:"textRun,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoText") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TextElement) MarshalJSON() ([]byte, error) {
	type NoMethod TextElement
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextRun: A TextElement kind that represents a run of text that all
// has the same
// styling.
type TextRun struct {
	// Content: The text of this run.
	Content string `json:"content,omitempty"`

	// Style: The styling applied to this run.
	Style *TextStyle `json:"style,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Content") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Content") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TextRun) MarshalJSON() ([]byte, error) {
	type NoMethod TextRun
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextStyle: Represents the styling that can be applied to a
// TextRun.
//
// If this text is contained in a shape with a parent placeholder, then
// these text styles may be
// inherited from the parent. Which text styles are inherited depend on
// the
// nesting level of lists:
//
// * A text run in a paragraph that is not in a list will inherit its
// text style
//   from the the newline character in the paragraph at the 0 nesting
// level of
//   the list inside the parent placeholder.
// * A text run in a paragraph that is in a list will inherit its text
// style
//   from the newline character in the paragraph at its corresponding
// nesting
//   level of the list inside the parent placeholder.
//
// Inherited text styles are represented as unset fields in this
// message. If
// text is contained in a shape without a parent placeholder, unsetting
// these
// fields will revert the style to a value matching the defaults in the
// Slides
// editor.
type TextStyle struct {
	// BackgroundColor: The background color of the text. If set, the color
	// is either opaque or
	// transparent, depending on if the `opaque_color` field in it is set.
	BackgroundColor *OptionalColor `json:"backgroundColor,omitempty"`

	// BaselineOffset: The text's vertical offset from its normal
	// position.
	//
	// Text with `SUPERSCRIPT` or `SUBSCRIPT` baseline offsets is
	// automatically
	// rendered in a smaller font size, computed based on the `font_size`
	// field.
	// The `font_size` itself is not affected by changes in this field.
	//
	// Possible values:
	//   "BASELINE_OFFSET_UNSPECIFIED" - The text's baseline offset is
	// inherited from the parent.
	//   "NONE" - The text is not vertically offset.
	//   "SUPERSCRIPT" - The text is vertically offset upwards
	// (superscript).
	//   "SUBSCRIPT" - The text is vertically offset downwards (subscript).
	BaselineOffset string `json:"baselineOffset,omitempty"`

	// Bold: Whether or not the text is rendered as bold.
	Bold bool `json:"bold,omitempty"`

	// FontFamily: The font family of the text.
	//
	// The font family can be any font from the Font menu in Slides or
	// from
	// [Google Fonts] (https://fonts.google.com/). If the font name
	// is
	// unrecognized, the text is rendered in `Arial`.
	//
	// Some fonts can affect the weight of the text. If an update
	// request
	// specifies values for both `font_family` and `bold`, the
	// explicitly-set
	// `bold` value is used.
	FontFamily string `json:"fontFamily,omitempty"`

	// FontSize: The size of the text's font. When read, the `font_size`
	// will specified in
	// points.
	FontSize *Dimension `json:"fontSize,omitempty"`

	// ForegroundColor: The color of the text itself. If set, the color is
	// either opaque or
	// transparent, depending on if the `opaque_color` field in it is set.
	ForegroundColor *OptionalColor `json:"foregroundColor,omitempty"`

	// Italic: Whether or not the text is italicized.
	Italic bool `json:"italic,omitempty"`

	// Link: The hyperlink destination of the text. If unset, there is no
	// link. Links
	// are not inherited from parent text.
	//
	// Changing the link in an update request causes some other changes to
	// the
	// text style of the range:
	//
	// * When setting a link, the text foreground color will be set to
	//   ThemeColorType.HYPERLINK and the text will
	//   be underlined. If these fields are modified in the same
	//   request, those values will be used instead of the link defaults.
	// * Setting a link on a text range that overlaps with an existing link
	// will
	//   also update the existing link to point to the new URL.
	// * Links are not settable on newline characters. As a result, setting
	// a link
	//   on a text range that crosses a paragraph boundary, such as
	// "ABC\n123",
	//   will separate the newline character(s) into their own text runs.
	// The
	//   link will be applied separately to the runs before and after the
	// newline.
	// * Removing a link will update the text style of the range to match
	// the
	//   style of the preceding text (or the default text styles if the
	// preceding
	//   text is another link) unless different styles are being set in the
	// same
	//   request.
	Link *Link `json:"link,omitempty"`

	// SmallCaps: Whether or not the text is in small capital letters.
	SmallCaps bool `json:"smallCaps,omitempty"`

	// Strikethrough: Whether or not the text is struck through.
	Strikethrough bool `json:"strikethrough,omitempty"`

	// Underline: Whether or not the text is underlined.
	Underline bool `json:"underline,omitempty"`

	// WeightedFontFamily: The font family and rendered weight of the
	// text.
	//
	// This field is an extension of `font_family` meant to support explicit
	// font
	// weights without breaking backwards compatibility. As such, when
	// reading the
	// style of a range of text, the value of
	// `weighted_font_family#font_family`
	// will always be equal to that of `font_family`. However, when writing,
	// if
	// both fields are included in the field mask (either explicitly or
	// through
	// the wildcard "*"), their values are reconciled as follows:
	//
	// * If `font_family` is set and `weighted_font_family` is not, the
	// value of
	//   `font_family` is applied with weight `400` ("normal").
	// * If both fields are set, the value of `font_family` must match that
	// of
	//   `weighted_font_family#font_family`. If so, the font family and
	// weight of
	//   `weighted_font_family` is applied. Otherwise, a 400 bad request
	// error is
	//   returned.
	// * If `weighted_font_family` is set and `font_family` is not, the
	// font
	//   family and weight of `weighted_font_family` is applied.
	// * If neither field is set, the font family and weight of the text
	// inherit
	//   from the parent. Note that these properties cannot inherit
	// separately
	//   from each other.
	//
	// If an update request specifies values for both `weighted_font_family`
	// and
	// `bold`, the `weighted_font_family` is applied first, then `bold`.
	//
	// If `weighted_font_family#weight` is not set, it defaults to
	// `400`.
	//
	// If `weighted_font_family` is set, then
	// `weighted_font_family#font_family`
	// must also be set with a non-empty value. Otherwise, a 400 bad request
	// error
	// is returned.
	WeightedFontFamily *WeightedFontFamily `json:"weightedFontFamily,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackgroundColor") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackgroundColor") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TextStyle) MarshalJSON() ([]byte, error) {
	type NoMethod TextStyle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ThemeColorPair: A pair mapping a theme color type to the concrete
// color it represents.
type ThemeColorPair struct {
	// Color: The concrete color corresponding to the theme color type
	// above.
	Color *RgbColor `json:"color,omitempty"`

	// Type: The type of the theme color.
	//
	// Possible values:
	//   "THEME_COLOR_TYPE_UNSPECIFIED" - Unspecified theme color. This
	// value should not be used.
	//   "DARK1" - Represents the first dark color.
	//   "LIGHT1" - Represents the first light color.
	//   "DARK2" - Represents the second dark color.
	//   "LIGHT2" - Represents the second light color.
	//   "ACCENT1" - Represents the first accent color.
	//   "ACCENT2" - Represents the second accent color.
	//   "ACCENT3" - Represents the third accent color.
	//   "ACCENT4" - Represents the fourth accent color.
	//   "ACCENT5" - Represents the fifth accent color.
	//   "ACCENT6" - Represents the sixth accent color.
	//   "HYPERLINK" - Represents the color to use for hyperlinks.
	//   "FOLLOWED_HYPERLINK" - Represents the color to use for visited
	// hyperlinks.
	//   "TEXT1" - Represents the first text color.
	//   "BACKGROUND1" - Represents the first background color.
	//   "TEXT2" - Represents the second text color.
	//   "BACKGROUND2" - Represents the second background color.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Color") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ThemeColorPair) MarshalJSON() ([]byte, error) {
	type NoMethod ThemeColorPair
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Thumbnail: The thumbnail of a page.
type Thumbnail struct {
	// ContentUrl: The content URL of the thumbnail image.
	//
	// The URL to the image has a default lifetime of 30 minutes.
	// This URL is tagged with the account of the requester. Anyone with the
	// URL
	// effectively accesses the image as the original requester. Access to
	// the
	// image may be lost if the presentation's sharing settings change.
	// The mime type of the thumbnail image is the same as specified in
	// the
	// `GetPageThumbnailRequest`.
	ContentUrl string `json:"contentUrl,omitempty"`

	// Height: The positive height in pixels of the thumbnail image.
	Height int64 `json:"height,omitempty"`

	// Width: The positive width in pixels of the thumbnail image.
	Width int64 `json:"width,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ContentUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentUrl") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Thumbnail) MarshalJSON() ([]byte, error) {
	type NoMethod Thumbnail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UngroupObjectsRequest: Ungroups objects, such as groups.
type UngroupObjectsRequest struct {
	// ObjectIds: The object IDs of the objects to ungroup.
	//
	// Only groups that are not inside other
	// groups can be ungrouped. All the groups
	// should be on the same page. The group itself is deleted. The visual
	// sizes
	// and positions of all the children are preserved.
	ObjectIds []string `json:"objectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectIds") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectIds") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UngroupObjectsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UngroupObjectsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UnmergeTableCellsRequest: Unmerges cells in a Table.
type UnmergeTableCellsRequest struct {
	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableRange: The table range specifying which cells of the table to
	// unmerge.
	//
	// All merged cells in this range will be unmerged, and cells that are
	// already
	// unmerged will not be affected. If the range has no merged cells,
	// the
	// request will do nothing. If there is text in any of the merged cells,
	// the
	// text will remain in the upper-left ("head") cell of the resulting
	// block of
	// unmerged cells.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UnmergeTableCellsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UnmergeTableCellsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateImagePropertiesRequest: Update the properties of an Image.
type UpdateImagePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `imageProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the image outline color, set `fields`
	// to
	// "outline.outlineFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ImageProperties: The image properties to update.
	ImageProperties *ImageProperties `json:"imageProperties,omitempty"`

	// ObjectId: The object ID of the image the updates are applied to.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateImagePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateImagePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateLineCategoryRequest: Updates the category of a line.
type UpdateLineCategoryRequest struct {
	// LineCategory: The line category to update to.
	//
	// The exact line type is determined based
	// on the category to update to and how it's routed to connect to other
	// page
	// elements.
	//
	// Possible values:
	//   "LINE_CATEGORY_UNSPECIFIED" - Unspecified line category.
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	LineCategory string `json:"lineCategory,omitempty"`

	// ObjectId: The object ID of the line the update is applied to.
	//
	// Only a line with a category
	// indicating it is a "connector" can be updated.
	//
	// The line may be rerouted after updating its category.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LineCategory") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LineCategory") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateLineCategoryRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateLineCategoryRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateLinePropertiesRequest: Updates the properties of a Line.
type UpdateLinePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `lineProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the line solid fill color, set `fields`
	// to
	// "lineFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// LineProperties: The line properties to update.
	LineProperties *LineProperties `json:"lineProperties,omitempty"`

	// ObjectId: The object ID of the line the update is applied to.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateLinePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateLinePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePageElementAltTextRequest: Updates the alt text title and/or
// description of a
// page element.
type UpdatePageElementAltTextRequest struct {
	// Description: The updated alt text description of the page element. If
	// unset the existing
	// value will be maintained. The description is exposed to screen
	// readers
	// and other accessibility interfaces. Only use human readable values
	// related
	// to the content of the page element.
	Description string `json:"description,omitempty"`

	// ObjectId: The object ID of the page element the updates are applied
	// to.
	ObjectId string `json:"objectId,omitempty"`

	// Title: The updated alt text title of the page element. If unset
	// the
	// existing value will be maintained. The title is exposed to screen
	// readers
	// and other accessibility interfaces. Only use human readable values
	// related
	// to the content of the page element.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePageElementAltTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePageElementAltTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePageElementTransformRequest: Updates the transform of a page
// element.
//
// Updating the transform of a group will change the absolute transform
// of the
// page elements in that group, which can change their visual
// appearance. See
// the documentation for PageElement.transform for more details.
type UpdatePageElementTransformRequest struct {
	// ApplyMode: The apply mode of the transform update.
	//
	// Possible values:
	//   "APPLY_MODE_UNSPECIFIED" - Unspecified mode.
	//   "RELATIVE" - Applies the new AffineTransform matrix to the existing
	// one, and
	// replaces the existing one with the resulting concatenation.
	//   "ABSOLUTE" - Replaces the existing AffineTransform matrix with the
	// new one.
	ApplyMode string `json:"applyMode,omitempty"`

	// ObjectId: The object ID of the page element to update.
	ObjectId string `json:"objectId,omitempty"`

	// Transform: The input transform matrix used to update the page
	// element.
	Transform *AffineTransform `json:"transform,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApplyMode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApplyMode") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePageElementTransformRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePageElementTransformRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePageElementsZOrderRequest: Updates the Z-order of page
// elements. Z-order is an ordering of the elements
// on the page from back to front. The page element in the front may
// cover the
// elements that are behind it.
type UpdatePageElementsZOrderRequest struct {
	// Operation: The Z-order operation to apply on the page elements.
	//
	// When applying the operation on multiple page elements, the
	// relative
	// Z-orders within these page elements before the operation is
	// maintained.
	//
	// Possible values:
	//   "Z_ORDER_OPERATION_UNSPECIFIED" - Unspecified operation.
	//   "BRING_TO_FRONT" - Brings the page elements to the front of the
	// page.
	//   "BRING_FORWARD" - Brings the page elements forward on the page by
	// one element relative to the
	// forwardmost one in the specified page elements.
	//   "SEND_BACKWARD" - Sends the page elements backward on the page by
	// one element relative to the
	// furthest behind one in the specified page elements.
	//   "SEND_TO_BACK" - Sends the page elements to the back of the page.
	Operation string `json:"operation,omitempty"`

	// PageElementObjectIds: The object IDs of the page elements to
	// update.
	//
	// All the page elements must be on the same page and must not be
	// grouped.
	PageElementObjectIds []string `json:"pageElementObjectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Operation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Operation") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePageElementsZOrderRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePageElementsZOrderRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePagePropertiesRequest: Updates the properties of a Page.
type UpdatePagePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `pageProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the page background solid fill color, set
	// `fields`
	// to "pageBackgroundFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the page the update is applied to.
	ObjectId string `json:"objectId,omitempty"`

	// PageProperties: The page properties to update.
	PageProperties *PageProperties `json:"pageProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePagePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePagePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateParagraphStyleRequest: Updates the styling for all of the
// paragraphs within a Shape or Table that
// overlap with the given text index range.
type UpdateParagraphStyleRequest struct {
	// CellLocation: The location of the cell in the table containing the
	// paragraph(s) to
	// style. If `object_id` refers to a table, `cell_location` must have a
	// value.
	// Otherwise, it must not.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `style` is implied
	// and
	// should not be specified. A single "*" can be used as short-hand
	// for
	// listing every field.
	//
	// For example, to update the paragraph alignment, set `fields`
	// to
	// "alignment".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the shape or table with the text to be
	// styled.
	ObjectId string `json:"objectId,omitempty"`

	// Style: The paragraph's style.
	Style *ParagraphStyle `json:"style,omitempty"`

	// TextRange: The range of text containing the paragraph(s) to style.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateParagraphStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateParagraphStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateShapePropertiesRequest: Update the properties of a Shape.
type UpdateShapePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `shapeProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the shape background solid fill color, set
	// `fields`
	// to "shapeBackgroundFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the shape the updates are applied to.
	ObjectId string `json:"objectId,omitempty"`

	// ShapeProperties: The shape properties to update.
	ShapeProperties *ShapeProperties `json:"shapeProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateShapePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateShapePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateSlidesPositionRequest: Updates the position of slides in the
// presentation.
type UpdateSlidesPositionRequest struct {
	// InsertionIndex: The index where the slides should be inserted, based
	// on the slide
	// arrangement before the move takes place. Must be between zero and
	// the
	// number of slides in the presentation, inclusive.
	InsertionIndex int64 `json:"insertionIndex,omitempty"`

	// SlideObjectIds: The IDs of the slides in the presentation that should
	// be moved.
	// The slides in this list must be in existing presentation order,
	// without
	// duplicates.
	SlideObjectIds []string `json:"slideObjectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InsertionIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InsertionIndex") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *UpdateSlidesPositionRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateSlidesPositionRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableBorderPropertiesRequest: Updates the properties of the
// table borders in a Table.
type UpdateTableBorderPropertiesRequest struct {
	// BorderPosition: The border position in the table range the updates
	// should apply to. If a
	// border position is not specified, the updates will apply to all
	// borders in
	// the table range.
	//
	// Possible values:
	//   "ALL" - All borders in the range.
	//   "BOTTOM" - Borders at the bottom of the range.
	//   "INNER" - Borders on the inside of the range.
	//   "INNER_HORIZONTAL" - Horizontal borders on the inside of the range.
	//   "INNER_VERTICAL" - Vertical borders on the inside of the range.
	//   "LEFT" - Borders at the left of the range.
	//   "OUTER" - Borders along the outside of the range.
	//   "RIGHT" - Borders at the right of the range.
	//   "TOP" - Borders at the top of the range.
	BorderPosition string `json:"borderPosition,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root
	// `tableBorderProperties` is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the table border solid fill color, set
	// `fields` to "tableBorderFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableBorderProperties: The table border properties to update.
	TableBorderProperties *TableBorderProperties `json:"tableBorderProperties,omitempty"`

	// TableRange: The table range representing the subset of the table to
	// which the updates
	// are applied. If a table range is not specified, the updates will
	// apply to
	// the entire table.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BorderPosition") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BorderPosition") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableBorderPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableBorderPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableCellPropertiesRequest: Update the properties of a
// TableCell.
type UpdateTableCellPropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `tableCellProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the table cell background solid fill color,
	// set
	// `fields` to "tableCellBackgroundFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableCellProperties: The table cell properties to update.
	TableCellProperties *TableCellProperties `json:"tableCellProperties,omitempty"`

	// TableRange: The table range representing the subset of the table to
	// which the updates
	// are applied. If a table range is not specified, the updates will
	// apply to
	// the entire table.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableCellPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableCellPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableColumnPropertiesRequest: Updates the properties of a Table
// column.
type UpdateTableColumnPropertiesRequest struct {
	// ColumnIndices: The list of zero-based indices specifying which
	// columns to update. If no
	// indices are provided, all columns in the table will be updated.
	ColumnIndices []int64 `json:"columnIndices,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root
	// `tableColumnProperties` is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the column width, set `fields` to
	// "column_width".
	//
	// If '"column_width"' is included in the field mask but the property is
	// left
	// unset, the column width will default to 406,400 EMU (32 points).
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableColumnProperties: The table column properties to update.
	//
	// If the value of `table_column_properties#column_width` in the request
	// is
	// less than 406,400 EMU (32 points), a 400 bad request error is
	// returned.
	TableColumnProperties *TableColumnProperties `json:"tableColumnProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnIndices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnIndices") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableColumnPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableColumnPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableRowPropertiesRequest: Updates the properties of a Table
// row.
type UpdateTableRowPropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `tableRowProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the minimum row height, set `fields`
	// to
	// "min_row_height".
	//
	// If '"min_row_height"' is included in the field mask but the property
	// is
	// left unset, the minimum row height will default to 0.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// RowIndices: The list of zero-based indices specifying which rows to
	// update. If no
	// indices are provided, all rows in the table will be updated.
	RowIndices []int64 `json:"rowIndices,omitempty"`

	// TableRowProperties: The table row properties to update.
	TableRowProperties *TableRowProperties `json:"tableRowProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableRowPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableRowPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTextStyleRequest: Update the styling of text in a Shape
// or
// Table.
type UpdateTextStyleRequest struct {
	// CellLocation: The location of the cell in the table containing the
	// text to style. If
	// `object_id` refers to a table, `cell_location` must have a
	// value.
	// Otherwise, it must not.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `style` is implied
	// and
	// should not be specified. A single "*" can be used as short-hand
	// for
	// listing every field.
	//
	// For example, to update the text style to bold, set `fields` to
	// "bold".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the shape or table with the text to be
	// styled.
	ObjectId string `json:"objectId,omitempty"`

	// Style: The style(s) to set on the text.
	//
	// If the value for a particular style matches that of the parent, that
	// style
	// will be set to inherit.
	//
	// Certain text style changes may cause other changes meant to mirror
	// the
	// behavior of the Slides editor. See the documentation of
	// TextStyle for more information.
	Style *TextStyle `json:"style,omitempty"`

	// TextRange: The range of text to style.
	//
	// The range may be extended to include adjacent newlines.
	//
	// If the range fully contains a paragraph belonging to a list,
	// the
	// paragraph's bullet is also updated with the matching text style.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTextStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTextStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateVideoPropertiesRequest: Update the properties of a Video.
type UpdateVideoPropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `videoProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the video outline color, set `fields`
	// to
	// "outline.outlineFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the video the updates are applied to.
	ObjectId string `json:"objectId,omitempty"`

	// VideoProperties: The video properties to update.
	VideoProperties *VideoProperties `json:"videoProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateVideoPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateVideoPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Video: A PageElement kind representing a
// video.
type Video struct {
	// Id: The video source's unique identifier for this video.
	Id string `json:"id,omitempty"`

	// Source: The video source.
	//
	// Possible values:
	//   "SOURCE_UNSPECIFIED" - The video source is unspecified.
	//   "YOUTUBE" - The video source is YouTube.
	//   "DRIVE" - The video source is Google Drive.
	Source string `json:"source,omitempty"`

	// Url: An URL to a video. The URL is valid as long as the source video
	// exists and
	// sharing settings do not change.
	Url string `json:"url,omitempty"`

	// VideoProperties: The properties of the video.
	VideoProperties *VideoProperties `json:"videoProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Video) MarshalJSON() ([]byte, error) {
	type NoMethod Video
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VideoProperties: The properties of the Video.
type VideoProperties struct {
	// AutoPlay: Whether to enable video autoplay when the page is displayed
	// in present
	// mode. Defaults to false.
	AutoPlay bool `json:"autoPlay,omitempty"`

	// End: The time at which to end playback, measured in seconds from the
	// beginning
	// of the video.
	// If set, the end time should be after the start time.
	// If not set or if you set this to a value that exceeds the video's
	// length,
	// the video will be played until its end.
	End int64 `json:"end,omitempty"`

	// Mute: Whether to mute the audio during video playback. Defaults to
	// false.
	Mute bool `json:"mute,omitempty"`

	// Outline: The outline of the video. The default outline matches the
	// defaults for new
	// videos created in the Slides editor.
	Outline *Outline `json:"outline,omitempty"`

	// Start: The time at which to start playback, measured in seconds from
	// the beginning
	// of the video.
	// If set, the start time should be before the end time.
	// If you set this to a value that exceeds the video's length in
	// seconds, the
	// video will be played from the last second.
	// If not set, the video will be played from the beginning.
	Start int64 `json:"start,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoPlay") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoPlay") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VideoProperties) MarshalJSON() ([]byte, error) {
	type NoMethod VideoProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WeightedFontFamily: Represents a font family and weight used to style
// a TextRun.
type WeightedFontFamily struct {
	// FontFamily: The font family of the text.
	//
	// The font family can be any font from the Font menu in Slides or
	// from
	// [Google Fonts] (https://fonts.google.com/). If the font name
	// is
	// unrecognized, the text is rendered in `Arial`.
	FontFamily string `json:"fontFamily,omitempty"`

	// Weight: The rendered weight of the text. This field can have any
	// value that is a
	// multiple of `100` between `100` and `900`, inclusive. This
	// range
	// corresponds to the numerical values described in the CSS
	// 2.1
	// Specification,
	// [section
	// 15.6](https://www.w3.org/TR/CSS21/fonts.html#font-boldness),
	// with non-numerical values disallowed. Weights greater than or equal
	// to
	// `700` are considered bold, and weights less than `700`are not bold.
	// The
	// default value is `400` ("normal").
	Weight int64 `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FontFamily") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "FontFamily") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *WeightedFontFamily) MarshalJSON() ([]byte, error) {
	type NoMethod WeightedFontFamily
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WordArt: A PageElement kind representing
// word art.
type WordArt struct {
	// RenderedText: The text rendered as word art.
	RenderedText string `json:"renderedText,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RenderedText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RenderedText") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *WordArt) MarshalJSON() ([]byte, error) {
	type NoMethod WordArt
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WriteControl: Provides control over how write requests are executed.
type WriteControl struct {
	// RequiredRevisionId: The revision ID of the presentation required for
	// the write request. If
	// specified and the `required_revision_id` doesn't exactly match
	// the
	// presentation's current `revision_id`, the request will not be
	// processed and
	// will return a 400 bad request error.
	RequiredRevisionId string `json:"requiredRevisionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RequiredRevisionId")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RequiredRevisionId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *WriteControl) MarshalJSON() ([]byte, error) {
	type NoMethod WriteControl
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "slides.presentations.batchUpdate":

type PresentationsBatchUpdateCall struct {
	s                              *Service
	presentationId                 string
	batchupdatepresentationrequest *BatchUpdatePresentationRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// BatchUpdate: Applies one or more updates to the presentation.
//
// Each request is validated before
// being applied. If any request is not valid, then the entire request
// will
// fail and nothing will be applied.
//
// Some requests have replies to
// give you some information about how they are applied. Other requests
// do
// not need to return information; these each return an empty reply.
// The order of replies matches that of the requests.
//
// For example, suppose you call batchUpdate with four updates, and only
// the
// third one returns information. The response would have two empty
// replies:
// the reply to the third request, and another empty reply, in that
// order.
//
// Because other users may be editing the presentation, the
// presentation
// might not exactly reflect your changes: your changes may
// be altered with respect to collaborator changes. If there are
// no
// collaborators, the presentation should reflect your changes. In any
// case,
// the updates in your request are guaranteed to be applied
// together
// atomically.
func (r *PresentationsService) BatchUpdate(presentationId string, batchupdatepresentationrequest *BatchUpdatePresentationRequest) *PresentationsBatchUpdateCall {
	c := &PresentationsBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	c.batchupdatepresentationrequest = batchupdatepresentationrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsBatchUpdateCall) Fields(s ...googleapi.Field) *PresentationsBatchUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsBatchUpdateCall) Context(ctx context.Context) *PresentationsBatchUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190802")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.batchupdatepresentationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{presentationId}:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.batchUpdate" call.
// Exactly one of *BatchUpdatePresentationResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchUpdatePresentationResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PresentationsBatchUpdateCall) Do(opts ...googleapi.CallOption) (*BatchUpdatePresentationResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchUpdatePresentationResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Applies one or more updates to the presentation.\n\nEach request is validated before\nbeing applied. If any request is not valid, then the entire request will\nfail and nothing will be applied.\n\nSome requests have replies to\ngive you some information about how they are applied. Other requests do\nnot need to return information; these each return an empty reply.\nThe order of replies matches that of the requests.\n\nFor example, suppose you call batchUpdate with four updates, and only the\nthird one returns information. The response would have two empty replies:\nthe reply to the third request, and another empty reply, in that order.\n\nBecause other users may be editing the presentation, the presentation\nmight not exactly reflect your changes: your changes may\nbe altered with respect to collaborator changes. If there are no\ncollaborators, the presentation should reflect your changes. In any case,\nthe updates in your request are guaranteed to be applied together\natomically.",
	//   "flatPath": "v1/presentations/{presentationId}:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "slides.presentations.batchUpdate",
	//   "parameterOrder": [
	//     "presentationId"
	//   ],
	//   "parameters": {
	//     "presentationId": {
	//       "description": "The presentation to apply the updates to.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{presentationId}:batchUpdate",
	//   "request": {
	//     "$ref": "BatchUpdatePresentationRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdatePresentationResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/spreadsheets",
	//     "https://www.googleapis.com/auth/spreadsheets.readonly"
	//   ]
	// }

}

// method id "slides.presentations.create":

type PresentationsCreateCall struct {
	s            *Service
	presentation *Presentation
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a blank presentation using the title given in the
// request. If a
// `presentationId` is provided, it is used as the ID of the new
// presentation.
// Otherwise, a new ID is generated. Other fields in the request,
// including
// any provided content, are ignored.
// Returns the created presentation.
func (r *PresentationsService) Create(presentation *Presentation) *PresentationsCreateCall {
	c := &PresentationsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentation = presentation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsCreateCall) Fields(s ...googleapi.Field) *PresentationsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsCreateCall) Context(ctx context.Context) *PresentationsCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190802")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.presentation)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.create" call.
// Exactly one of *Presentation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Presentation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PresentationsCreateCall) Do(opts ...googleapi.CallOption) (*Presentation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Presentation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a blank presentation using the title given in the request. If a\n`presentationId` is provided, it is used as the ID of the new presentation.\nOtherwise, a new ID is generated. Other fields in the request, including\nany provided content, are ignored.\nReturns the created presentation.",
	//   "flatPath": "v1/presentations",
	//   "httpMethod": "POST",
	//   "id": "slides.presentations.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/presentations",
	//   "request": {
	//     "$ref": "Presentation"
	//   },
	//   "response": {
	//     "$ref": "Presentation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/presentations"
	//   ]
	// }

}

// method id "slides.presentations.get":

type PresentationsGetCall struct {
	s              *Service
	presentationId string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Gets the latest version of the specified presentation.
func (r *PresentationsService) Get(presentationId string) *PresentationsGetCall {
	c := &PresentationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsGetCall) Fields(s ...googleapi.Field) *PresentationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PresentationsGetCall) IfNoneMatch(entityTag string) *PresentationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsGetCall) Context(ctx context.Context) *PresentationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190802")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{+presentationId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.get" call.
// Exactly one of *Presentation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Presentation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PresentationsGetCall) Do(opts ...googleapi.CallOption) (*Presentation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Presentation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest version of the specified presentation.",
	//   "flatPath": "v1/presentations/{presentationsId}",
	//   "httpMethod": "GET",
	//   "id": "slides.presentations.get",
	//   "parameterOrder": [
	//     "presentationId"
	//   ],
	//   "parameters": {
	//     "presentationId": {
	//       "description": "The ID of the presentation to retrieve.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{+presentationId}",
	//   "response": {
	//     "$ref": "Presentation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/presentations.readonly"
	//   ]
	// }

}

// method id "slides.presentations.pages.get":

type PresentationsPagesGetCall struct {
	s              *Service
	presentationId string
	pageObjectId   string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Gets the latest version of the specified page in the
// presentation.
func (r *PresentationsPagesService) Get(presentationId string, pageObjectId string) *PresentationsPagesGetCall {
	c := &PresentationsPagesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	c.pageObjectId = pageObjectId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsPagesGetCall) Fields(s ...googleapi.Field) *PresentationsPagesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PresentationsPagesGetCall) IfNoneMatch(entityTag string) *PresentationsPagesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsPagesGetCall) Context(ctx context.Context) *PresentationsPagesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsPagesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsPagesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190802")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{presentationId}/pages/{pageObjectId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
		"pageObjectId":   c.pageObjectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.pages.get" call.
// Exactly one of *Page or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Page.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *PresentationsPagesGetCall) Do(opts ...googleapi.CallOption) (*Page, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Page{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest version of the specified page in the presentation.",
	//   "flatPath": "v1/presentations/{presentationId}/pages/{pageObjectId}",
	//   "httpMethod": "GET",
	//   "id": "slides.presentations.pages.get",
	//   "parameterOrder": [
	//     "presentationId",
	//     "pageObjectId"
	//   ],
	//   "parameters": {
	//     "pageObjectId": {
	//       "description": "The object ID of the page to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "presentationId": {
	//       "description": "The ID of the presentation to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{presentationId}/pages/{pageObjectId}",
	//   "response": {
	//     "$ref": "Page"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/presentations.readonly"
	//   ]
	// }

}

// method id "slides.presentations.pages.getThumbnail":

type PresentationsPagesGetThumbnailCall struct {
	s              *Service
	presentationId string
	pageObjectId   string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// GetThumbnail: Generates a thumbnail of the latest version of the
// specified page in the
// presentation and returns a URL to the thumbnail image.
//
// This request counts as an [expensive read request](/slides/limits)
// for
// quota purposes.
func (r *PresentationsPagesService) GetThumbnail(presentationId string, pageObjectId string) *PresentationsPagesGetThumbnailCall {
	c := &PresentationsPagesGetThumbnailCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	c.pageObjectId = pageObjectId
	return c
}

// ThumbnailPropertiesMimeType sets the optional parameter
// "thumbnailProperties.mimeType": The optional mime type of the
// thumbnail image.
//
// If you don't specify the mime type, the default mime type will be
// PNG.
//
// Possible values:
//   "PNG"
func (c *PresentationsPagesGetThumbnailCall) ThumbnailPropertiesMimeType(thumbnailPropertiesMimeType string) *PresentationsPagesGetThumbnailCall {
	c.urlParams_.Set("thumbnailProperties.mimeType", thumbnailPropertiesMimeType)
	return c
}

// ThumbnailPropertiesThumbnailSize sets the optional parameter
// "thumbnailProperties.thumbnailSize": The optional thumbnail image
// size.
//
// If you don't specify the size, the server chooses a default size of
// the
// image.
//
// Possible values:
//   "THUMBNAIL_SIZE_UNSPECIFIED"
//   "LARGE"
//   "MEDIUM"
//   "SMALL"
func (c *PresentationsPagesGetThumbnailCall) ThumbnailPropertiesThumbnailSize(thumbnailPropertiesThumbnailSize string) *PresentationsPagesGetThumbnailCall {
	c.urlParams_.Set("thumbnailProperties.thumbnailSize", thumbnailPropertiesThumbnailSize)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsPagesGetThumbnailCall) Fields(s ...googleapi.Field) *PresentationsPagesGetThumbnailCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PresentationsPagesGetThumbnailCall) IfNoneMatch(entityTag string) *PresentationsPagesGetThumbnailCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsPagesGetThumbnailCall) Context(ctx context.Context) *PresentationsPagesGetThumbnailCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsPagesGetThumbnailCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsPagesGetThumbnailCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190802")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
		"pageObjectId":   c.pageObjectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.pages.getThumbnail" call.
// Exactly one of *Thumbnail or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Thumbnail.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PresentationsPagesGetThumbnailCall) Do(opts ...googleapi.CallOption) (*Thumbnail, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Thumbnail{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generates a thumbnail of the latest version of the specified page in the\npresentation and returns a URL to the thumbnail image.\n\nThis request counts as an [expensive read request](/slides/limits) for\nquota purposes.",
	//   "flatPath": "v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail",
	//   "httpMethod": "GET",
	//   "id": "slides.presentations.pages.getThumbnail",
	//   "parameterOrder": [
	//     "presentationId",
	//     "pageObjectId"
	//   ],
	//   "parameters": {
	//     "pageObjectId": {
	//       "description": "The object ID of the page whose thumbnail to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "presentationId": {
	//       "description": "The ID of the presentation to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "thumbnailProperties.mimeType": {
	//       "description": "The optional mime type of the thumbnail image.\n\nIf you don't specify the mime type, the default mime type will be PNG.",
	//       "enum": [
	//         "PNG"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "thumbnailProperties.thumbnailSize": {
	//       "description": "The optional thumbnail image size.\n\nIf you don't specify the size, the server chooses a default size of the\nimage.",
	//       "enum": [
	//         "THUMBNAIL_SIZE_UNSPECIFIED",
	//         "LARGE",
	//         "MEDIUM",
	//         "SMALL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail",
	//   "response": {
	//     "$ref": "Thumbnail"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/presentations.readonly"
	//   ]
	// }

}
