mekari_sso 0.0.1.2 → 0.0.1.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f33247db096802659c274da652372c7497ad5f2d37a909e0809438d829ff92e1
4
- data.tar.gz: 16c05aeda1d56fbe59e810ec95751553ee21bdb12ee9d3aee2e29623b477da88
3
+ metadata.gz: 6c098d8be18851ce75ba104d1222fe458a94e6cbc0550aa4b5e39044b618f08b
4
+ data.tar.gz: 442811bd5ef6c8a60b5c492396280ff202f081455db0a513bbaf7dd3337271be
5
5
  SHA512:
6
- metadata.gz: d284d8c15d544eeb522f149ed7e2546d1284b17939f766b86f73c2625a94bf3085663cb27409b7f08a43a86c15352019785922524f34756055d6269517c33490
7
- data.tar.gz: 6d5c1839006f0d06c0437662e201712983a938640043d73236edaabc797e9abe236ba184e4eb2f855faaba9718dc2ee23b94dab396d87f2848af6dff190b84b5
6
+ metadata.gz: 07dda5783020f080843f24f79bd243dd079ccc6f8cb330de7f6ea8cb2f820f2c65a59831a5ab48402dfd9b352b370c0bb4303fd7074031a4cf923244ee6fc0c7
7
+ data.tar.gz: ae032b080d461f9cb2fa83b144663e0aec0c0b464e3f394d0e8e58453ea1c4a51bce06b45f9e5dda830043ed54f394c4e952fa294089abf7c18aaac1b8c5dd99
data/lib/mekari_sso.rb CHANGED
@@ -1,19 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'config'
4
+ require 'requests/add_user_to_company'
5
+ require 'requests/cities'
6
+ require 'requests/companies'
7
+ require 'requests/company_member'
4
8
  require 'requests/current_user'
5
9
  require 'requests/generate_credential_client'
6
10
  require 'requests/generate_credential_code'
7
11
  require 'requests/industries'
12
+ require 'requests/postal_codes'
13
+ require 'requests/provincies'
8
14
  require 'requests/refresh'
9
15
  require 'requests/revoke'
10
16
  require 'requests/sender'
11
17
  require 'requests/register_company'
12
18
  require 'requests/register_user'
13
19
  require 'requests/remove_company'
20
+ require 'requests/remove_user_from_company'
21
+ require 'requests/update_user'
22
+ require 'requests/update_avatar'
23
+ require 'requests/verify_email_user'
24
+
25
+ require 'params/add_user_company'
26
+ require 'params/city'
14
27
  require 'params/user_register'
15
28
  require 'params/company_register'
16
29
  require 'params/company_remove'
30
+ require 'params/company'
31
+ require 'params/province'
32
+ require 'params/remove_user_company'
33
+ require 'params/list'
34
+ require 'params/user_update'
35
+ require 'params/user_avatar'
36
+ require 'params/user_verify_email'
37
+
17
38
 
18
39
  require 'active_support'
19
40
  require 'active_support/core_ext'
@@ -80,5 +101,85 @@ module MekariSso
80
101
  sender = MekariSso::Sender.new
81
102
  sender >> MekariSso::RemoveCompany.new(@options, company)
82
103
  end
104
+
105
+ def companies(params)
106
+ company = MekariSso::List.new(params)
107
+ company.validate_required!
108
+
109
+ sender = MekariSso::Sender.new
110
+ sender >> MekariSso::Companies.new(@options, company)
111
+ end
112
+
113
+ def provincies(params)
114
+ prov = MekariSso::List.new(params)
115
+ prov.validate_required!
116
+
117
+ sender = MekariSso::Sender.new
118
+ sender >> MekariSso::Provincies.new(@options, prov)
119
+ end
120
+
121
+ def cities(params)
122
+ cities = MekariSso::Province.new(params)
123
+ cities.validate_required!
124
+
125
+ sender = MekariSso::Sender.new
126
+ sender >> MekariSso::Cities.new(@options, cities)
127
+ end
128
+
129
+ def postal_codes(params)
130
+ postal_code = MekariSso::City.new(params)
131
+ postal_code.validate_required!
132
+
133
+ sender = MekariSso::Sender.new
134
+ sender >> MekariSso::PostalCodes.new(@options, postal_code)
135
+ end
136
+
137
+ def add_user_to_company(params)
138
+ user = MekariSso::AddUserCompany.new(params)
139
+ user.validate_required!
140
+
141
+ sender = MekariSso::Sender.new
142
+ sender >> MekariSso::AddUserToCompany.new(@options, user)
143
+ end
144
+
145
+ def remove_user_from_company(params)
146
+ user = MekariSso::RemoveUserCompany.new(params)
147
+ user.validate_required!
148
+
149
+ sender = MekariSso::Sender.new
150
+ sender >> MekariSso::RemoveUserFromCompany.new(@options, user)
151
+ end
152
+
153
+ def company_member(params)
154
+ user = MekariSso::Company.new(params)
155
+ user.validate_required!
156
+
157
+ sender = MekariSso::Sender.new
158
+ sender >> MekariSso::CompanyMember.new(@options, user)
159
+ end
160
+
161
+ def update_user(params)
162
+ user = MekariSso::UserUpdate.new(params)
163
+ user.validate_required!
164
+
165
+ sender = MekariSso::Sender.new
166
+ sender >> MekariSso::UpdateUser.new(@options, user)
167
+ end
168
+
169
+ def update_avatar(params)
170
+ user = MekariSso::UserAvatar.new(params)
171
+ user.validate_required!
172
+
173
+ sender = MekariSso::Sender.new
174
+ sender >> MekariSso::UpdateAvatar.new(@options, user)
175
+ end
176
+
177
+ def verify_user_email(params)
178
+ user = MekariSso::UserVerifyEmail.new(params)
179
+ user.validate_required!
180
+
181
+ sender = MekariSso::Sender.new
182
+ sender >> MekariSso::VerifyEmailUser.new(@options, user)
183
+ end
83
184
  end
