google-cloud-pubsub 0.33.2 → 0.34.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +4 -4
  3. data/CHANGELOG.md +45 -0
  4. data/EMULATOR.md +2 -2
  5. data/OVERVIEW.md +81 -43
  6. data/lib/google-cloud-pubsub.rb +10 -7
  7. data/lib/google/cloud/pubsub.rb +38 -21
  8. data/lib/google/cloud/pubsub/async_publisher.rb +8 -6
  9. data/lib/google/cloud/pubsub/batch_publisher.rb +7 -5
  10. data/lib/google/cloud/pubsub/convert.rb +5 -3
  11. data/lib/google/cloud/pubsub/credentials.rb +6 -4
  12. data/lib/google/cloud/pubsub/message.rb +9 -6
  13. data/lib/google/cloud/pubsub/policy.rb +12 -10
  14. data/lib/google/cloud/pubsub/project.rb +30 -28
  15. data/lib/google/cloud/pubsub/publish_result.rb +3 -1
  16. data/lib/google/cloud/pubsub/received_message.rb +11 -10
  17. data/lib/google/cloud/pubsub/service.rb +47 -37
  18. data/lib/google/cloud/pubsub/snapshot.rb +11 -9
  19. data/lib/google/cloud/pubsub/snapshot/list.rb +10 -8
  20. data/lib/google/cloud/pubsub/subscriber.rb +32 -6
  21. data/lib/google/cloud/pubsub/subscriber/enumerator_queue.rb +3 -1
  22. data/lib/google/cloud/pubsub/subscriber/inventory.rb +4 -2
  23. data/lib/google/cloud/pubsub/subscriber/stream.rb +23 -43
  24. data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +221 -0
  25. data/lib/google/cloud/pubsub/subscription.rb +157 -80
  26. data/lib/google/cloud/pubsub/subscription/list.rb +12 -10
  27. data/lib/google/cloud/pubsub/topic.rb +79 -51
  28. data/lib/google/cloud/pubsub/topic/list.rb +10 -8
  29. data/lib/google/cloud/pubsub/v1/credentials.rb +4 -2
  30. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/iam_policy.rb +1 -43
  31. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/policy.rb +1 -108
  32. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/duration.rb +1 -1
  33. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/empty.rb +1 -1
  34. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/field_mask.rb +1 -1
  35. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/timestamp.rb +1 -1
  36. data/lib/google/cloud/pubsub/v1/doc/google/pubsub/v1/pubsub.rb +107 -61
  37. data/lib/google/cloud/pubsub/v1/publisher_client.rb +58 -55
  38. data/lib/google/cloud/pubsub/v1/publisher_client_config.json +0 -4
  39. data/lib/google/cloud/pubsub/v1/subscriber_client.rb +177 -128
  40. data/lib/google/cloud/pubsub/v1/subscriber_client_config.json +0 -4
  41. data/lib/google/cloud/pubsub/version.rb +4 -2
  42. data/lib/google/pubsub/v1/pubsub_pb.rb +48 -40
  43. data/lib/google/pubsub/v1/pubsub_services_pb.rb +201 -161
  44. metadata +6 -7
  45. data/lib/google/cloud/pubsub/subscriber/async_stream_pusher.rb +0 -223
  46. data/lib/google/cloud/pubsub/subscriber/async_unary_pusher.rb +0 -271
@@ -45,7 +45,7 @@ module Google
45
45
  # @param [Hash] client_config A hash of values to override the default
46
46
  # behavior of the API client. Optional.
47
47
  #
48
- # @return [Google::Cloud::Pubsub::Project]
48
+ # @return [Google::Cloud::PubSub::Project]
49
49
  #
50
50
  # @example
51
51
  # require "google/cloud"
@@ -63,8 +63,9 @@ module Google
63
63
  # pubsub = gcloud.pubsub scope: platform_scope
64
64
  #
65
65
  def pubsub scope: nil, timeout: nil, client_config: nil
66
- Google::Cloud.pubsub @project, @keyfile, scope: scope,
67
- timeout: (timeout || @timeout),
66
+ timeout ||= @timeout
67
+ Google::Cloud.pubsub @project, @keyfile, scope: scope,
68
+ timeout: timeout,
68
69
  client_config: client_config
