softie 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.asc CHANGED
@@ -2,17 +2,17 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQIcBAABAgAGBQJRScSfAAoJEH1ncb0Txu7XV9gQAJURRT9GuhUyJDHHYyd1wZT7
6
- PSTIcJgkp9BpnD0bOCs2zar0SoOYBW77BybJ/PuRD6EMsm7+nrdnT5rpbBmYanLi
7
- SBKGHE0wAPufkr/hO4S8KStjcU11MRZwWmXKK3p7r4q4WbiQVDizurMPjPdbeZkB
8
- 6slYAILvHD9XHsV6EYiEXjojpWzZO7L74EJceimshiSb78gt9FaS2Z0Sc7B92UiV
9
- qrjEtV8r7hQxoAqfIF/ugJkHgyJkJJ1J6mQedztTXnpUSGGXcbHKDbXLHcI5LoAq
10
- NzzPUdj6gN2BBq7gYPv4bL6BSR80eiEo5gdHYTFJqoPB+DxnbFdPYf6USbW3v2HT
11
- Gz9LC56uFBDho4qFPerClj9ntuOQnm+cI6tFSzKSDUzR365NGVXDNz2N6jXh3A7Z
12
- O7Dnd4ULD3sQyLF8z4R13QJaegiTD20qP09S+ZhYt8MNgRoO3eMASQSAnrswbZ6g
13
- vhIBHp/WScur3rvGFMsML0siocOHAJFPIvDwe2Uoh3PR/PmVJplMN5DNJHTqkuTf
14
- plW8LJIxW5JlgcFXcZPwoy2xdgEws8tbOshSchLDIvyfBx1zSa8NhFxmxC7jLS9w
15
- oNm6AYMmroFHwTUHV4eIHCCKqCUGDV3ZNt4sd5BtTYO9/GZ+61LVwSCEVKrM9rS/
16
- bFcGoYfZKl/SvlCBUMux
17
- =A5ej
5
+ iQIcBAABAgAGBQJRSr8SAAoJEH1ncb0Txu7XtxoP/jgZPcbK6zZtubUFZGC0HiPY
6
+ GiXpPJaPQ2Tn0ERBOgvHHVTf2uqgWnQaSVTuYIitzj66GBvr3YSpHF4F7ynZSOOI
7
+ Jm15ChX4v57F2pqa1H4zz7YkxBVaAqmQIGjizt8staijgcfIp7fU+f34F6Okshw3
8
+ U9/bbq6v2aCi7wJxIaqIBQiNVC4S1CxP6/ZR9e4YPfYVt0Gl4IRZQa9r2ISiPAst
9
+ T0XymgYGTRFGDntVE1Q6x0by/TFgeKIH+BwaMWYRp8Turk65M7oWO+bpzjZ8jVf4
10
+ Xy3hZnmKHmHgHybtY1fB6EEFAglhueJ5lZVTSjYsUsoK6qHjezOC8PC73lRr8R7H
11
+ SNs3usylRfV+3cGgo5YpTYZ8LljRbKDM0q9ORTTBrVh/Rq9ZRXoXMMVp0EIk+9gP
12
+ FamxC0YVA+GKTRNFNU6iSryWyJmU8LcPo0rutyhd/JKdNhKEwU3rooBXVOQuSJmM
13
+ J5N1hbUizPcfaKM4wGUBE3tvW3Bi02FJVbW6NhbuI6lGdw1KqxhJtpOT7M1p//37
14
+ 5fAutg7n/qtH5RBarOd9cMQA9KWyih5tAieCrVSX+yFrdsRf6bs2OrOPmW13abmy
15
+ vCNHwPPPHJT4APPAjbvhIyzMbPiHW5fk5gKugTO20Dx5FgvhP478rfCKWBBj/hzq
16
+ 0zDm6PsQVXyyrReS1MH5
17
+ =lQsK
18
18
  -----END PGP SIGNATURE-----
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "rbx-19mode"
6
+ services:
7
+ - mongodb
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+ gem "bson_ext"
5
+ gem "debugger"
data/README.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # Softie
2
2
 
