mangusta 0.4.6 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d2f20cc69e65ae5f20dc801665a0251238fb74ddb128a3952616c62145aac15
4
- data.tar.gz: 04bcf00cb49c97528926b9fd5b0338f92718a99dfc35c68ca570c1ea811e076e
3
+ metadata.gz: 3025be0dedcde244996c477c8e879032a60a2e872aed4667f0858df3aec06be5
4
+ data.tar.gz: 71c12d3fcd5bb8887527ea04bc6b767fdbcdf94e54a29613a9b4b60df3f2731b
5
5
  SHA512:
6
- metadata.gz: 4a913616f90146b989f11582d7d2c4a401983cc1841f3f87c4f5d63c555a401e5f5dac6177e280f7671b6ec49ebf5ad0e3cbba2d060bd9be1ad1ba7196ecd79a
7
- data.tar.gz: 023f8792d2c6d8d45310a7e3c09def270db9c6a3966c7a97bc5308e32a213b3b03dd18fabc4f427b2ae8060dce1101c967fe792082b3518f050930bc91685d21
6
+ metadata.gz: da37743a7de44df5814952d6e06df610cecb001b6cd9e989a54c3ca87a4ee99957a2809ee63fd0b3b188dcc94afb169e64361e31d4558a927835ff08078209e3
7
+ data.tar.gz: df54fe5798baedc2a4492dfb5498965d053fd53e2ff380a49eb1c66d193c3f36fce57335a162cd93fa68bae21fa01b37bc58230685437bcada5a42dbdcbfe38b
data/Gemfile CHANGED
@@ -3,5 +3,5 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in mangusta.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 12.0"
6
+ gem "rake", "~> 13.0"
7
7
  gem "rspec", "~> 3.0"
@@ -1,46 +1,39 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mangusta (0.3.2)
4
+ mangusta (0.4.6)
5
5
  italian-ruby (~> 0.1)
6
6
  mongo (~> 2.11)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- bson (4.8.2)
11
+ bson (4.9.1)
12
12
  diff-lcs (1.3)
13
- italian-ruby (0.2.7)
14
- ruby2ruby (~> 2.4)
15
- mongo (2.12.0)
13
+ italian-ruby (0.8.0)
14
+ mongo (2.12.1)
16
15
  bson (>= 4.8.2, < 5.0.0)
17
- rake (12.3.3)
16
+ rake (13.0.1)
18
17
  rspec (3.9.0)
19
18
  rspec-core (~> 3.9.0)
20
19
  rspec-expectations (~> 3.9.0)
21
20
  rspec-mocks (~> 3.9.0)
22
- rspec-core (3.9.1)
23
- rspec-support (~> 3.9.1)
24
- rspec-expectations (3.9.1)
21
+ rspec-core (3.9.2)
22
+ rspec-support (~> 3.9.3)
23
+ rspec-expectations (3.9.2)
25
24
  diff-lcs (>= 1.2.0, < 2.0)
26
25
  rspec-support (~> 3.9.0)
27
26
  rspec-mocks (3.9.1)
28
27
  diff-lcs (>= 1.2.0, < 2.0)
29
28
  rspec-support (~> 3.9.0)
30
- rspec-support (3.9.2)
31
- ruby2ruby (2.4.4)
32
- ruby_parser (~> 3.1)
33
- sexp_processor (~> 4.6)
34
- ruby_parser (3.14.2)
35
- sexp_processor (~> 4.9)
36
- sexp_processor (4.14.1)
29
+ rspec-support (3.9.3)
37
30
 
38
31
  PLATFORMS
39
32
  ruby
40
33
 
41
34
  DEPENDENCIES
42
35
  mangusta!
43
- rake (~> 12.0)
36
+ rake (~> 13.0)
44
37
  rspec (~> 3.0)
45
38
 
46
39
  BUNDLED WITH
@@ -12,6 +12,7 @@ module Mongo
12
12
  class View
13
13
  alias :primo :first
14
14
  alias :lista :entries
15
+ alias :conteggio :count
15
16
  end
16
17
  end
17
18
  end
@@ -13,9 +13,13 @@ modulo Mangusta
13
13
  # includi Mangusta::Documento
14
14
  #
