cryptopunks 2.0.1 → 2.1.0
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/README.md +108 -1
- data/Rakefile +1 -1
- data/config/spritesheet.csv +762 -402
- data/config/spritesheet.png +0 -0
- data/lib/cryptopunks/generator.rb +108 -22
- data/lib/cryptopunks/tool.rb +107 -1
- data/lib/cryptopunks/version.rb +2 -2
- data/lib/cryptopunks.rb +90 -5
- metadata +4 -4
data/config/spritesheet.png
CHANGED
Binary file
|
@@ -5,18 +5,20 @@ module Cryptopunks
|
|
5
5
|
### todo/fix:
|
6
6
|
## move into Punks::Metadata or such
|
7
7
|
class Sprite
|
8
|
-
attr_reader :id, :name, :type, :gender, :more_names
|
8
|
+
attr_reader :id, :name, :type, :gender, :size, :more_names
|
9
9
|
|
10
10
|
|
11
11
|
def initialize( id:,
|
12
12
|
name:,
|
13
13
|
type:,
|
14
14
|
gender:,
|
15
|
+
size:,
|
15
16
|
more_names: [] )
|
16
17
|
@id = id # zero-based index eg. 0,1,2,3, etc.
|
17
18
|
@name = name
|
18
19
|
@type = type
|
19
20
|
@gender = gender
|
21
|
+
@size = size
|
20
22
|
@more_names = more_names
|
21
23
|
end
|
22
24
|
|
@@ -24,6 +26,15 @@ module Cryptopunks
|
|
24
26
|
## use (alternate name/alias) base or face for archetypes? any others?
|
25
27
|
def attribute?() @type.downcase.start_with?( 'attribute' ); end
|
26
28
|
def archetype?() @type.downcase.start_with?( 'archetype' ); end
|
29
|
+
|
30
|
+
def small?() @size == 's'; end
|
31
|
+
def large?() @size == 'l'; end
|
32
|
+
def universal?() @size == 'u'; end
|
33
|
+
alias_method :unisize?, :universal? ## add unisize or allsizes or such - why? why not?
|
34
|
+
|
35
|
+
def male?() @gender == 'm'; end
|
36
|
+
def female?() @gender == 'f'; end
|
37
|
+
def unisex?() @gender == 'u'; end
|
27
38
|
end # class Metadata::Sprite
|
28
39
|
end # class Metadata
|
29
40
|
|
@@ -35,32 +46,49 @@ module Cryptopunks
|
|
35
46
|
######
|
36
47
|
# static helpers - (turn into "true" static self.class methods - why? why not?)
|
37
48
|
#
|
38
|
-
def normalize_key( str )
|
39
|
-
|
49
|
+
def self.normalize_key( str )
|
50
|
+
## add & e.g. B&W
|
51
|
+
str.downcase.gsub(/[ ()&°_-]/, '').strip
|
40
52
|
end
|
41
53
|
|
42
|
-
def normalize_gender( str )
|
54
|
+
def self.normalize_gender( str )
|
43
55
|
## e.g. Female => f
|
44
56
|
## F => f
|
45
|
-
## always return f
|
57
|
+
## always return f/m
|
58
|
+
str.downcase[0]
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.normalize_size( str )
|
62
|
+
## e.g. U or Unisize or Univeral => u
|
63
|
+
## S or Small => s
|
64
|
+
## L or Large => l
|
65
|
+
## always return u/l/s
|
46
66
|
str.downcase[0]
|
47
67
|
end
|
48
68
|
|
49
|
-
def normalize_name( str )
|
69
|
+
def self.normalize_name( str )
|
50
70
|
## normalize spaces in more names
|
51
71
|
str.strip.gsub( /[ ]{2,}/, ' ' )
|
52
72
|
end
|
53
73
|
|
74
|
+
def normalize_key( str ) self.class.normalize_key( str ); end
|
75
|
+
def normalize_gender( str ) self.class.normalize_gender( str ); end
|
76
|
+
def normalize_size( str ) self.class.normalize_size( str ); end
|
77
|
+
def normalize_name( str ) self.class.normalize_name( str ); end
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
|
54
82
|
|
55
83
|
|
56
84
|
def build_attributes_by_name( recs )
|
57
85
|
h = {}
|
58
86
|
recs.each_with_index do |rec|
|
59
87
|
names = [rec.name] + rec.more_names
|
60
|
-
names.each do |name|
|
61
88
|
|
89
|
+
names.each do |name|
|
62
90
|
key = normalize_key( name )
|
63
|
-
key << "_(#{rec.gender})" if rec.attribute?
|
91
|
+
key << "_(#{rec.gender}+#{rec.size})" if rec.attribute?
|
64
92
|
|
65
93
|
if h[ key ]
|
66
94
|
puts "!!! ERROR - attribute name is not unique:"
|
@@ -98,6 +126,7 @@ module Cryptopunks
|
|
98
126
|
id = rec['id'].to_i( 10 )
|
99
127
|
name = normalize_name( rec['name'] )
|
100
128
|
gender = normalize_gender( rec['gender'] )
|
129
|
+
size = normalize_size( rec['size'] )
|
101
130
|
type = rec['type']
|
102
131
|
|
103
132
|
more_names = (rec['more_names'] || '').split( '|' )
|
@@ -108,6 +137,7 @@ module Cryptopunks
|
|
108
137
|
name: name,
|
109
138
|
type: type,
|
110
139
|
gender: gender,
|
140
|
+
size: size,
|
111
141
|
more_names: more_names )
|
112
142
|
end
|
113
143
|
recs
|
@@ -138,24 +168,74 @@ module Cryptopunks
|
|
138
168
|
|
139
169
|
|
140
170
|
|
141
|
-
def find_meta( q, gender: nil
|
171
|
+
def find_meta( q, gender: nil,
|
172
|
+
size: nil,
|
173
|
+
style: nil ) ## note: gender (m/f) required for attributes!!!
|
142
174
|
|
143
175
|
key = normalize_key( q ) ## normalize q(uery) string/symbol
|
144
|
-
key << "_(#{normalize_gender( gender )})" if gender
|
145
176
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
177
|
+
keys = [] ## note allow lookup by more than one keys
|
178
|
+
## e.g. if gender set try f/m first and than try unisex as fallback
|
179
|
+
if gender
|
180
|
+
gender = normalize_gender( gender )
|
181
|
+
## auto-fill size if not passed in
|
182
|
+
## for f(emale) => s(mall)
|
183
|
+
## m(ale) => l(arge)
|
184
|
+
size = if size.nil?
|
185
|
+
gender == 'f' ? 's' : 'l'
|
186
|
+
else
|
187
|
+
normalize_size( size )
|
188
|
+
end
|
189
|
+
|
190
|
+
###
|
191
|
+
# try (auto-add) style-specific version first (fallback to "regular" if not found)
|
192
|
+
if style
|
193
|
+
## for now only support natural series
|
194
|
+
style_key = if style.downcase.start_with?( 'natural' )
|
195
|
+
'natural'
|
196
|
+
else
|
197
|
+
puts "!! ERROR - unknown attribute style #{style}; sorry"
|
198
|
+
exit 1
|
199
|
+
end
|
200
|
+
|
201
|
+
keys << "#{key}#{style_key}_(#{gender}+#{size})"
|
202
|
+
## auto-add (u)niversal size as fallback
|
203
|
+
keys << "#{key}#{style_key}_(#{gender}+u)" if size == 's' || size == 'l'
|
204
|
+
## auto-add u(nisex) as fallback
|
205
|
+
keys << "#{key}#{style_key}_(u+#{size})" if gender == 'f' || gender == 'm'
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
keys << "#{key}_(#{gender}+#{size})"
|
210
|
+
## auto-add (u)niversal size as fallback
|
211
|
+
keys << "#{key}_(#{gender}+u)" if size == 's' || size == 'l'
|
212
|
+
## auto-add u(nisex) as fallback
|
213
|
+
keys << "#{key}_(u+#{size})" if gender == 'f' || gender == 'm'
|
150
214
|
else
|
151
|
-
|
215
|
+
keys << key
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
rec = nil
|
220
|
+
keys.each do |key|
|
221
|
+
rec = @attributes_by_name[ key ]
|
222
|
+
if rec
|
223
|
+
puts " lookup >#{key}< => #{rec.id}: #{rec.name} / #{rec.type} (#{rec.gender}+#{rec.size})"
|
224
|
+
# pp rec
|
225
|
+
break
|
226
|
+
end
|
152
227
|
end
|
228
|
+
|
229
|
+
if rec.nil?
|
230
|
+
puts "!! WARN - no lookup found for #{keys.size} key(s) >#{keys.inspect}<"
|
231
|
+
end
|
232
|
+
|
153
233
|
rec
|
154
234
|
end
|
155
235
|
|
156
236
|
|
157
|
-
def find( q, gender: nil ) ## gender (m/f) required for attributes!!!
|
158
|
-
rec = find_meta( q, gender: gender )
|
237
|
+
def find( q, gender: nil, size: nil, style: nil ) ## gender (m/f) required for attributes!!!
|
238
|
+
rec = find_meta( q, gender: gender, size: size, style: style )
|
159
239
|
|
160
240
|
## return image if record found
|
161
241
|
rec ? @sheet[ rec.id ] : nil
|
@@ -164,10 +244,11 @@ module Cryptopunks
|
|
164
244
|
|
165
245
|
|
166
246
|
|
167
|
-
def to_recs( *values )
|
247
|
+
def to_recs( *values, style: nil )
|
168
248
|
archetype_name = values[0]
|
169
249
|
|
170
250
|
### todo/fix: check for nil/not found!!!!
|
251
|
+
## todo/check/fix: assert meta record returned is archetype NOT attribute!!!!
|
171
252
|
archetype = find_meta( archetype_name )
|
172
253
|
if archetype.nil?
|
173
254
|
puts "!! ERROR - archetype >#{archetype}< not found; sorry"
|
@@ -179,11 +260,15 @@ module Cryptopunks
|
|
179
260
|
attribute_names = values[1..-1]
|
180
261
|
## note: attribute lookup requires gender from archetype!!!!
|
181
262
|
attribute_gender = archetype.gender
|
263
|
+
attribute_size = archetype.size
|
182
264
|
|
183
265
|
attribute_names.each do |attribute_name|
|
184
|
-
attribute = find_meta( attribute_name,
|
266
|
+
attribute = find_meta( attribute_name,
|
267
|
+
gender: attribute_gender,
|
268
|
+
size: attribute_size,
|
269
|
+
style: style )
|
185
270
|
if attribute.nil?
|
186
|
-
puts "!! ERROR - attribute >#{attribute_name}< for (#{attribute_gender}) not found; sorry"
|
271
|
+
puts "!! ERROR - attribute >#{attribute_name}< for (#{attribute_gender}+#{attribute_size}) not found; sorry"
|
187
272
|
exit 1
|
188
273
|
end
|
189
274
|
recs << attribute
|
@@ -195,12 +280,13 @@ module Cryptopunks
|
|
195
280
|
|
196
281
|
|
197
282
|
|
198
|
-
def generate_image( *values,
|
283
|
+
def generate_image( *values, style: nil,
|
284
|
+
background: nil )
|
199
285
|
|
200
286
|
ids = if values[0].is_a?( Integer ) ## assume integer number (indexes)
|
201
287
|
values
|
202
288
|
else ## assume strings (names)
|
203
|
-
to_recs( *values ).map { |rec| rec.id }
|
289
|
+
to_recs( *values, style: style ).map { |rec| rec.id }
|
204
290
|
end
|
205
291
|
|
206
292
|
|
data/lib/cryptopunks/tool.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
module Cryptopunks
|
2
1
|
|
2
|
+
module Cryptopunks
|
3
3
|
|
4
4
|
|
5
5
|
class Tool
|
@@ -21,6 +21,8 @@ class Opts
|
|
21
21
|
@zoom = options[:zoom] if options[:zoom]
|
22
22
|
@offset = options[:offset] if options[:offset]
|
23
23
|
|
24
|
+
@seed = options[:seed] if options[:seed]
|
25
|
+
|
24
26
|
@verbose = true if options[:verbose] == true
|
25
27
|
end
|
26
28
|
|
@@ -45,6 +47,13 @@ class Opts
|
|
45
47
|
|
46
48
|
def outdir() @outdir || '.'; end
|
47
49
|
def outdir?() @outdir; end
|
50
|
+
|
51
|
+
### use a standard (default) seed - why? why not?
|
52
|
+
def seed() @seed || 4142; end
|
53
|
+
def seed?() @seed; end
|
54
|
+
|
55
|
+
|
56
|
+
|
48
57
|
end # class Opts
|
49
58
|
|
50
59
|
|
@@ -71,12 +80,21 @@ arg_name 'NUM'
|
|
71
80
|
default_value opts.offset
|
72
81
|
flag [:offset], type: Integer
|
73
82
|
|
83
|
+
|
84
|
+
desc "Seed for random number generation / shuffle"
|
85
|
+
arg_name 'NUM'
|
86
|
+
default_value opts.seed
|
87
|
+
flag [:seed], type: Integer
|
88
|
+
|
89
|
+
|
90
|
+
|
74
91
|
desc "Output directory"
|
75
92
|
arg_name 'DIR'
|
76
93
|
default_value opts.outdir
|
77
94
|
flag [:d, :dir,
|
78
95
|
:o, :out, :outdir], type: String
|
79
96
|
|
97
|
+
|
80
98
|
### todo/check: move option to -t/--tile command only - why? why not?
|
81
99
|
desc "True Official Genuine CryptoPunks™ all-in-one composite image"
|
82
100
|
arg_name 'FILE'
|
@@ -92,6 +110,94 @@ switch [:verbose], negatable: false ## todo: use -w for short form? check rub
|
|
92
110
|
|
93
111
|
|
94
112
|
|
113
|
+
desc "Flip (vertically) all punk characters in all-in-one punk series composite (#{opts.file})"
|
114
|
+
command [:f, :flip] do |c|
|
115
|
+
c.action do |g,o,args|
|
116
|
+
puts "==> reading >#{opts.file}<..."
|
117
|
+
punks = ImageComposite.read( opts.file )
|
118
|
+
|
119
|
+
## note: for now always assume 24x24
|
120
|
+
cols = punks.width / 24
|
121
|
+
rows = punks.height / 24
|
122
|
+
tile_width = 24
|
123
|
+
tile_height = 24
|
124
|
+
|
125
|
+
phunks = ImageComposite.new( cols, rows,
|
126
|
+
width: tile_width,
|
127
|
+
height: tile_height )
|
128
|
+
|
129
|
+
punks.each do |punk|
|
130
|
+
phunks << punk.flip_vertically
|
131
|
+
end
|
132
|
+
|
133
|
+
## make sure outdir exits (default is current working dir e.g. .)
|
134
|
+
FileUtils.mkdir_p( opts.outdir ) unless Dir.exist?( opts.outdir )
|
135
|
+
|
136
|
+
## note: allways assume .png extension for now
|
137
|
+
basename = File.basename( opts.file, File.extname( opts.file ) )
|
138
|
+
path = "#{opts.outdir}/#{basename}-flipped.png"
|
139
|
+
puts "==> saving phunks flipped one-by-one by hand to >#{path}<..."
|
140
|
+
|
141
|
+
phunks.save( path )
|
142
|
+
puts 'Done.'
|
143
|
+
end # action
|
144
|
+
end # command flip
|
145
|
+
|
146
|
+
|
147
|
+
desc "Shuffle all punk characters (randomly) in all-in-one punk series composite (#{opts.file})"
|
148
|
+
command [:s, :shuffle] do |c|
|
149
|
+
c.action do |g,o,args|
|
150
|
+
puts "==> reading >#{opts.file}<..."
|
151
|
+
punks = ImageComposite.read( opts.file )
|
152
|
+
|
153
|
+
## note: for now always assume 24x24
|
154
|
+
cols = punks.width / 24
|
155
|
+
rows = punks.height / 24
|
156
|
+
tile_width = 24
|
157
|
+
tile_height = 24
|
158
|
+
|
159
|
+
phunks = ImageComposite.new( cols, rows,
|
160
|
+
width: tile_width,
|
161
|
+
height: tile_height )
|
162
|
+
|
163
|
+
tiles = cols * rows
|
164
|
+
indexes = (0..tiles-1).to_a
|
165
|
+
srand( opts.seed ) ## note: for new reset **global** random seed and use (builtin) Array#shuffle
|
166
|
+
puts " using random generation number seed >#{opts.seed}< for shuffle"
|
167
|
+
indexes = indexes.shuffle
|
168
|
+
|
169
|
+
###
|
170
|
+
# seed 4142 ends in [..., 7566, 828, 8987, 9777]
|
171
|
+
# 333 ends in [..., 6067, 9635, 973, 8172]
|
172
|
+
|
173
|
+
|
174
|
+
indexes.each_with_index do |old_index,new_index|
|
175
|
+
puts " ##{old_index} now ##{new_index}"
|
176
|
+
phunks << punks[old_index]
|
177
|
+
end
|
178
|
+
|
179
|
+
puts " all #{tiles} old index numbers (zero-based) for reference using seed #{opts.seed}:"
|
180
|
+
puts indexes.inspect
|
181
|
+
|
182
|
+
## make sure outdir exits (default is current working dir e.g. .)
|
183
|
+
FileUtils.mkdir_p( opts.outdir ) unless Dir.exist?( opts.outdir )
|
184
|
+
|
185
|
+
## note: allways assume .png extension for now
|
186
|
+
basename = File.basename( opts.file, File.extname( opts.file ) )
|
187
|
+
path = "#{opts.outdir}/#{basename}-#{opts.seed}.png"
|
188
|
+
puts "==> saving p(h)unks shuffled one-by-one by hand to >#{path}<..."
|
189
|
+
|
190
|
+
phunks.save( path )
|
191
|
+
puts 'Done.'
|
192
|
+
end # action
|
193
|
+
end # command shuffle
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
95
201
|
desc "Get punk characters via image tiles from all-in-one punk series composite (#{opts.file}) - for IDs use 0 to 9999"
|
96
202
|
command [:t, :tile] do |c|
|
97
203
|
c.action do |g,o,args|
|
data/lib/cryptopunks/version.rb
CHANGED
data/lib/cryptopunks.rb
CHANGED
@@ -50,24 +50,103 @@ module Cryptopunks
|
|
50
50
|
end
|
51
51
|
|
52
52
|
class Image
|
53
|
-
|
54
|
-
|
53
|
+
def self.generate( *values, style: nil )
|
54
|
+
|
55
|
+
##### add style option / hack - why? why not?
|
56
|
+
if style
|
57
|
+
values = if style.downcase.index( 'natural') && style.downcase.index( '2')
|
58
|
+
["#{values[0]} (N2)"] + values[1..-1]
|
59
|
+
elsif style.downcase[0] == 'n' ## starting with n - always assume natural(s)
|
60
|
+
## auto-add (N) for Natural to archetype
|
61
|
+
["#{values[0]} (N)"] + values[1..-1]
|
62
|
+
else
|
63
|
+
puts "!! ERROR - unknown punk style #{style}; sorry"
|
64
|
+
exit 1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
###### hack for black&white
|
70
|
+
## auto-add b&w (black&white) to all attribute names e.g.
|
71
|
+
## Eyes => Eyes B&W
|
72
|
+
## Smile => Smile B&W
|
73
|
+
## ....
|
74
|
+
|
75
|
+
archetype_key = Generator.normalize_key( values[0] )
|
76
|
+
if archetype_key.end_with?( 'bw' ) || ## e.g. B&W
|
77
|
+
archetype_key.end_with?( '1bit') ## e.g. 1-Bit or 1Bit
|
78
|
+
|
79
|
+
values = [values[0]] + values[1..-1].map do |attribute|
|
80
|
+
attribute_key = Generator.normalize_key( attribute )
|
81
|
+
if ['wildhair'].include?( attribute_key ) ## pass through known b&w attributes by "default"
|
82
|
+
attribute
|
83
|
+
elsif attribute_key.index( "black" )
|
84
|
+
attribute ## pass through as-is
|
85
|
+
else
|
86
|
+
"#{attribute} B&W"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
pp values
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# note: female mouth by default has "custom" colors (not black)
|
95
|
+
# for every 1/2/3/4 (human) skin tone and for zombie
|
96
|
+
# auto-"magically" add mapping
|
97
|
+
#
|
98
|
+
# todo/check/fix - add more "contraints"
|
99
|
+
# for mapping to only kick-in for "basic" versions
|
100
|
+
# and not "colored" e.g. golden and such - why? why not?
|
101
|
+
#
|
102
|
+
# move this mapping here to "post-lookup" processing
|
103
|
+
# to get/incl. more "meta" attribute info - why? why not?
|
104
|
+
if archetype_key.index( 'female1' ) ||
|
105
|
+
archetype_key.index( 'female2' ) ||
|
106
|
+
archetype_key.index( 'female3' ) ||
|
107
|
+
archetype_key.index( 'female4' ) ||
|
108
|
+
archetype_key.index( 'zombiefemale' )
|
109
|
+
|
110
|
+
values = [values[0]] + values[1..-1].map do |attribute|
|
111
|
+
attribute_key = Generator.normalize_key( attribute )
|
112
|
+
|
113
|
+
if attribute_key == 'smile' || attribute_key == 'frown'
|
114
|
+
attribute += if archetype_key.index( 'zombiefemale' ) then ' Zombie'
|
115
|
+
elsif archetype_key.index( 'female1' ) then ' 1'
|
116
|
+
elsif archetype_key.index( 'female2' ) then ' 2'
|
117
|
+
elsif archetype_key.index( 'female3' ) then ' 3'
|
118
|
+
elsif archetype_key.index( 'female4' ) then ' 4'
|
119
|
+
else
|
120
|
+
puts "!! ERROR - smile or frown (mouth expression) not supported for archetype:"
|
121
|
+
pp values
|
122
|
+
exit 1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
attribute
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
img = Cryptopunks.generator.generate( *values, style: style )
|
55
130
|
## note: unwrap inner image before passing on to c'tor (requires ChunkyPNG image for now)
|
56
131
|
new( img.image )
|
57
|
-
end
|
132
|
+
end # method Image.generate
|
133
|
+
|
58
134
|
end # class Image
|
59
135
|
|
60
136
|
|
61
137
|
class Spritesheet
|
62
138
|
## note: for now class used for "namespace" only
|
63
|
-
def self.find_by( name:, gender: nil ) ## return archetype/attribute image by name
|
139
|
+
def self.find_by( name:, gender: nil, size: nil ) ## return archetype/attribute image by name
|
64
140
|
# note: pass along name as q (query string)
|
65
|
-
Cryptopunks.generator.find( name,
|
141
|
+
Cryptopunks.generator.find( name,
|
142
|
+
gender: gender,
|
143
|
+
size: size )
|
66
144
|
end
|
67
145
|
end # class Spritesheet
|
68
146
|
## add convenience (alternate spelling) alias - why? why not?
|
69
147
|
SpriteSheet = Spritesheet
|
70
148
|
Sheet = Spritesheet
|
149
|
+
Sprite = Spritesheet
|
71
150
|
end # module Cryptopunks
|
72
151
|
|
73
152
|
|
@@ -98,6 +177,12 @@ end ## module Cryptopunks
|
|
98
177
|
### add some convenience shortcuts
|
99
178
|
CryptoPunks = Cryptopunks
|
100
179
|
Punks = Cryptopunks
|
180
|
+
## add singular too -why? why not?
|
181
|
+
Cryptopunk = Cryptopunks
|
182
|
+
CryptoPunk = Cryptopunks
|
183
|
+
Punk = Cryptopunks
|
184
|
+
|
185
|
+
|
101
186
|
|
102
187
|
|
103
188
|
###
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cryptopunks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pixelart
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.2.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.2.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: csvreader
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|