84
185
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+
5
+ module MekariSso
6
+ class AddUserCompany < MekariSso::Config
7
+ attr_accessor :company_id, :user_id, :access_token
8
+
9
+ def initialize(options = nil)
10
+ apply(options) if options
11
+ end
12
+
13
+ def available_keys
14
+ %i[company_id user_id access_token]
15
+ end
16
+
17
+ def validate_required!
18
+ unless @company_id.present?
19
+ raise ArgumentError, "Params company_id is required options"
20
+ end
21
+
22
+ unless @user_id.present?
23
+ raise ArgumentError, "Params user_id is required options"
24
+ end
25
+
26
+ unless @access_token.present?
27
+ raise ArgumentError, "Params access_token is required options"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+
5
+ module MekariSso
6
+ class City < MekariSso::Config
7
+ attr_accessor :city_id
8
+
9
+ def initialize(options = nil)
10
+ apply(options) if options
11
+ end
12
+
13
+ def available_keys
14
+ %i[city_id access_token]
15
+ end
16
+
17
+ def validate_required!
18
+ unless @city_id.present?
19
+ raise ArgumentError, "Params city_id is required options"
20
+ end
21
+
22
+ unless @access_token.present?
23
+ raise ArgumentError, "Params access_token is required options"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+
5
+ module MekariSso
6
+ class Company < MekariSso::Config
7
+ attr_accessor :access_token, :page, :company_id
8
+
9
+ def initialize(options = nil)
10
+ apply(options) if options
11
+ end
12
+
13
+ def available_keys
14
+ %i[access_token company_id]
15
+ end
16
+
17
+ def validate_required!
18
+ unless @access_token.present?
19
+ raise ArgumentError, "Params access_token is required options"
20
+ end
21
+
22
+ unless @company_id.present?
23
+ raise ArgumentError, "Params company_id is required options"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+
5
+ module MekariSso
6
+ class List < MekariSso::Config
7
+ attr_accessor :access_token, :page
8
+
9
+ def initialize(options = nil)
10
+ apply(options) if options
11
+ end
12
+
13
+ def available_keys
14
+ %i[access_token page]
15
+ end
16
+
17
+ def validate_required!
18
+ unless @access_token.present?
19
+ raise ArgumentError, "Params access_token is required options"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+ require_relative 'list'
5
+
6
+ module MekariSso
7
+ class Province < MekariSso::List
8
+ attr_accessor :province_id
9
+
10
+ def initialize(options = nil)
11
+ apply(options) if options
12
+ end
13
+
14
+ def available_keys
15
+ super + %i[province_id]
16
+ end
17
+
18
+ def validate_required!
19
+ unless @province_id.present?
20
+ raise ArgumentError, "Params province_id is required options"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+
5
+ module MekariSso
6
+ class RemoveUserCompany < MekariSso::AddUserCompany
7
+ end
8
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+
5
+ module MekariSso
6
+ class UserAvatar < MekariSso::Config
7
+ attr_accessor :user_id, :avatar, :access_token
8
+
9
+ def initialize(options = nil)
10
+ apply(options) if options
11
+ end
12
+
13
+ def available_keys
14
+ %i[user_id avatar access_token]
15
+ end
16
+
17
+ def validate_required!
18
+ unless @access_token.present?
19
+ raise ArgumentError, "Params access_token is required options"
20
+ end
21
+
22
+ unless @user_id.present?
23
+ raise ArgumentError, "Params user_id is required options"
24
+ end
25
+
26
+ unless @avatar.present?
27
+ raise ArgumentError, "Params avatar is required options"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -23,10 +23,6 @@ module MekariSso
23
23
  raise ArgumentError, "Params first_name is required options"
