1 | package com.jsql.model.injection.vendor; | |
2 | ||
3 | import com.jsql.model.InjectionModel; | |
4 | import com.jsql.model.bean.util.Header; | |
5 | import com.jsql.model.bean.util.Interaction; | |
6 | import com.jsql.model.bean.util.Request; | |
7 | import com.jsql.model.injection.vendor.model.Vendor; | |
8 | import com.jsql.model.injection.vendor.model.VendorYaml; | |
9 | import com.jsql.util.I18nUtil; | |
10 | import com.jsql.util.LogLevelUtil; | |
11 | import org.apache.commons.lang3.StringUtils; | |
12 | import org.apache.commons.lang3.SystemUtils; | |
13 | import org.apache.logging.log4j.LogManager; | |
14 | import org.apache.logging.log4j.Logger; | |
15 | ||
16 | import java.net.URLEncoder; | |
17 | import java.nio.charset.StandardCharsets; | |
18 | import java.time.LocalDate; | |
19 | import java.time.format.DateTimeFormatter; | |
20 | import java.util.Arrays; | |
21 | import java.util.EnumMap; | |
22 | import java.util.List; | |
23 | import java.util.Map; | |
24 | ||
25 | public class MediatorVendor { | |
26 | | |
27 | /** | |
28 | * Log4j logger sent to view. | |
29 | */ | |
30 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
31 | | |
32 | private static final String LOG_VENDOR = "{} [{}]"; | |
33 | ||
34 | /** | |
35 | * Database vendor currently used. | |
36 | * It can be switched to another vendor by automatic detection or manual selection. | |
37 | */ | |
38 | private Vendor vendor; | |
39 | ||
40 | /** | |
41 | * Database vendor selected by user (default UNDEFINED). | |
42 | * If not UNDEFINED then the next injection will be forced to use the selected vendor. | |
43 | */ | |
44 | private Vendor vendorByUser; | |
45 | ||
46 | // TODO Replace with enum | |
47 | private final Vendor auto; | |
48 | private final Vendor cubrid; | |
49 | private final Vendor db2; | |
50 | private final Vendor derby; | |
51 | private final Vendor firebird; | |
52 | private final Vendor h2; | |
53 | private final Vendor hsqldb; | |
54 | private final Vendor informix; | |
55 | private final Vendor mckoi; | |
56 | private final Vendor mimer; | |
57 | private final Vendor monetdb; | |
58 | private final Vendor mysql; | |
59 | private final Vendor neo4j; | |
60 | private final Vendor oracle; | |
61 | private final Vendor postgresql; | |
62 | private final Vendor sqlite; | |
63 | private final Vendor sqlserver; | |
64 | private final Vendor sybase; | |
65 | private final Vendor vertica; | |
66 | ||
67 | private final List<Vendor> vendors; | |
68 | | |
69 | private final InjectionModel injectionModel; | |
70 | | |
71 | public MediatorVendor(InjectionModel injectionModel) { | |
72 | | |
73 | this.injectionModel = injectionModel; | |
74 | | |
75 | Vendor access = new Vendor(new VendorYaml("access.yml", injectionModel)); | |
76 | Vendor altibase = new Vendor(new VendorYaml("altibase.yml", injectionModel)); | |
77 | Vendor ctreeace = new Vendor(new VendorYaml("ctreeace.yml", injectionModel)); | |
78 | Vendor exasol = new Vendor(new VendorYaml("exasol.yml", injectionModel)); | |
79 | Vendor frontbase = new Vendor(new VendorYaml("frontbase.yml", injectionModel)); | |
80 | Vendor hana = new Vendor(new VendorYaml("hana.yml", injectionModel)); | |
81 | Vendor ingres = new Vendor(new VendorYaml("ingres.yml", injectionModel)); | |
82 | Vendor iris = new Vendor(new VendorYaml("iris.yml", injectionModel)); | |
83 | Vendor maxdb = new Vendor(new VendorYaml("maxdb.yml", injectionModel)); | |
84 | Vendor netezza = new Vendor(new VendorYaml("netezza.yml", injectionModel)); | |
85 | Vendor nuodb = new Vendor(new VendorYaml("nuodb.yml", injectionModel)); | |
86 | Vendor presto = new Vendor(new VendorYaml("presto.yml", injectionModel)); | |
87 | Vendor teradata = new Vendor(new VendorYaml("teradata.yml", injectionModel)); | |
88 | ||
89 | this.auto = new Vendor(); | |
90 | this.cubrid = new Vendor(new VendorYaml("cubrid.yml", injectionModel)); | |
91 | this.db2 = new Vendor(new VendorYaml("db2.yml", injectionModel)); | |
92 | this.derby = new Vendor(new VendorYaml("derby.yml", injectionModel)); | |
93 | this.firebird = new Vendor(new VendorYaml("firebird.yml", injectionModel)); | |
94 | this.h2 = new Vendor(new VendorYaml("h2.yml", injectionModel)); | |
95 | this.hsqldb = new Vendor(new VendorYaml("hsqldb.yml", injectionModel)); | |
96 | this.informix = new Vendor(new VendorYaml("informix.yml", injectionModel)); | |
97 | this.mckoi = new Vendor(new VendorYaml("mckoi.yml", injectionModel)); | |
98 | this.mimer = new Vendor(new VendorYaml("mimersql.yml", injectionModel)); | |
99 | this.monetdb = new Vendor(new VendorYaml("monetdb.yml", injectionModel)); | |
100 | this.mysql = new Vendor(new VendorYaml("mysql.yml", injectionModel)); | |
101 | this.neo4j = new Vendor(new VendorYaml("neo4j.yml", injectionModel)); | |
102 | this.oracle = new Vendor(new VendorYaml("oracle.yml", injectionModel)); | |
103 | this.postgresql = new Vendor(new VendorYaml("postgresql.yml", injectionModel)); | |
104 | this.sqlite = new Vendor(new VendorYaml("sqlite.yml", injectionModel)) { | |
105 | ||
106 | @Override | |
107 | public String transformSqlite(String resultToParse) { | |
108 | ||
109 | var resultSqlite = new StringBuilder(); | |
110 | ||
111 | String resultTmp = resultToParse | |
112 | .replaceFirst("[^(]+\\(", StringUtils.EMPTY) | |
113 | .trim() | |
114 | .replaceAll("\\)$", StringUtils.EMPTY); | |
115 | ||
116 | resultTmp = resultTmp.replaceAll("\\([^)]+\\)", StringUtils.EMPTY); | |
117 | ||
118 | for (String columnNameAndType: resultTmp.split(",")) { | |
119 | ||
120 |
1
1. transformSqlite : negated conditional → NO_COVERAGE |
if (columnNameAndType.trim().startsWith("primary key")) { |
121 | continue; | |
122 | } | |
123 | ||
124 | // Some recent SQLite use tabulation character as a separator => split() by any white space \s | |
125 | String columnName = columnNameAndType.trim().split("\\s")[0]; | |
126 | ||
127 | // Some recent SQLite enclose names with ` => strip those ` | |
128 | columnName = StringUtils.strip(columnName, "`"); | |
129 | ||
130 | if ( | |
131 |
1
1. transformSqlite : negated conditional → NO_COVERAGE |
!"CONSTRAINT".equals(columnName) |
132 |
1
1. transformSqlite : negated conditional → NO_COVERAGE |
&& !"UNIQUE".equals(columnName) |
133 | ) { | |
134 | // Generate pattern \4\5\4\6 for injection parsing | |
135 | resultSqlite.append((char) 4).append(columnName).append((char) 5).append("0").append((char) 4).append((char) 6); | |
136 | } | |
137 | } | |
138 | ||
139 |
1
1. transformSqlite : replaced return value with "" for com/jsql/model/injection/vendor/MediatorVendor$1::transformSqlite → NO_COVERAGE |
return resultSqlite.toString(); |
140 | } | |
141 | }; | |
142 | this.sqlserver = new Vendor(new VendorYaml("sqlserver.yml", injectionModel)); | |
143 | this.sybase = new Vendor(new VendorYaml("sybase.yml", injectionModel)); | |
144 | this.vertica = new Vendor(new VendorYaml("vertica.yml", injectionModel)); | |
145 | ||
146 | this.vendors = Arrays.asList( | |
147 | this.auto, | |
148 | access, | |
149 | altibase, | |
150 | ctreeace, | |
151 | this.cubrid, | |
152 | this.db2, | |
153 | this.derby, | |
154 | exasol, | |
155 | this.firebird, | |
156 | frontbase, | |
157 | this.h2, | |
158 | hana, | |
159 | this.hsqldb, | |
160 | this.informix, | |
161 | ingres, | |
162 | iris, | |
163 | maxdb, | |
164 | this.mckoi, | |
165 | this.mimer, | |
166 | this.monetdb, | |
167 | this.mysql, | |
168 | this.neo4j, | |
169 | netezza, | |
170 | nuodb, | |
171 | this.oracle, | |
172 | this.postgresql, | |
173 | presto, | |
174 | this.sqlite, | |
175 | this.sqlserver, | |
176 | this.sybase, | |
177 | teradata, | |
178 | this.vertica | |
179 | ); | |
180 | | |
181 |
1
1. <init> : removed call to com/jsql/model/injection/vendor/MediatorVendor::setVendor → SURVIVED |
this.setVendor(this.mysql); |
182 | this.vendorByUser = this.auto; | |
183 | } | |
184 | | |
185 | public boolean isSqlite() { | |
186 |
2
1. isSqlite : negated conditional → NO_COVERAGE 2. isSqlite : replaced boolean return with true for com/jsql/model/injection/vendor/MediatorVendor::isSqlite → NO_COVERAGE |
return this.getVendor() == this.getSqlite(); |
187 | } | |
188 | | |
189 | public Vendor fingerprintVendor() { | |
190 | | |
191 | Vendor vendorFound = null; | |
192 | | |
193 |
1
1. fingerprintVendor : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorVendor().getVendorByUser() != this.injectionModel.getMediatorVendor().getAuto()) { |
194 | | |
195 | vendorFound = this.injectionModel.getMediatorVendor().getVendorByUser(); | |
196 | LOGGER.log( | |
197 | LogLevelUtil.CONSOLE_INFORM, | |
198 | MediatorVendor.LOG_VENDOR, | |
199 |
1
1. lambda$fingerprintVendor$0 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$fingerprintVendor$0 → NO_COVERAGE |
() -> I18nUtil.valueByKey("LOG_DATABASE_TYPE_FORCED_BY_USER"), |
200 |
1
1. lambda$fingerprintVendor$1 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$fingerprintVendor$1 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendorByUser() |
201 | ); | |
202 | } else { | |
203 | | |
204 | LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Fingerprinting database..."); | |
205 | | |
206 | var insertionCharacter = URLEncoder.encode("'\"#-)'\"*", StandardCharsets.UTF_8); | |
207 | String pageSource = this.injectionModel.injectWithoutIndex(insertionCharacter, "test#vendor"); | |
208 | | |
209 | var mediatorVendor = this.injectionModel.getMediatorVendor(); | |
210 | Vendor[] vendorsWithoutAuto = mediatorVendor.getVendors() | |
211 | .stream() | |
212 |
2
1. lambda$fingerprintVendor$2 : replaced boolean return with true for com/jsql/model/injection/vendor/MediatorVendor::lambda$fingerprintVendor$2 → NO_COVERAGE 2. lambda$fingerprintVendor$2 : negated conditional → NO_COVERAGE |
.filter(v -> v != mediatorVendor.getAuto()) |
213 |
1
1. lambda$fingerprintVendor$3 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$fingerprintVendor$3 → NO_COVERAGE |
.toArray(Vendor[]::new); |
214 | | |
215 | // Test each vendor | |
216 | for (Vendor vendorTest: vendorsWithoutAuto) { | |
217 |
1
1. fingerprintVendor : negated conditional → NO_COVERAGE |
if (pageSource.matches(vendorTest.instance().fingerprintErrorsAsRegex())) { |
218 | | |
219 | vendorFound = vendorTest; | |
220 | LOGGER.log( | |
221 | LogLevelUtil.CONSOLE_SUCCESS, | |
222 | MediatorVendor.LOG_VENDOR, | |
223 |
1
1. lambda$fingerprintVendor$4 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$fingerprintVendor$4 → NO_COVERAGE |
() -> "Basic fingerprint matching vendor", |
224 |
1
1. lambda$fingerprintVendor$5 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$fingerprintVendor$5 → NO_COVERAGE |
() -> vendorTest |
225 | ); | |
226 | break; | |
227 | } | |
228 | } | |
229 | | |
230 | vendorFound = this.initializeVendor(vendorFound); | |
231 | } | |
232 | ||
233 |
1
1. fingerprintVendor : removed call to com/jsql/model/InjectionModel::appendAnalysisReport → NO_COVERAGE |
this.injectionModel.appendAnalysisReport( |
234 | "<span style=color:rgb(0,0,255)># Date: " + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) | |
235 | + "<br># Tested on: " + String.format("%s (v%s)", SystemUtils.OS_NAME, SystemUtils.OS_VERSION) | |
236 | + "<br># Tool: jSQL Injection v" + this.injectionModel.getVersionJsql() | |
237 | + " (<a href="+this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperties().get("github.url")+">" | |
238 | + this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperties().get("github.url") | |
239 | + "</a>)" | |
240 | + "<br># Database: " + vendorFound | |
241 | + "<br><br>## Vulnerability summary</span>", | |
242 | true | |
243 | ); | |
244 | ||
245 | var requestSetVendor = new Request(); | |
246 |
1
1. fingerprintVendor : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE |
requestSetVendor.setMessage(Interaction.SET_VENDOR); |
247 | Map<Header, Object> msgHeader = new EnumMap<>(Header.class); | |
248 | msgHeader.put(Header.URL, this.injectionModel.getMediatorUtils().getConnectionUtil().getUrlByUser()); | |
249 | msgHeader.put(Header.VENDOR, vendorFound); | |
250 |
1
1. fingerprintVendor : removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE |
requestSetVendor.setParameters(msgHeader); |
251 |
1
1. fingerprintVendor : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE |
this.injectionModel.sendToViews(requestSetVendor); |
252 | | |
253 |
1
1. fingerprintVendor : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::fingerprintVendor → NO_COVERAGE |
return vendorFound; |
254 | } | |
255 | ||
256 | public Vendor initializeVendor(Vendor vendor) { | |
257 | | |
258 | var vendorFixed = vendor; | |
259 | | |
260 |
1
1. initializeVendor : negated conditional → NO_COVERAGE |
if (vendorFixed == null) { |
261 | | |
262 | vendorFixed = this.injectionModel.getMediatorVendor().getMysql(); | |
263 | LOGGER.log( | |
264 | LogLevelUtil.CONSOLE_INFORM, | |
265 | MediatorVendor.LOG_VENDOR, | |
266 |
1
1. lambda$initializeVendor$6 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$initializeVendor$6 → NO_COVERAGE |
() -> I18nUtil.valueByKey("LOG_DATABASE_TYPE_NOT_FOUND"), |
267 |
1
1. lambda$initializeVendor$7 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$initializeVendor$7 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getMysql() |
268 | ); | |
269 | } else { | |
270 | | |
271 | LOGGER.log( | |
272 | LogLevelUtil.CONSOLE_INFORM, | |
273 | MediatorVendor.LOG_VENDOR, | |
274 |
1
1. lambda$initializeVendor$8 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$initializeVendor$8 → NO_COVERAGE |
() -> I18nUtil.valueByKey("LOG_USING_DATABASE_TYPE"), |
275 |
1
1. lambda$initializeVendor$9 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::lambda$initializeVendor$9 → NO_COVERAGE |
() -> vendor |
276 | ); | |
277 | | |
278 | Map<Header, Object> msgHeader = new EnumMap<>(Header.class); | |
279 | msgHeader.put( | |
280 | Header.URL, | |
281 | this.injectionModel.getMediatorUtils().getConnectionUtil().getUrlByUser() | |
282 | ); | |
283 | msgHeader.put(Header.VENDOR, vendorFixed); | |
284 | | |
285 | var requestDatabaseIdentified = new Request(); | |
286 |
1
1. initializeVendor : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE |
requestDatabaseIdentified.setMessage(Interaction.DATABASE_IDENTIFIED); |
287 |
1
1. initializeVendor : removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE |
requestDatabaseIdentified.setParameters(msgHeader); |
288 |
1
1. initializeVendor : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE |
this.injectionModel.sendToViews(requestDatabaseIdentified); |
289 | } | |
290 | | |
291 |
1
1. initializeVendor : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::initializeVendor → NO_COVERAGE |
return vendorFixed; |
292 | } | |
293 | | |
294 | | |
295 | // Getter and setter | |
296 | | |
297 | public Vendor getAuto() { | |
298 |
1
1. getAuto : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getAuto → NO_COVERAGE |
return this.auto; |
299 | } | |
300 | ||
301 | public Vendor getCubrid() { | |
302 |
1
1. getCubrid : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getCubrid → NO_COVERAGE |
return this.cubrid; |
303 | } | |
304 | ||
305 | public Vendor getH2() { | |
306 |
1
1. getH2 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getH2 → NO_COVERAGE |
return this.h2; |
307 | } | |
308 | ||
309 | public Vendor getPostgresql() { | |
310 |
1
1. getPostgresql : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getPostgresql → NO_COVERAGE |
return this.postgresql; |
311 | } | |
312 | ||
313 | public Vendor getMysql() { | |
314 |
1
1. getMysql : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getMysql → NO_COVERAGE |
return this.mysql; |
315 | } | |
316 | ||
317 | public Vendor getSqlite() { | |
318 |
1
1. getSqlite : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getSqlite → NO_COVERAGE |
return this.sqlite; |
319 | } | |
320 | ||
321 | public Vendor getSqlserver() { | |
322 |
1
1. getSqlserver : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getSqlserver → NO_COVERAGE |
return this.sqlserver; |
323 | } | |
324 | ||
325 | public Vendor getNeo4j() { | |
326 |
1
1. getNeo4j : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getNeo4j → NO_COVERAGE |
return this.neo4j; |
327 | } | |
328 | | |
329 | public Vendor getVendor() { | |
330 |
1
1. getVendor : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getVendor → NO_COVERAGE |
return this.vendor; |
331 | } | |
332 | ||
333 | public void setVendor(Vendor vendor) { | |
334 | this.vendor = vendor; | |
335 | } | |
336 | ||
337 | public Vendor getVendorByUser() { | |
338 |
1
1. getVendorByUser : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getVendorByUser → NO_COVERAGE |
return this.vendorByUser; |
339 | } | |
340 | ||
341 | public void setVendorByUser(Vendor vendorByUser) { | |
342 | this.vendorByUser = vendorByUser; | |
343 | } | |
344 | ||
345 | public List<Vendor> getVendors() { | |
346 |
1
1. getVendors : replaced return value with Collections.emptyList for com/jsql/model/injection/vendor/MediatorVendor::getVendors → NO_COVERAGE |
return this.vendors; |
347 | } | |
348 | ||
349 | public Vendor getDb2() { | |
350 |
1
1. getDb2 : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getDb2 → NO_COVERAGE |
return this.db2; |
351 | } | |
352 | ||
353 | public Vendor getHsqldb() { | |
354 |
1
1. getHsqldb : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getHsqldb → NO_COVERAGE |
return this.hsqldb; |
355 | } | |
356 | ||
357 | public Vendor getDerby() { | |
358 |
1
1. getDerby : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getDerby → NO_COVERAGE |
return this.derby; |
359 | } | |
360 | ||
361 | public Vendor getOracle() { | |
362 |
1
1. getOracle : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getOracle → NO_COVERAGE |
return this.oracle; |
363 | } | |
364 | ||
365 | public Vendor getFirebird() { | |
366 |
1
1. getFirebird : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getFirebird → NO_COVERAGE |
return firebird; |
367 | } | |
368 | ||
369 | public Vendor getMonetdb() { | |
370 |
1
1. getMonetdb : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getMonetdb → NO_COVERAGE |
return monetdb; |
371 | } | |
372 | ||
373 | public Vendor getMimer() { | |
374 |
1
1. getMimer : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getMimer → NO_COVERAGE |
return mimer; |
375 | } | |
376 | ||
377 | public Vendor getMckoi() { | |
378 |
1
1. getMckoi : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getMckoi → NO_COVERAGE |
return mckoi; |
379 | } | |
380 | ||
381 | public Vendor getInformix() { | |
382 |
1
1. getInformix : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getInformix → NO_COVERAGE |
return informix; |
383 | } | |
384 | ||
385 | public Vendor getSybase() { | |
386 |
1
1. getSybase : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getSybase → NO_COVERAGE |
return sybase; |
387 | } | |
388 | ||
389 | public Vendor getVertica() { | |
390 |
1
1. getVertica : replaced return value with null for com/jsql/model/injection/vendor/MediatorVendor::getVertica → NO_COVERAGE |
return vertica; |
391 | } | |
392 | } | |
Mutations | ||
120 |
1.1 |
|
131 |
1.1 |
|
132 |
1.1 |
|
139 |
1.1 |
|
181 |
1.1 |
|
186 |
1.1 2.2 |
|
193 |
1.1 |
|
199 |
1.1 |
|
200 |
1.1 |
|
212 |
1.1 2.2 |
|
213 |
1.1 |
|
217 |
1.1 |
|
223 |
1.1 |
|
224 |
1.1 |
|
233 |
1.1 |
|
246 |
1.1 |
|
250 |
1.1 |
|
251 |
1.1 |
|
253 |
1.1 |
|
260 |
1.1 |
|
266 |
1.1 |
|
267 |
1.1 |
|
274 |
1.1 |
|
275 |
1.1 |
|
286 |
1.1 |
|
287 |
1.1 |
|
288 |
1.1 |
|
291 |
1.1 |
|
298 |
1.1 |
|
302 |
1.1 |
|
306 |
1.1 |
|
310 |
1.1 |
|
314 |
1.1 |
|
318 |
1.1 |
|
322 |
1.1 |
|
326 |
1.1 |
|
330 |
1.1 |
|
338 |
1.1 |
|
346 |
1.1 |
|
350 |
1.1 |
|
354 |
1.1 |
|
358 |
1.1 |
|
362 |
1.1 |
|
366 |
1.1 |
|
370 |
1.1 |
|
374 |
1.1 |
|
378 |
1.1 |
|
382 |
1.1 |
|
386 |
1.1 |
|
390 |
1.1 |