gooddata 2.1.10-java → 2.1.15-java
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 +4 -4
- data/.gdc-ii-config.yaml +1 -1
- data/CHANGELOG.md +29 -0
- data/Dockerfile +5 -3
- data/README.md +17 -0
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/run_brick.rb +3 -0
- data/bin/test_projects_cleanup.rb +6 -2
- data/dev-gooddata-sso.pub.encrypted +40 -40
- data/gdc_fossa_lcm.yaml +2 -0
- data/gdc_fossa_ruby_sdk.yaml +5 -0
- data/gooddata.gemspec +3 -3
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +32 -12
- data/lib/gooddata.rb +2 -0
- data/lib/gooddata/helpers/global_helpers_params.rb +2 -2
- data/lib/gooddata/lcm/actions/base_action.rb +0 -2
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +2 -1
- data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +116 -0
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +10 -1
- data/lib/gooddata/lcm/lcm2.rb +1 -2
- data/lib/gooddata/lcm/types/base_type.rb +0 -2
- data/lib/gooddata/models/blueprint/project_blueprint.rb +0 -2
- data/lib/gooddata/models/data_source.rb +662 -0
- data/lib/gooddata/models/domain.rb +1 -2
- data/lib/gooddata/models/from_wire.rb +1 -0
- data/lib/gooddata/models/metadata/scheduled_mail.rb +1 -1
- data/lib/gooddata/models/process.rb +11 -3
- data/lib/gooddata/models/project.rb +121 -13
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +0 -1
- data/lib/gooddata/models/user_group.rb +0 -1
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +14 -10
@@ -5,7 +5,6 @@
|
|
5
5
|
# LICENSE file in the root directory of this source tree.
|
6
6
|
|
7
7
|
require 'cgi'
|
8
|
-
require 'active_support/core_ext/hash/compact'
|
9
8
|
|
10
9
|
require_relative 'profile'
|
11
10
|
require_relative '../extensions/enumerable'
|
@@ -241,7 +240,7 @@ module GoodData
|
|
241
240
|
|
242
241
|
all_users
|
243
242
|
else
|
244
|
-
find_user_by_login(domain, id)
|
243
|
+
find_user_by_login(domain, id, opts)
|
245
244
|
end
|
246
245
|
end
|
247
246
|
|
@@ -105,6 +105,7 @@ module GoodData
|
|
105
105
|
d[:title] = date_dim['dateDimension']['title']
|
106
106
|
d[:urn] = date_dim['dateDimension']['urn']
|
107
107
|
d[:identifier_prefix] = date_dim['dateDimension']['identifierPrefix']
|
108
|
+
d[:identifier] = date_dim['dateDimension']['identifier'] if date_dim['dateDimension']['identifier']
|
108
109
|
d[:columns] = parse_bridges(date_dim)
|
109
110
|
end
|
110
111
|
end
|
@@ -118,11 +118,13 @@ module GoodData
|
|
118
118
|
GoodData.logger.info("Deploying #{path}") if verbose
|
119
119
|
|
120
120
|
deployed_path = Process.upload_package(path, files_to_exclude, client: client, project: project)
|
121
|
+
data_sources = options[:data_sources] || []
|
121
122
|
data = {
|
122
123
|
:process => {
|
123
124
|
:name => deploy_name,
|
124
125
|
:path => "/uploads/#{File.basename(deployed_path)}",
|
125
|
-
:type => type
|
126
|
+
:type => type,
|
127
|
+
:dataSources => data_sources
|
126
128
|
}
|
127
129
|
}
|
128
130
|
|
@@ -171,10 +173,12 @@ module GoodData
|
|
171
173
|
verbose = options[:verbose] || false
|
172
174
|
GoodData.logger.info("Deploying #{path}") if verbose
|
173
175
|
|
176
|
+
data_sources = options[:data_sources] || []
|
174
177
|
data = {
|
175
178
|
process: {
|
176
179
|
name: deploy_name,
|
177
180
|
path: path,
|
181
|
+
dataSources: data_sources,
|
178
182
|
type: 'RUBY'
|
179
183
|
}
|
180
184
|
}
|
@@ -185,7 +189,7 @@ module GoodData
|
|
185
189
|
def deploy_component(data, options = { client: GoodData.client, project: GoodData.project })
|
186
190
|
client, project = GoodData.get_client_and_project(options)
|
187
191
|
data = { process: data } unless data[:process]
|
188
|
-
data[:process] = GoodData::Helpers.symbolize_keys(data[:process]).select { |k| %i[type name component].include? k }
|
192
|
+
data[:process] = GoodData::Helpers.symbolize_keys(data[:process]).select { |k| %i[type name component dataSources].include? k }
|
189
193
|
data[:process][:component] = GoodData::Helpers.symbolize_keys(data[:process][:component]).select { |k| %i[name version configLocation config].include? k }
|
190
194
|
|
191
195
|
save(data, options)
|
@@ -266,7 +270,7 @@ module GoodData
|
|
266
270
|
# @option options [String] :name Readable name of the process
|
267
271
|
# @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
|
268
272
|
def deploy(path, options = {})
|
269
|
-
Process.deploy(path, { client: client, process_id: process_id, :project => project, :name => name, :type => type }.merge(options))
|
273
|
+
Process.deploy(path, { client: client, process_id: process_id, :project => project, :name => name, :type => type, :data_sources => data_sources }.merge(options))
|
270
274
|
end
|
271
275
|
|
272
276
|
# Downloads the process from S3 in a zipped form.
|
@@ -326,6 +330,10 @@ module GoodData
|
|
326
330
|
process['component']
|
327
331
|
end
|
328
332
|
|
333
|
+
def data_sources
|
334
|
+
process['dataSources']
|
335
|
+
end
|
336
|
+
|
329
337
|
# Determines whether the process is an ADDv2 component.
|
330
338
|
# @return [Bool] True if the process is an ADDv2 component.
|
331
339
|
def add_v2_component?
|
@@ -13,7 +13,6 @@ require 'zip'
|
|
13
13
|
require 'net/smtp'
|
14
14
|
|
15
15
|
require 'active_support/core_ext/hash/except'
|
16
|
-
require 'active_support/core_ext/hash/compact'
|
17
16
|
require 'active_support/core_ext/hash/slice'
|
18
17
|
|
19
18
|
require_relative '../exceptions/no_project_error'
|
@@ -261,21 +260,26 @@ module GoodData
|
|
261
260
|
# @option ads_output_stage_uri Uri of the source output stage. It must be in the same domain as the target project.
|
262
261
|
def transfer_processes(from_project, to_project, options = {})
|
263
262
|
options = GoodData::Helpers.symbolize_keys(options)
|
263
|
+
aliases = {}
|
264
264
|
to_project_processes = to_project.processes
|
265
265
|
additional_hidden_params = options[:additional_hidden_params] || {}
|
266
266
|
result = from_project.processes.uniq(&:name).map do |process|
|
267
|
-
fail "The process name #{process.name} must be unique in
|
267
|
+
fail "The process name #{process.name} must be unique in transferred project #{to_project}" if to_project_processes.count { |p| p.name == process.name } > 1
|
268
268
|
next if process.type == :dataload || process.add_v2_component?
|
269
|
+
collect_process_aliases(process.data, from_project.client, aliases)
|
269
270
|
|
270
271
|
to_process = to_project_processes.find { |p| p.name == process.name }
|
271
272
|
|
273
|
+
data_sources = GoodData::Helpers.symbolize_keys_recursively!(process.data_sources)
|
274
|
+
data_sources = replace_data_source_ids(data_sources, to_project.client, aliases)
|
272
275
|
to_process = if process.path
|
273
276
|
to_process.delete if to_process
|
274
|
-
|
277
|
+
Process.deploy_from_appstore(process.path, name: process.name, client: to_project.client, project: to_project, data_sources: data_sources)
|
275
278
|
elsif process.component
|
276
279
|
to_process.delete if to_process
|
277
280
|
process_hash = GoodData::Helpers::DeepMergeableHash[GoodData::Helpers.symbolize_keys(process.to_hash)].deep_merge(additional_hidden_params)
|
278
|
-
|
281
|
+
process_hash = replace_process_data_source_ids(process_hash, to_project.client, aliases)
|
282
|
+
Process.deploy_component(process_hash, project: to_project, client: to_project.client)
|
279
283
|
else
|
280
284
|
Dir.mktmpdir('etl_transfer') do |dir|
|
281
285
|
dir = Pathname(dir)
|
@@ -283,11 +287,10 @@ module GoodData
|
|
283
287
|
File.open(filename, 'w') do |f|
|
284
288
|
f << process.download
|
285
289
|
end
|
286
|
-
|
287
290
|
if to_process
|
288
|
-
to_process.deploy(filename, type: process.type, name: process.name)
|
291
|
+
to_process.deploy(filename, type: process.type, name: process.name, data_sources: data_sources)
|
289
292
|
else
|
290
|
-
to_project.deploy_process(filename, type: process.type, name: process.name)
|
293
|
+
to_project.deploy_process(filename, type: process.type, name: process.name, data_sources: data_sources)
|
291
294
|
end
|
292
295
|
end
|
293
296
|
end
|
@@ -318,6 +321,78 @@ module GoodData
|
|
318
321
|
result.compact
|
319
322
|
end
|
320
323
|
|
324
|
+
def collect_process_aliases(process_data, client, aliases)
|
325
|
+
data_sources = process_data.dig('process', 'dataSources')
|
326
|
+
unless data_sources.blank?
|
327
|
+
data_sources.map do |data_source|
|
328
|
+
get_data_source_alias(data_source['id'], client, aliases)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
component = process_data.dig('process', 'component')
|
332
|
+
get_data_source_alias(component['configLocation']['dataSourceConfig']['id'], client, aliases) if component&.dig('configLocation', 'dataSourceConfig')
|
333
|
+
aliases
|
334
|
+
end
|
335
|
+
|
336
|
+
def get_data_source_alias(data_source_id, client, aliases)
|
337
|
+
unless aliases[data_source_id]
|
338
|
+
data_source = GoodData::DataSource.from_id(data_source_id, client: client)
|
339
|
+
if data_source&.dig('dataSource', 'alias')
|
340
|
+
aliases[data_source_id] = {
|
341
|
+
:type => get_data_source_type(data_source),
|
342
|
+
:alias => data_source['dataSource']['alias']
|
343
|
+
}
|
344
|
+
end
|
345
|
+
end
|
346
|
+
aliases[data_source_id]
|
347
|
+
end
|
348
|
+
|
349
|
+
def get_data_source_type(data_source_data)
|
350
|
+
data_source_data&.dig('dataSource', 'connectionInfo') ? data_source_data['dataSource']['connectionInfo'].first[0].upcase : ""
|
351
|
+
end
|
352
|
+
|
353
|
+
def replace_process_data_source_ids(process_data, client, aliases)
|
354
|
+
component = process_data.dig(:process, :component)
|
355
|
+
if component&.dig(:configLocation, :dataSourceConfig)
|
356
|
+
the_alias = aliases[component[:configLocation][:dataSourceConfig][:id]]
|
357
|
+
process_data[:process][:component][:configLocation][:dataSourceConfig][:id] = verify_data_source_alias(the_alias, client)
|
358
|
+
end
|
359
|
+
process_data[:process][:dataSources] = replace_data_source_ids(process_data[:process][:dataSources], client, aliases)
|
360
|
+
process_data
|
361
|
+
end
|
362
|
+
|
363
|
+
def replace_data_source_ids(data_sources, client, aliases)
|
364
|
+
array_data_sources = []
|
365
|
+
if data_sources && !data_sources.empty?
|
366
|
+
data_sources.map do |data_source|
|
367
|
+
new_id = verify_data_source_alias(aliases[data_source[:id]], client)
|
368
|
+
array_data_sources.push(:id => new_id)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
array_data_sources
|
372
|
+
end
|
373
|
+
|
374
|
+
# Verify whether the data source exists in the domain using its alias
|
375
|
+
#
|
376
|
+
# @param [String] ds_alias The data source's alias
|
377
|
+
# @param [Object] client The Rest Client object
|
378
|
+
# @return [String] Id of the data source or failed with the reason
|
379
|
+
def verify_data_source_alias(ds_alias, client)
|
380
|
+
domain = client.connection.server.url
|
381
|
+
fail "The data source alias is empty, check your data source configuration." unless ds_alias
|
382
|
+
|
383
|
+
uri = "/gdc/dataload/dataSources/internal/availableAlias?alias=#{ds_alias[:alias]}"
|
384
|
+
res = client.get(uri)
|
385
|
+
fail "Unable to get information about the Data Source '#{ds_alias[:alias]}' in the domain '#{domain}'" unless res
|
386
|
+
fail "Unable to find the #{ds_alias[:type]} Data Source '#{ds_alias[:alias]}' in the domain '#{domain}'" if res['availableAlias']['available']
|
387
|
+
|
388
|
+
ds_type = res['availableAlias']['existingDataSource']['type']
|
389
|
+
if ds_type && ds_type != ds_alias[:type]
|
390
|
+
fail "Wrong Data Source type - the '#{ds_type}' type is expected but the Data Source '#{ds_alias[:alias]}' in the domain '#{domain}' has the '#{ds_alias[:type]}' type"
|
391
|
+
else
|
392
|
+
res['availableAlias']['existingDataSource']['id']
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
321
396
|
def transfer_user_groups(from_project, to_project)
|
322
397
|
from_project.user_groups.map do |ug|
|
323
398
|
# migrate groups
|
@@ -625,6 +700,7 @@ module GoodData
|
|
625
700
|
def blueprint(options = {})
|
626
701
|
options = { include_ca: true }.merge(options)
|
627
702
|
result = client.get("/gdc/projects/#{pid}/model/view", params: { includeDeprecated: true, includeGrain: true, includeCA: options[:include_ca] })
|
703
|
+
|
628
704
|
polling_url = result['asyncTask']['link']['poll']
|
629
705
|
model = client.poll_on_code(polling_url, options)
|
630
706
|
bp = GoodData::Model::FromWire.from_wire(model, options)
|
@@ -1606,14 +1682,19 @@ module GoodData
|
|
1606
1682
|
def import_users(new_users, options = {})
|
1607
1683
|
role_list = roles
|
1608
1684
|
users_list = users
|
1609
|
-
new_users = new_users.map { |x| ((x.is_a?(Hash) && x[:user] && x[:user].to_hash.merge(role: x[:role])) || x.to_hash).tap { |u| u[:login].downcase! } }
|
1610
1685
|
|
1611
1686
|
GoodData.logger.warn("Importing users to project (#{pid})")
|
1687
|
+
new_users = new_users.map { |x| ((x.is_a?(Hash) && x[:user] && x[:user].to_hash.merge(role: x[:role])) || x.to_hash).tap { |u| u[:login].downcase! } }
|
1688
|
+
# First check that if groups are provided we have them set up
|
1689
|
+
user_groups_cache, change_groups = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)
|
1612
1690
|
|
1613
|
-
|
1691
|
+
unless change_groups.empty?
|
1692
|
+
new_users.each do |user|
|
1693
|
+
user[:user_group].map! { |e| change_groups[e].nil? ? e : change_groups[e] }
|
1694
|
+
end
|
1695
|
+
end
|
1614
1696
|
|
1615
|
-
|
1616
|
-
user_groups_cache = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)
|
1697
|
+
whitelisted_new_users, whitelisted_users = whitelist_users(new_users.map(&:to_hash), users_list, options[:whitelists])
|
1617
1698
|
|
1618
1699
|
# conform the role on list of new users so we can diff them with the users coming from the project
|
1619
1700
|
diffable_new_with_default_role = whitelisted_new_users.map do |u|
|
@@ -1760,7 +1841,20 @@ module GoodData
|
|
1760
1841
|
def check_groups(specified_groups, user_groups_cache = nil, options = {})
|
1761
1842
|
current_user_groups = user_groups if user_groups_cache.nil? || user_groups_cache.empty?
|
1762
1843
|
groups = current_user_groups.map(&:name)
|
1763
|
-
missing_groups =
|
1844
|
+
missing_groups = []
|
1845
|
+
change_groups = {}
|
1846
|
+
specified_groups.each do |group|
|
1847
|
+
found_group = groups.find { |name| name.casecmp(group).zero? }
|
1848
|
+
if found_group.nil?
|
1849
|
+
missing_groups << group
|
1850
|
+
else
|
1851
|
+
# Change groups when they have similar group name with difference of case sensitivity
|
1852
|
+
if found_group != group
|
1853
|
+
change_groups[group] = found_group
|
1854
|
+
GoodData.logger.warn("Group with name #{group} is existed in project with name #{found_group}.")
|
1855
|
+
end
|
1856
|
+
end
|
1857
|
+
end
|
1764
1858
|
if options[:create_non_existing_user_groups]
|
1765
1859
|
missing_groups.each do |g|
|
1766
1860
|
GoodData.logger.info("Creating group #{g}")
|
@@ -1773,7 +1867,7 @@ module GoodData
|
|
1773
1867
|
"#{groups.join(',')} and you asked for #{missing_groups.join(',')}"
|
1774
1868
|
end
|
1775
1869
|
end
|
1776
|
-
current_user_groups
|
1870
|
+
[current_user_groups, change_groups]
|
1777
1871
|
end
|
1778
1872
|
|
1779
1873
|
# Update user
|
@@ -1904,6 +1998,20 @@ module GoodData
|
|
1904
1998
|
[user, roles]
|
1905
1999
|
end
|
1906
2000
|
|
2001
|
+
def upgrade_custom_v2(message, options = {})
|
2002
|
+
uri = "/gdc/md/#{pid}/datedimension/upgrade"
|
2003
|
+
poll_result = client&.post(uri, message)
|
2004
|
+
|
2005
|
+
return poll_result['wTaskStatus']['status'] if poll_result['wTaskStatus'] && poll_result['wTaskStatus']['status']
|
2006
|
+
|
2007
|
+
polling_uri = poll_result['asyncTask']['link']['poll']
|
2008
|
+
result = client&.poll_on_response(polling_uri, options) do |body|
|
2009
|
+
body && body['wTaskStatus'] && body['wTaskStatus']['status'] == 'RUNNING'
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
result['wTaskStatus']['status'] == 'OK' ? 'OK' : 'FAIL'
|
2013
|
+
end
|
2014
|
+
|
1907
2015
|
def add
|
1908
2016
|
@add ||= GoodData::AutomatedDataDistribution.new(self)
|
1909
2017
|
@add
|
@@ -1,51 +1,51 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
1
|
+
WX5YSUEbFPPD1bbGFJCkV/mUvZe41EFHmDd60AQo4+Pw6ejd2BVzZSJTtUez
|
2
|
+
UXYABeTg7+j/vo3HPBRVO8zm5+qzpBniWM24Vyzijp70/Gpiam2Yj+J7EqCX
|
3
|
+
HPpusljVkJXDQPZUNHMAMN8fuqJusHlj69KFW01TPjNzi8/AYVhu9bfgUYRa
|
4
|
+
HqZeIFpPMX/l7V4Xm2l5CRqUVoLYsHh842PUjyr1bab09t3nOtuMeWcPFxWD
|
5
|
+
ZTNzjjnhqJAZM5UJr4VEtNVSkjCbdPo7Dl6Sc8czZ3xJem64cEF5kwKSrVpR
|
6
|
+
cYu62qc4zUSAANRJUH8lRXnfelrYCH0PBvMZoHX2cFLSMSfM5tzBfsBzx9Ah
|
7
|
+
xUooyKQFRHYgFc/UF6Hb/Chl9UDPAD7Tvo9dRfJkr2PMBLxqg7u96hRQAbKd
|
8
|
+
XfP/MSlAp6+88IO0UmQu57M5HKZUupA7W2yx6U57I5z1NM4vRAzMbvkJWCLE
|
9
|
+
OCoHk+2hhDj6ltd9GOzUW8ew7VmK5t/fdhoi1BYJXzGYi9tiikp+l4+3vgeY
|
10
|
+
OJuoQWp7uAsr+G9tXS/ZyJ296fv4uuF05QFTWIxxziqzgTL5PZF8o6E+THdO
|
11
|
+
AYp/8ChpNvUpwwBtTVEszYf495IX7mW7WcxOEu3+gsM47Mm+/vgOXPhQQJ3e
|
12
|
+
tWun6pkZwJ/o5WGPMviBQLwxAhJEqdEUWbmp6NL6RBl/1xuIfEVto6hyoVsp
|
13
|
+
j30KqS9ZsxrkhI9LiqwjEv+zF224nKKgJ2VO28hU4izvwt4rzQOkcSYor8W6
|
14
|
+
q1QykCy9lmpuZFWL1awbMbp2GzK3I0Kpfa+/vsnwzutoNfHbW3MPg7f0C4rS
|
15
|
+
eR/hCG20IRsuSFm3CSmr2MrGbCC6tODUA0JJGpJFPnE3c/srNjYWls1XPhFY
|
16
|
+
6TjpuU1jHogzITHAGN24K8cJB6FyQJCiGTdeBpJj2Vrb27T5r1ViJefogpFD
|
17
|
+
j+PATgq1KXmXy6BAm0lvGHNkM9SDblPSCEDRzWw/ynBau/lfKNtKEb+DHIq2
|
18
|
+
lCQBWyfWfKUOyEoPdmcnHNLy7vgihvmfiP4DuyR4q6zg1wPRbb5+dsGx5edT
|
19
|
+
bMAonfjMptG57O1zQrFvumgDCRZzi5MSBv5bggam15eBOBi+vZHu8oOZZ8Ib
|
20
|
+
SumE6KwJLrDAy8gFST7k0/8b21xjfr0ARUc0y6RiI/BO549430+HLEYUf8MV
|
21
|
+
t7lbmq9Nb22GCrAfmPolBkZ2fISf4QwfABHIZEy92IEqhLuhpSou6bcq1wyy
|
22
|
+
bpD/ITDkAWIcZO62oReNcI7gg9lUREVs3HQHTOhwAMpBABVxgTzGsuPLiN7R
|
23
|
+
vESTwDydlkPjg5V8waCVDpr05vd65eKb51eTmGewPwFEf5Irg2HWKQ76bTaE
|
24
|
+
REB3E5410PIM6MDZuhPILqV82p07rreLPFczUqErZGhq/bpKu1HNyByOePik
|
25
|
+
IhTdkpgoufDb8Tdueyrr8GZXEI+k4VKEvNlWGLnFDGzK/7pEedgkpogp8I4M
|
26
|
+
TulS2U09HbkuLQe0BUfJE5thwkeYk0hGGDHRAx82xwamIkKXC1MfjN7wJvEt
|
27
|
+
qmIlmOtUKMV7oJsDDR4dPxkUOz/8qVh4YCtb8wvRF3HpaL3gz8RQd6TJ8JMf
|
28
|
+
Oq1ph9kJfNq2dEFXJHoMke+qJFTdS6OMm9Gi2XkhFkA+omcoq9uo3NiBVBR4
|
29
|
+
oVXa8Xw/MeMVrR14+cheU09s5vWU3tQGFawJAypSAY94EqmApqnDzI/e6hcQ
|
30
|
+
JGv9Uny69XBHLLo+QMZm2dv/VFbzkCTcY9ZNlpSPMQv4VfDLQ2DNwCWxS3pq
|
31
|
+
ijY9BIp38yZL7GuSuEjafoJGi10jrzzies7nE3bQAcfX+rjS9MlL7U3LzaZS
|
32
|
+
20ss5EOX0XxGe/iypgXuW4Xa+wTo6Mw2HInrhwFG/a5/ZbKm0TPoCIt88eZC
|
33
|
+
veUU3FvbFuEiX6SyS8LGzT9ecAvy7T9aeIwnGQZedHKLB52mg0BXY/QBtGyf
|
34
|
+
rxL+IiLAegqbqwA2gUsCMCTgcv7wENrrh086UNbVOAG+WMAR615PQSD1lSBx
|
35
|
+
WKcKX2tqYl/rgOuSkIT6x0BbbZLbGI90XIRvpl3Kl8Txl6/Qvc3bhBGgan50
|
36
|
+
lct25VsE5FC/Qyoh9aQqcjjHStY5uo8ss0Bf+q2tBF+2PpG7BUM4AWJh6Z/9
|
37
|
+
Iha8YqnflReNh0q5LbklpR96WUuiri7PphAqCWZOlAmxqw/ueTxG4DPMtJOE
|
38
|
+
PqArQlQ4cxkTQ3J34HndAk8M/Pll404reu6Qq/1Ru7VJbLkR8iqt/MykiASn
|
39
|
+
K/qKGoi2JbIm6LgkY6KG/PK18vdQZqj/ldX0HFVFll5cxKcDoKYdWq9pyiM7
|
40
|
+
R12rMBC9Sg5dybDs5Xza9SSaKv6a8ac3k2BkLord7MxBv4ru0+MfsGOfvk53
|
41
|
+
OFs27o01FUoY8/IyOEE6S8qURAQB0qBLC4WSML0atV3vkRYQYZWxbv9NHkzO
|
42
|
+
+cY2Rs9NCveXbldLesGYOb/9rD9lp/aPWBvUkPM/M1tE4L6lJU9aSoXpJdSe
|
43
|
+
LC3D3U7BkVmZ4wlWoJj0LQW8U7xLccJxKKPQIHr1GTjhryDCnGG0kT03AqB/
|
44
|
+
V5UHNZCDvo5IZB7FT4Z9cgqkGPC/LmUpNzCVPzDDFmLYMO+7mddtlNCPYOEg
|
45
|
+
ukTi9NaBoIQfqejlj/L880MQYVWIfzrvIFCLmk+aERSgHaFMKD+Z5lsppdAC
|
46
|
+
FmFhFtoU3iqkuZt3QrgofwJUUUsYMcbpmwu9YkviwxoYA5WiNLAHj4h9bn2D
|
47
|
+
5CjE3yXARb0C1Hwjkpjyc29oHBC6W8vRZUBOG0xzhVYZfVR6pcZvHdP5XTKj
|
48
|
+
zU8aufwtwr2Xlus6ADJBPmFMqeral7KWUNUUMEUtR7LCy3lDiy/BUCda5AM5
|
49
|
+
LVXTK+pAZ23cupadvZsQRUkHJr6vL+ctcf5uYenB3cdh67GjghNhM2qeIOka
|
50
|
+
d0dFTK+FS328CIESa0ZUEIk6EL50mW0i9RJAi03Me26OgbW5egLixhVK4KC0
|
51
|
+
Ci5CZG2Xf5mWx5mUGrK5ZNB3in/9jEzX3oQx8Jd6twfkQzMG0kA=
|
@@ -1,109 +1,109 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
/
|
21
|
-
/
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
+
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
1
|
+
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
|
109
|
+
5UICsw==
|