15
15
  # campo :titolo, valore_iniziale: "Il Signore degli Anelli"
16
+ #
16
17
  # appartiene_a :autore,
17
18
  # ripostiglio: "RipostiglioAutori",
18
19
  # nome_campo: :id_autore
20
+ #
21
+ # incorpora_molte :ristampe,
22
+ # nome_classe: "Libro::Ristampa"
19
23
  # fine
20
24
  #
21
25
  # Il metodo di classe `campo` ha come primo argomento obbligatorio il nome del campo,
@@ -25,24 +29,53 @@ modulo Mangusta
25
29
  #
26
30
  # I metodi di classe `appartiene_a`, `ha_molte`, `ha_e_appartiene_a_molte` (gli ultimi
27
31
  # due hanno alias `ha_molti` e `ha_e_appartiene_a_molti`) definiscono delle relazioni.
32
+ #
33
+ # I metodi di classe `incorpora_un` (alias `incorpora_una`) e `incorpora_molti` (alias
34
+ # `incorpora_molte`) definiscono dei documenti incorporati. Un esempio di documento
35
+ # incorporato è questo:
36
+ #
37
+ # classe Libro
38
+ # classe Ristampa
39
+ # includi Mangusta::Documento
40
+ #
41
+ # campo :anno
42
+ #
43
+ # incorporato_in :libro,
44
+ # nome_classe: "Libro"
45
+ # fine
46
+ # fine
28
47
  modulo Documento
29
48
 
30
49
  ##
31
50
  # Inizializzatore di un documento.
32
51
  # Si preoccupa di impostare campi ed eventuali valori iniziali.
33
52
  definisci inizializzatore(**attributi)
34
- ritorna se se_stesso.classe.campi.nullo? o se_stesso.classe.campi.vuoto?
53
+ ritorna se campi.nessuno?
54
+ _assegna_valori_iniziali
55
+ assegna **attributi
56
+ assegna _id: IdOggetto.nuovo se _id.nullo?
57
+ fine
35
58
 
36
- se_stesso.classe.campi.per_ognuno esegui |campo|
37
- _inizializza_campo campo
59
+ ##
60
+ # Assegna dei valori al documento.
61
+ definisci assegna(**attributi)
62
+ attributi.per_ognuno esegui |nome_attributo, valore_attributo|
63
+ metodo_assegnazione = "#{nome_attributo}="
64
+ prossimo se se_stesso.non_risponde_a? metodo_assegnazione
65
+ se_stesso.manda metodo_assegnazione, valore_attributo
38
66
  fine
39
67
 
40
- assegna **attributi
41
- _genera_nuovo_id se ottieni_valore(:_id).nullo?
42
- _genera_documento_padre **attributi se attributi.ha_chiave? :_padre
43
- _memorizza_attributi_originali **attributi
68
+ se_stesso
44
69
  fine
45
70
 
71
+ ##
72
+ # Espone il documento come JSON.
73
+ definisci esponi(*chiavi_richieste, **relazioni_richieste)
74
+ espositore = Mangusta::Documento::Espositore.nuovo se_stesso, *chiavi_richieste, **relazioni_richieste
75
+ espositore.esponi
76
+ fine
77
+ alias :in_mappa :esponi
78
+
46
79
  ##
47
80
  # Recupera i campi definiti.
48
81
  definisci campi
@@ -57,141 +90,29 @@ modulo Mangusta
57
90
 
58
91
  ##
59
92
  # Recupera i documenti incorporati.
