spud_media 0.9.5 → 0.9.6
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.
- data/app/assets/javascripts/spud/admin/media/picker.js +13 -2
- data/app/assets/javascripts/spud/admin/media/plugin.js +1 -0
- data/app/assets/libs/jcrop/js/jquery.Jcrop.js +26 -26
- data/app/controllers/spud/admin/media_controller.rb +7 -4
- data/app/models/spud_media.rb +19 -14
- data/app/views/spud/admin/media/index.html.erb +4 -3
- data/app/views/spud/admin/media/replace.html.erb +26 -0
- data/config/routes.rb +5 -4
- data/lib/spud_media/version.rb +1 -1
- metadata +6 -5
@@ -1,5 +1,5 @@
|
|
1
1
|
spud.admin.mediapicker = new function(){
|
2
|
-
|
2
|
+
|
3
3
|
var self = this;
|
4
4
|
var supportsHtml5Upload = false;
|
5
5
|
var selectedFile = {};
|
@@ -18,6 +18,7 @@ spud.admin.mediapicker = new function(){
|
|
18
18
|
$('.spud_media_picker_tabs a').first().click();
|
19
19
|
$('.spud_media_picker_tab_advanced').on('spud_media_picker_tab_activated', self.activatedAdvancedTab);
|
20
20
|
$('.spud_media_picker_option_dimensions').on('blur', 'input', self.dimensionsChanged);
|
21
|
+
$('.spud_media_picker_option').on('keyup', 'input[type=text]', self.pickerOptionKeyDown);
|
21
22
|
};
|
22
23
|
|
23
24
|
self.clickedTab = function(e){
|
@@ -150,6 +151,7 @@ spud.admin.mediapicker = new function(){
|
|
150
151
|
else{
|
151
152
|
$('.spud_media_picker_option_target').show();
|
152
153
|
$('.spud_media_picker_option_text').show();
|
154
|
+
$('.spud_media_picker_option_text input').val(tinyMCEPopup.editor.selection.getContent());
|
153
155
|
$('.spud_media_picker_option_float').hide();
|
154
156
|
$('.spud_media_picker_option_title').hide();
|
155
157
|
$('.spud_media_picker_option_dimensions').hide();
|
@@ -162,7 +164,6 @@ spud.admin.mediapicker = new function(){
|
|
162
164
|
img.onload = function(){
|
163
165
|
_originalWidth = img.width;
|
164
166
|
_originalHeight = img.height;
|
165
|
-
console.log(_originalWidth, _originalHeight);
|
166
167
|
};
|
167
168
|
img.src = url;
|
168
169
|
};
|
@@ -201,8 +202,18 @@ spud.admin.mediapicker = new function(){
|
|
201
202
|
else{
|
202
203
|
selectedFile.target = $('select[name="spud_media_picker_option_target"]').val();
|
203
204
|
selectedFile.text = $('input[name="spud_media_picker_option_text"]').val();
|
205
|
+
if(!selectedFile.text){
|
206
|
+
window.alert("Link Text is a required field.");
|
207
|
+
return;
|
208
|
+
}
|
204
209
|
}
|
205
210
|
tinyMCEPopup.editor.execCommand('spudMediaInsertSelected', false, selectedFile);
|
206
211
|
tinyMCEPopup.close();
|
207
212
|
};
|
213
|
+
|
214
|
+
self.pickerOptionKeyDown = function(e){
|
215
|
+
if(e.keyCode == 13){
|
216
|
+
self.clickedInsert(e);
|
217
|
+
}
|
218
|
+
};
|
208
219
|
};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
2
|
* jquery.Jcrop.js v0.9.10
|
3
|
-
* jQuery Image Cropping Plugin - released under MIT License
|
3
|
+
* jQuery Image Cropping Plugin - released under MIT License
|
4
4
|
* Author: Kelly Hallman <khallman@gmail.com>
|
5
5
|
* http://github.com/tapmodo/Jcrop
|
6
6
|
* Copyright (c) 2008-2012 Tapmodo Interactive LLC {{{
|
@@ -168,7 +168,7 @@
|
|
168
168
|
if ((ord === 'move') && !options.allowMove) {
|
169
169
|
return false;
|
170
170
|
}
|
171
|
-
|
171
|
+
|
172
172
|
// Fix position of crop area when dragged the very first time.
|
173
173
|
// Necessary when crop image is in a hidden element when page is loaded.
|
174
174
|
docOffset = getPos($img);
|
@@ -254,7 +254,7 @@
|
|
254
254
|
function newTracker() //{{{
|
255
255
|
{
|
256
256
|
var trk = $('<div></div>').addClass(cssClass('tracker'));
|
257
|
-
if (
|
257
|
+
if (navigator.userAgent.match(/msie/i)) {
|
258
258
|
trk.css({
|
259
259
|
opacity: 0,
|
260
260
|
backgroundColor: 'white'
|
@@ -267,9 +267,9 @@
|
|
267
267
|
// }}}
|
268
268
|
// Initialization {{{
|
269
269
|
// Sanitize some options {{{
|
270
|
-
|
271
|
-
|
272
|
-
|
270
|
+
ie6mode = ( navigator.userAgent.match(/msie/i) && navigator.userAgent.match(/6/) );
|
271
|
+
|
272
|
+
|
273
273
|
if (typeof(obj) !== 'object') {
|
274
274
|
obj = $(obj)[0];
|
275
275
|
}
|
@@ -304,12 +304,12 @@
|
|
304
304
|
$origimg.width($origimg[0].width);
|
305
305
|
$origimg.height($origimg[0].height);
|
306
306
|
} else {
|
307
|
-
// Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0).
|
307
|
+
// Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0).
|
308
308
|
var tempImage = new Image();
|
309
309
|
tempImage.src = $origimg[0].src;
|
310
310
|
$origimg.width(tempImage.width);
|
311
311
|
$origimg.height(tempImage.height);
|
312
|
-
}
|
312
|
+
}
|
313
313
|
|
314
314
|
var $img = $origimg.clone().removeAttr('id').css(img_css).show();
|
315
315
|
|
@@ -327,8 +327,8 @@
|
|
327
327
|
|
328
328
|
var boundx = $img.width(),
|
329
329
|
boundy = $img.height(),
|
330
|
-
|
331
|
-
|
330
|
+
|
331
|
+
|
332
332
|
$div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({
|
333
333
|
position: 'relative',
|
334
334
|
backgroundColor: options.bgColor
|
@@ -340,24 +340,24 @@
|
|
340
340
|
|
341
341
|
var $img2 = $('<div />'),
|
342
342
|
|
343
|
-
$img_holder = $('<div />')
|
343
|
+
$img_holder = $('<div />')
|
344
344
|
.width('100%').height('100%').css({
|
345
345
|
zIndex: 310,
|
346
346
|
position: 'absolute',
|
347
347
|
overflow: 'hidden'
|
348
348
|
}),
|
349
349
|
|
350
|
-
$hdl_holder = $('<div />')
|
351
|
-
.width('100%').height('100%').css('zIndex', 320),
|
350
|
+
$hdl_holder = $('<div />')
|
351
|
+
.width('100%').height('100%').css('zIndex', 320),
|
352
352
|
|
353
|
-
$sel = $('<div />')
|
353
|
+
$sel = $('<div />')
|
354
354
|
.css({
|
355
355
|
position: 'absolute',
|
356
356
|
zIndex: 600
|
357
357
|
}).dblclick(function(){
|
358
358
|
var c = Coords.getFixed();
|
359
359
|
options.onDblClick.call(api,c);
|
360
|
-
}).insertBefore($img).append($img_holder, $hdl_holder);
|
360
|
+
}).insertBefore($img).append($img_holder, $hdl_holder);
|
361
361
|
|
362
362
|
if (img_mode) {
|
363
363
|
|
@@ -393,7 +393,7 @@
|
|
393
393
|
// }}}
|
394
394
|
// }}}
|
395
395
|
// Internal Modules {{{
|
396
|
-
// Touch Module {{{
|
396
|
+
// Touch Module {{{
|
397
397
|
var Touch = (function () {
|
398
398
|
// Touch support detection function adapted (under MIT License)
|
399
399
|
// from code by Jeffrey Sambells - http://github.com/iamamused/
|
@@ -529,8 +529,8 @@
|
|
529
529
|
// This function could use some optimization I think...
|
530
530
|
var aspect = options.aspectRatio,
|
531
531
|
min_x = options.minSize[0] / xscale,
|
532
|
-
|
533
|
-
|
532
|
+
|
533
|
+
|
534
534
|
//min_y = options.minSize[1]/yscale,
|
535
535
|
max_x = options.maxSize[0] / xscale,
|
536
536
|
max_y = options.maxSize[1] / yscale,
|
@@ -1049,7 +1049,7 @@
|
|
1049
1049
|
{
|
1050
1050
|
seehandles = false;
|
1051
1051
|
$hdl_holder.hide();
|
1052
|
-
}
|
1052
|
+
}
|
1053
1053
|
//}}}
|
1054
1054
|
function animMode(v) //{{{
|
1055
1055
|
{
|
@@ -1058,13 +1058,13 @@
|
|
1058
1058
|
} else {
|
1059
1059
|
enableHandles();
|
1060
1060
|
}
|
1061
|
-
}
|
1061
|
+
}
|
1062
1062
|
//}}}
|
1063
1063
|
function done() //{{{
|
1064
1064
|
{
|
1065
1065
|
animMode(false);
|
1066
1066
|
refresh();
|
1067
|
-
}
|
1067
|
+
}
|
1068
1068
|
//}}}
|
1069
1069
|
// Insert draggable elements {{{
|
1070
1070
|
// Insert border divs for outline
|
@@ -1120,7 +1120,7 @@
|
|
1120
1120
|
done: done
|
1121
1121
|
};
|
1122
1122
|
}());
|
1123
|
-
|
1123
|
+
|
1124
1124
|
//}}}
|
1125
1125
|
// Tracker Module {{{
|
1126
1126
|
var Tracker = (function () {
|
@@ -1143,7 +1143,7 @@
|
|
1143
1143
|
.bind('mousemove.jcrop',trackMove)
|
1144
1144
|
.bind('mouseup.jcrop',trackUp);
|
1145
1145
|
}
|
1146
|
-
}
|
1146
|
+
}
|
1147
1147
|
//}}}
|
1148
1148
|
function toBack() //{{{
|
1149
1149
|
{
|
@@ -1151,13 +1151,13 @@
|
|
1151
1151
|
zIndex: 290
|
1152
1152
|
});
|
1153
1153
|
$(document).unbind('.jcrop');
|
1154
|
-
}
|
1154
|
+
}
|
1155
1155
|
//}}}
|
1156
1156
|
function trackMove(e) //{{{
|
1157
1157
|
{
|
1158
1158
|
onMove(mouseAbs(e));
|
1159
1159
|
return false;
|
1160
|
-
}
|
1160
|
+
}
|
1161
1161
|
//}}}
|
1162
1162
|
function trackUp(e) //{{{
|
1163
1163
|
{
|
@@ -1576,7 +1576,7 @@
|
|
1576
1576
|
}
|
1577
1577
|
};
|
1578
1578
|
|
1579
|
-
if (
|
1579
|
+
if (navigator.userAgent.match(/msie/i))
|
1580
1580
|
$div.bind('selectstart', function () { return false; });
|
1581
1581
|
|
1582
1582
|
$origimg.data('Jcrop', api);
|
@@ -2,8 +2,8 @@ class Spud::Admin::MediaController < Spud::Admin::ApplicationController
|
|
2
2
|
layout 'layouts/spud/admin/detail'
|
3
3
|
add_breadcrumb "Media", :spud_admin_media_path
|
4
4
|
belongs_to_spud_app :media
|
5
|
-
before_filter :load_media,:only => [:edit,:update,:show,:destroy,:set_private,:set_access]
|
6
|
-
|
5
|
+
before_filter :load_media,:only => [:edit,:update,:show,:destroy,:set_private,:set_access, :replace]
|
6
|
+
|
7
7
|
def index
|
8
8
|
@media = SpudMedia.order("created_at DESC").paginate :page => params[:page]
|
9
9
|
respond_with @media
|
@@ -22,7 +22,7 @@ class Spud::Admin::MediaController < Spud::Admin::ApplicationController
|
|
22
22
|
@media = SpudMedia.new(params[:spud_media])
|
23
23
|
location = spud_admin_media_path
|
24
24
|
if @media.save
|
25
|
-
flash[:notice] = "File uploaded successfully"
|
25
|
+
flash[:notice] = "File uploaded successfully"
|
26
26
|
if @media.is_image?
|
27
27
|
location = edit_spud_admin_medium_path(@media.id)
|
28
28
|
end
|
@@ -43,6 +43,9 @@ class Spud::Admin::MediaController < Spud::Admin::ApplicationController
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
def replace
|
47
|
+
end
|
48
|
+
|
46
49
|
def update
|
47
50
|
if @media.update_attributes(params[:spud_media])
|
48
51
|
@media.attachment.reprocess!
|
@@ -68,6 +71,6 @@ private
|
|
68
71
|
flash[:error] = "Media Asset not found!"
|
69
72
|
redirect_to spud_admin_media_url() and return
|
70
73
|
end
|
71
|
-
|
74
|
+
|
72
75
|
end
|
73
76
|
end
|
data/app/models/spud_media.rb
CHANGED
@@ -3,10 +3,10 @@ class SpudMedia < ActiveRecord::Base
|
|
3
3
|
has_attached_file :attachment,
|
4
4
|
:storage => Spud::Media.paperclip_storage,
|
5
5
|
:s3_credentials => Spud::Media.s3_credentials,
|
6
|
-
:s3_permissions => lambda { |attachment, style|
|
7
|
-
attachment.instance.is_protected ? 'private' : 'public-read'
|
6
|
+
:s3_permissions => lambda { |attachment, style|
|
7
|
+
attachment.instance.is_protected ? 'private' : 'public-read'
|
8
8
|
},
|
9
|
-
:path => Spud::Media.paperclip_storage == :s3 ? Spud::Media.storage_path : lambda { |attachment|
|
9
|
+
:path => Spud::Media.paperclip_storage == :s3 ? Spud::Media.storage_path : lambda { |attachment|
|
10
10
|
attachment.instance.is_protected ? Spud::Media.storage_path_protected : Spud::Media.storage_path
|
11
11
|
},
|
12
12
|
:url => Spud::Media.storage_url,
|
@@ -17,10 +17,15 @@ class SpudMedia < ActiveRecord::Base
|
|
17
17
|
validates_numericality_of :crop_x, :crop_y, :crop_w, :crop_h, :crop_s, :allow_nil => true
|
18
18
|
|
19
19
|
before_create :rename_file
|
20
|
+
before_update :rename_file
|
20
21
|
#after_create :validate_permissions
|
21
22
|
before_update :validate_permissions
|
22
23
|
|
23
24
|
def rename_file
|
25
|
+
if self.attachment_file_name_changed? && self.attachment_file_name_was.nil? == false
|
26
|
+
attachment.instance_write :file_name, self.attachment_file_name_was
|
27
|
+
return
|
28
|
+
end
|
24
29
|
# remove periods and other unsafe characters from file name to make routing easier
|
25
30
|
extension = File.extname(attachment_file_name)
|
26
31
|
filename = attachment_file_name.chomp(extension).parameterize
|
@@ -34,35 +39,35 @@ class SpudMedia < ActiveRecord::Base
|
|
34
39
|
|
35
40
|
elsif self.attachment_content_type.blank?
|
36
41
|
return "spud/admin/files_thumbs/dat_thumb.png"
|
37
|
-
|
42
|
+
|
38
43
|
elsif self.attachment_content_type.match(/jpeg|jpg/)
|
39
44
|
return "spud/admin/files_thumbs/jpg_thumb.png"
|
40
|
-
|
45
|
+
|
41
46
|
elsif self.attachment_content_type.match(/png/)
|
42
47
|
return "spud/admin/files_thumbs/png_thumb.png"
|
43
|
-
|
48
|
+
|
44
49
|
elsif self.attachment_content_type.match(/zip|tar|tar\.gz|gz/)
|
45
50
|
return "spud/admin/files_thumbs/zip_thumb.png"
|
46
|
-
|
51
|
+
|
47
52
|
elsif self.attachment_content_type.match(/xls|xlsx/)
|
48
53
|
return "spud/admin/files_thumbs/xls_thumb.png"
|
49
|
-
|
54
|
+
|
50
55
|
elsif self.attachment_content_type.match(/doc|docx/)
|
51
56
|
return "spud/admin/files_thumbs/doc_thumb.png"
|
52
|
-
|
57
|
+
|
53
58
|
elsif self.attachment_content_type.match(/ppt|pptx/)
|
54
59
|
return "spud/admin/files_thumbs/ppt_thumb.png"
|
55
|
-
|
60
|
+
|
56
61
|
elsif self.attachment_content_type.match(/txt|text/)
|
57
62
|
return "spud/admin/files_thumbs/txt_thumb.png"
|
58
|
-
|
63
|
+
|
59
64
|
elsif self.attachment_content_type.match(/pdf|ps/)
|
60
65
|
return "spud/admin/files_thumbs/pdf_thumb.png"
|
61
|
-
|
66
|
+
|
62
67
|
elsif self.attachment_content_type.match(/mp3|wav|aac/)
|
63
68
|
return "spud/admin/files_thumbs/mp3_thumb.png"
|
64
69
|
end
|
65
|
-
|
70
|
+
|
66
71
|
return "spud/admin/files_thumbs/dat_thumb.png"
|
67
72
|
end
|
68
73
|
|
@@ -130,7 +135,7 @@ private
|
|
130
135
|
new_path = Paperclip::Interpolations.interpolate(Spud::Media.config.storage_path_protected, attachment, 'original')
|
131
136
|
else
|
132
137
|
old_path = Paperclip::Interpolations.interpolate(Spud::Media.config.storage_path_protected, attachment, 'original')
|
133
|
-
new_path = Paperclip::Interpolations.interpolate(Spud::Media.config.storage_path, attachment, 'original')
|
138
|
+
new_path = Paperclip::Interpolations.interpolate(Spud::Media.config.storage_path, attachment, 'original')
|
134
139
|
end
|
135
140
|
new_base_dir = File.dirname(File.dirname(new_path))
|
136
141
|
old_base_dir= File.dirname(File.dirname(old_path))
|
@@ -5,14 +5,14 @@
|
|
5
5
|
<div class="page_list">
|
6
6
|
<%@media.each do |media|%>
|
7
7
|
<div class="page_row">
|
8
|
-
|
8
|
+
|
9
9
|
<span class="row_meta">
|
10
10
|
<% if media.is_protected && (media.is_image? || media.is_pdf?) %>
|
11
11
|
<img src="<%= media.image_from_type %>" class="size-50-thumb" />
|
12
12
|
<% else %>
|
13
13
|
<%= image_tag(media.image_from_type, :class => "size-50-thumb") %>
|
14
14
|
<% end %>
|
15
|
-
<%= link_to media.attachment.url.split("/").last, media.attachment_url %>
|
15
|
+
<%= link_to media.attachment.url.split("/").last, media.attachment_url %>
|
16
16
|
</span>
|
17
17
|
|
18
18
|
<span class="edit_controls">
|
@@ -24,9 +24,10 @@
|
|
24
24
|
<% else %>
|
25
25
|
<%= link_to 'Public', set_access_spud_admin_medium_path(media.id, :protected => true), :method => :put, :class => 'btn' %>
|
26
26
|
<% end %>
|
27
|
+
<%= link_to "Replace", replace_spud_admin_medium_path(:id => media.id), :class => "btn"%>
|
27
28
|
<%=link_to "Remove", spud_admin_medium_path(:id => media.id),:method => :delete,:class => 'btn btn-danger',:confirm => "Are you sure you want to remove this file?"%>
|
28
29
|
</span>
|
29
|
-
|
30
|
+
|
30
31
|
<br style="clear:both;"/>
|
31
32
|
</div>
|
32
33
|
<%end%>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
<%=form_for @media,:url => spud_admin_medium_path(:id => @media.id),:html=>{:class=>"form-horizontal", :multipart => true, :method => :put} do |f|%>
|
5
|
+
<fieldset>
|
6
|
+
<legend>Replace File</legend>
|
7
|
+
|
8
|
+
<div class="control-group">
|
9
|
+
<%=f.label :attachment, "Choose File",:class =>"control-label"%>
|
10
|
+
<div class="controls">
|
11
|
+
<%=f.file_field :attachment%>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div class="control-group">
|
16
|
+
<%= f.label :is_protected, 'Protected File', :class => 'control-label' %>
|
17
|
+
<div class="controls">
|
18
|
+
<%= f.check_box :is_protected %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="form-actions">
|
23
|
+
<%=f.submit "Upload", :class=>"btn btn-primary","data-loading-text"=>"Uploading..."%> or <%=link_to "cancel",spud_admin_media_path,:class => "btn"%>
|
24
|
+
</div>
|
25
|
+
<%end%>
|
26
|
+
|
data/config/routes.rb
CHANGED
@@ -2,12 +2,13 @@ Rails.application.routes.draw do
|
|
2
2
|
namespace :spud do
|
3
3
|
namespace :admin do
|
4
4
|
resources :media do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
put 'set_access', :on => :member
|
6
|
+
get 'replace', :on => :member
|
7
|
+
end
|
8
|
+
resources :media_picker, :only => [:index, :create]
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
11
12
|
#get '/media/protected/:id/:style/:filename' => 'ProtectedMedia#show', :as => 'protected_media'
|
12
13
|
get Spud::Media.config.storage_url => 'ProtectedMedia#show', :as => 'protected_media'
|
13
|
-
end
|
14
|
+
end
|
data/lib/spud_media/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spud_media
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -238,6 +238,7 @@ files:
|
|
238
238
|
- app/views/spud/admin/media/edit.html.erb
|
239
239
|
- app/views/spud/admin/media/index.html.erb
|
240
240
|
- app/views/spud/admin/media/new.html.erb
|
241
|
+
- app/views/spud/admin/media/replace.html.erb
|
241
242
|
- app/views/spud/admin/media_picker/_media.html.erb
|
242
243
|
- app/views/spud/admin/media_picker/create.html.erb
|
243
244
|
- app/views/spud/admin/media_picker/create.js.erb
|
@@ -269,7 +270,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
269
270
|
version: '0'
|
270
271
|
segments:
|
271
272
|
- 0
|
272
|
-
hash:
|
273
|
+
hash: 2768522942128927229
|
273
274
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
274
275
|
none: false
|
275
276
|
requirements:
|
@@ -278,10 +279,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
278
279
|
version: '0'
|
279
280
|
segments:
|
280
281
|
- 0
|
281
|
-
hash:
|
282
|
+
hash: 2768522942128927229
|
282
283
|
requirements: []
|
283
284
|
rubyforge_project:
|
284
|
-
rubygems_version: 1.8.
|
285
|
+
rubygems_version: 1.8.25
|
285
286
|
signing_key:
|
286
287
|
specification_version: 3
|
287
288
|
summary: Spud File upload/management module
|