metasploit_data_models 6.0.5 → 6.0.7

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: d0f6a352c3f586ad9ebcd620dcf0f581006b2ea32e63588d3f17bd3933009c76
4
- data.tar.gz: 350592d2f75705120a89a8893d02d8414c78704ccdf284f80ca563931659a920
3
+ metadata.gz: f40cd6914e210d182f683f528eb8af20e813821d9f7d6c17b0c942ad7b3f5f13
4
+ data.tar.gz: 036f11d4a71fc2269462be6133ad5234475d41e914e26a651ac8e2e26543b9cc
5
5
  SHA512:
6
- metadata.gz: 2ea341d26e26025d795a1cad1856c965fe2cec748245da1cab188f91152a7f1c2445ab5111807f6c62a3b58070783228027778592ea0fbc59db26d0b2aa633df
7
- data.tar.gz: 68394ec5e5127a4f5ef1e3c395e80c732a8e117cd4b488a5d3e98fa38f53c6a8f7f215a22857abfdb273ba2e3b2f51b5f378d8ca24c5b52b99a8b63d5e0abeb7
6
+ metadata.gz: 252a1fc665e44c1487479f1870a4ad0fccb8512f107b5feac8898ec6e07f3f9433be3883c5ac2e44d6f40a986bf985d4792a0a0b43a1479fb569acbc5955207e
7
+ data.tar.gz: bdd04378b8f40a80336790223c87a162bf2b5a9ff1dfef6d531581ef86c59459063e4562624ac7d2ddb8d5a3ac28d09e3c8bedc9e2435044a68b26ff7038f781
data/Gemfile CHANGED
@@ -11,15 +11,14 @@ end
11
11
 
12
12
  # used by dummy application
13
13
  group :development, :test do
14
- # Upload coverage reports to coveralls.io
15
- gem 'coveralls', require: false
16
14
  # supplies factories for producing model instance for specs
17
15
  # Version 4.1.0 or newer is needed to support generate calls without the 'FactoryBot.' in factory definitions syntax.
18
16
  gem 'factory_bot'
19
17
  # auto-load factories from spec/factories
20
18
  gem 'factory_bot_rails'
21
19
 
22
- gem 'rails', '~> 7.0'
20
+ # Enforce tests to run on 7.0.X
21
+ gem 'rails', '~> 7.0.0'
23
22
  gem 'net-smtp', require: false
24
23
 
25
24
  # Used to create fake data
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- #MetasploitDataModels [![Build Status](https://travis-ci.org/rapid7/metasploit_data_models.png)](https://travis-ci.org/rapid7/metasploit_data_models)[![Code Climate](https://codeclimate.com/github/rapid7/metasploit_data_models.png)](https://codeclimate.com/github/rapid7/metasploit_data_models)[![Coverage Status](https://coveralls.io/repos/rapid7/metasploit_data_models/badge.png)](https://coveralls.io/r/rapid7/metasploit_data_models)[![Dependency Status](https://gemnasium.com/rapid7/metasploit_data_models.png)](https://gemnasium.com/rapid7/metasploit_data_models)[![Gem Version](https://badge.fury.io/rb/metasploit_data_models.png)](http://badge.fury.io/rb/metasploit_data_models)
1
+ #MetasploitDataModels [![Build Status](https://travis-ci.org/rapid7/metasploit_data_models.png)](https://travis-ci.org/rapid7/metasploit_data_models)[![Code Climate](https://codeclimate.com/github/rapid7/metasploit_data_models.png)](https://codeclimate.com/github/rapid7/metasploit_data_models)[![Dependency Status](https://gemnasium.com/rapid7/metasploit_data_models.png)](https://gemnasium.com/rapid7/metasploit_data_models)[![Gem Version](https://badge.fury.io/rb/metasploit_data_models.png)](http://badge.fury.io/rb/metasploit_data_models)
2
2
 
3
3
  Part of Metasploit's database layer