24
24
  end
25
25
 
26
- unless @last_name.present?
27
- raise ArgumentError, "Params last_name is required options"
28
- end
29
-
30
26
  unless @password.present?
31
27
  raise ArgumentError, "Params password is required options"
32
28
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+ require_relative 'user_register'
5
+
6
+ module MekariSso
7
+ class UserUpdate < MekariSso::UserRegister
8
+ attr_accessor :email, :first_name, :last_name, :password, :phone, :access_token, :user_id
9
+
10
+ def initialize(options = nil)
11
+ apply(options) if options
12
+ end
13
+
14
+ def available_keys
15
+ super + %i[user_id]
16
+ end
17
+
18
+ def validate_required!
19
+ unless @user_id.present?
20
+ raise ArgumentError, "Params user_id is required options"
21
+ end
22
+
23
+ unless @access_token.present?
24
+ raise ArgumentError, "Params access_token is required options"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'config'
4
+ require_relative 'user_register'
5
+
6
+ module MekariSso
7
+ class UserVerifyEmail < MekariSso::Config
8
+ attr_accessor :redirect_path, :access_token, :user_id
9
+
10
+ def initialize(options = nil)
11
+ apply(options) if options
12
+ end
13
+
14
+ def available_keys
15
+ %i[user_id access_token redirect_path]
16
+ end
17
+
18
+ def validate_required!
19
+ unless @access_token.present?
20
+ raise ArgumentError, "Params access_token is required options"
21
+ end
22
+
23
+ unless @user_id.present?
24
+ raise ArgumentError, "Params user_id is required options"
25
+ end
26
+
27
+ unless @redirect_path.present?
28
+ raise ArgumentError, "Params redirect_path is required options"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class AddUserToCompany < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def params
17
+ {
18
+ user_id: @params.user_id
19
+ }
20
+ end
21
+
22
+ def headers_request
23
+ headers.merge({
24
+ authorization: "Bearer #{@params.access_token}"
25
+ })
26
+ end
27
+
28
+ def send
29
+ RestClient.post "#{@config.base_url}/v1/companies/#{@params.company_id}/users", params, headers_request
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class Cities < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def headers_request
17
+ headers.merge({
18
+ authorization: "Bearer #{@params.access_token}"
19
+ })
20
+ end
21
+
22
+ def page
23
+ @params.page.present? ? @params.page : 1
24
+ end
25
+
26
+ def send
27
+ RestClient.get "#{@config.base_url}/v1.1/provinces/#{@params.province_id}/cities?page=#{page}", headers_request
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class Companies < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def headers_request
17
+ headers.merge({
18
+ authorization: "Bearer #{@params.access_token}"
19
+ })
20
+ end
21
+
22
+ def page
23
+ @params.page.present? ? @params.page : 1
24
+ end
25
+
26
+ def send
27
+ RestClient.get "#{@config.base_url}/v1.1/companies?page=#{page}", headers_request
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class CompanyMember < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def headers_request
17
+ headers.merge({
18
+ authorization: "Bearer #{@params.access_token}"
19
+ })
20
+ end
21
+
22
+ def page
23
+ @params.page.present? ? @params.page : 1
24
+ end
25
+
26
+ def send
27
+ RestClient.get "#{@config.base_url}/v1.1/companies/#{params.company_id}/users?page=#{page}", headers_request
28
+ end
29
+ end
30
+
31
+ end
@@ -16,16 +16,13 @@ module MekariSso
16
16
  end
17
17
 
18
18
  def after_success(data)
19
- {
20
- response: data
21
- }
19
+ result = Struct.new(:response)
20
+ result.new(data)
22
21
  end
23
22
 
24
23
  def after_error(data, error)
25
- {
26
- response: data,
27
- error: error
28
- }
24
+ result = Struct.new(:response, :error)
25
+ result.new(data, error)
29
26
  end
30
27
 
31
28
  def original_response
@@ -36,16 +33,17 @@ module MekariSso
36
33
  def handle_response(response)
37
34
  if @with_original_response
38
35
  begin
39
- result = Struct.new
40
- return result.new(JSON.parse(response.body))
36
+ return JSON.parse(response.body)
41
37
  rescue StandardError
42
38
  return response.body
43
39
  end
44
40
  end
45
41
 
46
- result = JSON.parse(response)
42
+ result = JSON.parse(response.body)
47
43
 
48
44
  after_success(result)
45
+ rescue
46
+ response
49
47
  end
50
48
 
51
49
  def handle_error(response, error)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class PostalCodes < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def headers_request