60
- definisci documenti_incorporati
61
- se_stesso.classe.documenti_incorporati || []
62
- fine
63
-
64
- ##
65
- # Recupera il valore di un campo del documento.
66
- definisci ottieni_valore(nome_campo)
67
- valore_campo = ottieni_variabile_istanza "@#{nome_campo}"
68
- ritorna valore_campo se valore_campo.non_è_una? Mappa
69
- valore_campo.simbolizza
70
- fine
71
-
72
- ##
73
- # Imposta il valore di un campo del documento.
74
- definisci imposta_valore(nome_campo, valore_campo)
75
- imposta_variabile_istanza "@#{nome_campo}", valore_campo
76
- fine
77
-
78
- ##
79
- # Ottiene la rappresentazione per stampa dell'oggetto.
80
- definisci inspect
81
- "#<#{se_stesso.classe} #{se_stesso.esponi}>"
82
- fine
83
- definisci ai(opzioni = Mappa.nuova)
84
- se definito? AwesomePrint
85
- ap = AwesomePrint::Inspector.nuovo opzioni.fondi(indent: 2, ruby19_syntax: si)
86
- "#<#{se_stesso.classe} #{ap.awesome se_stesso.esponi}>"
87
- altrimenti
88
- inspect
89
- fine
90
- fine
91
-
92
- ##
93
- # Uguaglianza di documenti.
94
- definisci ==(documento)
95
- _id == documento._id
96
- fine
97
- definisci ===(documento)
98
- se_stesso == documento
99
- fine
100
- definisci eql?(documento)
101
- se_stesso == documento
102
- fine
103
-
104
- ##
105
- # Ottiene la rappresentazione in Mappa dei campi del documento.
106
- definisci esponi(*chiavi_richieste, **relazioni_richieste)
107
- Espositore.nuovo(se_stesso, *chiavi_richieste, **relazioni_richieste).esponi
93
+ definisci incorporati
94
+ se_stesso.classe.incorporati || []
108
95
  fine
109
96
 
110
97
  ##
111
- # Assegna i parametri passati al documento. Considera anche gli alias.
112
- definisci assegna(**parametri)
113
- parametri.per_ognuno esegui |nome_parametro, valore_parametro|
114
- nome_metodo_assegnamento = "#{nome_parametro}="
115
- prossimo se se_stesso.non_risponde_a? nome_metodo_assegnamento
116
- se_stesso.manda nome_metodo_assegnamento, _converti_in_id(valore_parametro)
98
+ # Codice da eseguire quando questo modulo verrà incluso.
99
+ definisci se_stesso.quando_incluso(classe_documento)
100
+ classe_documento.apri_classe esegui
101
+ includi Mangusta::Documento::MetodiCondivisi
102
+ estendi Mangusta::Documento::MetodiDiClasse
103
+ _inizializza_documento
117
104
  fine
118
- se_stesso
119
- fine
120
-
121
- ##
122
- # Accede al valore dell'attributo originale del documento,
123
- # passando oltre gli accessori, per accedere a campi non modellati.
124
- definisci [](attributo)
125
- @_attributi_originali.prendi attributo
126
- fine
127
-
128
- ##
129
- # Accede al documento padre, se presente.
130
- definisci _padre
131
- @_padre
132
105
  fine
133
106
 
134
107
  privati
135
108
 
136
109
  ##
137
- # Imposta il valore iniziale di un campo.
138
- definisci _inizializza_campo(campo)
139
- se campo.ha_valore_iniziale?
140
- imposta_variabile_istanza "@#{campo.nome}", campo.valore_iniziale
141
- altrimenti
142
- imposta_variabile_istanza "@#{campo.nome}", nullo
110
+ # Assegna i valori iniziali ai campi.
111
+ definisci _assegna_valori_iniziali
112
+ campi.seleziona { |campo| campo.ha_valore_iniziale? }.per_ognuno esegui |campo|
113
+ campo.assegna se_stesso, campo.valore_iniziale
143
114
  fine
144
115
  fine
145
116
 
146
- ##
147
- # Genera un nuovo id.
148
- definisci _genera_nuovo_id
149
- imposta_valore :_id, IdOggetto.nuovo
150
- fine
151
-
152
- ##
153
- # Genera il puntatore al documento padre.
154
- definisci _genera_documento_padre(**attributi)
155
- @_padre = attributi.prendi :_padre
156
- fine
157
-
158
- ##
159
- # Converte in IdOggetto una stringa.
160
- # Se la conversione fallisce, ritorna la stringa iniziale.
161
- definisci _converti_in_id(stringa)
162
- ritorna stringa se stringa.non_è_una? Stringa
163
- IdOggetto.converti(stringa)
164
- recupera
165
- stringa
166
- fine
167
-
168
- ##
169
- # Memorizza gli attiributi originali del documento.
170
- definisci _memorizza_attributi_originali(**attributi)
171
- @_attributi_originali = attributi
172
- fine
173
-
174
- ##
175
- # Codice da eseguire quando questo modulo verrà incluso.
176
- definisci se_stesso.quando_incluso(classe_documento)
177
-
178
- classe_documento.apri_classe esegui
179
- estendi Mangusta::Documento::MetodiDiClasse
180
-
181
- classe << se_stesso
182
- accessore :campi
183
- accessore :relazioni
184
- accessore :documenti_incorporati
185
- fine
186
-
187
- se_stesso.campi = []
188
- se_stesso.relazioni = []
189
- se_stesso.documenti_incorporati = []
190
-
191
- _memorizza_campo :_id
192
- fine
193
-
194
- fine
195
-
196
117
  fine