4
4
 
@@ -73,9 +73,9 @@ class Mdm::Event < ApplicationRecord
73
73
  #
74
74
  # @return [Hash]
75
75
  if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
76
- serialize :info, coder: MetasploitDataModels::Base64Serializer.new
76
+ serialize :info, coder: MetasploitDataModels::Base64Serializer.new(coerce: true)
77
77
  else
78
- serialize :info, MetasploitDataModels::Base64Serializer.new
78
+ serialize :info, MetasploitDataModels::Base64Serializer.new(coerce: true)
79
79
  end
80
80
 
81
81
  #
@@ -70,9 +70,9 @@ class Mdm::Listener < ApplicationRecord
70
70
  #
71
71
  # @return [Hash]
72
72
  if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
73
- serialize :options, coder: MetasploitDataModels::Base64Serializer.new
73
+ serialize :options, coder: MetasploitDataModels::Base64Serializer.new(coerce: true)
74
74
  else
75
- serialize :options, MetasploitDataModels::Base64Serializer.new
75
+ serialize :options, MetasploitDataModels::Base64Serializer.new(coerce: true)
76
76
  end
77
77
 
78
78
  #
@@ -92,10 +92,18 @@ class Mdm::Payload < ApplicationRecord
92
92
 
93
93
  #
94
94
  # Serializations
95
- #
96
95
 
97
- serialize :urls
98
- serialize :build_opts
96
+ if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
97
+ serialize :urls, coder: YAML
98
+ else
99
+ serialize :urls
100
+ end
101
+
102
+ if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
103
+ serialize :build_opts, coder: YAML
104
+ else
105
+ serialize :build_opts
106
+ end
99
107
 
100
108
  public
101
109
 
@@ -173,9 +173,9 @@ class Mdm::Session < ApplicationRecord
173
173
  #
174
174
 
175
175
  if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
176
- serialize :datastore, coder: ::MetasploitDataModels::Base64Serializer.new
176
+ serialize :datastore, coder: ::MetasploitDataModels::Base64Serializer.new(coerce: true)
177
177
  else
178
- serialize :datastore, ::MetasploitDataModels::Base64Serializer.new
178
+ serialize :datastore, ::MetasploitDataModels::Base64Serializer.new(coerce: true)
179
179
  end
180
180
 
181
181
  # Returns whether the session can be upgraded to a meterpreter session from a shell session on Windows.
@@ -131,27 +131,27 @@ class Mdm::Task < ApplicationRecord
131
131
  #
132
132
  # @return [Hash]
133
133
  if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
134
- serialize :options, coder: MetasploitDataModels::Base64Serializer.new
134
+ serialize :options, coder: MetasploitDataModels::Base64Serializer.new(coerce: true)
135
135
  else
136
- serialize :options, MetasploitDataModels::Base64Serializer.new
136
+ serialize :options, MetasploitDataModels::Base64Serializer.new(coerce: true)
137
137
  end
138
138
 
139
139
  # Result of task running.
140
140
  #
141
141
  # @return [Hash]
142
142
  if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
143
- serialize :result, coder: MetasploitDataModels::Base64Serializer.new
143
+ serialize :result, coder: MetasploitDataModels::Base64Serializer.new(coerce: true)
144
144
  else
145
- serialize :result, MetasploitDataModels::Base64Serializer.new
145
+ serialize :result, MetasploitDataModels::Base64Serializer.new(coerce: true)
146
146
  end
147
147
 
148
148
  # Settings used to configure this task outside of the {#options module options}.
149
149
  #
150
150
  # @return [Hash]
151
151
  if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
152
- serialize :settings, coder: MetasploitDataModels::Base64Serializer.new
152
+ serialize :settings, coder: MetasploitDataModels::Base64Serializer.new(coerce: true)
153
153
  else
154
- serialize :settings, MetasploitDataModels::Base64Serializer.new
154
+ serialize :settings, MetasploitDataModels::Base64Serializer.new(coerce: true)
155
155
  end