69
70
  end
70
71
 
@@ -80,7 +81,8 @@ module Google
80
81
  # credentials is used.
81
82
  # @param [String, Hash, Google::Auth::Credentials] credentials The path to
82
83
  # the keyfile as a String, the contents of the keyfile as a Hash, or a
83
- # Google::Auth::Credentials object. (See {Pubsub::Credentials})
84
+ # Google::Auth::Credentials object.
85
+ # (See {Google::Cloud::PubSub::Credentials})
84
86
  # @param [String, Array<String>] scope The OAuth 2.0 scopes controlling the
85
87
  # set of resources and operations that the connection can access. See
86
88
  # [Using OAuth 2.0 to Access Google
@@ -93,7 +95,7 @@ module Google
93
95
  # @param [Hash] client_config A hash of values to override the default
94
96
  # behavior of the API client. Optional.
95
97
  #
96
- # @return [Google::Cloud::Pubsub::Project]
98
+ # @return [Google::Cloud::PubSub::Project]
97
99
  #
98
100
  # @example
99
101
  # require "google/cloud"
@@ -106,7 +108,7 @@ module Google
106
108
  def self.pubsub project_id = nil, credentials = nil, scope: nil,
107
109
  timeout: nil, client_config: nil
108
110
  require "google/cloud/pubsub"
109
- Google::Cloud::Pubsub.new project_id: project_id,
111
+ Google::Cloud::PubSub.new project_id: project_id,
110
112
  credentials: credentials,
111
113
  scope: scope, timeout: timeout,
112
114
  client_config: client_config
@@ -132,7 +134,7 @@ Google::Cloud.configure.add_config! :pubsub do |config|
132
134
  config.add_field! :project_id, default_project, match: String, allow_nil: true
133
135
  config.add_alias! :project, :project_id
134
136
  config.add_field! :credentials, default_creds,
135
- match: [String, Hash, Google::Auth::Credentials],
137
+ match: [String, Hash, Google::Auth::Credentials],
136
138
  allow_nil: true
137
139
  config.add_alias! :keyfile, :credentials
138
140
  config.add_field! :scope, nil, match: [String, Array]
@@ -140,4 +142,5 @@ Google::Cloud.configure.add_config! :pubsub do |config|
140
142
  config.add_field! :client_config, nil, match: Hash
141
143
  config.add_field! :emulator_host, default_emulator,
142
144
  match: String, allow_nil: true
145
+ config.add_field! :on_error, nil, match: Proc
143
146
  end
@@ -32,7 +32,9 @@ module Google
32
32
  #
33
33
  # See {file:OVERVIEW.md Google Cloud Pub/Sub Overview}.
34
34
  #
35
- module Pubsub
35
+ module PubSub
36
+ # rubocop:disable Metrics/AbcSize
37
+
36
38
  ##
37
39
  # Creates a new object for connecting to the Pub/Sub service.
38
40
  # Each call creates a new connection.
@@ -45,7 +47,7 @@ module Google
45
47
  # credentials is used.
46
48
  # @param [String, Hash, Google::Auth::Credentials] credentials The path to
47
49
  # the keyfile as a String, the contents of the keyfile as a Hash, or a
48
- # Google::Auth::Credentials object. (See {Pubsub::Credentials})
50
+ # Google::Auth::Credentials object. (See {PubSub::Credentials})
49
51
  # @param [String, Array<String>] scope The OAuth 2.0 scopes controlling
50
52
  # the set of resources and operations that the connection can access.
51
53
  # See [Using OAuth 2.0 to Access Google
@@ -63,7 +65,7 @@ module Google
63
65
  # @param [String] keyfile Alias for the `credentials` argument.
64
66
  # Deprecated.
65
67
  #
66
- # @return [Google::Cloud::Pubsub::Project]
68
+ # @return [Google::Cloud::PubSub::Project]
67
69
  #
68
70
  # @example
69
71
  # require "google/cloud/pubsub"
@@ -76,17 +78,18 @@ module Google
76
78
  def self.new project_id: nil, credentials: nil, scope: nil, timeout: nil,