197
118
  fine
@@ -6,12 +6,16 @@ modulo Mangusta
6
6
 
7
7
  accessore :nome
8
8
  accessore :valore_iniziale
9
+ accessore :per_relazione
10
+ accessore :per_incorporato
9
11
 
10
12
  ##
11
13
  # Imposta nome e valore iniziale.
12
- definisci inizializzatore(nome, **parametri)
13
- se_stesso.nome = nome
14
- se_stesso.valore_iniziale = parametri.prendi(:valore_iniziale, nullo)
14
+ definisci inizializzatore(nome, **opzioni)
15
+ se_stesso.nome = nome
16
+ se_stesso.valore_iniziale = opzioni.prendi :valore_iniziale, nullo
17
+ se_stesso.per_relazione = opzioni.prendi :per_relazione, no
18
+ se_stesso.per_incorporato = opzioni.prendi :per_incorporato, no
15
19
  fine
16
20
 
17
21
  ##
@@ -20,6 +24,36 @@ modulo Mangusta
20
24
  se_stesso.valore_iniziale.esiste?
21
25
  fine
22
26
 
27
+ ##
28
+ # Determina se il campo è stato creato per una relazione.
29
+ definisci per_relazione?
30
+ se_stesso.per_relazione == si
31
+ fine
32
+
33
+ ##
34
+ # Determina se il campo è stato creato per un documento incorporato.
35
+ definisci per_incorporato?
36
+ se_stesso.per_incorporato == si
37
+ fine
38
+
39
+ ##
40
+ # Ottiene il valore del campo.
41
+ definisci valore(documento)
42
+ valore_campo = documento.ottieni_variabile_istanza "@#{nome}"
43
+
44
+ se valore_campo.risponde_a? :simbolizza
45
+ valore_campo.simbolizza
46
+ altrimenti
47
+ valore_campo
48
+ fine
49
+ fine
50
+
51
+ ##
52
+ # Assegna il valore al campo.
53
+ definisci assegna(documento, valore_da_assegnare)
54
+ documento.imposta_variabile_istanza "@#{nome}", valore_da_assegnare
55
+ fine
56
+
23
57
  fine
24
58
  fine
25
59
  fine
@@ -5,63 +5,139 @@ modulo Mangusta
5
5
  classe Espositore
6
6
 
7
7
  ##
