mindee 4.7.1 → 4.8.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +6 -6
  4. data/Rakefile +1 -0
  5. data/lib/mindee/errors/mindee_http_error_v2.rb +23 -4
  6. data/lib/mindee/errors/mindee_http_unknown_error_v2.rb +18 -0
  7. data/lib/mindee/http/endpoint.rb +1 -0
  8. data/lib/mindee/input/sources/local_input_source.rb +9 -1
  9. data/lib/mindee/parsing/v2/error_item.rb +21 -0
  10. data/lib/mindee/parsing/v2/error_response.rb +18 -3
  11. data/lib/mindee/parsing/v2/inference_result.rb +4 -0
  12. data/lib/mindee/parsing/v2/rag_metadata.rb +17 -0
  13. data/lib/mindee/product.rb +0 -1
  14. data/lib/mindee/version.rb +1 -1
  15. data/mindee.gemspec +1 -0
  16. data/sig/mindee/errors/mindee_http_error_v2.rbs +4 -1
  17. data/sig/mindee/errors/mindee_http_unknown_error_v2.rbs +9 -0
  18. data/sig/mindee/http/endpoint.rbs +1 -0
  19. data/sig/mindee/input/sources/local_input_source.rbs +1 -1
  20. data/sig/mindee/parsing/v2/error_item.rbs +13 -0
  21. data/sig/mindee/parsing/v2/error_response.rbs +3 -0
  22. data/sig/mindee/parsing/v2/inference_result.rbs +1 -0
  23. data/sig/mindee/parsing/v2/rag_metadata.rbs +13 -0
  24. metadata +22 -47
  25. data/docs/advanced_file_operations.md +0 -109
  26. data/docs/code_samples/us_mail_v2_async.txt +0 -24
  27. data/docs/getting_started.md +0 -257
  28. data/docs/global_products/barcode_reader_v1.md +0 -125
  29. data/docs/global_products/bill_of_lading_v1.md +0 -276
  30. data/docs/global_products/business_card_v1.md +0 -194
  31. data/docs/global_products/cropper_v1.md +0 -123
  32. data/docs/global_products/delivery_notes_v1.md +0 -168
  33. data/docs/global_products/driver_license_v1.md +0 -212
  34. data/docs/global_products/expense_receipts_v5.md +0 -415
  35. data/docs/global_products/financial_document_v1.md +0 -615
  36. data/docs/global_products/international_id_v2.md +0 -264
  37. data/docs/global_products/invoice_splitter_v1.md +0 -127
  38. data/docs/global_products/invoices_v4.md +0 -576
  39. data/docs/global_products/multi_receipts_detector_v1.md +0 -131
  40. data/docs/global_products/nutrition_facts_v1.md +0 -399
  41. data/docs/global_products/passport_v1.md +0 -207
  42. data/docs/global_products/resume_v1.md +0 -384
  43. data/docs/global_products/universal.md +0 -113
  44. data/docs/global_products.md +0 -6
  45. data/docs/loading_a_document.md +0 -330
  46. data/docs/localized_products/bank_account_details_v2.md +0 -158
  47. data/docs/localized_products/bank_check_v1.md +0 -205
  48. data/docs/localized_products/bank_statement_fr_v2.md +0 -269
  49. data/docs/localized_products/carte_grise_v1.md +0 -475
  50. data/docs/localized_products/energy_bill_fra_v1.md +0 -342
  51. data/docs/localized_products/french_healthcard_v1.md +0 -142
  52. data/docs/localized_products/idcard_fr_v2.md +0 -284
  53. data/docs/localized_products/ind_passport_v1.md +0 -307
  54. data/docs/localized_products/payslip_fra_v3.md +0 -344
  55. data/docs/localized_products/us_healthcare_cards_v1.md +0 -258
  56. data/docs/localized_products/us_mail_v3.md +0 -152
  57. data/docs/localized_products.md +0 -6
  58. data/lib/mindee/product/us/us_mail/us_mail_v2.rb +0 -47
  59. data/lib/mindee/product/us/us_mail/us_mail_v2_document.rb +0 -105
  60. data/lib/mindee/product/us/us_mail/us_mail_v2_page.rb +0 -38
  61. data/lib/mindee/product/us/us_mail/us_mail_v2_recipient_address.rb +0 -105
  62. data/lib/mindee/product/us/us_mail/us_mail_v2_recipient_addresses.rb +0 -63
  63. data/lib/mindee/product/us/us_mail/us_mail_v2_sender_address.rb +0 -66
  64. data/sig/mindee/product/us/us_mail/us_mail_v2.rbs +0 -13
  65. data/sig/mindee/product/us/us_mail/us_mail_v2_document.rbs +0 -20
  66. data/sig/mindee/product/us/us_mail/us_mail_v2_page.rbs +0 -17
  67. data/sig/mindee/product/us/us_mail/us_mail_v2_recipient_address.rbs +0 -22
  68. data/sig/mindee/product/us/us_mail/us_mail_v2_recipient_addresses.rbs +0 -15
  69. data/sig/mindee/product/us/us_mail/us_mail_v2_sender_address.rbs +0 -18