156
156
 
157
157
  #
@@ -142,9 +142,9 @@ class Mdm::WebVuln < ApplicationRecord
142
142
  #
143
143
  # @return [Array<Array(String, String)>] Array of parameter key value pairs
144
144
  if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
145
- serialize :params, coder: MetasploitDataModels::Base64Serializer.new(:default => DEFAULT_PARAMS)
145
+ serialize :params, coder: MetasploitDataModels::Base64Serializer.new(default: DEFAULT_PARAMS)
146
146
  else
147
- serialize :params, MetasploitDataModels::Base64Serializer.new(:default => DEFAULT_PARAMS)
147
+ serialize :params, MetasploitDataModels::Base64Serializer.new(default: DEFAULT_PARAMS)
148
148
  end
149
149
 
150
150
  #
data/cortex.yaml CHANGED
@@ -10,6 +10,8 @@ info:
10
10
  x-cortex-type: service
11
11
  x-cortex-domain-parents:
12
12
  - tag: metasploit
13
+ x-cortex-groups:
14
+ - exposure:external-ship
13
15
  openapi: 3.0.1
14
16
  servers:
15
17
  - url: "/"
@@ -1,7 +1,11 @@
1
1
  class AddSessionTable < ActiveRecord::Migration[4.2]
2
2
 
3
3
  class Event < ApplicationRecord
4
- serialize :info
4
+ if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
5
+ serialize :info, coder: YAML
6
+ else
7
+ serialize :info
8
+ end
5
9
  end
6
10
 
7
11
  class SessionEvent < ApplicationRecord
@@ -10,7 +14,11 @@ class AddSessionTable < ActiveRecord::Migration[4.2]
10
14
 
11
15
  class Session < ApplicationRecord
12
16
  has_many :events, :class_name => 'AddSessionTable::SessionEvent'
13
- serialize :datastore
17
+ if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
18
+ serialize :datastore, coder: YAML
19
+ else
20
+ serialize :datastore
21
+ end
14
22
  end
15
23
 
16
24
  def self.up
@@ -3,11 +3,19 @@ class ConvertBinary < ActiveRecord::Migration[4.2]
3
3
 
4
4
 
5
5
  class WebPage < ApplicationRecord
6
- serialize :headers
6
+ if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
7
+ serialize :headers, coder: YAML
8
+ else
9
+ serialize :headers
10
+ end
7
11
  end
8
12
 
9
13
  class WebVuln < ApplicationRecord
10
- serialize :params
14
+ if ActiveRecord::VERSION::MAJOR >= 7 && ActiveRecord::VERSION::MINOR >= 1
15
+ serialize :params, coder: YAML
16
+ else
17
+ serialize :params
18
+ end
11
19
  end
12
20
 
13
21
  def bfilter(str)
@@ -15,6 +15,10 @@ class MetasploitDataModels::Base64Serializer
15
15
 
16
16
  # The default for {#default}
17
17
  DEFAULT = {}
18
+
19
+ # The default for {#coerce}
20
+ COERCE_DEFAULT = false
21
+
18
22
  # Deserializers for {#load}
19
23
  # 1. Base64 decoding and then unmarshalling the value.
20
24
  # 2. Parsing the value as YAML.
@@ -47,6 +51,24 @@ class MetasploitDataModels::Base64Serializer
47
51
  end
48
52
 
49
53
  attr_writer :default
54
+ attr_writer :coerce
55
+
56
+ # Recursively coerce the object that has been passed in, keeping primitive types as their original type,
57
+ # while changing objects that cannot be serialized into a string representation of the object data.
58
+ def coerce_object(value)
59
+ case value
60
+ when Hash
61
+ value.transform_values { |v| coerce_object(v) }
62
+ when Array
63
+ value.map { |v| coerce_object(v) }
64
+ when File, IO
65
+ value.inspect
66
+ when String, Integer, Float, TrueClass, FalseClass, NilClass, Symbol
67
+ value
68
+ else
69
+ value.to_s
70
+ end
71
+ end
50
72
 
