google-cloud-profiler-v2 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,526 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2023 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Auto-generated by gapic-generator-ruby. DO NOT EDIT!
18
+
19
+ require "google/cloud/errors"
20
+ require "google/devtools/cloudprofiler/v2/profiler_pb"
21
+ require "google/cloud/profiler/v2/profiler_service/rest/service_stub"
22
+
23
+ module Google
24
+ module Cloud
25
+ module Profiler
26
+ module V2
27
+ module ProfilerService
28
+ module Rest
29
+ ##
30
+ # REST client for the ProfilerService service.
31
+ #
32
+ # Manage the collection of continuous profiling data provided by profiling
33
+ # agents running in the cloud or by an offline provider of profiling data.
34
+ #
35
+ # General guidelines:
36
+ # * Profiles for a single deployment must be created in ascending time order.
37
+ # * Profiles can be created in either online or offline mode, see below.
38
+ #
39
+ class Client
40
+ include Paths
41
+
42
+ # @private
43
+ attr_reader :profiler_service_stub
44
+
45
+ ##
46
+ # Configure the ProfilerService Client class.
47
+ #
48
+ # See {::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client::Configuration}
49
+ # for a description of the configuration fields.
50
+ #
51
+ # @example
52
+ #
53
+ # # Modify the configuration for all ProfilerService clients
54
+ # ::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client.configure do |config|
55
+ # config.timeout = 10.0
56
+ # end
57
+ #
58
+ # @yield [config] Configure the Client client.
59
+ # @yieldparam config [Client::Configuration]
60
+ #
61
+ # @return [Client::Configuration]
62
+ #
63
+ def self.configure
64
+ @configure ||= begin
65
+ namespace = ["Google", "Cloud", "Profiler", "V2"]
66
+ parent_config = while namespace.any?
67
+ parent_name = namespace.join "::"
68
+ parent_const = const_get parent_name
69
+ break parent_const.configure if parent_const.respond_to? :configure
70
+ namespace.pop
71
+ end
72
+ default_config = Client::Configuration.new parent_config
73
+
74
+ default_config.timeout = 60.0
75
+ default_config.retry_policy = {
76
+ initial_delay: 1.0, max_delay: 10.0, multiplier: 1.3, retry_codes: [14]
77
+ }
78
+
79
+ default_config.rpcs.create_profile.timeout = 3610.0
80
+
81
+ default_config.rpcs.create_offline_profile.timeout = 30.0
82
+
83
+ default_config.rpcs.update_profile.timeout = 30.0
84
+
85
+ default_config
86
+ end
87
+ yield @configure if block_given?
88
+ @configure
89
+ end
90
+
91
+ ##
92
+ # Configure the ProfilerService Client instance.
93
+ #
94
+ # The configuration is set to the derived mode, meaning that values can be changed,
95
+ # but structural changes (adding new fields, etc.) are not allowed. Structural changes
96
+ # should be made on {Client.configure}.
97
+ #
98
+ # See {::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client::Configuration}
99
+ # for a description of the configuration fields.
100
+ #
101
+ # @yield [config] Configure the Client client.
102
+ # @yieldparam config [Client::Configuration]
103
+ #
104
+ # @return [Client::Configuration]
105
+ #
106
+ def configure
107
+ yield @config if block_given?
108
+ @config
109
+ end
110
+
111
+ ##
112
+ # Create a new ProfilerService REST client object.
113
+ #
114
+ # @example
115
+ #
116
+ # # Create a client using the default configuration
117
+ # client = ::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client.new
118
+ #
119
+ # # Create a client using a custom configuration
120
+ # client = ::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client.new do |config|
121
+ # config.timeout = 10.0
122
+ # end
123
+ #
124
+ # @yield [config] Configure the ProfilerService client.
125
+ # @yieldparam config [Client::Configuration]
126
+ #
127
+ def initialize
128
+ # Create the configuration object
129
+ @config = Configuration.new Client.configure
130
+
131
+ # Yield the configuration if needed
132
+ yield @config if block_given?
133
+
134
+ # Create credentials
135
+ credentials = @config.credentials
136
+ # Use self-signed JWT if the endpoint is unchanged from default,
137
+ # but only if the default endpoint does not have a region prefix.
138
+ enable_self_signed_jwt = @config.endpoint == Client.configure.endpoint &&
139
+ !@config.endpoint.split(".").first.include?("-")
140
+ credentials ||= Credentials.default scope: @config.scope,
141
+ enable_self_signed_jwt: enable_self_signed_jwt
142
+ if credentials.is_a?(::String) || credentials.is_a?(::Hash)
143
+ credentials = Credentials.new credentials, scope: @config.scope
144
+ end
145
+
146
+ @quota_project_id = @config.quota_project
147
+ @quota_project_id ||= credentials.quota_project_id if credentials.respond_to? :quota_project_id
148
+
149
+ @profiler_service_stub = ::Google::Cloud::Profiler::V2::ProfilerService::Rest::ServiceStub.new endpoint: @config.endpoint, credentials: credentials
150
+ end
151
+
152
+ # Service calls
153
+
154
+ ##
155
+ # CreateProfile creates a new profile resource in the online mode.
156
+ #
157
+ # The server ensures that the new profiles are created at a constant rate per
158
+ # deployment, so the creation request may hang for some time until the next
159
+ # profile session is available.
160
+ #
161
+ # The request may fail with ABORTED error if the creation is not available
162
+ # within ~1m, the response will indicate the duration of the backoff the
163
+ # client should take before attempting creating a profile again. The backoff
164
+ # duration is returned in google.rpc.RetryInfo extension on the response
165
+ # status. To a gRPC client, the extension will be return as a
166
+ # binary-serialized proto in the trailing metadata item named
167
+ # "google.rpc.retryinfo-bin".
168
+ #
169
+ # @overload create_profile(request, options = nil)
170
+ # Pass arguments to `create_profile` via a request object, either of type
171
+ # {::Google::Cloud::Profiler::V2::CreateProfileRequest} or an equivalent Hash.
172
+ #
173
+ # @param request [::Google::Cloud::Profiler::V2::CreateProfileRequest, ::Hash]
174
+ # A request object representing the call parameters. Required. To specify no
175
+ # parameters, or to keep all the default parameter values, pass an empty Hash.
176
+ # @param options [::Gapic::CallOptions, ::Hash]
177
+ # Overrides the default settings for this call, e.g, timeout, retries etc. Optional.
178
+ #
179
+ # @overload create_profile(parent: nil, deployment: nil, profile_type: nil)
180
+ # Pass arguments to `create_profile` via keyword arguments. Note that at
181
+ # least one keyword argument is required. To specify no parameters, or to keep all
182
+ # the default parameter values, pass an empty Hash as a request object (see above).
183
+ #
184
+ # @param parent [::String]
185
+ # Parent project to create the profile in.
186
+ # @param deployment [::Google::Cloud::Profiler::V2::Deployment, ::Hash]
187
+ # Deployment details.
188
+ # @param profile_type [::Array<::Google::Cloud::Profiler::V2::ProfileType>]
189
+ # One or more profile types that the agent is capable of providing.
190
+ # @yield [result, operation] Access the result along with the TransportOperation object
191
+ # @yieldparam result [::Google::Cloud::Profiler::V2::Profile]
192
+ # @yieldparam operation [::Gapic::Rest::TransportOperation]
193
+ #
194
+ # @return [::Google::Cloud::Profiler::V2::Profile]
195
+ #
196
+ # @raise [::Google::Cloud::Error] if the REST call is aborted.
197
+ def create_profile request, options = nil
198
+ raise ::ArgumentError, "request must be provided" if request.nil?
199
+
200
+ request = ::Gapic::Protobuf.coerce request, to: ::Google::Cloud::Profiler::V2::CreateProfileRequest
201
+
202
+ # Converts hash and nil to an options object
203
+ options = ::Gapic::CallOptions.new(**options.to_h) if options.respond_to? :to_h
204
+
205
+ # Customize the options with defaults
206
+ call_metadata = @config.rpcs.create_profile.metadata.to_h
207
+
208
+ # Set x-goog-api-client and x-goog-user-project headers
209
+ call_metadata[:"x-goog-api-client"] ||= ::Gapic::Headers.x_goog_api_client \
210
+ lib_name: @config.lib_name, lib_version: @config.lib_version,
211
+ gapic_version: ::Google::Cloud::Profiler::V2::VERSION,
212
+ transports_version_send: [:rest]
213
+
214
+ call_metadata[:"x-goog-user-project"] = @quota_project_id if @quota_project_id
215
+
216
+ options.apply_defaults timeout: @config.rpcs.create_profile.timeout,
217
+ metadata: call_metadata,
218
+ retry_policy: @config.rpcs.create_profile.retry_policy
219
+
220
+ options.apply_defaults timeout: @config.timeout,
221
+ metadata: @config.metadata,
222
+ retry_policy: @config.retry_policy
223
+
224
+ @profiler_service_stub.create_profile request, options do |result, operation|
225
+ yield result, operation if block_given?
226
+ return result
227
+ end
228
+ rescue ::Gapic::Rest::Error => e
229
+ raise ::Google::Cloud::Error.from_error(e)
230
+ end
231
+
232
+ ##
233
+ # CreateOfflineProfile creates a new profile resource in the offline mode.
234
+ # The client provides the profile to create along with the profile bytes, the
235
+ # server records it.
236
+ #
237
+ # @overload create_offline_profile(request, options = nil)
238
+ # Pass arguments to `create_offline_profile` via a request object, either of type
239
+ # {::Google::Cloud::Profiler::V2::CreateOfflineProfileRequest} or an equivalent Hash.
240
+ #
241
+ # @param request [::Google::Cloud::Profiler::V2::CreateOfflineProfileRequest, ::Hash]
242
+ # A request object representing the call parameters. Required. To specify no
243
+ # parameters, or to keep all the default parameter values, pass an empty Hash.
244
+ # @param options [::Gapic::CallOptions, ::Hash]
245
+ # Overrides the default settings for this call, e.g, timeout, retries etc. Optional.
246
+ #
247
+ # @overload create_offline_profile(parent: nil, profile: nil)
248
+ # Pass arguments to `create_offline_profile` via keyword arguments. Note that at
249
+ # least one keyword argument is required. To specify no parameters, or to keep all
250
+ # the default parameter values, pass an empty Hash as a request object (see above).
251
+ #
252
+ # @param parent [::String]
253
+ # Parent project to create the profile in.
254
+ # @param profile [::Google::Cloud::Profiler::V2::Profile, ::Hash]
255
+ # Contents of the profile to create.
256
+ # @yield [result, operation] Access the result along with the TransportOperation object
257
+ # @yieldparam result [::Google::Cloud::Profiler::V2::Profile]
258
+ # @yieldparam operation [::Gapic::Rest::TransportOperation]
259
+ #
260
+ # @return [::Google::Cloud::Profiler::V2::Profile]
261
+ #
262
+ # @raise [::Google::Cloud::Error] if the REST call is aborted.
263
+ def create_offline_profile request, options = nil
264
+ raise ::ArgumentError, "request must be provided" if request.nil?
265
+
266
+ request = ::Gapic::Protobuf.coerce request, to: ::Google::Cloud::Profiler::V2::CreateOfflineProfileRequest
267
+
268
+ # Converts hash and nil to an options object
269
+ options = ::Gapic::CallOptions.new(**options.to_h) if options.respond_to? :to_h
270
+
271
+ # Customize the options with defaults
272
+ call_metadata = @config.rpcs.create_offline_profile.metadata.to_h
273
+
274
+ # Set x-goog-api-client and x-goog-user-project headers
275
+ call_metadata[:"x-goog-api-client"] ||= ::Gapic::Headers.x_goog_api_client \
276
+ lib_name: @config.lib_name, lib_version: @config.lib_version,
277
+ gapic_version: ::Google::Cloud::Profiler::V2::VERSION,
278
+ transports_version_send: [:rest]
279
+
280
+ call_metadata[:"x-goog-user-project"] = @quota_project_id if @quota_project_id
281
+
282
+ options.apply_defaults timeout: @config.rpcs.create_offline_profile.timeout,
283
+ metadata: call_metadata,
284
+ retry_policy: @config.rpcs.create_offline_profile.retry_policy
285
+
286
+ options.apply_defaults timeout: @config.timeout,
287
+ metadata: @config.metadata,
288
+ retry_policy: @config.retry_policy
289
+
290
+ @profiler_service_stub.create_offline_profile request, options do |result, operation|
291
+ yield result, operation if block_given?
292
+ return result
293
+ end
294
+ rescue ::Gapic::Rest::Error => e
295
+ raise ::Google::Cloud::Error.from_error(e)
296
+ end
297
+
298
+ ##
299
+ # UpdateProfile updates the profile bytes and labels on the profile resource
300
+ # created in the online mode. Updating the bytes for profiles created in the
301
+ # offline mode is currently not supported: the profile content must be
302
+ # provided at the time of the profile creation.
303
+ #
304
+ # @overload update_profile(request, options = nil)
305
+ # Pass arguments to `update_profile` via a request object, either of type
306
+ # {::Google::Cloud::Profiler::V2::UpdateProfileRequest} or an equivalent Hash.
307
+ #
308
+ # @param request [::Google::Cloud::Profiler::V2::UpdateProfileRequest, ::Hash]
309
+ # A request object representing the call parameters. Required. To specify no
310
+ # parameters, or to keep all the default parameter values, pass an empty Hash.
311
+ # @param options [::Gapic::CallOptions, ::Hash]
312
+ # Overrides the default settings for this call, e.g, timeout, retries etc. Optional.
313
+ #
314
+ # @overload update_profile(profile: nil, update_mask: nil)
315
+ # Pass arguments to `update_profile` via keyword arguments. Note that at
316
+ # least one keyword argument is required. To specify no parameters, or to keep all
317
+ # the default parameter values, pass an empty Hash as a request object (see above).
318
+ #
319
+ # @param profile [::Google::Cloud::Profiler::V2::Profile, ::Hash]
320
+ # Profile to update.
321
+ # @param update_mask [::Google::Protobuf::FieldMask, ::Hash]
322
+ # Field mask used to specify the fields to be overwritten. Currently only
323
+ # profile_bytes and labels fields are supported by UpdateProfile, so only
324
+ # those fields can be specified in the mask. When no mask is provided, all
325
+ # fields are overwritten.
326
+ # @yield [result, operation] Access the result along with the TransportOperation object
327
+ # @yieldparam result [::Google::Cloud::Profiler::V2::Profile]
328
+ # @yieldparam operation [::Gapic::Rest::TransportOperation]
329
+ #
330
+ # @return [::Google::Cloud::Profiler::V2::Profile]
331
+ #
332
+ # @raise [::Google::Cloud::Error] if the REST call is aborted.
333
+ def update_profile request, options = nil
334
+ raise ::ArgumentError, "request must be provided" if request.nil?
335
+
336
+ request = ::Gapic::Protobuf.coerce request, to: ::Google::Cloud::Profiler::V2::UpdateProfileRequest
337
+
338
+ # Converts hash and nil to an options object
339
+ options = ::Gapic::CallOptions.new(**options.to_h) if options.respond_to? :to_h
340
+
341
+ # Customize the options with defaults
342
+ call_metadata = @config.rpcs.update_profile.metadata.to_h
343
+
344
+ # Set x-goog-api-client and x-goog-user-project headers
345
+ call_metadata[:"x-goog-api-client"] ||= ::Gapic::Headers.x_goog_api_client \
346
+ lib_name: @config.lib_name, lib_version: @config.lib_version,
347
+ gapic_version: ::Google::Cloud::Profiler::V2::VERSION,
348
+ transports_version_send: [:rest]
349
+
350
+ call_metadata[:"x-goog-user-project"] = @quota_project_id if @quota_project_id
351
+
352
+ options.apply_defaults timeout: @config.rpcs.update_profile.timeout,
353
+ metadata: call_metadata,
354
+ retry_policy: @config.rpcs.update_profile.retry_policy
355
+
356
+ options.apply_defaults timeout: @config.timeout,
357
+ metadata: @config.metadata,
358
+ retry_policy: @config.retry_policy
359
+
360
+ @profiler_service_stub.update_profile request, options do |result, operation|
361
+ yield result, operation if block_given?
362
+ return result
363
+ end
364
+ rescue ::Gapic::Rest::Error => e
365
+ raise ::Google::Cloud::Error.from_error(e)
366
+ end
367
+
368
+ ##
369
+ # Configuration class for the ProfilerService REST API.
370
+ #
371
+ # This class represents the configuration for ProfilerService REST,
372
+ # providing control over timeouts, retry behavior, logging, transport
373
+ # parameters, and other low-level controls. Certain parameters can also be
374
+ # applied individually to specific RPCs. See
375
+ # {::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client::Configuration::Rpcs}
376
+ # for a list of RPCs that can be configured independently.
377
+ #
378
+ # Configuration can be applied globally to all clients, or to a single client
379
+ # on construction.
380
+ #
381
+ # @example
382
+ #
383
+ # # Modify the global config, setting the timeout for
384
+ # # create_profile to 20 seconds,
385
+ # # and all remaining timeouts to 10 seconds.
386
+ # ::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client.configure do |config|
387
+ # config.timeout = 10.0
388
+ # config.rpcs.create_profile.timeout = 20.0
389
+ # end
390
+ #
391
+ # # Apply the above configuration only to a new client.
392
+ # client = ::Google::Cloud::Profiler::V2::ProfilerService::Rest::Client.new do |config|
393
+ # config.timeout = 10.0
394
+ # config.rpcs.create_profile.timeout = 20.0
395
+ # end
396
+ #
397
+ # @!attribute [rw] endpoint
398
+ # The hostname or hostname:port of the service endpoint.
399
+ # Defaults to `"cloudprofiler.googleapis.com"`.
400
+ # @return [::String]
401
+ # @!attribute [rw] credentials
402
+ # Credentials to send with calls. You may provide any of the following types:
403
+ # * (`String`) The path to a service account key file in JSON format
404
+ # * (`Hash`) A service account key as a Hash
405
+ # * (`Google::Auth::Credentials`) A googleauth credentials object
406
+ # (see the [googleauth docs](https://rubydoc.info/gems/googleauth/Google/Auth/Credentials))
407
+ # * (`Signet::OAuth2::Client`) A signet oauth2 client object
408
+ # (see the [signet docs](https://rubydoc.info/gems/signet/Signet/OAuth2/Client))
409
+ # * (`nil`) indicating no credentials
410
+ # @return [::Object]
411
+ # @!attribute [rw] scope
412
+ # The OAuth scopes
413
+ # @return [::Array<::String>]
414
+ # @!attribute [rw] lib_name
415
+ # The library name as recorded in instrumentation and logging
416
+ # @return [::String]
417
+ # @!attribute [rw] lib_version
418
+ # The library version as recorded in instrumentation and logging
419
+ # @return [::String]
420
+ # @!attribute [rw] timeout
421
+ # The call timeout in seconds.
422
+ # @return [::Numeric]
423
+ # @!attribute [rw] metadata
424
+ # Additional headers to be sent with the call.
425
+ # @return [::Hash{::Symbol=>::String}]
426
+ # @!attribute [rw] retry_policy
427
+ # The retry policy. The value is a hash with the following keys:
428
+ # * `:initial_delay` (*type:* `Numeric`) - The initial delay in seconds.
429
+ # * `:max_delay` (*type:* `Numeric`) - The max delay in seconds.
430
+ # * `:multiplier` (*type:* `Numeric`) - The incremental backoff multiplier.
431
+ # * `:retry_codes` (*type:* `Array<String>`) - The error codes that should
432
+ # trigger a retry.
433
+ # @return [::Hash]
434
+ # @!attribute [rw] quota_project
435
+ # A separate project against which to charge quota.
436
+ # @return [::String]
437
+ #
438
+ class Configuration
439
+ extend ::Gapic::Config
440
+
441
+ config_attr :endpoint, "cloudprofiler.googleapis.com", ::String
442
+ config_attr :credentials, nil do |value|
443
+ allowed = [::String, ::Hash, ::Proc, ::Symbol, ::Google::Auth::Credentials, ::Signet::OAuth2::Client, nil]
444
+ allowed.any? { |klass| klass === value }
445
+ end
446
+ config_attr :scope, nil, ::String, ::Array, nil
447
+ config_attr :lib_name, nil, ::String, nil
448
+ config_attr :lib_version, nil, ::String, nil
449
+ config_attr :timeout, nil, ::Numeric, nil
450
+ config_attr :metadata, nil, ::Hash, nil
451
+ config_attr :retry_policy, nil, ::Hash, ::Proc, nil
452
+ config_attr :quota_project, nil, ::String, nil
453
+
454
+ # @private
455
+ def initialize parent_config = nil
456
+ @parent_config = parent_config unless parent_config.nil?
457
+
458
+ yield self if block_given?
459
+ end
460
+
461
+ ##
462
+ # Configurations for individual RPCs
463
+ # @return [Rpcs]
464
+ #
465
+ def rpcs
466
+ @rpcs ||= begin
467
+ parent_rpcs = nil
468
+ parent_rpcs = @parent_config.rpcs if defined?(@parent_config) && @parent_config.respond_to?(:rpcs)
469
+ Rpcs.new parent_rpcs
470
+ end
471
+ end
472
+
473
+ ##
474
+ # Configuration RPC class for the ProfilerService API.
475
+ #
476
+ # Includes fields providing the configuration for each RPC in this service.
477
+ # Each configuration object is of type `Gapic::Config::Method` and includes
478
+ # the following configuration fields:
479
+ #
480
+ # * `timeout` (*type:* `Numeric`) - The call timeout in seconds
481
+ # * `metadata` (*type:* `Hash{Symbol=>String}`) - Additional headers
482
+ # * `retry_policy (*type:* `Hash`) - The retry policy. The policy fields
483
+ # include the following keys:
484
+ # * `:initial_delay` (*type:* `Numeric`) - The initial delay in seconds.
485
+ # * `:max_delay` (*type:* `Numeric`) - The max delay in seconds.
486
+ # * `:multiplier` (*type:* `Numeric`) - The incremental backoff multiplier.
487
+ # * `:retry_codes` (*type:* `Array<String>`) - The error codes that should
488
+ # trigger a retry.
489
+ #
490
+ class Rpcs
491
+ ##
492
+ # RPC-specific configuration for `create_profile`
493
+ # @return [::Gapic::Config::Method]
494
+ #
495
+ attr_reader :create_profile
496
+ ##
497
+ # RPC-specific configuration for `create_offline_profile`
498
+ # @return [::Gapic::Config::Method]
499
+ #
500
+ attr_reader :create_offline_profile
501
+ ##
502
+ # RPC-specific configuration for `update_profile`
503
+ # @return [::Gapic::Config::Method]
504
+ #
505
+ attr_reader :update_profile
506
+
507
+ # @private
508
+ def initialize parent_rpcs = nil
509
+ create_profile_config = parent_rpcs.create_profile if parent_rpcs.respond_to? :create_profile
510
+ @create_profile = ::Gapic::Config::Method.new create_profile_config
511
+ create_offline_profile_config = parent_rpcs.create_offline_profile if parent_rpcs.respond_to? :create_offline_profile
512
+ @create_offline_profile = ::Gapic::Config::Method.new create_offline_profile_config
513
+ update_profile_config = parent_rpcs.update_profile if parent_rpcs.respond_to? :update_profile
514
+ @update_profile = ::Gapic::Config::Method.new update_profile_config
515
+
516
+ yield self if block_given?
517
+ end
518
+ end
519
+ end
520
+ end
521
+ end
522
+ end
523
+ end
524
+ end
525
+ end
526
+ end