77
79
  client_config: nil, emulator_host: nil, project: nil,
78
80
  keyfile: nil
79
- project_id ||= (project || default_project_id)
80
- project_id = project_id.to_s # Always cast to a string
81
- raise ArgumentError, "project_id is missing" if project_id.empty?
82
-
83
- scope ||= configure.scope
84
- timeout ||= configure.timeout
81
+ project_id ||= (project || default_project_id)
82
+ scope ||= configure.scope
83
+ timeout ||= configure.timeout
85
84
  client_config ||= configure.client_config
86
85
  emulator_host ||= configure.emulator_host
86
+
87
87
  if emulator_host
88
- return Pubsub::Project.new(
89
- Pubsub::Service.new(
88
+ project_id = project_id.to_s # Always cast to a string
89
+ raise ArgumentError, "project_id is missing" if project_id.empty?
90
+
91
+ return PubSub::Project.new(
92
+ PubSub::Service.new(
90
93
  project_id, :this_channel_is_insecure,
91
94
  host: emulator_host, timeout: timeout,
92
95
  client_config: client_config
@@ -96,27 +99,35 @@ module Google
96
99
 
97
100
  credentials ||= (keyfile || default_credentials(scope: scope))
98
101
  unless credentials.is_a? Google::Auth::Credentials
99
- credentials = Pubsub::Credentials.new credentials, scope: scope
102
+ credentials = PubSub::Credentials.new credentials, scope: scope
100
103
  end
101
104
 
102
- Pubsub::Project.new(
103
- Pubsub::Service.new(
104
- project_id, credentials, timeout: timeout,
105
+ if credentials.respond_to? :project_id
106
+ project_id ||= credentials.project_id
107
+ end
108
+ project_id = project_id.to_s # Always cast to a string
109
+ raise ArgumentError, "project_id is missing" if project_id.empty?
110
+
111
+ PubSub::Project.new(
112
+ PubSub::Service.new(
113
+ project_id, credentials, timeout: timeout,
105
114
  client_config: client_config
106
115
  )
107
116
  )
108
117
  end
109
118
 
119
+ # rubocop:enable Metrics/AbcSize
120
+
110
121
  ##
111
- # Configure the Google Cloud Pubsub library.
122
+ # Configure the Google Cloud PubSub library.
112
123
  #
113
- # The following Pubsub configuration parameters are supported:
124
+ # The following PubSub configuration parameters are supported:
114
125
  #
115
- # * `project_id` - (String) Identifier for a Pubsub project. (The
126
+ # * `project_id` - (String) Identifier for a PubSub project. (The
116
127
  # parameter `project` is considered deprecated, but may also be used.)
117
128
  # * `credentials` - (String, Hash, Google::Auth::Credentials) The path to
118
129
  # the keyfile as a String, the contents of the keyfile as a Hash, or a
119
- # Google::Auth::Credentials object. (See {Pubsub::Credentials}) (The
130
+ # Google::Auth::Credentials object. (See {PubSub::Credentials}) (The
120
131
  # parameter `keyfile` is considered deprecated, but may also be used.)
121
132
  # * `scope` - (String, Array<String>) The OAuth 2.0 scopes controlling
122
133
  # the set of resources and operations that the connection can access.
@@ -127,9 +138,12 @@ module Google
127
138
  # behavior of the API client.
128
139
  # * `emulator_host` - (String) Host name of the emulator. Defaults to
129
140
  # `ENV["PUBSUB_EMULATOR_HOST"]`
141
+ # * `on_error` - (Proc) A Proc to be run when an error is encountered
142
+ # on a background thread. The Proc must take the error object as the
143
+ # single argument. (See {Subscriber.on_error}.)
130
144
  #
131
145
  # @return [Google::Cloud::Config] The configuration object the
132
- # Google::Cloud::Pubsub library uses.
146
+ # Google::Cloud::PubSub library uses.
133
147
  #
134
148
  def self.configure
135
149
  yield Google::Cloud.configure.pubsub if block_given?
@@ -150,8 +164,11 @@ module Google
150
164
  def self.default_credentials scope: nil
151
165
  Google::Cloud.configure.pubsub.credentials ||
152
166
  Google::Cloud.configure.credentials ||
153
- Pubsub::Credentials.default(scope: scope)
167
+ PubSub::Credentials.default(scope: scope)
154
168
  end
155
169
  end
170
+
171
+ ## Legacy namespace
172
+ Pubsub = PubSub unless const_defined? :Pubsub
156
173
  end
157
174
  end
@@ -20,15 +20,15 @@ require "google/cloud/pubsub/service"
20
20
 
21
21
  module Google
22
22
  module Cloud
23
- module Pubsub
23
+ module PubSub
24
24
  ##
25
25
  # Used to publish multiple messages in batches to a topic. See
26
- # {Google::Cloud::Pubsub::Topic#async_publisher}
26
+ # {Google::Cloud::PubSub::Topic#async_publisher}
27
27
  #
28
28
  # @example
29
29
  # require "google/cloud/pubsub"
30
30
  #
31
- # pubsub = Google::Cloud::Pubsub.new
31
+ # pubsub = Google::Cloud::PubSub.new
32
32
  #
33
33
  # topic = pubsub.topic "my-topic"
34
34
  # topic.publish_async "task completed" do |result|
@@ -88,7 +88,7 @@ module Google
88
88
  ##
89
89
  # Add a message to the async publisher to be published to the topic.
90
90
  # Messages will be collected in batches and published together.
91
- # See {Google::Cloud::Pubsub::Topic#publish_async}
91
+ # See {Google::Cloud::PubSub::Topic#publish_async}
92
92
  def publish data = nil, attributes = {}, &block
93
93
  msg = create_pubsub_message data, attributes
94
94
 
@@ -281,8 +281,8 @@ module Google
281
281
  # Convert attributes to strings to match the protobuf definition
282
282
  attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
283
283
 
284
- Google::Pubsub::V1::PubsubMessage.new data: data_bytes,
285
- attributes: attributes
284
+ Google::Cloud::PubSub::V1::PubsubMessage.new data: data_bytes,
285
+ attributes: attributes
286
286
  end
287
287
 
288
288
  ##
@@ -337,5 +337,7 @@ module Google
337
337
  end
338
338
  end
339
339
  end
340
+
341
+ Pubsub = PubSub unless const_defined? :Pubsub
340
342
  end
341
343
  end
@@ -15,7 +15,7 @@
15
15
 
16
16
  module Google
17
17
  module Cloud
18
- module Pubsub
18
+ module PubSub
19
19
  ##
20
20
  # Topic Batch Publisher object used to publish multiple messages at
21
21
  # once.
@@ -23,7 +23,7 @@ module Google
23
23
  # @example
24
24
  # require "google/cloud/pubsub"
25
25
  #
26
- # pubsub = Google::Cloud::Pubsub.new
26
+ # pubsub = Google::Cloud::PubSub.new
27
27
  #
28
28
  # topic = pubsub.topic "my-topic"
29
29
  # msgs = topic.publish do |t|
@@ -49,7 +49,7 @@ module Google
49
49
  ##
50
50
  # Add a message to the batch to be published to the topic.
51
51
  # All messages added to the batch will be published at once.
52
- # See {Google::Cloud::Pubsub::Topic#publish}
52
+ # See {Google::Cloud::PubSub::Topic#publish}
53
53
  def publish data, attributes = {}
54
54
  @messages << create_pubsub_message(data, attributes)
55
55
  end
@@ -90,10 +90,12 @@ module Google
90
90
  # Convert attributes to strings to match the protobuf definition
91
91
  attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
92
92
 
93
- Google::Pubsub::V1::PubsubMessage.new data: data_bytes,
94
- attributes: attributes
93
+ Google::Cloud::PubSub::V1::PubsubMessage.new data: data_bytes,
94
+ attributes: attributes
95
95
  end
96
96
  end
97
97
  end
98
+
99
+ Pubsub = PubSub unless const_defined? :Pubsub
98
100
  end
99
101
  end
@@ -17,7 +17,7 @@ require "time"
17
17
 
18
18
  module Google
19
19
  module Cloud
20
- module Pubsub
20
+ module PubSub
21
21
  ##
22
22
  # @private Helper module for converting Pub/Sub values.
23
23
  module Convert
@@ -30,7 +30,7 @@ module Google
30
30
 
31
31
  Google::Protobuf::Timestamp.new \
32
32
  seconds: time.to_i,
33
- nanos: time.nsec
33
+ nanos: time.nsec
34
34
  end
35
35
 
36
36
  def timestamp_to_time timestamp
@@ -44,7 +44,7 @@ module Google
44
44
 
45
45
  Google::Protobuf::Duration.new \
46
46
  seconds: number.to_i,
47
- nanos: (number.remainder(1) * 1000000000).round
47
+ nanos: (number.remainder(1) * 1000000000).round
48
48
  end
49
49
 
50
50
  def duration_to_number duration
@@ -59,5 +59,7 @@ module Google
59
59
  extend ClassMethods
60
60
  end
61
61
  end
62
+
63
+ Pubsub = PubSub unless const_defined? :Pubsub
62
64
  end
63
65
  end
@@ -18,7 +18,7 @@ require "google/cloud/pubsub/v1/credentials.rb"
18
18
 
19
19
  module Google
20
20
  module Cloud
21
- module Pubsub
21
+ module PubSub
22
22
  ##
23
23
  # # Credentials
24
24
  #
@@ -29,17 +29,19 @@ module Google
29
29
  # require "google/cloud/pubsub"
30
30
  #
31
31
  # keyfile = "/path/to/keyfile.json"
32
- # creds = Google::Cloud::Pubsub::Credentials.new keyfile
32
+ # creds = Google::Cloud::PubSub::Credentials.new keyfile
33
33
  #
34
- # pubsub = Google::Cloud::Pubsub.new(
34
+ # pubsub = Google::Cloud::PubSub.new(
35
35
  # project_id: "my-project",
36
36
  # credentials: creds
37
37
  # )
38
38
  #
39
39
  # pubsub.project_id #=> "my-project"
40
40
  #
41
- class Credentials < Google::Cloud::Pubsub::V1::Credentials
41
+ class Credentials < Google::Cloud::PubSub::V1::Credentials
42
42
  end
43
43
  end
44
+
45
+ Pubsub = PubSub unless const_defined? :Pubsub
44
46
  end
45
47
  end
@@ -18,7 +18,7 @@ require "google/cloud/errors"
18
18
 
19
19
  module Google
20
20
  module Cloud
21
- module Pubsub
21
+ module PubSub
22
22
  ##
23
23
  # # Message
24
24
  #
@@ -32,7 +32,7 @@ module Google
32
32
  # @example
33
33
  # require "google/cloud/pubsub"
34
34
  #
35
- # pubsub = Google::Cloud::Pubsub.new
35
+ # pubsub = Google::Cloud::PubSub.new
36
36
  #
37
37
  # # Publish a message
38
38
  # topic = pubsub.topic "my-topic"
@@ -54,7 +54,7 @@ module Google
54
54
  #
55
55
  class Message
56
56
  ##
57
- # @private The gRPC Google::Pubsub::V1::PubsubMessage object.
57
+ # @private The gRPC Google::Cloud::PubSub::V1::PubsubMessage object.
58
58
  attr_accessor :grpc
59
59
 
60
60
  ##
@@ -64,8 +64,8 @@ module Google
64
64
  # Convert attributes to strings to match the protobuf definition
65
65
  attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
66
66
 
67
- @grpc = Google::Pubsub::V1::PubsubMessage.new(
68
- data: String(data).dup.force_encoding(Encoding::ASCII_8BIT),
67
+ @grpc = Google::Cloud::PubSub::V1::PubsubMessage.new(
68
+ data: String(data).dup.force_encoding(Encoding::ASCII_8BIT),
69
69
  attributes: attributes
70
70
  )
71
71
  end
@@ -101,7 +101,8 @@ module Google
101
101
  alias publish_time published_at
102
102
 
103
103
  ##
104
- # @private New Message from a Google::Pubsub::V1::PubsubMessage object.
104
+ # @private New Message from a Google::Cloud::PubSub::V1::PubsubMessage
105
+ # object.
105
106
  def self.from_grpc grpc
106
107
  new.tap do |m|
107
108
  m.instance_variable_set :@grpc, grpc
@@ -109,5 +110,7 @@ module Google
109
110
  end
110
111
  end
111
112
  end
113
+
114
+ Pubsub = PubSub unless const_defined? :Pubsub
112
115
  end
113
116
  end
@@ -17,7 +17,7 @@ require "google/cloud/errors"
17
17
 
18
18
  module Google
19
19
  module Cloud
20
- module Pubsub
20
+ module PubSub
21
21
  ##
22
22
  # # Policy
23
23
  #
@@ -27,7 +27,7 @@ module Google
27
27
  # is to read the current data from the service, update the data locally,
28
28
  # and then send the modified data for writing. This pattern may result in
29
29
  # a conflict if two or more processes attempt the sequence simultaneously.
30
- # IAM solves this problem with the {Google::Cloud::Pubsub::Policy#etag}
30
+ # IAM solves this problem with the {Google::Cloud::PubSub::Policy#etag}
31
31
  # property, which is used to verify whether the policy has changed since
32
32
  # the last request. When you make a request to with an `etag` value, Cloud
33
33
  # IAM compares the `etag` value in the request with the existing `etag`
@@ -37,8 +37,8 @@ module Google
37
37
  # When you update a policy, first read the policy (and its current `etag`)
38
38
  # from the service, then modify the policy locally, and then write the
39
39
  # modified policy to the service. See
40
- # {Google::Cloud::Pubsub::Topic#policy} and
41
- # {Google::Cloud::Pubsub::Topic#policy=}.
40
+ # {Google::Cloud::PubSub::Topic#policy} and
41
+ # {Google::Cloud::PubSub::Topic#policy=}.
42
42
  #
43
43
  # @see https://cloud.google.com/iam/docs/managing-policies Managing
44
44
  # policies
@@ -58,7 +58,7 @@ module Google
58
58
  # @example
59
59
  # require "google/cloud/pubsub"
60
60
  #
61
- # pubsub = Google::Cloud::Pubsub.new
61
+ # pubsub = Google::Cloud::PubSub.new
62
62
  # topic = pubsub.topic "my-topic"
63
63
  #
64
64
  # topic.policy do |p|
@@ -93,7 +93,7 @@ module Google
93
93
  # @example
94
94
  # require "google/cloud/pubsub"
95
95
  #
96
- # pubsub = Google::Cloud::Pubsub.new
96
+ # pubsub = Google::Cloud::PubSub.new
97
97
  # topic = pubsub.topic "my-topic"
98
98
  #
99
99
  # topic.policy do |p|
@@ -120,7 +120,7 @@ module Google
120
120
  # @example
121
121
  # require "google/cloud/pubsub"
122
122
  #
123
- # pubsub = Google::Cloud::Pubsub.new
123
+ # pubsub = Google::Cloud::PubSub.new
124
124
  # topic = pubsub.topic "my-topic"
125
125
  #
126
126
  # topic.policy do |p|
@@ -145,7 +145,7 @@ module Google
145
145
  # @example
146
146
  # require "google/cloud/pubsub"
147
147
  #
148
- # pubsub = Google::Cloud::Pubsub.new
148
+ # pubsub = Google::Cloud::PubSub.new
149
149
  # topic = pubsub.topic "my-topic"
150
150
  #
151
151
  # topic.policy do |p|
@@ -160,11 +160,11 @@ module Google
160
160
  # @private Convert the Policy to a Google::Iam::V1::Policy object.
161
161
  def to_grpc
162
162
  Google::Iam::V1::Policy.new(
163
- etag: etag,
163
+ etag: etag,
164
164
  bindings: roles.keys.map do |role_name|
165
165
  next if roles[role_name].empty?
166
166
  Google::Iam::V1::Binding.new(
167
- role: role_name,
167
+ role: role_name,
168
168
  members: roles[role_name]
169
169
  )
170
170
  end
@@ -181,5 +181,7 @@ module Google
181
181
  end
182
182
  end
183
183
  end
184
+
185
+ Pubsub = PubSub unless const_defined? :Pubsub
184
186
  end
185
187
  end