@@ -1,109 +0,0 @@
1
- ---
2
- title: Advanced File Operations
3
- category: 622b805aaec68102ea7fcbc2
4
- slug: ruby-advanced-file-operations
5
- parentDoc: 6294d97ee723f1008d2ab28e
6
- ---
7
-
8
- > ❗️ Disclaimer: the file operations listed below do not directly manipulate the files you will pass to the library,
9
- > They will instead create a copy before applying any operations, which means that the file you send may not be an exact copy of the file the server will receive.
10
- > To avoid any unexpected or unwanted result, you can save a copy of the created file locally to inspect it visually before sending it.
11
-
12
- ## Image compression
13
-
14
- The compression functionality for image files (JPEG, PNG, etc.) via the `compress!` method available on a
15
- LocalInputSource. This method allows you to reduce file size by specifying quality and dimension constraints.
16
-
17
- Example:
18
-
19
- ```rb
20
- # Compress an image with custom parameters.
21
- input_source.compress!(quality: 85, max_width: 1024, max_height: 768)
22
- ```
23
- > ⚠️ Warning: Compression alters the original image data.
24
- > We strongly advise you inspect a compressed file before sending it:
25
- > ```rb
26
- > # Compress using a quality of 50%:
27
- > input_source.compress!(quality: 50)
28
- > input_source.write_to_file('path/to/my/compressed/file_50.jpg')
29
- > ```
30
-
31
- For reference, here's what the following levels of compression on this image will look like:
32
-
33
- **Original:**
34
- ![Invoice sample](https://github.com/mindee/client-lib-test-data/blob/main/products/invoices/default_sample.jpg?raw=true)
35
-
36
- **85% compressed:**
37
- ![85% sample](https://github.com/mindee/client-lib-test-data/blob/main/file_operations/compression/compressed_ruby_85.jpg?raw=true)
38
-
39
- **50% compressed:**
40
- ![50% sample](https://github.com/mindee/client-lib-test-data/blob/main/file_operations/compression/compressed_ruby_50.jpg?raw=true)
41
-
42
- **10% compressed:**
43
- ![10% sample](https://github.com/mindee/client-lib-test-data/blob/main/file_operations/compression/compressed_ruby_10.jpg?raw=true)
44
-
45
-
46
- ## PDF operations
47
-
48
- PDF operations include both compression and fixing features.
49
- These are specifically designed to handle challenges associated with PDF files, such as large file sizes and formatting
50
- issues.
51
-
52
- ### PDF compression
53
-
54
- > 🧪 PDF compression is an **experimental** feature that rasterizes each page of the PDF (similar to how images are
55
- > compressed) to reduce its overall size.
56
- >
57
- > Because the process involves re-rendering the PDF’s contents, some source text may be lost or rendered differently.
58
- > Use this feature with caution.
59
-
60
-
61
- ```rb
62
- # Load a local input source.
63
- input_file_path = "path/to/your/file.pdf"
64
- output_file_path = "path/to/the/compressed/file.pdf"
65
- pdf_input = Mindee::Input::Source::PathInputSource.new(input_file_path)
66
-
67
- # We advise you test the quality value yourself, as results may vary greatly depending on the input file
68
- pdf_input.compress!(quality: 50)
69
-
70
- # Write the output file locally for visual checking:
71
- File.write(output_file_path, pdf_input.io_stream.read)
72
- ```
73
-
74
- > 🚧 Be warned that the source text (the text embedded in the PDF itself) might not render properly,
75
- > and so source PDFs will be ignored by default.
76
- >
77
- > You can bypass this using:
78
-
79
- ```rb
80
- pdf_input.compress!(quality: 50, force_source_text: true)
81
- ```
82
-
83
- Or alternatively, you can try to approximate the re-rendering of the source-text using:
84
-
85
- ```rb
86
- pdf_input.compress!(quality: 50, force_source_text: true, disable_source_text: false)
87
- ```
88
-
89
- ### PDF Repair
90
-
91
- The PDF repair feature attempts to rescue PDFs with invalid or broken header information.
92
- This can sometimes help when files get rejected by the server.
93
-
94
- Example:
95
- ```rb
96
- # Load a PDF file with the repair_pdf flag enabled.
97
- input_source = mindee_client.source_from_file(file, "document.pdf", repair_pdf: true)
98
- ```
99
-
100
- > ⚠️ Warning: PDF fixing alters the input file by re-writing header information.
101
- > Use this feature only when required, as it might affect the integrity of the document file.
102
-
103
- ---
104
-
105
- Feel free to expand these examples and adjust the parameters as needed for your projects. For further details on
106
- authentication and usage, you can refer to the [Getting Started Guide](getting_started.md).
107
-
108
- # Questions?
109
- [Join our Slack](https://join.slack.com/t/mindee-community/shared_invite/zt-2d0ds7dtz-DPAF81ZqTy20chsYpQBW5g)
@@ -1,24 +0,0 @@
1
- #
2
- # Install the Ruby client library by running:
3
- # gem install mindee
4
- #
5
-
6
- require 'mindee'
7
-
8
- # Init a new client
9
- mindee_client = Mindee::Client.new(api_key: 'my-api-key')
10
-
11
- # Load a file from disk
12
- input_source = mindee_client.source_from_path('/path/to/the/file.ext')
13
-
14
- # Parse the file
15
- result = mindee_client.parse(
16
- input_source,
17
- Mindee::Product::US::UsMail::UsMailV2
18
- )
19
-
20
- # Print a full summary of the parsed data in RST format
21
- puts result.document
22
-
23
- # Print the document-level parsed data
24
- # puts result.document.inference.prediction
@@ -1,257 +0,0 @@
1
- ---
2
- title: Getting Started
3
- category: 622b805aaec68102ea7fcbc2
4
- slug: ruby-getting-started
5
- parentDoc: 6294d97ee723f1008d2ab28e
6
- ---
7
- > 📘 This guide will help you get the most out of the Mindee Ruby client library to easily extract data from your documents.
8
-
9
- ## Installation
10
-
11
- ### Requirements
12
- The following Ruby versions are tested and supported: 3.0, 3.1, 3.2, 3.3
13
-
14
- ### Standard Installation
15
- To quickly get started with the Ruby Client Library, Install by adding this line to your application's Gemfile:
16
-
17
- ```shell
18
- gem 'mindee'
19
- ```
20
- And then execute:
21
-
22
- ```shell
23
- bundle install
24
- ```
25
- Or you can install it like this:
26
-
27
- ```shell
28
- gem install mindee
29
- ```
30
- Finally, Ruby away!
31
-
32
- ### Development Installation
33
- If you'll be modifying the source code, you'll need to install the required libraries to get started.
34
-
35
- We recommend using [Bundler](https://bundler.io/).
36
-
37
- 1. First clone the repo.
38
-
39
- ```shell
40
- git clone git@github.com:mindee/mindee-api-ruby.git
41
- ```
42
-
43
- 2. Navigate to the cloned directory and install all required libraries.
44
-
45
- ```shell
46
- cd mindee-api-ruby
47
- bundle install
48
- ```
49
-
50
- ### Updating the Library
51
- It is important to always check the version of the Mindee OCR SDK you are using, as new and updated
52
- features won’t work on older versions.
53
-
54
- To get the latest version of your OCR SDK:
55
-
56
- ```shell
57
- gem install mindee
58
- ```
59
-
60
- To install a specific version of Mindee:
61
-
62
- ```shell
63
- gem install mindee@<version>
64
- ```
65
-
66
- ## Usage
67
-
68
- Using Mindee's APIs can be broken down into the following steps:
69
-
70
- 1. [Initialize a Client](#initializing-the-client)
71
- 2. [Load a File](#loading-a-document-file)
72
- 3. [Send the File](#sending-a-file) to Mindee's API
73
- 4. [Process the Result](#process-the-result) in some way
74
-
75
- Let's take a deep dive into how this works.
76
-
77
- ## Initializing the Client
78
- The `Client` automatically connects to the default endpoints for each product (or creates one with given parameters for
79
- Universal APIs).
80
-
81
- The `Client` requires your [API key](https://developers.mindee.com/docs/make-your-first-request#create-an-api-key).
82
-
83
- You can either pass these directly to the constructor or through environment variables.
84
-
85
-
86
- ### Pass the API key directly
87
- ```rb
88
- # Init a new client and passing the key directly
89
- mindee_client = Mindee::Client.new(api_key: 'my-api-key')
90
- ```
91
-
92
- ### Set the API key in the environment
93
- API keys should be set as environment variables, especially for any production deployment.
94
-
95
- The following environment variable will set the global API key:
96
- ```shell
97
- MINDEE_API_KEY=my-api-key
98
- ```
99
-
100
- Then in your code:
101
- ```rb
102
- # Init a new client without an API key
103
- mindee_client = Mindee::Client.new
104
- ```
105
-
106
- ### Setting the Request Timeout
107
- The request timeout can be set using an environment variable:
108
- ```shell
109
- MINDEE_REQUEST_TIMEOUT=200
110
- ```
111
-
112
-
113
- ## Loading a Document File
114
- Before being able to send a document to the API, it must first be loaded.
115
-
116
- You don't need to worry about different MIME types, the library will take care of handling
117
- all supported types automatically.
118
-
119
- Once a document is loaded, interacting with it is done in exactly the same way, regardless
120
- of how it was loaded.
121
-
122
- There are a few different ways of loading a document file, depending on your use case, you can use a:
123
-
124
- * [File path](https://developers.mindee.com/docs/ruby-document-loading#loading-from-a-local-path): using the Mindee Client's `source_from_path()` method.
125
- * [File Object](https://developers.mindee.com/docs/ruby-document-loading#loading-from-a-file-object): using the Mindee Client's `source_from_file()` method.
126
- * [Base64 String](https://developers.mindee.com/docs/ruby-document-loading#loading-from-a-base64-encoded-string): using the Mindee Client's `source_from_b64string()` method.
127
- * [Raw Byte sequence](https://developers.mindee.com/docs/ruby-document-loading#loading-from-raw-bytes): using the Mindee Client's `source_from_bytes()` method.
128
- * [URL](https://developers.mindee.com/docs/ruby-document-loading#loading-by-url): using the Mindee Client's `source_from_url()` method.
129
-
130
- More details about file loading on the [dedicated page](https://developers.mindee.com/docs/ruby-document-loading).
131
-
132
- ## Sending a File
133
- To send a file to the API, we need to specify how to process the document.
134
- This will determine which API endpoint is used and how the API return will be handled internally by the library.
135
-
136
- More specifically, we need to set a `Mindee::Product` class as the first parameter of the `create_endpoint` method.
137
-
138
- This is because the `Endpoint`'s urls will be set according to it
139
-
140
- Each document type available in the library has its corresponding class, which inherit from the base
141
- `Mindee::Parsing::Common::Predict` class.
142
-
143
- This is detailed in each document-specific guide.
144
-
145
- ### Off-the-Shelf Documents
146
- Simply setting the correct class is enough:
147
-
148
- ```rb
149
-
150
- result = mindee_client.parse(
151
- input_source,
152
- Mindee::Product::Invoice::InvoiceV4
153
- )
154
- ```
155
-
156
- #### Specific call method
157
- Some products, such as InvoiceV4, ReceiptV5 & FinancialDocumentV1 support both asynchronous polling and synchronous
158
- HTTP calls.
159
- We recommend letting the client library decide which is better by default, but you can override the behavior by setting
160
- the `enqueue` parameter to `true` or `false`.
161
-
162
- ```rb
163
-
164
- result = mindee_client.parse(
165
- input_source,
166
- Mindee::Product::Invoice::InvoiceV4,
167
- enqueue: false
168
- )
169
- ```
170
-
171
- > 🚧 WARNING: this feature is not available for all products, and may result in errors if used inappropriately.
172
- > Only use it if you are certain of what you are doing.
173
- ### Universal Documents (docTI)
174
- For custom documents, the endpoint to use must also be set, and it must take in an `endpoint_name`:
175
-
176
- ```rb
177
- endpoint = mindee_client.create_endpoint(endpoint_name: 'wnine', account_name: 'my-account')
178
-
179
- result = mindee_client.parse(
180
- input_source,
181
- Mindee::Product::Universal::Universal,
182
- endpoint: endpoint
183
- )
184
- ```
185
-
186
- This is because the `Universal` class is enough to handle the return processing, but the actual endpoint needs to be
187
- specified.
188
-
189
- ## Process the Result
190
- The response object is common to all documents, including custom documents (using the Universal product). The main
191
- properties are:
192
-
193
- * `id` — Mindee ID of the document
194
- * `name` — Filename sent to the API
195
- * `inference` — [Inference](#inference)
196
-
197
- ### Inference
198
- Regroups the predictions at the page level, as well as predictions for the entire document.
199
-
200
- * `prediction` — [Document level prediction](#document-level-prediction)
201
- * `pages` — [Page level prediction](#page-level-prediction)
202
-
203
- #### Document level prediction
204
- The `prediction` attribute is a `Prediction` object specific to the type of document being processed.
205
- It contains the data extracted from the entire document, all pages combined.
206
-
207
- It's possible to have the same field in various pages, but at the document level,
208
- only the highest confidence field data will be shown (this is all done automatically at the API level).
209
-
210
- ```rb
211
- # as an object, complete
212
- pp result.document.inference.prediction
213
-
214
- # as a string, summary in RST format
215
- puts result.document.inference.prediction
216
- ```
217
-
218
- #### Page level prediction
219
- The `pages` attribute is a list of `Prediction` objects.
220
-
221
- Each page element contains the data extracted for a particular page of the document.
222
- The order of the elements in the array matches the order of the pages in the document.
223
-
224
- All response objects have this property, regardless of the number of pages.
225
- Single page documents will have a single entry.
226
-
227
- Iteration is done like any Ruby array:
228
- ```rb
229
- response.document.inference.pages.each do |page|
230
- # as an object, complete
231
- pp page.prediction
232
-
233
- # as a string, summary in RST format
234
- puts page.prediction
235
- end
236
- ```
237
-
238
- #### Page Orientation
239
- The orientation field is only available at the page level as it describes whether the page image should be rotated to
240
- be upright.
241
-
242
- If the page requires rotation for correct display, the orientation field gives a prediction among these 3 possible
243
- outputs:
244
-
245
- * 0 degrees: the page is already upright
246
- * 90 degrees: the page must be rotated clockwise to be upright
247
- * 270 degrees: the page must be rotated counterclockwise to be upright
248
-
249
- ```rb
250
- response.document.inference.pages.each do |page|
251
- puts page.orientation.value
252
- end
253
- ```
254
-
255
-
256
- ## Questions?
257
- [Join our Slack](https://join.slack.com/t/mindee-community/shared_invite/zt-2d0ds7dtz-DPAF81ZqTy20chsYpQBW5g)
@@ -1,125 +0,0 @@
1
- ---
2
- title: Barcode Reader
3
- category: 622b805aaec68102ea7fcbc2
4
- slug: ruby-barcode-reader-ocr
5
- parentDoc: 67b49df15b843f3fa9cd622b
6
- ---
7
- The Ruby Client Library supports the [Barcode Reader API](https://platform.mindee.com/mindee/barcode_reader).
8
-
9
-
10
- > 📝 Product Specs
11
- >
12
- > | Specification | Details |
13
- > | ------------------------------ | -------------------------------------------------- |
14
- > | Endpoint Name | `barcode_reader` |
15
- > | Recommended Version | `v1.0` |
16
- > | Supports Polling/Webhooks | ❌ No |
17
- > | Support Synchronous HTTP Calls | ✔️ Yes |
18
- > | Geography | 🌐 Global |
19
-
20
-
21
- Using the [sample below](https://github.com/mindee/client-lib-test-data/blob/main/products/barcode_reader/default_sample.jpg),
22
- we are going to illustrate how to extract the data that we want using the Ruby Client Library.
23
- ![Barcode Reader sample](https://github.com/mindee/client-lib-test-data/blob/main/products/barcode_reader/default_sample.jpg?raw=true)
24
-
25
- # Quick-Start
26
- ```rb
27
- #
28
- # Install the Ruby client library by running:
29
- # gem install mindee
30
- #
31
-
32
- require 'mindee'
33
-
34
- # Init a new client
35
- mindee_client = Mindee::Client.new(api_key: 'my-api-key')
36
-
37
- # Load a file from disk
38
- input_source = mindee_client.source_from_path('/path/to/the/file.ext')
39
-
40
- # Parse the file
41
- result = mindee_client.parse(
42
- input_source,
43
- Mindee::Product::BarcodeReader::BarcodeReaderV1
44
- )
45
-
46
- # Print a full summary of the parsed data in RST format
47
- puts result.document
48
-
49
- # Print the document-level parsed data
50
- # puts result.document.inference.prediction
51
- ```
52
-
53
- **Output (RST):**
54
- ```rst
55
- ########
56
- Document
57
- ########
58
- :Mindee ID: f9c48da1-a306-4805-8da8-f7231fda2d88
59
- :Filename: default_sample.jpg
60
-
61
- Inference
62
- #########
63
- :Product: mindee/barcode_reader v1.0
64
- :Rotation applied: Yes
65
-
66
- Prediction
67
- ==========
68
- :Barcodes 1D: Mindee
69
- :Barcodes 2D: https://developers.mindee.com/docs/barcode-reader-ocr
70
- I love paperwork! - Said no one ever
71
-
72
- Page Predictions
73
- ================
74
-
75
- Page 0
76
- ------
77
- :Barcodes 1D: Mindee
78
- :Barcodes 2D: https://developers.mindee.com/docs/barcode-reader-ocr
79
- I love paperwork! - Said no one ever
80
- ```
81
-
82
- # Field Types
83
- ## Standard Fields
84
- These fields are generic and used in several products.
85
-
86
- ### Basic Field
87
- Each prediction object contains a set of fields that inherit from the generic `Field` class.
88
- A typical `Field` object will have the following attributes:
89
-
90
- * **value** (`String`, `Float`, `Integer`, `bool`): corresponds to the field value. Can be `nil` if no value was extracted.
91
- * **confidence** (Float, nil): the confidence score of the field prediction.
92
- * **bounding_box** (`Mindee::Geometry::Quadrilateral`, `nil`): contains exactly 4 relative vertices (points) coordinates of a right rectangle containing the field in the document.
93
- * **polygon** (`Mindee::Geometry::Polygon`, `nil`): contains the relative vertices coordinates (`Point`) of a polygon containing the field in the image.
94
- * **page_id** (`Integer`, `nil`): the ID of the page, always `nil` when at document-level.
95
- * **reconstructed** (`bool`): indicates whether an object was reconstructed (not extracted as the API gave it).
96
-
97
-
98
- Aside from the previous attributes, all basic fields have access to a `to_s` method that can be used to print their value as a string.
99
-
100
- ### String Field
101
- The text field `StringField` only has one constraint: it's **value** is a `String` (or `nil`).
102
-
103
- # Attributes
104
- The following fields are extracted for Barcode Reader V1:
105
-
106
- ## Barcodes 1D
107
- **codes_1d** (Array<[StringField](#string-field)>): List of decoded 1D barcodes.
108
-
109
- ```rb
110
- result.document.inference.prediction.codes_1d do |codes_1d_elem|
111
- puts codes_1d_elem.value
112
- end
113
- ```
114
-
115
- ## Barcodes 2D
116
- **codes_2d** (Array<[StringField](#string-field)>): List of decoded 2D barcodes.
117
-
118
- ```rb
119
- result.document.inference.prediction.codes_2d do |codes_2d_elem|
120
- puts codes_2d_elem.value
121
- end
122
- ```
123
-
124
- # Questions?
125
- [Join our Slack](https://join.slack.com/t/mindee-community/shared_invite/zt-2d0ds7dtz-DPAF81ZqTy20chsYpQBW5g)