diff --git a/examples/categories.rb b/examples/categories.rb index a2e6328..39cdfbd 100644 --- a/examples/categories.rb +++ b/examples/categories.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -categories_url_data = 'http://www.onlocationvacations.com/2015/03/05/the-new-ghostbusters-movie-begins-filming-in-boston-in-june/' +categories_url_data = "http://www.onlocationvacations.com/2015/03/05/the-new-ghostbusters-movie-begins-filming-in-boston-in-june/" begin params = DocumentParameters.new(content_uri: categories_url_data) response = rosette_api.get_categories(params) diff --git a/examples/entities.rb b/examples/entities.rb index 7af0f13..e30f5ca 100644 --- a/examples/entities.rb +++ b/examples/entities.rb @@ -9,7 +9,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -entities_text_data = "Bill Murray will appear in new Ghostbusters film: Dr. Peter Venkman was spotted filming a cameo in Boston this… http://dlvr.it/BnsFfS" +entities_text_data = "The Securities and Exchange Commission today announced the leadership of the agency’s trial unit. Bridget Fitzpatrick has been named Chief Litigation Counsel of the SEC and David Gottesman will continue to serve as the agency’s Deputy Chief Litigation Counsel. Since December 2016, Ms. Fitzpatrick and Mr. Gottesman have served as Co-Acting Chief Litigation Counsel. In that role, they were jointly responsible for supervising the trial unit at the agency’s Washington D.C. headquarters as well as coordinating with litigators in the SEC’s 11 regional offices around the country." begin params = DocumentParameters.new(content: entities_text_data, genre: 'social-media') response = rosette_api.get_entities(params) diff --git a/examples/language_multilingual.rb b/examples/language_multilingual.rb new file mode 100644 index 0000000..b4af0c3 --- /dev/null +++ b/examples/language_multilingual.rb @@ -0,0 +1,20 @@ +require 'rosette_api' + +api_key, url = ARGV + +if !url + rosette_api = RosetteAPI.new(api_key) +else + rosette_api = RosetteAPI.new(api_key, url) +end + +language_multilingual_data = "On Thursday, as protesters gathered in Washington D.C., the United States Federal Communications Commission under Chairman Ajit Pai voted 3-2 to overturn a 2015 decision, commonly called Net Neutrality, that forbade Internet service providers (ISPs) such as Verizon, Comcast, and AT&T from blocking individual websites or charging websites or customers more for faster load times. Quatre femmes ont été nommées au Conseil de rédaction de la loi du Qatar. Jeudi, le décret royal du Qatar a annoncé que 28 nouveaux membres ont été nommés pour le Conseil de la Choura du pays. ذكرت مصادر أمنية يونانية، أن 9 موقوفين من منظمة \"د هـ ك ب ج\" الذين كانت قد أوقفتهم الشرطة اليونانية في وقت سابق كانوا يخططون لاغتيال الرئيس التركي رجب طيب أردوغان." +begin + params = DocumentParameters.new(content: language_multilingual_data) + params.rosette_options = { 'multilingual' => 'true' } + params.custom_headers = { 'X-RosetteAPI-App' => 'ruby-app' } + response = rosette_api.get_language(params) + puts JSON.pretty_generate(response) +rescue RosetteAPIError => rosette_api_error + printf('Rosette API Error (%s): %s', rosette_api_error.status_code, rosette_api_error.message) +end diff --git a/examples/morphology_complete.rb b/examples/morphology_complete.rb index 0603749..a5cdfe6 100644 --- a/examples/morphology_complete.rb +++ b/examples/morphology_complete.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -morphology_complete_data = "The quick brown fox jumped over the lazy dog. Yes he did." +morphology_complete_data = "The quick brown fox jumped over the lazy dog. 👍🏾 Yes he did. B)" begin params = DocumentParameters.new(content: morphology_complete_data) response = rosette_api.get_morphology_complete(params) diff --git a/examples/name_deduplication.rb b/examples/name_deduplication.rb index d022949..504456c 100644 --- a/examples/name_deduplication.rb +++ b/examples/name_deduplication.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -name_dedupe_data = 'John Smith,Johnathon Smith,Fred Jones' +name_dedupe_data = "Alice Terry,Alice Thierry,Betty Grable,Betty Gable,Norma Shearer,Norm Shearer,Brigitte Helm,Bridget Helem,Judy Holliday,Julie Halliday" threshold = 0.75 names = name_dedupe_data.split(',').map { |n| NameParameter.new(n) } diff --git a/examples/name_similarity.rb b/examples/name_similarity.rb index f03683a..44cd2d5 100644 --- a/examples/name_similarity.rb +++ b/examples/name_similarity.rb @@ -8,8 +8,8 @@ rosette_api = RosetteAPI.new(api_key, url) end -matched_name_data1 = 'Michael Jackson' -matched_name_data2 = '迈克尔·杰克逊' +matched_name_data1 = "Michael Jackson" +matched_name_data2 = "迈克尔·杰克逊" begin name1 = NameParameter.new(matched_name_data1, entity_type: 'PERSON', language: 'eng') params = NameSimilarityParameters.new(name1, matched_name_data2) diff --git a/examples/name_translation.rb b/examples/name_translation.rb index 0d3ca25..63c0ae0 100644 --- a/examples/name_translation.rb +++ b/examples/name_translation.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -translated_name_data = 'معمر محمد أبو منيار القذاف' +translated_name_data = "معمر محمد أبو منيار القذاف" begin params = NameTranslationParameters.new(translated_name_data, 'eng', target_script: 'Latn') response = rosette_api.get_name_translation(params) diff --git a/examples/relationships.rb b/examples/relationships.rb index d7b1e0b..529be4d 100644 --- a/examples/relationships.rb +++ b/examples/relationships.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -relationships_text_data = "Bill Gates, Microsoft's former CEO, is a philanthropist." +relationships_text_data = "FLIR Systems is headquartered in Oregon and produces thermal imaging, night vision, and infrared cameras and sensor systems. According to the SEC’s order instituting a settled administrative proceeding, FLIR entered into a multi-million dollar contract to provide thermal binoculars to the Saudi government in November 2008. Timms and Ramahi were the primary sales employees responsible for the contract, and also were involved in negotiations to sell FLIR’s security cameras to the same government officials. At the time, Timms was the head of FLIR’s Middle East office in Dubai." begin params = DocumentParameters.new(content: relationships_text_data) params.rosette_options = { accuracyMode: 'PRECISION' } diff --git a/examples/sentences.rb b/examples/sentences.rb index afdb362..d93d4f5 100644 --- a/examples/sentences.rb +++ b/examples/sentences.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -sentences_data = "This land is your land. This land is my land\nFrom California to the New York island;\nFrom the red wood forest to the Gulf Stream waters\n\nThis land was made for you and Me.\n\nAs I was walking that ribbon of highway,\nI saw above me that endless skyway:\nI saw below me that golden valley:\nThis land was made for you and me." +sentences_data = "This land is your land. This land is my land, from California to the New York island; from the red wood forest to the Gulf Stream waters. This land was made for you and Me. As I was walking that ribbon of highway, I saw above me that endless skyway: I saw below me that golden valley: This land was made for you and me." begin params = DocumentParameters.new diff --git a/examples/sentiment.rb b/examples/sentiment.rb index 016017a..de8dea8 100644 --- a/examples/sentiment.rb +++ b/examples/sentiment.rb @@ -10,7 +10,7 @@ end file = Tempfile.new(%w[foo .html]) -sentiment_file_data = '
Original Ghostbuster Dan Aykroyd, who also co-wrote the 1984 Ghostbusters film, couldn’t be more pleased with the new all-female Ghostbusters cast, telling The Hollywood Reporter, “The Aykroyd family is delighted by this inheritance of the Ghostbusters torch by these most magnificent women in comedy.”
' +sentiment_file_data = "Original Ghostbuster Dan Aykroyd, who also co-wrote the 1984 Ghostbusters film, couldn’t be more pleased with the new all-female Ghostbusters cast, telling The Hollywood Reporter, “The Aykroyd family is delighted by this inheritance of the Ghostbusters torch by these most magnificent women in comedy.”
" file.write(sentiment_file_data) file.close begin diff --git a/examples/syntax_dependencies.rb b/examples/syntax_dependencies.rb index 4b40327..4e7f9be 100644 --- a/examples/syntax_dependencies.rb +++ b/examples/syntax_dependencies.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -syntax_dependencies_data = 'Yoshinori Ohsumi, a Japanese cell biologist, was awarded the Nobel Prize in Physiology or Medicine on Monday.' +syntax_dependencies_data = "Yoshinori Ohsumi, a Japanese cell biologist, was awarded the Nobel Prize in Physiology or Medicine on Monday." begin params = DocumentParameters.new(content: syntax_dependencies_data) response = rosette_api.get_syntax_dependencies(params) diff --git a/examples/text_embedding.rb b/examples/text_embedding.rb index 35e3cc4..6d89b69 100644 --- a/examples/text_embedding.rb +++ b/examples/text_embedding.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -embeddings_data = 'Cambridge, Massachusetts' +embeddings_data = "Cambridge, Massachusetts" begin params = DocumentParameters.new(content: embeddings_data) response = rosette_api.get_text_embedding(params) diff --git a/examples/tokens.rb b/examples/tokens.rb index de53adb..594a7ca 100644 --- a/examples/tokens.rb +++ b/examples/tokens.rb @@ -8,7 +8,7 @@ rosette_api = RosetteAPI.new(api_key, url) end -tokens_data = '北京大学生物系主任办公室内部会议' +tokens_data = "北京大学生物系主任办公室内部会议" begin params = DocumentParameters.new(content: tokens_data) response = rosette_api.get_tokens(params) diff --git a/lib/request_builder.rb b/lib/request_builder.rb index 12c8bd8..1fd094f 100644 --- a/lib/request_builder.rb +++ b/lib/request_builder.rb @@ -17,6 +17,8 @@ class RequestBuilder attr_accessor :user_key # Rosette API binding version attr_accessor :binding_version + # User-Agent string + attr_reader :user_agent def initialize(user_key, alternate_url, http_client, params = {}, url_parameters = nil, binding_version) @user_key = user_key @@ -24,6 +26,7 @@ def initialize(user_key, alternate_url, http_client, params = {}, url_parameters @http_client = http_client @params = params @binding_version = binding_version + @user_agent = 'Ruby/' + binding_version + '/' + RUBY_VERSION return unless url_parameters @alternate_url = @alternate_url + '?' + URI.encode_www_form(url_parameters) @@ -61,6 +64,7 @@ def prepare_plain_request(params) request['X-RosetteAPI-Key'] = @user_key request['Content-Type'] = 'application/json' request['Accept'] = 'application/json' + request['User-Agent'] = @user_agent request['X-RosetteAPI-Binding'] = 'ruby' request['X-RosetteAPI-Binding-Version'] = @binding_version request.body = params.to_json @@ -123,6 +127,7 @@ def prepare_multipart_request(params) end request.add_field 'Content-Type', "multipart/form-data; boundary=#{boundary}" + request.add_field 'User-Agent', @user_agent request.add_field 'X-RosetteAPI-Key', @user_key request.add_field 'X-RosetteAPI-Binding', 'ruby' request.add_field 'X-RosetteAPI-Binding-Version', @binding_version @@ -143,6 +148,7 @@ def send_get_request raise RosetteAPIError.new 'connectionError', 'Failed to establish connection with Rosette API server.' end request['X-RosetteAPI-Key'] = @user_key + request['User-Agent'] = @user_agent get_response @http_client, request end diff --git a/lib/rosette_api.rb b/lib/rosette_api.rb index 2b03ac4..24bc442 100644 --- a/lib/rosette_api.rb +++ b/lib/rosette_api.rb @@ -398,6 +398,11 @@ def ping .send_get_request end + # Gets the User-Agent string + def user_agent + RequestBuilder.new(@user_key, @alternate_url + PING, @http_client, @url_parameters, BINDING_VERSION).user_agent + end + private # Checks that the right parameter type is being passed in. diff --git a/tests/tests_spec.rb b/tests/tests_spec.rb index 195de7a..05cb496 100644 --- a/tests/tests_spec.rb +++ b/tests/tests_spec.rb @@ -9,6 +9,14 @@ RSpec.configure do |config| config.before(:example) { @content = 'Sample Content' } config.before(:example) { @json = {content: 'Sample Content'}.to_json } + config.before(:example) { @user_agent = 'Ruby/' + RosetteAPI::BINDING_VERSION + '/' + RUBY_VERSION } + end + + describe '.user_agent' do + it 'check User-Agent string' do + result = RosetteAPI.new('0123456789').user_agent + expect(result).to eq @user_agent + end end describe '.get_language' do @@ -18,7 +26,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -52,7 +60,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -73,7 +81,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -94,7 +102,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -115,7 +123,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -136,7 +144,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -157,7 +165,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -179,7 +187,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -210,7 +218,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -231,7 +239,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -253,7 +261,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -280,7 +288,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -318,7 +326,7 @@ headers: {'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -331,7 +339,7 @@ headers: {'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -382,7 +390,7 @@ headers: {'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -415,7 +423,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -436,7 +444,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -457,7 +465,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -476,7 +484,7 @@ stub_request(:get, 'https://api.rosette.com/rest/v1/info') .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789' }) .to_return(status: 200, body: '{"test": "info"}', headers: {}) end @@ -491,7 +499,7 @@ stub_request(:get, 'https://api.rosette.com/rest/v1/ping') .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789' }) .to_return(status: 200, body: '{"test": "ping"}', headers: {}) end @@ -508,7 +516,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0', @@ -529,7 +537,7 @@ stub_request(:get, 'https://api.rosette.com/rest/v1/info') .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789' }) .to_return(status: 409, body: '{"code": "incompatibleClientVersion"}', headers: {}) end @@ -545,7 +553,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' }) @@ -566,7 +574,7 @@ headers: { 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/json', - 'User-Agent' => 'Ruby', + 'User-Agent' => @user_agent, 'X-Rosetteapi-Key' => '0123456789', 'X-Rosetteapi-Binding' => 'ruby', 'X-Rosetteapi-Binding-Version' => '1.8.0' })