3
- TODO: Write a gem description
3
+ [![Build Status](https://travis-ci.org/PerfectlyNormal/softie.png)](https://travis-ci.org/PerfectlyNormal/softie)
4
+
5
+ Softie has troubles letting go.
6
+ It is a plugin for [MongoMapper](http://mongomapper.com/), and lets records be soft-deleted easily.
7
+
8
+ It contains the bare minimum that I use at the moment.
9
+ Softie does not add a default scope, but it does add *a* scope (configurable).
10
+ Softie does not override `#destroy`, `#delete` and other methods.
11
+
12
+ The app this was extracted from stores which `User` deleted the record in `deleted_by`. This feature is disabled by default, but can easily be enabled, and the field name and class configured.
4
13
 
5
14
  ## Installation
6
15
 
@@ -8,17 +17,41 @@ Add this line to your application's Gemfile:
8
17
 
9
18
  gem 'softie'
10
19
 
11
- And then execute:
12
-
13
- $ bundle
14
-
15
20
  Or install it yourself as:
16
21
 
17
22
  $ gem install softie
18
23
 
24
+ ## Configuration
25
+
26
+ Either load it into all models, or individual models:
27
+
28
+ # add to all models
29
+ MongoMapper::Document.plugin Softie
30
+
31
+ # add to a specific model
32
+ class Item
33
+ include MongoMapper::Document
34
+ plugin Softie
35
+ end
36
+
37
+ Then call `softie` to configure it
38
+
39
+ softie [options]
40
+
41
+ The supported options are as follows:
42
+
43
+ * `key`: Symbol. Defaults to `:deleted_at`
44
+ * `scope`: Symbol. Defaults to `:active`. Set to a falsy value to disable.
45
+ * `deleted_by_field`: Symbol. Defaults to `:deleted_by`
46
+ * `deleted_by_class`: Class. Defaults to `nil`. Set to a class to enable this functionality.
47
+
19
48
  ## Usage
20
49
 
21
- TODO: Write usage instructions here
50
+ Call `deleted!` on your document. This sets `deleted_at` to `Time.now.utc` and saves the document. If you are tracking who deleted it, pass it as `deleted!(by: current_user)`.
51
+
52
+ To restore a document, call `restore!`.
53
+
54
+ If you want to handle saving manually, use `deleted` and `restore`.
22
55
 
23
56
  ## Contributing
24
57
 
data/Rakefile CHANGED
@@ -1 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
data/lib/softie.rb CHANGED
@@ -1,4 +1,59 @@
1
1
  require "softie/version"
2
2
 
3
3
  module Softie
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def softie(options = {})
8
+ class_attribute :softie_options
9
+
10
+ self.softie_options = {
11
+ key: :deleted_at,
12
+ scope: :active,
13
+ deleted_by_class: nil,
14
+ deleted_by_key: :deleted_by
15
+ }.merge(options)
16
+
17
+ key softie_options[:key], Time
18
+
19
+ if softie_options[:deleted_by_class]
20
+ key softie_options[:deleted_by_key],
21
+ softie_options[:deleted_by_class]
22
+ end
23
+
24
+ scope softie_options[:scope], lambda {
25
+ where(softie_options[:key] => nil)
26
+ } if softie_options[:scope]
27
+ end
28
+ end
29
+
30
+ def deleted(options = {})
31
+ public_send("#{softie_options[:key]}=", Time.now.utc)
32
+
33
+ if softie_options[:deleted_by_class]
34
+ public_send("#{softie_options[:deleted_by_key]}=", options.delete(:by))
35
+ end
36
+ end
37
+
38
+ def deleted!(options = {})
39
+ deleted(options)
40
+ save
41
+ end
42
+
43
+ def restore
44
+ public_send("#{softie_options[:key]}=", nil)
45
+
46
+ if softie_options[:deleted_by_class]
47
+ public_send("#{softie_options[:deleted_by_key]}=", nil)
48
+ end
49
+ end
50
+
51
+ def restore!
52
+ restore
53
+ save
54
+ end
55
+
56
+ def deleted?
57
+ public_send(softie_options[:key]) != nil
58
+ end
4
59
  end
@@ -1,3 +1,3 @@
1
1
  module Softie
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.0"
3
3
  end
data/softie.gemspec CHANGED
@@ -8,16 +8,19 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Softie::VERSION
9
9
  spec.authors = ["Per Christian B. Viken"]
10
10
  spec.email = ["perchr@northblue.org"]
11
- spec.description = %q{Write a gem description}
12
- spec.summary = %q{Write a gem summary}
13
- spec.homepage = "https://eastblue.org/blag/"
11
+ spec.summary = %q{MongoMapper plugin that adds soft-delete functionality}
12
+ spec.description = %q{Softie adds soft-delete functionality to MongoMapper documents with minimal fuss}
13
+ spec.homepage = "https://github.com/PerfectlyNormal/softie"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.test_files = spec.files.grep(%r{^spec/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.specification_version = 3
22
+ spec.add_runtime_dependency "mongo_mapper", ">= 0.9.0"
23
+ spec.add_development_dependency "rspec", "~> 2.11"
22
24
  spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "timecop"
23
26
  end
@@ -0,0 +1,225 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Softie do
4
+
5
+ describe "with defaults" do
6
+ before :each do
7
+ @article = DefaultArticle.new(title: "Softie with Defaults")
8
+ end
9
+
10
+ it "should add a .active scope" do
11
+ DefaultArticle.should respond_to(:active)
12
+ end
13
+
14
+ it "should add a key called :deleted_at" do
15
+ @article.keys.keys.should include("deleted_at")
16
+ end
17
+
18
+ it "should not add a key called :deleted_by" do
19
+ @article.keys.keys.should_not include("deleted_by")
20
+ end
21
+
22
+ it "should add a method for deleting" do
23
+ @article.should respond_to(:deleted!)
24
+ end
25
+
26
+ it "should add a method for checking if the document is deleted" do
27
+ @article.should respond_to(:deleted?)
28
+ end
29
+
30
+ it "should add a method for restoring" do
31
+ @article.should respond_to(:restore!)
32
+ end
33
+
34
+ end
35
+
36
+ describe "#deleted?" do
37
+ before :each do
38
+ @article = DefaultArticle.new(title: "Softie with Defaults")
39
+ end
40
+
41
+ it "should not be true by default" do
42
+ @article.should_not be_deleted
43
+ end
44
+
45
+ it "should be true after a call to #deleted!" do
46
+ @article.deleted!
47
+ @article.should be_deleted
48
+ end
49
+
50
+ it "should be false after a call to #restore!" do
51
+ @article.deleted!
52
+ @article.restore!
53
+ @article.should_not be_deleted
54
+ end
55
+ end
56
+
57
+ describe "#deleted" do
58
+ before :each do
59
+ @article = DefaultArticle.new(title: "Softie with Defaults")
60
+ end
61
+
62
+ it "should store the current time" do
63
+ time = Time.utc(2013, 03, 20, 13, 37, 42)
64
+ Timecop.freeze(time) do
65
+ @article.deleted
66
+ @article.deleted_at.should == time
67
+ end
68
+ end
69
+
70
+ it "does not saves the document" do
71
+ @article.should_not_receive(:save)
72
+ @article.deleted
73
+ end
74
+
75
+ describe "with deleted_by functionality" do
76
+ it "should store the user" do
77
+ article = ArticleWithDeletedBy.new(title: "deleted_by is a User")
78
+ user = User.new(name: "Dummy User")
79
+
80
+ article.deleted(by: user)
81
+ article.deleted_by.should eq(user)
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "#deleted!" do
87
+ before :each do
88
+ @article = DefaultArticle.new(title: "Softie with Defaults")
89
+ end
90
+
91
+ it "should store the current time" do
92
+ time = Time.utc(2013, 03, 20, 13, 37, 42)
93
+ Timecop.freeze(time) do
94
+ @article.deleted!
95
+ @article.deleted_at.should == time
96
+ end
97
+ end
98
+
99
+ it "saves the document" do
100
+ @article.should_receive(:save).and_return(true)
101
+ @article.deleted!
102
+ end
103
+
104
+ describe "with deleted_by functionality" do
105
+ it "should store the user" do
106
+ article = ArticleWithDeletedBy.new(title: "deleted_by is a User")
107
+ user = User.new(name: "Dummy User")
108
+
109
+ article.deleted!(by: user)
110
+ article.deleted_by.should eq(user)
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "#restore" do
116
+ before :each do
117
+ @article = DefaultArticle.new(title: "Softie with Defaults")
118
+ @article.deleted
119
+ end
120
+
121
+ it "should not be deleted any more" do
122
+ @article.restore
123
+ @article.should_not be_deleted
124
+ end
125
+
126
+ it "does not save the document" do
127
+ @article.should_not_receive(:save)
128
+ @article.restore
129
+ end
130
+
131
+ describe "with deleted_by functionality" do
132
+ it "should clear the user" do
133
+ article = ArticleWithDeletedBy.new(title: "deleted_by is a User")
134
+ user = User.new(name: "Dummy User")
135
+ article.deleted!(by: user)
136
+
137
+ article.restore
138
+ article.deleted_by.should be_nil
139
+ end
140
+ end
141
+ end
142
+
143
+ describe "#restore!" do
144
+ before :each do
145
+ @article = DefaultArticle.new(title: "Softie with Defaults")
146
+ @article.deleted!
147
+ end
148
+
149
+ it "should not be deleted any more" do
150
+ @article.restore!
151
+ @article.should_not be_deleted
152
+ end
153
+
154
+ it "saves the document" do
155
+ @article.should_receive(:save).and_return(true)
156
+ @article.restore!
157
+ end
158
+
159
+ describe "with deleted_by functionality" do
160
+ it "should clear the user" do
161
+ article = ArticleWithDeletedBy.new(title: "deleted_by is a User")
162
+ user = User.new(name: "Dummy User")
163
+ article.deleted!(by: user)
164
+
165
+ article.restore!
166
+ article.deleted_by.should be_nil
167
+ end
168
+ end
169
+ end
170
+
171
+ describe "#deleted_by" do
172
+ describe "when enabled" do
173
+ it "should add a key called deleted_by" do
174
+ ArticleWithDeletedBy.new(
175
+ title: "deleted_by is a User"
176
+ ).keys.keys.should include("deleted_by")
177
+ end
178
+ end
179
+
180
+ describe "when not enabled" do
181
+ it "should not add the deleted_by key" do
182
+ @article = NonDefaultArticle.new(title: "Not tracking user")
183
+ @article.keys.keys.should_not include("deleted_by")
184
+ end
185
+ end
186
+
187
+ describe "enabled with a different key name" do
188
+ before :each do
189
+ @article = ArticleWithWasDeletedBy.new(title: "deleted_by key is was_deleted_by")
190
+ end
191
+
192
+ it "should add a key called was_deleted_by" do
193
+ @article.keys.keys.should include("was_deleted_by")
194
+ end
195
+
196
+ it "should not add the default key" do
197
+ @article.keys.keys.should_not include("deleted_by")
198
+ end
199
+ end
200
+ end
201
+
202
+ describe "with a different key name" do
203
+ before :each do
204
+ @article = NonDefaultArticle.new(title: "Different key names")
205
+ end
206
+
207
+ it "should add a key called was_deleted" do
208
+ @article.keys.keys.should include("was_deleted")
209
+ end
210
+
211
+ it "should not add a key called deleted_at" do
212
+ @article.keys.keys.should_not include("deleted_at")
213
+ end
214
+
215
+ it "should look at the right key in the scope" do
216
+ NonDefaultArticle.active.to_hash.should include(was_deleted: nil)
217
+ end
218
+ end
219
+
220
+ describe "with the scope disabled" do
221
+ it "should not generate the method" do
222
+ ArticleWithoutScope.should_not respond_to(:active)
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,60 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ require 'rspec'
5
+ require 'timecop'
6
+ require 'mongo_mapper'
7
+ require 'softie'
8
+
9
+ MongoMapper.database = 'softie-spec'
10
+
11
+ class DefaultArticle
12
+ include MongoMapper::Document
13
+ plugin Softie
14
+
15
+ key :title, String
16
+ softie
17
+ end
18
+
19
+ class NonDefaultArticle
20
+ include MongoMapper::Document
21
+ plugin Softie
22
+
23
+ key :title, String
24
+ softie key: :was_deleted
25
+ end
26
+
27
+ class ArticleWithoutScope
28
+ include MongoMapper::Document
29
+ plugin Softie
30
+
31
+ key :title, String
32
+ softie scope: false
33
+ end
34
+
35
+ class User
36
+ include MongoMapper::Document
37
+ key :name
38
+ end
39
+
40
+ class ArticleWithDeletedBy
41
+ include MongoMapper::Document
42
+ plugin Softie
43
+
44
+ key :title, String
45
+ softie deleted_by_class: ::User
46
+ end
47
+
48
+ class ArticleWithWasDeletedBy
49
+ include MongoMapper::Document
50
+ plugin Softie
51
+
52
+ key :title, String
53
+ softie deleted_by_class: ::User, deleted_by_key: :was_deleted_by
54
+ end
55
+
56
+ RSpec.configure do |config|
57
+ config.before :suite do
58
+ MongoMapper.database.connection.drop_database('softie-spec')
59
+ end
60
+ end
metadata CHANGED
@@ -2,31 +2,47 @@
2
2
  name: softie
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 1.0.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Per Christian B. Viken
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-20 00:00:00.000000000 Z
12
+ date: 2013-03-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: bundler
15
+ name: mongo_mapper
16
+ type: :runtime
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 0.9.0
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.9.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
16
32
  type: :development
17
33
  requirement: !ruby/object:Gem::Requirement
18
34
  none: false
19
35
  requirements:
20
36
  - - ~>
21
37
  - !ruby/object:Gem::Version
22
- version: '1.3'
38
+ version: '2.11'
23
39
  prerelease: false
24
40
  version_requirements: !ruby/object:Gem::Requirement
25
41
  none: false
26
42
  requirements:
27
43
  - - ~>
28
44
  - !ruby/object:Gem::Version
29
- version: '1.3'
45
+ version: '2.11'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: rake
32
48
  type: :development
@@ -43,7 +59,24 @@ dependencies:
43
59
  - - ! '>='
44
60
  - !ruby/object:Gem::Version
45
61
  version: '0'
46
- description: Write a gem description
62
+ - !ruby/object:Gem::Dependency
63
+ name: timecop
64
+ type: :development
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Softie adds soft-delete functionality to MongoMapper documents with minimal
79
+ fuss
47
80
  email:
48
81
  - perchr@northblue.org
49
82
  executables: []
@@ -51,6 +84,7 @@ extensions: []
51
84
  extra_rdoc_files: []
52
85
  files:
53
86
  - .gitignore
87
+ - .travis.yml
54
88
  - Gemfile
55
89
  - LICENSE.txt
56
90
  - README.md
@@ -58,7 +92,9 @@ files:
58
92
  - lib/softie.rb
59
93
  - lib/softie/version.rb
60
94
  - softie.gemspec
61
- homepage: https://eastblue.org/blag/
95
+ - spec/softie_spec.rb
96
+ - spec/spec_helper.rb
97
+ homepage: https://github.com/PerfectlyNormal/softie
62
98
  licenses:
63
99
  - MIT
64
100
  post_install_message:
@@ -82,5 +118,7 @@ rubyforge_project:
82
118
  rubygems_version: 1.8.24
83
119
  signing_key:
84
120
  specification_version: 3
85
- summary: Write a gem summary
86
- test_files: []
121
+ summary: MongoMapper plugin that adds soft-delete functionality
122
+ test_files:
123
+ - spec/softie_spec.rb
124
+ - spec/spec_helper.rb
metadata.gz.asc CHANGED
@@ -2,17 +2,17 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQIcBAABAgAGBQJRScSfAAoJEH1ncb0Txu7XJe4P/ir7Vkix2PHzV/KThqYxjSaF
6
- Urjxxc2Ty7v3F6nQjkTazhzfXrWDSoMwsNYbCNGFDeiVY1VerWEo/VDevlGBmg3W
7
- vo9WOO0vAC9+HmAWlCU43dnFwicAhMsg5KNFjcX9BdbSItCYkegB/cxr0mLqzvno
8
- c+YSXkYuXWzjO2yQ5nYNk0Kxw312xK2pa49AgwJTwujM3dT/fPOVYWues1+bjVGY
9
- WphjYPUEhYEInqoRImJeVC6u163geUh8fq1OuBW9iv4M1JMGdWgeCxm24i1cSy9c
10
- zx2axyNgZC6P6Vx5ZcKXGSsIcWKgGBR40Tf2CcjbruI1gS5W+lv8NKGrHZPH/LhQ
11
- BhLXMqHRdco21jr7YjrwA2Tgihh1OMdqBZppp2HNihsl2uaLkbSHWY/xBUmEYx/L
12
- E68M4bEVKcE2sJ77H1BO3YUMJqpGPvussaEd58sgcnDTcN1MNQtkPDZVoLP681aD
13
- JP+J3OlQ8moQjsL1Lxh/5kM7jNU0tAuHSUgbVyNf8zypriZoCS2MaSCi6ZaxwxNZ
14
- V58ggLNYOP1N7jYT/2eTJpUxOW7egbnIjRzjnb8pITY2SjSAHUfXZvrr2ivWohv1
15
- TqBcAhHwMJ1rTcAa8NEbyh1KgZ512w8CD43g6nOpT63AVLSpXqbHhh9ta0gxbAHh
16
- dKu4EJHyWY4fUTY2FQFo
17
- =Mw2L
5
+ iQIcBAABAgAGBQJRSr8SAAoJEH1ncb0Txu7XO3QP/0vsmqsmbR9UqHmqz1HMTe6b
6
+ NcRYXn9GzcJWNtH+0S+saFip1+ZF5wxZADXveGepYwRDXiOCAjVUg1gGYy1Q9VxX
7
+ dnhBvahlT1egfr/tVmNQ3RXdlZ7b4SK4HRtqisu+/fR/w/rRMULnmDJJvDJ5vWBb
8
+ A/u2X6IItiEZRHb++d6qTV/rP3vuOIRMlyYJXjcO6pmKBrEUVjwT+oENZoCmWTr9
9
+ yeSAo0g7ji/Iulvc4RGH8YHt0Iz2CrdUXtH8PiLKoxjf0xIXfmrmxzpWQQbbqQwn
10
+ Z4kpauUERj+uBEL3qeDSNdIT8Q1L3Ybq6mO7+o6UDMBCZTslU+yux4rx64j62WUT
11
+ 6+j/4C5b+b9AL8DInnxWEgve/GPVMIhd3q3Oglmi25PXfqfy5yfum0x0VVDC7dSl
12
+ QtBm1i/xb3MaHnTxDW/yvSc1/Azi3AzUWmPQtkna/iTwHvjQyFi9SMYxTvy39HWD
13
+ SkTTtK24c4sWelyEHpRb8xtLDCskFSD40e9Zfy0QDyDdiu2PdFlM1GMidEeSAV0l
14
+ bckTJjARIZ4bKc7XphnOGiPv8eg9IYsN9ntxwqTCn/lELEmO3FCaN18S/n/OLo9O
15
+ 4JbQn1oyGWL48ilB04wJ5n0Bn1H/KB0nY6VNgibYL/Y2E/j2m6/pg0QOBnEsSX6b
16
+ GOm8KDfiPnWCarfqZZIi
17
+ =v7t2
18
18
  -----END PGP SIGNATURE-----