51
73
  # Serializes the value by marshalling the value and then base64 encodes the marshaled value.
52
74
  #
@@ -54,7 +76,8 @@ class MetasploitDataModels::Base64Serializer
54
76
  # @return [String]
55
77
  def dump(value)
56
78
  # Always store data back in the Marshal format
57
- marshalled = Marshal.dump(value)
79
+ to_serialize = @coerce ? coerce_object(value) : value
80
+ marshalled = Marshal.dump(to_serialize)
58
81
  base64_encoded = [ marshalled ].pack('m')
59
82
 
60
83
  base64_encoded
@@ -63,9 +86,10 @@ class MetasploitDataModels::Base64Serializer
63
86
  # @param attributes [Hash] attributes
64
87
  # @option attributes [Object] :default ({}) Value to use for {#default}.
65
88
  def initialize(attributes={})
66
- attributes.assert_valid_keys(:default)
89
+ attributes.assert_valid_keys(:default, :coerce)
67
90
 
68
91
  @default = attributes.fetch(:default, DEFAULT)
92
+ @coerce = attributes.fetch(:coerce, COERCE_DEFAULT)
69
93
  end
70
94
 
71
95
  # Deserializes the value by either
@@ -1,6 +1,6 @@
1
1
  module MetasploitDataModels
2
2
  # VERSION is managed by GemRelease
3
- VERSION = '6.0.5'
3
+ VERSION = '6.0.7'
4
4
 
5
5
  # @return [String]
6
6
  #
@@ -0,0 +1,45 @@
1
+ RSpec.describe Mdm::Payload, type: :model do
2
+ it_should_behave_like 'Metasploit::Concern.run'
3
+
4
+ context 'factory' do
5
+ it 'should be valid' do
6
+ mdm_payload = FactoryBot.build(:mdm_payload)
7
+ expect(mdm_payload).to be_valid
8
+ end
9
+ end
10
+
11
+ context 'database' do
12
+
13
+ context 'timestamps'do
14
+ it { is_expected.to have_db_column(:created_at).of_type(:datetime) }
15
+ it { is_expected.to have_db_column(:updated_at).of_type(:datetime) }
16
+ end
17
+
18
+ context 'columns' do
19
+ it { is_expected.to have_db_column(:name).of_type(:string) }
20
+ it { is_expected.to have_db_column(:uuid).of_type(:string) }
21
+ it { is_expected.to have_db_column(:uuid_mask).of_type(:integer) }
22
+ it { is_expected.to have_db_column(:timestamp).of_type(:integer) }
23
+ it { is_expected.to have_db_column(:arch).of_type(:string) }
24
+ it { is_expected.to have_db_column(:platform).of_type(:string) }
25
+ it { is_expected.to have_db_column(:urls).of_type(:string) }
26
+ it { is_expected.to have_db_column(:description).of_type(:string) }
27
+ it { is_expected.to have_db_column(:raw_payload).of_type(:string) }
28
+ it { is_expected.to have_db_column(:raw_payload_hash).of_type(:string) }
29
+ it { is_expected.to have_db_column(:build_status).of_type(:string) }
30
+ it { is_expected.to have_db_column(:build_opts).of_type(:string) }
31
+ end
32
+ end
33
+
34
+ context '#destroy' do
35
+ it 'should successfully destroy the object' do
36
+ payload = FactoryBot.create(:mdm_payload)
37
+ expect {
38
+ payload.destroy
39
+ }.to_not raise_error
40
+ expect {
41
+ payload.reload
42
+ }.to raise_error(ActiveRecord::RecordNotFound)
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,6 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
-
2
+ require "logger"
3
+ require "active_support"
3
4
  require 'rails/all'
4
5
 