8
- # Imposta campi e relazioni richieste.
9
- definisci inizializzatore(documento, *chiavi_richieste, **relazioni_richieste)
10
- @documento = documento
11
- @campi_richiesti = chiavi_richieste.seleziona { |chiave| chiave.in? documento.campi.mappa(&:nome) }
12
- @relazioni_dirette = chiavi_richieste.seleziona { |chiave| chiave.in? documento.relazioni.mappa(&:nome) }
13
- @relazioni_annidate = relazioni_richieste.chiavi
14
- @relazioni_richieste = relazioni_richieste
8
+ # Inizializza l'espositore.
9
+ definisci inizializzatore(documento, *interi_richiesti, **filtrati_richiesti)
10
+ @documento = documento
11
+ @filtrati_richiesti = filtrati_richiesti
12
+
13
+ alza "campi, relazioni o incorporati da esporre interamente devono essere Simboli" se
14
+ interi_richiesti.almeno_uno? { |intero_richiesto| intero_richiesto.non_è_un? Simbolo }
15
+
16
+ alza "relazioni o incorporati da filtrare deve essere una Mappa con chiave Simbolo e valore Liste di Simboli" se
17
+ filtrati_richiesti.chiavi.almeno_una? { |chiave| chiave.non_è_un? Simbolo } o
18
+ filtrati_richiesti.valori.almeno_uno? { |lista| lista.non_è_una? Lista } o
19
+ filtrati_richiesti.valori.almeno_uno? { |lista| lista.almeno_uno? { |valore| valore.non_è_un? Simbolo } }
20
+
21
+ @campi = documento.campi.seleziona esegui |campo|
22
+ campo.nome.in? interi_richiesti
23
+ fine
24
+ @relazioni_intere = documento.relazioni.seleziona esegui |relazione|
25
+ relazione.nome.in? interi_richiesti
26
+ fine
27
+ @relazioni_filtrate = documento.relazioni.seleziona esegui |relazione|
28
+ relazione.nome.in? filtrati_richiesti.chiavi
29
+ fine
30
+ @incorporati_interi = documento.incorporati.seleziona esegui |incorporato|
31
+ incorporato.nome.in? interi_richiesti
32
+ fine
33
+ @incorporati_filtrati = documento.incorporati.seleziona esegui |incorporato|
34
+ incorporato.nome.in? filtrati_richiesti.chiavi
35
+ fine
36
+
37
+ @campi = @documento.campi se @campi.nessuno?
38
+ @incorporati_interi = @documento.incorporati se @incorporati_interi.nessuno? e @incorporati_filtrati.nessuno?
15
39
  fine
16
40
 
17
41
  ##
18
42
  # Espone il documento.
19
43
  definisci esponi
20
- @documento_convertito = Mangusta::Utilità.converti_in_json @documento,
21
- *(@relazioni_dirette + @relazioni_annidate)
44
+ documento_esposto = Mappa.nuova
22
45
 
23
- se @campi_richiesti.nessuno?
24
- @documento_convertito
25
- altrimenti
26
- filtra_esposizione
27
- fine
46
+ _esponi_campi_su documento_esposto
47
+ _esponi_incorporati_interi_su documento_esposto
48
+ _esponi_incorporati_filtrati_su documento_esposto
49
+ _esponi_relazioni_intere_su documento_esposto
50
+ _esponi_relazioni_filtrate_su documento_esposto
51
+
52
+ documento_esposto
28
53
  fine
29
54
 
30
- ##
31
- # Filtra l'esposizione del documento sui campi o relazioni richieste.
32
- definisci filtra_esposizione
33
- esposizione_filtrata = Mappa.nuova
55
+ privati
56
+
57
+ ##
58
+ # Espone i campi sul documento esposto.
59
+ definisci _esponi_campi_su(documento_esposto)
60
+ @campi.per_ognuno esegui |campo|
61
+ valore_campo = @documento.manda campo.nome
62
+ prossimo se valore_campo.nullo? o campo.nome == :_padre
63
+
64
+ se valore_campo.è_una? Mappa
65
+ valore_campo = valore_campo.simbolizza
66
+ altrimenti_se valore_campo.è_una? Lista
67
+ valore_campo = valore_campo.mappa(&:simbolizza) recupera valore_campo
68
+ fine
34
69
 
35
- @campi_richiesti.per_ognuno esegui |campo_richiesto|
36
- prossimo se campo_richiesto.non_è_un? Simbolo
37
- esposizione_filtrata.deposita campo_richiesto, @documento_convertito.prendi(campo_richiesto, nullo)
70
+ documento_esposto.deposita campo.nome, valore_campo
71
+ fine
38
72
  fine
39
73
 
40
- @relazioni_dirette.per_ognuna esegui |relazione_richiesta|
41
- alza Relazione::NonInclusa, "per poter esporre la relazione `#{relazione_richiesta}` è necessario prima includerla" se
42
- relazione_richiesta.non_è_un? Simbolo o @documento_convertito.non_ha_chiave? relazione_richiesta
43
- esposizione_filtrata.deposita relazione_richiesta, @documento_convertito.prendi(relazione_richiesta)
74
+ ##
75
+ # Espone gli incorporati interi.
76
+ definisci _esponi_incorporati_interi_su(documento_esposto)
77
+ @incorporati_interi.per_ognuno esegui |incorporato|
78
+ valore_incorporato = @documento.manda incorporato.nome
79
+ considera incorporato.tipologia
80
+ quando :singolo
81
+ documento_esposto.deposita incorporato.nome, valore_incorporato.esponi
82
+ quando :multiplo
83
+ documento_esposto.deposita incorporato.nome, valore_incorporato.mappa(&:esponi)
84
+ fine
85
+ fine
44
86
  fine