17
+ headers.merge({
18
+ authorization: "Bearer #{@params.access_token}"
19
+ })
20
+ end
21
+
22
+ def send
23
+ RestClient.get "#{@config.base_url}/v1.1/cities/#{@params.city_id}/postal_codes", headers_request
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class Provincies < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def headers_request
17
+ headers.merge({
18
+ authorization: "Bearer #{@params.access_token}"
19
+ })
20
+ end
21
+
22
+ def page
23
+ @params.page.present? ? @params.page : 1
24
+ end
25
+
26
+ def send
27
+ RestClient.get "#{@config.base_url}/v1.1/provinces?page=#{page}", headers_request
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class RemoveUserFromCompany < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def headers_request
17
+ headers.merge({
18
+ authorization: "Bearer #{@params.access_token}"
19
+ })
20
+ end
21
+
22
+ def send
23
+ RestClient.delete "#{@config.base_url}/v1/companies/#{@params.company_id}/users/#{@params.user_id}", headers_request
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class UpdateAvatar < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def params
17
+ {
18
+ avatar: @params.avatar
19
+ }
20
+ end
21
+
22
+ def headers_request
23
+ {
24
+ authorization: "Bearer #{@params.access_token}"
25
+ }
26
+ end
27
+
28
+ def send
29
+ RestClient.post "#{@config.base_url}/v1/users/#{@params.user_id}/avatar", params, headers_request
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class UpdateUser < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def params
17
+ {
18
+ email: @params.email,
19
+ first_name: @params.first_name,
20
+ last_name: @params.last_name,
21
+ password: @params.password,
22
+ phone: @params.phone
23
+ }
24
+ end
25
+
26
+ def headers_request
27
+ headers.merge({
28
+ authorization: "Bearer #{@params.access_token}"
29
+ })
30
+ end
31
+
32
+ def send
33
+ RestClient.put "#{@config.base_url}/v1/users/#{@params.user_id}", params, headers_request
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require_relative 'http_request'
5
+
6
+ module MekariSso
7
+ class VerifyEmailUser < MekariSso::HttpRequest
8
+
9
+ attr_reader :config, :params
10
+
11
+ def initialize(config, params)
12
+ @config = config
13
+ @params = params
14
+ end
15
+
16
+ def params
17
+ {
18
+ redirect_path: @params.redirect_path
19
+ }
20
+ end
21
+
22
+ def headers_request
23
+ headers.merge({
24
+ authorization: "Bearer #{@params.access_token}"
25
+ })
26
+ end
27
+
28
+ def send
29
+ RestClient.post "#{@config.base_url}/v1/users/#{@params.user_id}/verify_email", params, headers_request
30
+ end
31
+ end
32
+
33
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mekari_sso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.2
4
+ version: 0.0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - WSPDV
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-09 00:00:00.000000000 Z
11
+ date: 2022-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -66,20 +66,39 @@ extra_rdoc_files: []
66
66
  files:
67
67
  - lib/config.rb
68
68
  - lib/mekari_sso.rb
69
+ - lib/params/add_user_company.rb
70
+ - lib/params/city.rb
71
+ - lib/params/company.rb
69
72
  - lib/params/company_register.rb
70
73
  - lib/params/company_remove.rb
74
+ - lib/params/list.rb
75
+ - lib/params/province.rb
76
+ - lib/params/remove_user_company.rb
77
+ - lib/params/user_avatar.rb
71
78
  - lib/params/user_register.rb
79
+ - lib/params/user_update.rb
80
+ - lib/params/user_verify_email.rb
81
+ - lib/requests/add_user_to_company.rb
82
+ - lib/requests/cities.rb
83
+ - lib/requests/companies.rb
84
+ - lib/requests/company_member.rb
72
85
  - lib/requests/current_user.rb
73
86
  - lib/requests/generate_credential_client.rb
74
87
  - lib/requests/generate_credential_code.rb
75
88
  - lib/requests/http_request.rb
76
89
  - lib/requests/industries.rb
90
+ - lib/requests/postal_codes.rb
91
+ - lib/requests/provincies.rb
77
92
  - lib/requests/refresh.rb
78
93
  - lib/requests/register_company.rb
79
94
  - lib/requests/register_user.rb
80
95
  - lib/requests/remove_company.rb
96
+ - lib/requests/remove_user_from_company.rb
81
97
  - lib/requests/revoke.rb
82
98
  - lib/requests/sender.rb
99
+ - lib/requests/update_avatar.rb
100
+ - lib/requests/update_user.rb
101
+ - lib/requests/verify_email_user.rb
83
102
  homepage: https://gitlab.com/dwiheruwaspodo/mekari_sso
84
103
  licenses:
85
104
  - MIT