5
6
  Bundler.require(*Rails.groups)
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :mdm_payload, :aliases => [:payload], :class => Mdm::Payload do
3
+ #
4
+ # Associations
5
+ #
6
+ end
7
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,7 +8,6 @@ Bundler.setup(:default, :test)
8
8
  # Require simplecov before loading ..dummy/config/environment.rb because it will cause metasploit_data_models/lib to
9
9
  # be loaded, which would result in Coverage not recording hits for any of the files.
10
10
  require 'simplecov'
11
- require 'coveralls'
12
11
 
13
12
  # if ENV['TRAVIS'] == 'true'
14
13
  # # don't generate local report as it is inaccessible on travis-ci, which is why coveralls is being used.
metadata CHANGED
@@ -1,40 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metasploit_data_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.5
4
+ version: 6.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
- cert_chain:
11
- - |
12
- -----BEGIN CERTIFICATE-----
13
- MIIERDCCAqygAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBttc2Zk
14
- ZXYvREM9bWV0YXNwbG9pdC9EQz1jb20wHhcNMjMxMDMwMTYwNDI1WhcNMjUxMDI5
15
- MTYwNDI1WjAmMSQwIgYDVQQDDBttc2ZkZXYvREM9bWV0YXNwbG9pdC9EQz1jb20w
16
- ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDZN/EKv+yVjwiKWvjAVhjF
17
- aWNYI0E9bJ5d1qKd29omRYX9a+OOKBCu5+394fyF5RjwU4mYGr2iopX9ixRJrWXH
18
- ojs70tEvV1CmvP9rhz7JKzQQoJOkinrz4d+StIylxVxVdgm7DeiB3ruTwvl7qKUv
19
- piWzhrBFiVU6XIEAwq6wNEmnv2D+Omyf4h0Tf99hc6G0QmBnU3XydqvnZ+AzUbBV
20
- 24RH3+NQoigLbvK4M5aOeYhk19di58hznebOw6twHzNczshrBeMFQp985ScNgsvF
21
- rL+7HNNwpcpngERwZfzDNn7iYN5X3cyvTcykShtsuPMa5zXsYo42LZrsTF87DW38
22
- D8sxL6Dgdqu25Mltdw9m+iD4rHSfb1KJYEoNO+WwBJLO2Y4d6G1CR66tVeWsZspb
23
- zneOVC+sDuil7hOm+6a7Y2yrrRyT6IfL/07DywjPAIRUp5+Jn8ZrkWRNo2AOwWBG
24
- k5gz7SfJPHuyVnPlxoMA0MTFCUnnnbyHu882TGoJGgMCAwEAAaN9MHswCQYDVR0T
25
- BAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFIQfNa4E889ZE334cwU7eNu2hScH
26
- MCAGA1UdEQQZMBeBFW1zZmRldkBtZXRhc3Bsb2l0LmNvbTAgBgNVHRIEGTAXgRVt
27
- c2ZkZXZAbWV0YXNwbG9pdC5jb20wDQYJKoZIhvcNAQELBQADggGBAMfzvKcV27p7
28
- pctmpW2JmIXLMrjNLyGJAxELH/t9pJueXdga7uj2fJkYQDbwGw5x4MGyFqhqJLH4
29
- l/qsUF3PyAXDTSWLVaqXQVWO+IIHxecG0XjPXTNudzMU0hzqbqiBKvsW7/a3V5BP
30
- SWlFzrFkoXWlPouFpoakyYMJjpW4SGdPzRv7pM4OhXtkXpHiRvx5985FrHgHlI89
31
- NSIuIUbp8zqk4hP1i9MV0Lc/vTf2gOmo+RHnjqG1NiYfMCYyY/Mcd4W36kGOl468
32
- I8VDTwgCufkAzFu7BJ5yCOueqtDcuq+d3YhAyU7NI4+Ja8EwazOnB+07sWhKpg7z
33
- yuQ1mWYPmZfVQpoSVv1CvXsoqJYXVPBBLOacKKSj8ArVG6pPn9Bej7IOQdblaFjl
34
- DgscAao7wB3xW2BWEp1KnaDWkf1x9ttgoBEYyuYwU7uatB67kBQG1PKvLt79wHvz
35
- Dxs+KOjGbBRfMnPgVGYkORKVrZIwlaboHbDKxcVW5xv+oZc7KYXWGg==
36
- -----END CERTIFICATE-----
37
- date: 2024-06-12 00:00:00.000000000 Z
10
+ cert_chain: []
11
+ date: 2025-03-24 00:00:00.000000000 Z
38
12
  dependencies:
39
13
  - !ruby/object:Gem::Dependency
40
14
  name: metasploit-yard
@@ -268,7 +242,6 @@ executables: []
268
242
  extensions: []
269
243
  extra_rdoc_files: []
270
244
  files:
271
- - ".coveralls.yml"
272
245
  - ".github/workflows/verify.yml"
273
246
  - ".gitignore"
274
247
  - ".rspec"
@@ -544,6 +517,7 @@ files:
544
517
  - spec/app/models/mdm/module/target_spec.rb
545
518
  - spec/app/models/mdm/nexpose_console_spec.rb
546
519
  - spec/app/models/mdm/note_spec.rb
520
+ - spec/app/models/mdm/payload_spec.rb
547
521
  - spec/app/models/mdm/profile_spec.rb
548
522
  - spec/app/models/mdm/ref_spec.rb
549
523
  - spec/app/models/mdm/route_spec.rb
@@ -662,6 +636,7 @@ files:
662
636
  - spec/factories/mdm/module/targets.rb
663
637
  - spec/factories/mdm/nexpose_consoles.rb
664
638
  - spec/factories/mdm/notes.rb
639
+ - spec/factories/mdm/payloads.rb
665
640
  - spec/factories/mdm/refs.rb
666
641
  - spec/factories/mdm/routes.rb
667
642
  - spec/factories/mdm/services.rb
@@ -710,7 +685,7 @@ files:
710
685
  homepage: ''
711
686
  licenses: []
712
687
  metadata: {}
713
- post_install_message:
688
+ post_install_message:
714
689
  rdoc_options: []
715
690
  require_paths:
716
691
  - app/models
@@ -727,8 +702,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
727
702
  - !ruby/object:Gem::Version
728
703
  version: '0'
729
704
  requirements: []
730
- rubygems_version: 3.3.24
731
- signing_key:
705
+ rubygems_version: 3.4.19
706
+ signing_key:
732
707
  specification_version: 4
733
708
  summary: Database code for MSF and Metasploit Pro
734
709
  test_files: []
checksums.yaml.gz.sig DELETED
Binary file
data/.coveralls.yml DELETED
@@ -1 +0,0 @@
1
- service_name: travis-ci
data.tar.gz.sig DELETED
@@ -1,2 +0,0 @@
1
- jUU ?0��c�K��6��s�z�b�nb��7�*T7�~�v_�&~��V�;w�1,E\h�|���_��~��d���7�wt0x7���}��Ÿ��ե�q.��2��������5N��|��%X��e�� � �AE�n��ِ<r
2
- ��_���Hu����a��rc�����c��I!��9Ba6L�p���
metadata.gz.sig DELETED
@@ -1,2 +0,0 @@
1
- �?���Ѧ"��~δ��ݮ-͍}�j軠=yE:��*dߓ��S/Ն��84�o�o h�3h�y#z�i�~O�eC��2���+�O�������&����9A�e�nU���(��Ɵ)4Qp�6��
2
- �3O1�m�U��n���Ig�̋S;2�t�i�\̔��X���]��C���Ʌ�J�ʬv��j�9[~��P^[��h�-N��2H�M`&��eD��}�����&]l"�z��|Y�F['D��B��Y