45
87
 
46
- @relazioni_richieste.per_ognuna esegui |nome_relazione, campi_relazione_richiesti|
47
- prossima se campi_relazione_richiesti.non_è_una? Lista
48
- valore_relazione = @documento_convertito.prendi nome_relazione, nulla
49
- se valore_relazione.è_una? Mappa
50
- esposizione_filtrata.deposita nome_relazione, valore_relazione
51
- .seleziona { |chiave, valore| chiave.in? campi_relazione_richiesti }
52
- altrimenti_se valore_relazione.è_una? Lista
53
- valori_filtrati = valore_relazione.mappa esegui |singolo_valore_relazione|
54
- prossima se singolo_valore_relazione.non_è_una? Mappa
55
- singolo_valore_relazione.seleziona { |chiave, valore| chiave.in? campi_relazione_richiesti }
88
+ ##
89
+ # Espone gli incorporati filtrati.
90
+ definisci _esponi_incorporati_filtrati_su(documento_esposto)
91
+ @incorporati_filtrati.per_ognuno esegui |incorporato|
92
+ valore_incorporato = @documento.manda incorporato.nome
93
+ campi_incorporato_filtrati = @filtrati_richiesti.prendi incorporato.nome
94
+ considera incorporato.tipologia
95
+ quando :singolo
96
+ documento_esposto.deposita incorporato.nome, valore_incorporato.esponi(*campi_incorporato_filtrati)
97
+ quando :multiplo
98
+ documento_esposto.deposita incorporato.nome, valore_incorporato
99
+ .mappa { |documento_incorporato| documento_incorporato.esponi *campi_incorporato_filtrati }
56
100
  fine
57
- esposizione_filtrata.deposita nome_relazione, valori_filtrati.compatta
58
- altrimenti
59
- prossima
60
101
  fine
61
102
  fine
62
103
 
63
- esposizione_filtrata
64
- fine
104
+ ##
105
+ # Espone le relazioni intere.
106
+ definisci _esponi_relazioni_intere_su(documento_esposto)
107
+ @relazioni_intere.per_ognuna esegui |relazione|
108
+ alza Relazione::NonInclusa, "la relazione #{relazione.nome} deve essere inclusa per "\
109
+ "poter essere esposta" se relazione.documenti_in_memoria.nullo?
110
+
111
+ valore_relazione = @documento.manda relazione.nome
112
+ considera relazione.tipologia
113
+ quando :appartiene_a
114
+ documento_esposto.deposita relazione.nome, valore_relazione.esponi
115
+ quando :ha_molti, :ha_e_appartiene_a_molti
116
+ documento_esposto.deposita relazione.nome, valore_relazione.mappa(&:esponi)
117
+ fine
118
+ fine
119
+ fine
120
+
121
+ ##
122
+ # Espone le relazioni filtrate.
123
+ definisci _esponi_relazioni_filtrate_su(documento_esposto)
124
+ @relazioni_filtrate.per_ognuna esegui |relazione|
125
+ alza Relazione::NonInclusa, "la relazione #{relazione.nome} deve essere inclusa per "\
126
+ "poter essere esposta" se relazione.documenti_in_memoria.nullo?
127
+
128
+ valore_relazione = @documento.manda relazione.nome
129
+ prossima se valore_relazione.nulla?
130
+
131
+ campi_relazione_filtrati = @filtrati_richiesti.prendi relazione.nome
132
+ considera relazione.tipologia
133
+ quando :appartiene_a
134
+ documento_esposto.deposita relazione.nome, valore_relazione.esponi(*campi_relazione_filtrati)
135
+ quando :ha_molti, :ha_e_appartiene_a_molti
136
+ documento_esposto.deposita relazione.nome, valore_relazione
137
+ .mappa { |documento_relazionato| documento_relazionato.esponi *campi_relazione_filtrati }
138
+ fine
139
+ fine
140
+ fine
65
141
 
66
142
  fine
67
143
  fine