cloudinary 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@ require 'action_view'
5
5
  require 'cloudinary/helper'
6
6
  require 'rails/version'
7
7
 
8
- if Rails::VERSION::MAJOR == 3
8
+ if ::Rails::VERSION::MAJOR < 4
9
9
  def config
10
10
  @config ||= {}
11
11
  end
@@ -24,53 +24,85 @@ describe Cloudinary::Utils do
24
24
  describe "cloudinary_url" do
25
25
  context ":video_codec" do
26
26
  it 'should support a string value' do
27
- test_cloudinary_url("video_id", { :resource_type => 'video', :video_codec => 'auto' }, "#{upload_path}/vc_auto/video_id", {})
27
+ expect(["video_id", { :resource_type => 'video', :video_codec => 'auto' }])
28
+ .to produce_url("#{upload_path}/vc_auto/video_id")
29
+ .and empty_options
28
30
  end
29
31
  it 'should support a hash value' do
30
- test_cloudinary_url("video_id", { :resource_type => 'video', :video_codec => { :codec => 'h264', :profile => 'basic', :level => '3.1' } },
31
- "#{upload_path}/vc_h264:basic:3.1/video_id", {})
32
+ expect(["video_id", {
33
+ :resource_type => 'video',
34
+ :video_codec => {
35
+ :codec => 'h264',
36
+ :profile => 'basic',
37
+ :level => '3.1'
38
+ }
39
+ }])
40
+ .to produce_url("#{upload_path}/vc_h264:basic:3.1/video_id")
41
+ .and empty_options
32
42
  end
33
43
  end
34
44
  context ":audio_codec" do
35
45
  it 'should support a string value' do
36
- test_cloudinary_url("video_id", { :resource_type => 'video', :audio_codec => 'acc' }, "#{upload_path}/ac_acc/video_id", {})
46
+ expect(["video_id", { :resource_type => 'video', :audio_codec => 'acc' }])
47
+ .to produce_url("#{upload_path}/ac_acc/video_id")
48
+ .and empty_options
37
49
  end
38
50
  end
39
51
  context ":bit_rate" do
40
52
  it 'should support an integer value' do
41
- test_cloudinary_url("video_id", { :resource_type => 'video', :bit_rate => 2048 }, "#{upload_path}/br_2048/video_id", {})
53
+ expect(["video_id", { :resource_type => 'video', :bit_rate => 2048 }])
54
+ .to produce_url("#{upload_path}/br_2048/video_id")
55
+ .and empty_options
42
56
  end
43
57
  it 'should support "<integer>k" ' do
44
- test_cloudinary_url("video_id", { :resource_type => 'video', :bit_rate => '44k' }, "#{upload_path}/br_44k/video_id", {})
58
+ expect(["video_id", { :resource_type => 'video', :bit_rate => '44k' }])
59
+ .to produce_url("#{upload_path}/br_44k/video_id")
60
+ .and empty_options
45
61
  end
46
62
  it 'should support "<integer>m"' do
47
- test_cloudinary_url("video_id", { :resource_type => 'video', :bit_rate => '1m' }, "#{upload_path}/br_1m/video_id", {})
63
+ expect(["video_id", { :resource_type => 'video', :bit_rate => '1m' }])
64
+ .to produce_url("#{upload_path}/br_1m/video_id")
65
+ .and empty_options
48
66
  end
49
67
  end
50
68
  context ":audio_frequency" do
51
69
  it 'should support an integer value' do
52
- test_cloudinary_url("video_id", { :resource_type => 'video', :audio_frequency => 44100 }, "#{upload_path}/af_44100/video_id", {})
70
+ expect(["video_id", { :resource_type => 'video', :audio_frequency => 44100 }])
71
+ .to produce_url("#{upload_path}/af_44100/video_id")
72
+ .and empty_options
53
73
  end
54
74
  end
55
75
  context ":video_sampling" do
56
76
  it "should support an integer value" do
57
- test_cloudinary_url("video_id", { :resource_type => 'video', :video_sampling => 20 }, "#{upload_path}/vs_20/video_id", {})
77
+ expect(["video_id", { :resource_type => 'video', :video_sampling => 20 }])
78
+ .to produce_url("#{upload_path}/vs_20/video_id")
79
+ .and empty_options
58
80
  end
59
81
  it "should support an string value in the a form of \"<float>s\"" do
60
- test_cloudinary_url("video_id", { :resource_type => 'video', :video_sampling => "2.3s" }, "#{upload_path}/vs_2.3s/video_id", {})
82
+ expect(["video_id", { :resource_type => 'video', :video_sampling => "2.3s" }])
83
+ .to produce_url("#{upload_path}/vs_2.3s/video_id")
84
+ .and empty_options
61
85
  end
62
86
  end
63
87
  { :so => :start_offset, :eo => :end_offset, :du => :duration }.each do |short, long|
64
88
  context ":#{long}" do
65
89
  it "should support decimal seconds " do
66
- test_cloudinary_url("video_id", { :resource_type => 'video', long => 2.63 }, "#{upload_path}/#{short}_2.63/video_id", {})
67
- test_cloudinary_url("video_id", { :resource_type => 'video', long => '2.63' }, "#{upload_path}/#{short}_2.63/video_id", {})
90
+ expect(["video_id", { :resource_type => 'video', long => 2.63 }])
91
+ .to produce_url("#{upload_path}/#{short}_2.63/video_id")
92
+ .and empty_options
93
+ expect(["video_id", { :resource_type => 'video', long => '2.63' }])
94
+ .to produce_url("#{upload_path}/#{short}_2.63/video_id")
95
+ .and empty_options
68
96
  end
69
97
  it 'should support percents of the video length as "<number>p"' do
70
- test_cloudinary_url("video_id", { :resource_type => 'video', long => '35p' }, "#{upload_path}/#{short}_35p/video_id", {})
98
+ expect(["video_id", { :resource_type => 'video', long => '35p' }])
99
+ .to produce_url("#{upload_path}/#{short}_35p/video_id")
100
+ .and empty_options
71
101
  end
72
102
  it 'should support percents of the video length as "<number>%"' do
73
- test_cloudinary_url("video_id", { :resource_type => 'video', long => '35%' }, "#{upload_path}/#{short}_35p/video_id", {})
103
+ expect(["video_id", { :resource_type => 'video', long => '35%' }])
104
+ .to produce_url("#{upload_path}/#{short}_35p/video_id")
105
+ .and empty_options
74
106
  end
75
107
  end
76
108
  end
@@ -101,20 +133,29 @@ describe Cloudinary::Utils do
101
133
 
102
134
  { :overlay => :l, :underlay => :u }.each do |param, letter|
103
135
  it "should support #{param}" do
104
- test_cloudinary_url("test", { :resource_type => 'video', param => "text:hello" }, "#{upload_path}/#{letter}_text:hello/test", {})
136
+ expect(["test", { :resource_type => 'video', param => "text:hello" }])
137
+ .to produce_url("#{upload_path}/#{letter}_text:hello/test")
138
+ .and empty_options
105
139
  end
106
140
 
107
141
  it "should not pass width/height to html for #{param}" do
108
- test_cloudinary_url("test", { :resource_type => 'video', param => "text:hello", :height => 100, :width => 100 }, "#{upload_path}/h_100,#{letter}_text:hello,w_100/test", {})
142
+ expect(["test", { :resource_type => 'video', param => "text:hello", :height => 100, :width => 100 }])
143
+ .to produce_url("#{upload_path}/h_100,#{letter}_text:hello,w_100/test")
144
+ .and empty_options
109
145
  end
110
146
  end
111
147
  it "should produce the transformation string" do
112
- test_cloudinary_url("test", { :resource_type => 'video', :background => "#112233" }, "#{upload_path}/b_rgb:112233/test", {})
113
- test_cloudinary_url("test", { :resource_type => 'video',
114
- :x => 1, :y => 2, :radius => 3,
115
- :gravity => :center,
116
- :quality => 0.4,
117
- :prefix => "a" }, "#{upload_path}/g_center,p_a,q_0.4,r_3,x_1,y_2/test", {})
148
+ expect(["test", { :resource_type => 'video', :background => "#112233" }])
149
+ .to produce_url("#{upload_path}/b_rgb:112233/test")
150
+ .and empty_options
151
+ expect(["test", {
152
+ :resource_type => 'video',
153
+ :x => 1, :y => 2, :radius => 3,
154
+ :gravity => :center,
155
+ :quality => 0.4,
156
+ :prefix => "a" }])
157
+ .to produce_url("#{upload_path}/g_center,p_a,q_0.4,r_3,x_1,y_2/test")
158
+ .and empty_options
118
159
 
119
160
  end
120
161
  end
@@ -24,7 +24,7 @@
24
24
  */
25
25
  var JSON;if(!JSON){JSON={}}(function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];if(i&&typeof i==="object"&&typeof i.toJSON==="function"){i=i.toJSON(a)}if(typeof rep==="function"){i=rep.call(b,a,i)}switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i){return"null"}gap+=indent;h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c<f;c+=1){h[c]=str(c,i)||"null"}e=h.length===0?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]";gap=g;return e}if(rep&&typeof rep==="object"){f=rep.length;for(c=0;c<f;c+=1){if(typeof rep[c]==="string"){d=rep[c];e=str(d,i);if(e){h.push(quote(d)+(gap?": ":":")+e)}}}}else{for(d in i){if(Object.prototype.hasOwnProperty.call(i,d)){e=str(d,i);if(e){h.push(quote(d)+(gap?": ":":")+e)}}}}e=h.length===0?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}";gap=g;return e}}function quote(a){escapable.lastIndex=0;return escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b==="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function f(a){return a<10?"0"+a:a}"use strict";if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;if(typeof JSON.stringify!=="function"){JSON.stringify=function(a,b,c){var d;gap="";indent="";if(typeof c==="number"){for(d=0;d<c;d+=1){indent+=" "}}else if(typeof c==="string"){indent=c}rep=b;if(b&&typeof b!=="function"&&(typeof b!=="object"||typeof b.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":a})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&typeof e==="object"){for(c in e){if(Object.prototype.hasOwnProperty.call(e,c)){d=walk(e,c);if(d!==undefined){e[c]=d}else{delete e[c]}}}}return reviver.call(a,b,e)}var j;text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}})()
26
26
  /* end of json2.js */
27
-
27
+ ;
28
28
  function parse(query) {
29
29
  var result = {};
30
30
  var params = query.split("&");
@@ -35,12 +35,8 @@ var JSON;if(!JSON){JSON={}}(function(){function str(a,b){var c,d,e,f,g=gap,h,i=b
35
35
  return JSON.stringify(result);
36
36
  }
37
37
 
38
- // IE below version 9 doesn't have textContent, so we have to use innerText
39
- if (document.body.hasOwnProperty('textContent')) {
40
- document.body.textContent = parse(window.location.search.slice(1));
41
- } else {
42
- document.body.innerText = parse(window.location.search.slice(1));
43
- }
38
+ document.body.textContent = document.body.innerText = parse(window.location.search.slice(1));
39
+
44
40
  </script>
45
41
  </body>
46
42
  </html>
@@ -1 +1 @@
1
- (function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return(new Blob([new Uint8Array(100)])).size===100}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;a.split(",")[0].indexOf("base64")>=0?b=atob(a.split(",")[1]):b=decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f);for(h=0;h<b.length;h+=1)g[h]=b.charCodeAt(h);return i=a.split(",")[0].split(":")[1].split(";")[0],c?new Blob([d?g:f],{type:i}):(j=new e,j.append(f),j.getBlob(i))};a.HTMLCanvasElement&&!b.toBlob&&(b.mozGetAsFile?b.toBlob=function(a,c,d){d&&b.toDataURL&&f?a(f(this.toDataURL(c,d))):a(this.mozGetAsFile("blob",c))}:b.toDataURL&&f&&(b.toBlob=function(a,b,c){a(f(this.toDataURL(b,c)))})),typeof define=="function"&&define.amd?define(function(){return f}):a.dataURLtoBlob=f})(this);
1
+ !function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;for(b=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f),h=0;h<b.length;h+=1)g[h]=b.charCodeAt(h);return i=a.split(",")[0].split(":")[1].split(";")[0],c?new Blob([d?g:f],{type:i}):(j=new e,j.append(f),j.getBlob(i))};a.HTMLCanvasElement&&!b.toBlob&&(b.mozGetAsFile?b.toBlob=function(a,c,d){a(d&&b.toDataURL&&f?f(this.toDataURL(c,d)):this.mozGetAsFile("blob",c))}:b.toDataURL&&f&&(b.toBlob=function(a,b,c){a(f(this.toDataURL(b,c)))})),"function"==typeof define&&define.amd?define(function(){return f}):a.dataURLtoBlob=f}(window);
@@ -1,1001 +1,3482 @@
1
- /*
2
- * Cloudinary's jQuery library - v1.0.24
3
- * Copyright Cloudinary
4
- * see https://github.com/cloudinary/cloudinary_js
5
- */
6
-
7
- (function (factory) {
8
- 'use strict';
9
- if (typeof define === 'function' && define.amd) {
10
- // Register as an anonymous AMD module:
11
- define([
12
- 'jquery',
13
- 'jquery.ui.widget',
14
- 'jquery.iframe-transport',
15
- 'jquery.fileupload'
16
- ], factory);
17
- } else {
18
- // Browser globals:
19
- var $ = window.jQuery;
20
- factory($);
21
- $(function() {
22
- if($.fn.cloudinary_fileupload !== undefined) {
23
- $("input.cloudinary-fileupload[type=file]").cloudinary_fileupload();
24
- }
25
- });
26
- }
27
- }(function ($) {
28
- 'use strict';
29
- var CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
30
- var OLD_AKAMAI_SHARED_CDN = "cloudinary-a.akamaihd.net";
31
- var AKAMAI_SHARED_CDN = "res.cloudinary.com";
32
- var SHARED_CDN = AKAMAI_SHARED_CDN;
33
- var DEFAULT_POSTER_OPTIONS = { format: 'jpg', resource_type: 'video' };
34
- var DEFAULT_VIDEO_SOURCE_TYPES = ['webm', 'mp4', 'ogv'];
35
- function utf8_encode (argString) {
36
- // http://kevin.vanzonneveld.net
37
- // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
38
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
39
- // + improved by: sowberry
40
- // + tweaked by: Jack
41
- // + bugfixed by: Onno Marsman
42
- // + improved by: Yves Sucaet
43
- // + bugfixed by: Onno Marsman
44
- // + bugfixed by: Ulrich
45
- // + bugfixed by: Rafal Kukawski
46
- // + improved by: kirilloid
47
- // * example 1: utf8_encode('Kevin van Zonneveld');
48
- // * returns 1: 'Kevin van Zonneveld'
49
-
50
- if (argString === null || typeof argString === "undefined") {
51
- return "";
52
- }
53
-
54
- var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
55
- var utftext = '',
56
- start, end, stringl = 0;
57
-
58
- start = end = 0;
59
- stringl = string.length;
60
- for (var n = 0; n < stringl; n++) {
61
- var c1 = string.charCodeAt(n);
62
- var enc = null;
63
-
64
- if (c1 < 128) {
65
- end++;
66
- } else if (c1 > 127 && c1 < 2048) {
67
- enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128);
68
- } else {
69
- enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128);
70
- }
71
- if (enc !== null) {
72
- if (end > start) {
73
- utftext += string.slice(start, end);
74
- }
75
- utftext += enc;
76
- start = end = n + 1;
77
- }
78
- }
79
-
80
- if (end > start) {
81
- utftext += string.slice(start, stringl);
82
- }
83
-
84
- return utftext;
85
- }
86
-
87
- function crc32 (str) {
88
- // http://kevin.vanzonneveld.net
89
- // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
90
- // + improved by: T0bsn
91
- // + improved by: http://stackoverflow.com/questions/2647935/javascript-crc32-function-and-php-crc32-not-matching
92
- // - depends on: utf8_encode
93
- // * example 1: crc32('Kevin van Zonneveld');
94
- // * returns 1: 1249991249
95
- str = utf8_encode(str);
96
- var table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D";
97
-
98
- var crc = 0;
99
- var x = 0;
100
- var y = 0;
101
-
102
- crc = crc ^ (-1);
103
- for (var i = 0, iTop = str.length; i < iTop; i++) {
104
- y = (crc ^ str.charCodeAt(i)) & 0xFF;
105
- x = "0x" + table.substr(y * 9, 8);
106
- crc = (crc >>> 8) ^ x;
107
- }
108
-
109
- crc = crc ^ (-1);
110
- //convert to unsigned 32-bit int if needed
111
- if (crc < 0) {crc += 4294967296;}
112
- return crc;
113
- }
114
-
115
- function option_consume(options, option_name, default_value) {
116
- var result = options[option_name];
117
- delete options[option_name];
118
- return typeof(result) == 'undefined' ? default_value : result;
119
- }
120
-
121
- function build_array(arg) {
122
- if (arg === null || typeof(arg) == 'undefined') {
123
- return [];
124
- } else if ($.isArray(arg)) {
125
- return arg;
126
- } else {
127
- return [arg];
128
- }
129
- }
130
-
131
- function join_array_function(sep){
132
- return function(value) {
133
- return build_array(value).join(sep);
134
- };
135
- }
136
-
137
- function present(value) {
138
- return typeof value != 'undefined' && ("" + value).length > 0;
139
- }
140
-
141
- function process_base_transformations(options) {
142
- var transformations = build_array(options.transformation);
143
- var all_named = true;
144
- for (var i = 0; i < transformations.length; i++) {
145
- all_named = all_named && typeof(transformations[i]) == 'string';
146
- }
147
- if (all_named) {
148
- return [];
149
- }
150
- delete options.transformation;
151
- var base_transformations = [];
152
- for (var i = 0; i < transformations.length; i++) {
153
- var transformation = transformations[i];
154
- if (typeof(transformation) == 'string') {
155
- base_transformations.push("t_" + transformation);
156
- } else {
157
- base_transformations.push(generate_transformation_string($.extend({}, transformation)));
158
- }
159
- }
160
- return base_transformations;
161
- }
162
-
163
- function process_size(options) {
164
- var size = option_consume(options, 'size');
165
- if (size) {
166
- var split_size = size.split("x");
167
- options.width = split_size[0];
168
- options.height = split_size[1];
169
- }
170
- }
171
-
172
- function process_html_dimensions(options) {
173
- var width = options.width, height = options.height;
174
- var has_layer = options.overlay || options.underlay;
175
- var crop = options.crop;
176
- var use_as_html_dimensions = !has_layer && !options.angle && crop != "fit" && crop != "limit" && crop != "lfill";
177
- if (use_as_html_dimensions) {
178
- if (width && !options.html_width && width !== "auto" && parseFloat(width) >= 1) options.html_width = width;
179
- if (height && !options.html_height && parseFloat(height) >= 1) options.html_height = height;
180
- }
181
- if (!crop && !has_layer) {
182
- delete options.width;
183
- delete options.height;
184
- }
185
- }
186
-
187
- var TRANSFORMATION_PARAM_NAME_MAPPING = {
188
- angle: 'a',
189
- audio_codec: 'ac',
190
- audio_frequency: 'af',
191
- background: 'b',
192
- bit_rate: 'br',
193
- border: 'bo',
194
- color: 'co',
195
- color_space: 'cs',
196
- crop: 'c',
197
- default_image: 'd',
198
- delay: 'dl',
199
- density: 'dn',
200
- duration: 'du',
201
- dpr: 'dpr',
202
- effect: 'e',
203
- end_offset: 'eo',
204
- fetch_format: 'f',
205
- flags: 'fl',
206
- gravity: 'g',
207
- height: 'h',
208
- opacity: 'o',
209
- overlay: 'l',
210
- page: 'pg',
211
- prefix: 'p',
212
- quality: 'q',
213
- radius: 'r',
214
- start_offset: 'so',
215
- transformation: 't',
216
- underlay: 'u',
217
- video_codec: 'vc',
218
- video_sampling: 'vs',
219
- width: 'w',
220
- x: 'x',
221
- y: 'y',
222
- zoom: 'z'
223
- };
224
-
225
- var TRANSFORMATION_PARAM_VALUE_MAPPING = {
226
- angle: function(angle){ return build_array(angle).join("."); },
227
- background: function(background) { return background.replace(/^#/, 'rgb:');},
228
- border: function(border) {
229
- if ($.isPlainObject(border)) {
230
- var border_width = "" + (border.width || 2);
231
- var border_color = (border.color || "black").replace(/^#/, 'rgb:');
232
- border = border_width + "px_solid_" + border_color;
233
- }
234
- return border;
235
- },
236
- color: function(color) { return color.replace(/^#/, 'rgb:');},
237
- dpr: function(dpr) {
238
- dpr = dpr.toString();
239
- if (dpr === "auto") {
240
- return "1.0";
241
- } else if (dpr.match(/^\d+$/)) {
242
- return dpr + ".0";
243
- } else {
244
- return dpr;
245
- }
246
- },
247
- effect: join_array_function(":"),
248
- flags: join_array_function("."),
249
- transformation: join_array_function("."),
250
- video_codec: process_video_params,
251
- start_offset: norm_range_value,
252
- end_offset: norm_range_value,
253
- duration: norm_range_value
254
- };
255
-
256
- function generate_transformation_string(options) {
257
- var base_transformations = process_base_transformations(options);
258
- process_size(options);
259
- process_html_dimensions(options);
260
-
261
- if(options['offset'] !== undefined){
262
- var range = split_range(options['offset']);
263
- delete options['offset'];
264
- if(range !== null){
265
- options['start_offset'] = range[0];
266
- options['end_offset'] = range[1];
267
- }
268
- }
269
-
270
- var params = [];
271
- for (var param in TRANSFORMATION_PARAM_NAME_MAPPING) {
272
- var value = option_consume(options, param);
273
- if (!present(value)) continue;
274
- if (TRANSFORMATION_PARAM_VALUE_MAPPING[param]) {
275
- value = TRANSFORMATION_PARAM_VALUE_MAPPING[param](value);
276
- }
277
- if (!present(value)) continue;
278
- params.push(TRANSFORMATION_PARAM_NAME_MAPPING[param] + "_" + value);
279
- }
280
- params.sort();
281
-
282
- var raw_transformation = option_consume(options, 'raw_transformation');
283
- if (present(raw_transformation)) params.push(raw_transformation);
284
- var transformation = params.join(",");
285
- if (present(transformation)) base_transformations.push(transformation);
286
- return base_transformations.join("/");
287
- }
288
-
289
- var number_pattern = "([0-9]*)\\.([0-9]+)|([0-9]+)";
290
- var offset_any_pattern = "(" + number_pattern + ")([%pP])?";
291
-
292
- function split_range(range) {
293
- var splitted;
294
- switch(range.constructor){
295
- case String:
296
- var offset_any_pattern_re = "("+offset_any_pattern+ ")\.\.("+offset_any_pattern+")";
297
- if (range.match(offset_any_pattern_re )){
298
- splitted = range.split("..");
299
- }
300
- break;
301
- case Array:
302
- splitted = range;
303
- break;
304
- default :
305
- splitted = [null, null];
306
-
307
- }
308
- return splitted;
309
- }
310
-
311
- function norm_range_value(value) {
312
- var offset = String(value).match(new RegExp("^" + offset_any_pattern+ "$"));
313
- if( offset){
314
- var modifier = present(offset[5]) ? 'p' : '';
315
- value = (offset[1] || offset[4]) + modifier;
316
- }
317
- return value;
318
- }
319
-
320
- function absolutize(url) {
321
- if (!url.match(/^https?:\//)) {
322
- var prefix = document.location.protocol + "//" + document.location.host;
323
- if (url[0] == '?') {
324
- prefix += document.location.pathname;
325
- } else if (url[0] != '/') {
326
- prefix += document.location.pathname.replace(/\/[^\/]*$/, '/');
327
- }
328
- url = prefix + url;
329
- }
330
- return url;
331
- }
332
-
333
- function cloudinary_url_prefix(public_id, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname, secure, secure_distribution, protocol) {
334
- if (cloud_name.match(/^\//) && !secure) {
335
- return "/res" + cloud_name;
336
- }
337
-
338
- var prefix = secure ? 'https://' : (window.location.protocol === 'file:' ? "file://" : 'http://');
339
- prefix = protocol ? protocol + '//' : prefix;
340
-
341
- var shared_domain = !private_cdn;
342
- if (secure) {
343
- if (!secure_distribution || secure_distribution == OLD_AKAMAI_SHARED_CDN) {
344
- secure_distribution = private_cdn ? cloud_name + "-res.cloudinary.com" : SHARED_CDN;
345
- }
346
- shared_domain = shared_domain || secure_distribution == SHARED_CDN;
347
- if (secure_cdn_subdomain == null && shared_domain) {
348
- secure_cdn_subdomain = cdn_subdomain;
349
- }
350
- if (secure_cdn_subdomain) {
351
- secure_distribution = secure_distribution.replace('res.cloudinary.com', "res-" + ((crc32(public_id) % 5) + 1) + ".cloudinary.com");
352
- }
353
- prefix += secure_distribution;
354
- } else if (cname) {
355
- var subdomain = cdn_subdomain ? "a" + ((crc32(public_id) % 5) + 1) + "." : "";
356
- prefix += subdomain + cname;
357
- } else {
358
- prefix += (private_cdn ? cloud_name + "-res" : "res");
359
- prefix += (cdn_subdomain ? "-" + ((crc32(public_id) % 5) + 1) : "");
360
- prefix += ".cloudinary.com";
361
- }
362
- if (shared_domain) prefix += "/" + cloud_name;
363
- return prefix;
364
- }
365
-
366
- function finalize_resource_type(resource_type, type, url_suffix, use_root_path, shorten) {
367
- var resource_type_and_type = resource_type + "/" + type;
368
- if (url_suffix) {
369
- if (resource_type_and_type == "image/upload") {
370
- resource_type_and_type = "images";
371
- } else if (resource_type_and_type == "raw/upload") {
372
- resource_type_and_type = "files";
373
- } else {
374
- throw "URL Suffix only supported for image/upload and raw/upload";
375
- }
376
- }
377
- if (use_root_path) {
378
- if (resource_type_and_type == "image/upload" || resource_type_and_type == "images") {
379
- resource_type_and_type = "";
380
- } else {
381
- throw "Root path only supported for image/upload";
382
- }
383
- }
384
- if (shorten && resource_type_and_type == "image/upload") {
385
- resource_type_and_type = "iu";
386
- }
387
- return resource_type_and_type;
388
- }
389
-
390
- function cloudinary_url(public_id, options) {
391
- options = options || {};
392
- var type = option_consume(options, 'type', 'upload');
393
- if (type == 'fetch') {
394
- options.fetch_format = options.fetch_format || option_consume(options, 'format');
395
- }
396
- var transformation = generate_transformation_string(options);
397
- var resource_type = option_consume(options, 'resource_type', "image");
398
- var version = option_consume(options, 'version');
399
- var format = option_consume(options, 'format');
400
- var cloud_name = option_consume(options, 'cloud_name', $.cloudinary.config().cloud_name);
401
- if (!cloud_name) throw "Unknown cloud_name";
402
- var private_cdn = option_consume(options, 'private_cdn', $.cloudinary.config().private_cdn);
403
- var secure_distribution = option_consume(options, 'secure_distribution', $.cloudinary.config().secure_distribution);
404
- var cname = option_consume(options, 'cname', $.cloudinary.config().cname);
405
- var cdn_subdomain = option_consume(options, 'cdn_subdomain', $.cloudinary.config().cdn_subdomain);
406
- var secure_cdn_subdomain = option_consume(options, 'secure_cdn_subdomain', $.cloudinary.config().secure_cdn_subdomain);
407
- var shorten = option_consume(options, 'shorten', $.cloudinary.config().shorten);
408
- var secure = option_consume(options, 'secure', window.location.protocol == 'https:');
409
- var protocol = option_consume(options, 'protocol', $.cloudinary.config().protocol);
410
- var trust_public_id = option_consume(options, 'trust_public_id');
411
- var url_suffix = option_consume(options, 'url_suffix');
412
- var use_root_path = option_consume(options, 'use_root_path', $.cloudinary.config().use_root_path);
413
-
414
- if (url_suffix && !private_cdn) {
415
- throw "URL Suffix only supported in private CDN";
416
- }
417
-
418
- if (type == 'fetch') {
419
- public_id = absolutize(public_id);
420
- }
421
-
422
- if (public_id.search("/") >= 0 && !public_id.match(/^v[0-9]+/) && !public_id.match(/^https?:\//) && !present(version)) {
423
- version = 1;
424
- }
425
-
426
- if (public_id.match(/^https?:/)) {
427
- if (type == "upload" || type == "asset") return public_id;
428
- public_id = encodeURIComponent(public_id).replace(/%3A/g, ":").replace(/%2F/g, "/");
429
- } else {
430
- // Make sure public_id is URI encoded.
431
- public_id = encodeURIComponent(decodeURIComponent(public_id)).replace(/%3A/g, ":").replace(/%2F/g, "/");
432
- if (url_suffix) {
433
- if (url_suffix.match(/[\.\/]/)) throw "url_suffix should not include . or /";
434
- public_id = public_id + "/" + url_suffix;
435
- }
436
- if (format) {
437
- if (!trust_public_id) public_id = public_id.replace(/\.(jpg|png|gif|webp)$/, '');
438
- public_id = public_id + "." + format;
439
- }
440
- }
441
-
442
- var resource_type_and_type = finalize_resource_type(resource_type, type, url_suffix, use_root_path, shorten);
443
- var prefix = cloudinary_url_prefix(public_id, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname, secure, secure_distribution, protocol);
444
- var url = [prefix, resource_type_and_type, transformation, version ? "v" + version : "",
445
- public_id].join("/").replace(/([^:])\/+/g, '$1/');
446
- return url;
447
- }
448
-
449
- function default_stoppoints(width) {
450
- return 10 * Math.ceil(width / 10);
451
- }
452
-
453
- function prepare_html_url(public_id, options) {
454
- if ($.cloudinary.config('dpr') && !options.dpr) {
455
- options.dpr = $.cloudinary.config('dpr');
456
- }
457
- var url = cloudinary_url(public_id, options);
458
- var width = option_consume(options, 'html_width');
459
- var height = option_consume(options, 'html_height');
460
- if (width) options.width = width;
461
- if (height) options.height = height;
462
- return url;
463
- }
464
-
465
- function get_config(name, options, default_value) {
466
- var value = options[name] || $.cloudinary.config(name);
467
- if (typeof(value) == 'undefined') value = default_value;
468
- return value;
469
- }
470
-
471
- function closest_above(list, value) {
472
- var i = list.length - 2;
473
- while (i >= 0 && list[i] >= value) {
474
- i--;
475
- }
476
- return list[i+1];
477
- }
478
-
479
- /**
480
- * A video codec parameter can be either a String or a Hash.
481
- *
482
- * @param {object} param <code>vc_<codec>[ : <profile> : [<level>]]</code>
483
- * or <code>{ codec: 'h264', profile: 'basic', level: '3.1' }</code>
484
- * @return {string} <code><codec> : <profile> : [<level>]]</code> if a Hash was provided
485
- * or the param if a String was provided.
486
- * Returns NIL if param is not a Hash or String
487
- */
488
- function process_video_params(param) {
489
- switch (typeof param) {
490
- case "object":
491
- var video = "";
492
- if (param['codec'] !== undefined) {
493
- video = param['codec'];
494
- if (param['profile'] !== undefined) {
495
- video += ":" + param['profile'];
496
- if (param['level'] !== undefined) {
497
- video += ":" + param['level'];
498
- }
499
- }
500
- }
501
- return video;
502
- case "string":
503
- return param;
504
- default:
505
- return null;
506
- }
507
- }
508
-
509
- function join_pair(key, value) {
510
- if (!value) {
511
- return undefined;
512
- } else if (value === true) {
513
- return key;
514
- } else {
515
- return key + "=\"" + value + "\"";
516
- }
517
- }
518
-
519
- function html_attrs(attrs) {
520
- var pairs = $.map(attrs, function(value, key) { return join_pair(key, value); });
521
- pairs.sort();
522
- return pairs.filter(function(pair){return pair;}).join(" ");
523
- }
524
-
525
- var cloudinary_config = null;
526
- var responsive_config = null;
527
- var responsive_resize_initialized = false;
528
- var device_pixel_ratio_cache = {};
529
-
530
- $.cloudinary = {
531
- CF_SHARED_CDN: CF_SHARED_CDN,
532
- OLD_AKAMAI_SHARED_CDN: OLD_AKAMAI_SHARED_CDN,
533
- AKAMAI_SHARED_CDN: AKAMAI_SHARED_CDN,
534
- SHARED_CDN: SHARED_CDN,
535
- config: function(new_config, new_value) {
536
- if (!cloudinary_config) {
537
- cloudinary_config = {};
538
- $('meta[name^="cloudinary_"]').each(function() {
539
- cloudinary_config[$(this).attr('name').replace("cloudinary_", '')] = $(this).attr('content');
540
- });
541
- }
542
- if (typeof(new_value) != 'undefined') {
543
- cloudinary_config[new_config] = new_value;
544
- } else if (typeof(new_config) == 'string') {
545
- return cloudinary_config[new_config];
546
- } else if (new_config) {
547
- cloudinary_config = new_config;
548
- }
549
- return cloudinary_config;
550
- },
551
- url: function(public_id, options) {
552
- options = $.extend({}, options);
553
- return cloudinary_url(public_id, options);
554
- },
555
- video_url: function(public_id, options) {
556
- options = $.extend({ resource_type: 'video' }, options);
557
- return cloudinary_url(public_id, options);
558
- },
559
- video_thumbnail_url: function(public_id, options) {
560
- options = $.extend({}, DEFAULT_POSTER_OPTIONS, options);
561
- return cloudinary_url(public_id, options);
562
- },
563
- url_internal: cloudinary_url,
564
- transformation_string: function(options) {
565
- options = $.extend({}, options);
566
- return generate_transformation_string(options);
567
- },
568
- /**
569
- * Generate an HTML image tag based on the public ID and options
570
- * as a jQuery object. The tag is preinitialized with cloudinary functionality.
571
- * @param {String} public_id the cloudinary resource ID
572
- * @param {String} [options]
573
- * @returns {jQuery} Image tag
574
- */
575
- image: function(public_id, options) {
576
- options = $.extend({}, options);
577
- var url = prepare_html_url(public_id, options);
578
- var img = $('<img/>').data('src-cache', url).attr(options).cloudinary_update(options);
579
- return img;
580
- },
581
- video_thumbnail: function(public_id, options) {
582
- options = $.extend({}, DEFAULT_POSTER_OPTIONS, options);
583
- image(public_id, options);
584
- },
585
- facebook_profile_image: function(public_id, options) {
586
- return $.cloudinary.image(public_id, $.extend({type: 'facebook'}, options));
587
- },
588
- twitter_profile_image: function(public_id, options) {
589
- return $.cloudinary.image(public_id, $.extend({type: 'twitter'}, options));
590
- },
591
- twitter_name_profile_image: function(public_id, options) {
592
- return $.cloudinary.image(public_id, $.extend({type: 'twitter_name'}, options));
593
- },
594
- gravatar_image: function(public_id, options) {
595
- return $.cloudinary.image(public_id, $.extend({type: 'gravatar'}, options));
596
- },
597
- fetch_image: function(public_id, options) {
598
- return $.cloudinary.image(public_id, $.extend({type: 'fetch'}, options));
599
- },
600
- /**
601
- * Creates an HTML video tag for the provided public_id
602
- * @param {String} public_id the resource public ID
603
- * @param {Object} [options] options for the resource and HTML tag
604
- * @param {(String|Array<String>)} [options.source_types] Specify which
605
- * source type the tag should include. defaults to webm, mp4 and ogv.
606
- * @param {String} [options.source_transformation] specific transformations
607
- * to use for a specific source type.
608
- * @param {(String|Object)} [options.poster] image URL or
609
- * poster options that may include a <tt>public_id</tt> key and
610
- * poster-specific transformations
611
- * @example <caption>Exmaple of generating a video tag:</caption>
612
- * $.cloudinary.video("mymovie.mp4");
613
- * $.cloudinary.video("mymovie.mp4", {source_types: 'webm'});
614
- * $.cloudinary.video("mymovie.ogv", {poster: "myspecialplaceholder.jpg"});
615
- * $.cloudinary.video("mymovie.webm", {source_types: ['webm', 'mp4'], poster: {effect: 'sepia'}});
616
- * @return {string} HTML video tag
617
- */
618
- video: function(public_id, options) {
619
- options = options || {};
620
- public_id = public_id.replace(/\.(mp4|ogv|webm)$/, '');
621
- var source_types = option_consume(options, 'source_types', []);
622
- var source_transformation = option_consume(options, 'source_transformation', {});
623
- var fallback = option_consume(options, 'fallback_content', '');
624
-
625
- if (source_types.length == 0) source_types = DEFAULT_VIDEO_SOURCE_TYPES;
626
- var video_options = $.extend(true, {}, options);
627
-
628
- if (video_options.hasOwnProperty('poster')) {
629
- if ($.isPlainObject(video_options.poster)) {
630
- if (video_options.poster.hasOwnProperty('public_id')) {
631
- video_options.poster = cloudinary_url(video_options.poster.public_id, video_options.poster);
632
- } else {
633
- video_options.poster = cloudinary_url(public_id, $.extend({}, DEFAULT_POSTER_OPTIONS, video_options.poster));
634
- }
635
- }
636
- } else {
637
- video_options.poster = cloudinary_url(public_id, $.extend({}, DEFAULT_POSTER_OPTIONS, options));
638
- }
639
-
640
- if (!video_options.poster) delete video_options.poster;
641
-
642
- var html = '<video ';
643
-
644
- if (!video_options.hasOwnProperty('resource_type')) video_options.resource_type = 'video';
645
- var multi_source = $.isArray(source_types) && source_types.length > 1;
646
- var source = public_id;
647
- if (!multi_source){
648
- source = source + '.' + build_array(source_types)[0];
649
- }
650
- var src = cloudinary_url(source, video_options);
651
- if (!multi_source) video_options.src = src;
652
- if (video_options.hasOwnProperty("html_width")) video_options.width = option_consume(video_options, 'html_width');
653
- if (video_options.hasOwnProperty("html_height")) video_options.height = option_consume(video_options, 'html_height');
654
- html = html + html_attrs(video_options) + '>';
655
- if (multi_source) {
656
- for(var i = 0; i < source_types.length; i++) {
657
- var source_type = source_types[i];
658
- var transformation = source_transformation[source_type] || {};
659
- src = cloudinary_url(source + "." + source_type, $.extend(true, {resource_type: 'video'}, options, transformation));
660
- var video_type = source_type == 'ogv' ? 'ogg' : source_type;
661
- var mime_type = "video/" + video_type;
662
- html = html + '<source '+ html_attrs({src: src, type: mime_type}) + '>';
663
- }
664
- }
665
-
666
- html = html + fallback;
667
- html = html + '</video>';
668
- return html;
669
- },
670
- sprite_css: function(public_id, options) {
671
- options = $.extend({type: 'sprite'}, options);
672
- if (!public_id.match(/.css$/)) options.format = 'css';
673
- return $.cloudinary.url(public_id, options);
674
- },
675
- /**
676
- * Turn on hidpi (dpr_auto) and responsive (w_auto) processing according to the current container size and the device pixel ratio.
677
- * Use the following classes:
678
- * - cld-hidpi - only set dpr_auto
679
- * - cld-responsive - update both dpr_auto and w_auto
680
- * Stoppoints - to prevent creating a transformation for every pixel, stop-points can be configured. The smallest stop-point that is larger than
681
- * the wanted width will be used. The default stoppoints are all the multiples of 10. See calc_stoppoint for ways to override this.
682
- * @param {Object} options
683
- * @param {boolean} [options.responsive_resize=true] should responsive images be updated on resize (default: true).
684
- * @param {integer} [options.responsive_debounce=100] if set, how many milliseconds after resize is done before the image is replaces (default: 100). Set to 0 to disable.
685
- * @param {boolean|String} [options.responsive_use_stoppoints]
686
- * <ul><li>true - always use stoppoints for width</li>
687
- * <li>"resize" - use exact width on first render and stoppoints on resize (default)</li>
688
- * <li>false - always use exact width</li></ul>
689
- * @param {boolean} [options.responsive_preserve_height] if set to true, original css height is perserved. Should only be used if the transformation supports different aspect ratios.
690
- */
691
- responsive: function(options) {
692
- responsive_config = $.extend(responsive_config || {}, options);
693
- $('img.cld-responsive, img.cld-hidpi').cloudinary_update(responsive_config);
694
- var responsive_resize = get_config('responsive_resize', responsive_config, true);
695
- if (responsive_resize && !responsive_resize_initialized) {
696
- responsive_config.resizing = responsive_resize_initialized = true;
697
- var timeout = null;
698
- $(window).on('resize', function() {
699
- var debounce = get_config('responsive_debounce', responsive_config, 100);
700
- function reset() {
701
- if (timeout) {
702
- clearTimeout(timeout);
703
- timeout = null;
704
- }
705
- }
706
- function run() {
707
- $('img.cld-responsive').cloudinary_update(responsive_config);
708
- }
709
- function wait() {
710
- reset();
711
- setTimeout(function() { reset(); run(); }, debounce);
712
- }
713
- if (debounce) {
714
- wait();
715
- } else {
716
- run();
717
- }
718
- });
719
- }
720
- },
721
- /**
722
- * Compute the stoppoint for the given element and width.
723
- * By default the stoppoint will be the smallest multiple of 10 larger than the width.
724
- * These can be overridden by either setting the data-stoppoints attribute of an image or using $.cloudinary.config('stoppoints', stoppoints).
725
- * The value can be either:
726
- * - an ordered list of the wanted stoppoints
727
- * - a comma separated ordered list of stoppoints
728
- * - a function that returns the stoppoint given the wanted width.
729
- */
730
- calc_stoppoint: function (element, width) {
731
- var stoppoints = $(element).data('stoppoints') || $.cloudinary.config().stoppoints || default_stoppoints;
732
- if (typeof(stoppoints) === 'function') {
733
- return stoppoints(width);
734
- }
735
- if (typeof(stoppoints) === 'string') {
736
- stoppoints = $.map(stoppoints.split(","), function(val){ return parseInt(val); });
737
- }
738
- return closest_above(stoppoints, width);
739
- },
740
- device_pixel_ratio: function() {
741
- var dpr = window.devicePixelRatio || 1;
742
- var dpr_string = device_pixel_ratio_cache[dpr];
743
- if (!dpr_string) {
744
- // Find closest supported DPR (to work correctly with device zoom)
745
- var dpr_used = closest_above($.cloudinary.supported_dpr_values, dpr);
746
- dpr_string = dpr_used.toString();
747
- if (dpr_string.match(/^\d+$/)) dpr_string += ".0";
748
- device_pixel_ratio_cache[dpr] = dpr_string;
749
- }
750
- return dpr_string;
751
- },
752
- supported_dpr_values: [0.75, 1.0, 1.3, 1.5, 2.0, 3.0]
753
- };
754
-
755
- $.fn.cloudinary = function(options) {
756
- this.filter('img').each(function() {
757
- var img_options = $.extend({width: $(this).attr('width'), height: $(this).attr('height'),
758
- src: $(this).attr('src')}, $(this).data(), options);
759
- var public_id = option_consume(img_options, 'source', option_consume(img_options, 'src'));
760
- var url = prepare_html_url(public_id, img_options);
761
- $(this).data('src-cache', url).attr({width: img_options.width, height: img_options.height});
762
- }).cloudinary_update(options);
763
- return this;
764
- };
765
-
766
- /**
767
- * Update hidpi (dpr_auto) and responsive (w_auto) fields according to the current container size and the device pixel ratio.
768
- * Only images marked with the <tt>cld-responsive</tt> class have w_auto updated.
769
- * @param {Object} [options] Options
770
- * @param {boolean|String} [options.responsive_use_stoppoints]
771
- * <ul><li>true - always use stoppoints for width</li>
772
- * <li>"resize" - use exact width on first render and stoppoints on resize (default)</li>
773
- * <li>false - always use exact width</li></ul>
774
- * @param {boolean} [options.responsive] if true, enable responsice on this element. Note that $.cloudinary.responsive() should be called once on the page.
775
- * @param {boolean} [options.responsive_preserve_height] if set to true, original css height is perserved. Should only be used if the transformation supports different aspect ratios.
776
- * @return {$.fn}
777
- */
778
- $.fn.cloudinary_update = function(options) {
779
- options = options || {};
780
- var responsive_use_stoppoints = get_config('responsive_use_stoppoints', options, "resize");
781
- var exact = responsive_use_stoppoints === false || (responsive_use_stoppoints == "resize" && !options.resizing);
782
-
783
- this.filter('img').each(function() {
784
- if (options.responsive) {
785
- $(this).addClass('cld-responsive');
786
- }
787
- var attrs = {};
788
- var src = $(this).data('src-cache') || $(this).data('src');
789
-
790
- if (!src) return;
791
- var responsive = $(this).hasClass('cld-responsive') && src.match(/\bw_auto\b/);
792
- if (responsive) {
793
- var parents = $(this).parents(),
794
- parentsLength = parents.length,
795
- container,
796
- containerWidth = 0,
797
- nthParent;
798
-
799
- for (nthParent = 0; nthParent < parentsLength; nthParent+=1) {
800
- container = parents[nthParent];
801
- containerWidth = $(container).width();
802
- if (containerWidth) {
803
- break;
804
- }
805
- }
806
- if (containerWidth == 0) {
807
- // container doesn't know the size yet. Usually because the image is hidden or outside the DOM.
808
- return;
809
- }
810
-
811
- var requestedWidth = exact ? containerWidth : $.cloudinary.calc_stoppoint(this, containerWidth);
812
- var currentWidth = $(this).data('width') || 0;
813
- if (requestedWidth > currentWidth) {
814
- // requested width is larger, fetch new image
815
- $(this).data('width', requestedWidth);
816
- } else {
817
- // requested width is not larger - keep previous
818
- requestedWidth = currentWidth;
819
- }
820
- src = src.replace(/\bw_auto\b/g, "w_" + requestedWidth);
821
- attrs.width = null;
822
- if (!options.responsive_preserve_height) attrs.height = null;
823
- }
824
- // Update dpr according to the device's devicePixelRatio
825
- attrs.src = src.replace(/\bdpr_(1\.0|auto)\b/g, "dpr_" + $.cloudinary.device_pixel_ratio());
826
- $(this).attr(attrs);
827
- });
828
- return this;
829
- };
830
-
831
- var webp = null;
832
- $.fn.webpify = function(options, webp_options) {
833
- var that = this;
834
- options = options || {};
835
- webp_options = webp_options || options;
836
- if (!webp) {
837
- webp = $.Deferred();
838
- var webp_canary = new Image();
839
- webp_canary.onerror = webp.reject;
840
- webp_canary.onload = webp.resolve;
841
- webp_canary.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMwAgSSNtse/cXjxyCCmrYNWPwmHRH9jwMA';
842
- }
843
- $(function() {
844
- webp.done(function() {
845
- $(that).cloudinary($.extend({}, webp_options, {format: 'webp'}));
846
- }).fail(function() {
847
- $(that).cloudinary(options);
848
- });
849
- });
850
- return this;
851
- };
852
- $.fn.fetchify = function(options) {
853
- return this.cloudinary($.extend(options, {'type': 'fetch'}));
854
- };
855
- if (!$.fn.fileupload) {
856
- return;
857
- }
858
- $.cloudinary.delete_by_token = function(delete_token, options) {
859
- options = options || {};
860
- var url = options.url;
861
- if (!url) {
862
- var cloud_name = options.cloud_name || $.cloudinary.config().cloud_name;
863
- url = "https://api.cloudinary.com/v1_1/" + cloud_name + "/delete_by_token";
864
- }
865
- var dataType = $.support.xhrFileUpload ? "json" : "iframe json";
866
- return $.ajax({
867
- url: url,
868
- method: "POST",
869
- data: {token: delete_token},
870
- headers: {"X-Requested-With": "XMLHttpRequest"},
871
- dataType: dataType
872
- });
873
- };
874
-
875
- $.fn.cloudinary_fileupload = function(options) {
876
- var initializing = !this.data('blueimpFileupload');
877
- if (initializing) {
878
- options = $.extend({
879
- maxFileSize: 20000000,
880
- dataType: 'json',
881
- headers: {"X-Requested-With": "XMLHttpRequest"}
882
- }, options);
883
- }
884
- this.fileupload(options);
885
-
886
- if (initializing) {
887
- this.bind("fileuploaddone", function(e, data) {
888
- if (data.result.error) return;
889
- data.result.path = ["v", data.result.version, "/", data.result.public_id,
890
- data.result.format ? "." + data.result.format : ""].join("");
891
-
892
- if (data.cloudinaryField && data.form.length > 0) {
893
- var upload_info = [data.result.resource_type, data.result.type, data.result.path].join("/") + "#" + data.result.signature;
894
- var multiple = $(e.target).prop("multiple");
895
- var add_field = function() {
896
- $('<input/>').attr({type: "hidden", name: data.cloudinaryField}).val(upload_info).appendTo(data.form);
897
- };
898
-
899
- if (multiple) {
900
- add_field();
901
- } else {
902
- var field = $(data.form).find('input[name="' + data.cloudinaryField + '"]');
903
- if (field.length > 0) {
904
- field.val(upload_info);
905
- } else {
906
- add_field();
907
- }
908
- }
909
- }
910
- $(e.target).trigger('cloudinarydone', data);
911
- });
912
- this.bind("fileuploadsend", function(e, data) {
913
- // add a common unique ID to all chunks of the same uploaded file
914
- data.headers["X-Unique-Upload-Id"] = (Math.random() * 10000000000).toString(16);
915
- });
916
-
917
- this.bind("fileuploadstart", function(e){
918
- $(e.target).trigger('cloudinarystart');
919
- });
920
- this.bind("fileuploadstop", function(e){
921
- $(e.target).trigger('cloudinarystop');
922
- });
923
- this.bind("fileuploadprogress", function(e,data){
924
- $(e.target).trigger('cloudinaryprogress',data);
925
- });
926
- this.bind("fileuploadprogressall", function(e,data){
927
- $(e.target).trigger('cloudinaryprogressall',data);
928
- });
929
- this.bind("fileuploadfail", function(e,data){
930
- $(e.target).trigger('cloudinaryfail',data);
931
- });
932
- this.bind("fileuploadalways", function(e,data){
933
- $(e.target).trigger('cloudinaryalways',data);
934
- });
935
-
936
- if (!this.fileupload('option').url) {
937
- var cloud_name = options.cloud_name || $.cloudinary.config().cloud_name;
938
- var resource_type = options.resource_type || "auto";
939
- var type = options.type || "upload";
940
- var upload_url = "https://api.cloudinary.com/v1_1/" + cloud_name + "/" + resource_type + "/" + type;
941
- this.fileupload('option', 'url', upload_url);
942
- }
943
- }
944
- return this;
945
- };
946
-
947
- $.fn.cloudinary_upload_url = function(remote_url) {
948
- this.fileupload('option', 'formData').file = remote_url;
949
- this.fileupload('add', { files: [ remote_url ] });
950
- delete(this.fileupload('option', 'formData').file);
951
- };
952
-
953
- $.fn.unsigned_cloudinary_upload = function(upload_preset, upload_params, options) {
954
- options = options || {};
955
- upload_params = $.extend({}, upload_params) || {};
956
-
957
- var attrs_to_move = ["cloud_name", "resource_type", "type"];
958
- for (var i = 0; i < attrs_to_move.length; i++) {
959
- var attr = attrs_to_move[i];
960
- if (upload_params[attr]) {
961
- options[attr] = upload_params[attr];
962
- delete upload_params[attr];
963
- }
964
- }
965
-
966
- // Serialize upload_params
967
- for (var key in upload_params) {
968
- var value = upload_params[key];
969
- if ($.isPlainObject(value)) {
970
- upload_params[key] = $.map(value, function(v, k){return k + "=" + v;}).join("|");
971
- } else if ($.isArray(value)) {
972
- if (value.length > 0 && $.isArray(value[0])) {
973
- upload_params[key] = $.map(value, function(array_value){return array_value.join(",");}).join("|");
974
- } else {
975
- upload_params[key] = value.join(",");
976
- }
977
- }
978
- }
979
- if (!upload_params.callback) {
980
- upload_params.callback = "/cloudinary_cors.html";
981
- }
982
- upload_params.upload_preset = upload_preset;
983
-
984
- options.formData = upload_params;
985
-
986
- if (options.cloudinary_field) {
987
- options.cloudinaryField = options.cloudinary_field;
988
- delete options.cloudinary_field;
989
- }
990
-
991
- var html_options = options.html || {};
992
- html_options["class"] = "cloudinary_fileupload " + (html_options["class"] || "");
993
- if (options.multiple) html_options.multiple = true;
994
- this.attr(html_options).cloudinary_fileupload(options);
995
- return this;
996
- };
997
-
998
- $.cloudinary.unsigned_upload_tag = function(upload_preset, upload_params, options) {
999
- return $('<input/>').attr({type: "file", name: "file"}).unsigned_cloudinary_upload(upload_preset, upload_params, options);
1000
- };
1001
- }));
1
+ /*
2
+ * Cloudinary's JavaScript library - Version 2.0.3
3
+ * Copyright Cloudinary
4
+ * see https://github.com/cloudinary/cloudinary_js
5
+ */
6
+ (function() {
7
+ (function(root, factory) {
8
+ if ((typeof define === 'function') && define.amd) {
9
+ return define('utf8_encode',factory);
10
+ } else if (typeof exports === 'object') {
11
+ return module.exports = factory();
12
+ } else {
13
+ root.cloudinary || (root.cloudinary = {});
14
+ return root.cloudinary.utf8_encode = factory();
15
+ }
16
+ })(this, function() {
17
+ return function(argString) {
18
+ var c1, enc, end, n, start, string, stringl, utftext;
19
+ if (argString === null || typeof argString === 'undefined') {
20
+ return '';
21
+ }
22
+ string = argString + '';
23
+ utftext = '';
24
+ start = void 0;
25
+ end = void 0;
26
+ stringl = 0;
27
+ start = end = 0;
28
+ stringl = string.length;
29
+ n = 0;
30
+ while (n < stringl) {
31
+ c1 = string.charCodeAt(n);
32
+ enc = null;
33
+ if (c1 < 128) {
34
+ end++;
35
+ } else if (c1 > 127 && c1 < 2048) {
36
+ enc = String.fromCharCode(c1 >> 6 | 192, c1 & 63 | 128);
37
+ } else {
38
+ enc = String.fromCharCode(c1 >> 12 | 224, c1 >> 6 & 63 | 128, c1 & 63 | 128);
39
+ }
40
+ if (enc !== null) {
41
+ if (end > start) {
42
+ utftext += string.slice(start, end);
43
+ }
44
+ utftext += enc;
45
+ start = end = n + 1;
46
+ }
47
+ n++;
48
+ }
49
+ if (end > start) {
50
+ utftext += string.slice(start, stringl);
51
+ }
52
+ return utftext;
53
+ };
54
+ });
55
+
56
+ }).call(this);
57
+
58
+ (function() {
59
+ (function(root, factory) {
60
+ if ((typeof define === 'function') && define.amd) {
61
+ return define('crc32',['utf8_encode'], factory);
62
+ } else if (typeof exports === 'object') {
63
+ return module.exports = factory(require('utf8_encode'));
64
+ } else {
65
+ root.cloudinary || (root.cloudinary = {});
66
+ return root.cloudinary.crc32 = factory(root.cloudinary.utf8_encode);
67
+ }
68
+ })(this, function(utf8_encode) {
69
+ return function(str) {
70
+ var crc, i, iTop, table, x, y;
71
+ str = utf8_encode(str);
72
+ table = '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D';
73
+ crc = 0;
74
+ x = 0;
75
+ y = 0;
76
+ crc = crc ^ -1;
77
+ i = 0;
78
+ iTop = str.length;
79
+ while (i < iTop) {
80
+ y = (crc ^ str.charCodeAt(i)) & 0xFF;
81
+ x = '0x' + table.substr(y * 9, 8);
82
+ crc = crc >>> 8 ^ x;
83
+ i++;
84
+ }
85
+ crc = crc ^ -1;
86
+ if (crc < 0) {
87
+ crc += 4294967296;
88
+ }
89
+ return crc;
90
+ };
91
+ });
92
+
93
+ }).call(this);
94
+
95
+ (function() {
96
+ (function(root, factory) {
97
+ if ((typeof define === 'function') && define.amd) {
98
+ return define('util', ['jquery'], factory);
99
+ } else if (typeof exports === 'object') {
100
+ return module.exports = factory(require('jquery'));
101
+ } else {
102
+ root.cloudinary || (root.cloudinary = {});
103
+ return root.cloudinary.Util = factory(jQuery);
104
+ }
105
+ })(this, function(jQuery) {
106
+
107
+ /**
108
+ * Includes utility methods and lodash / jQuery shims
109
+ */
110
+
111
+ /**
112
+ * Get data from the DOM element.
113
+ *
114
+ * This method will use jQuery's `data()` method if it is available, otherwise it will get the `data-` attribute
115
+ * @param {Element} element - the element to get the data from
116
+ * @param {string} name - the name of the data item
117
+ * @returns the value associated with the `name`
118
+ *
119
+ */
120
+ var Util, addClass, allStrings, camelCase, cloneDeep, compact, contains, defaults, difference, functions, getAttribute, getData, hasClass, identity, isEmpty, isString, merge, reWords, setAttribute, setAttributes, setData, snakeCase, width, without;
121
+ getData = function(element, name) {
122
+ return jQuery(element).data(name);
123
+ };
124
+
125
+ /**
126
+ * Set data in the DOM element.
127
+ *
128
+ * This method will use jQuery's `data()` method if it is available, otherwise it will set the `data-` attribute
129
+ * @param {Element} element - the element to set the data in
130
+ * @param {string} name - the name of the data item
131
+ * @param {*} value - the value to be set
132
+ *
133
+ */
134
+ setData = function(element, name, value) {
135
+ return jQuery(element).data(name, value);
136
+ };
137
+
138
+ /**
139
+ * Get attribute from the DOM element.
140
+ *
141
+ * This method will use jQuery's `attr()` method if it is available, otherwise it will get the attribute directly
142
+ * @param {Element} element - the element to set the attribute for
143
+ * @param {string} name - the name of the attribute
144
+ * @returns {*} the value of the attribute
145
+ *
146
+ */
147
+ getAttribute = function(element, name) {
148
+ return jQuery(element).attr(name);
149
+ };
150
+
151
+ /**
152
+ * Set attribute in the DOM element.
153
+ *
154
+ * This method will use jQuery's `attr()` method if it is available, otherwise it will set the attribute directly
155
+ * @param {Element} element - the element to set the attribute for
156
+ * @param {string} name - the name of the attribute
157
+ * @param {*} value - the value to be set
158
+ *
159
+ */
160
+ setAttribute = function(element, name, value) {
161
+ return jQuery(element).attr(name, value);
162
+ };
163
+ setAttributes = function(element, attributes) {
164
+ return jQuery(element).attr(attributes);
165
+ };
166
+ hasClass = function(element, name) {
167
+ return jQuery(element).hasClass(name);
168
+ };
169
+ addClass = function(element, name) {
170
+ return jQuery(element).addClass(name);
171
+ };
172
+ width = function(element) {
173
+ return jQuery(element).width();
174
+ };
175
+ isEmpty = function(item) {
176
+ return (jQuery.isArray(item) || Util.isString(item)) && item.length === 0 || (jQuery.isPlainObject(item) && jQuery.isEmptyObject(item));
177
+ };
178
+ allStrings = function(list) {
179
+ var item, j, len;
180
+ for (j = 0, len = list.length; j < len; j++) {
181
+ item = list[j];
182
+ if (!Util.isString(item)) {
183
+ return false;
184
+ }
185
+ }
186
+ return true;
187
+ };
188
+ isString = function(item) {
189
+ return typeof item === 'string' || (item != null ? item.toString() : void 0) === '[object String]';
190
+ };
191
+ merge = function() {
192
+ var args, i;
193
+ args = (function() {
194
+ var j, len, results;
195
+ results = [];
196
+ for (j = 0, len = arguments.length; j < len; j++) {
197
+ i = arguments[j];
198
+ results.push(i);
199
+ }
200
+ return results;
201
+ }).apply(this, arguments);
202
+ args.unshift(true);
203
+ return jQuery.extend.apply(this, args);
204
+ };
205
+
206
+ /** Used to match words to create compound words. */
207
+ reWords = (function() {
208
+ var lower, upper;
209
+ upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]';
210
+ lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';
211
+ return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
212
+ })();
213
+ camelCase = function(source) {
214
+ var i, word, words;
215
+ words = source.match(reWords);
216
+ words = (function() {
217
+ var j, len, results;
218
+ results = [];
219
+ for (i = j = 0, len = words.length; j < len; i = ++j) {
220
+ word = words[i];
221
+ word = word.toLocaleLowerCase();
222
+ if (i) {
223
+ results.push(word.charAt(0).toLocaleUpperCase() + word.slice(1));
224
+ } else {
225
+ results.push(word);
226
+ }
227
+ }
228
+ return results;
229
+ })();
230
+ return words.join('');
231
+ };
232
+ snakeCase = function(source) {
233
+ var i, word, words;
234
+ words = source.match(reWords);
235
+ words = (function() {
236
+ var j, len, results;
237
+ results = [];
238
+ for (i = j = 0, len = words.length; j < len; i = ++j) {
239
+ word = words[i];
240
+ results.push(word.toLocaleLowerCase());
241
+ }
242
+ return results;
243
+ })();
244
+ return words.join('_');
245
+ };
246
+ compact = function(arr) {
247
+ var item, j, len, results;
248
+ results = [];
249
+ for (j = 0, len = arr.length; j < len; j++) {
250
+ item = arr[j];
251
+ if (item) {
252
+ results.push(item);
253
+ }
254
+ }
255
+ return results;
256
+ };
257
+ cloneDeep = function() {
258
+ var args;
259
+ args = jQuery.makeArray(arguments);
260
+ args.unshift({});
261
+ args.unshift(true);
262
+ return jQuery.extend.apply(this, args);
263
+ };
264
+ contains = function(arr, item) {
265
+ var i, j, len;
266
+ for (j = 0, len = arr.length; j < len; j++) {
267
+ i = arr[j];
268
+ if (i === item) {
269
+ return true;
270
+ }
271
+ }
272
+ return false;
273
+ };
274
+ defaults = function() {
275
+ var a, args, first, j, len;
276
+ args = [];
277
+ if (arguments.length === 1) {
278
+ return arguments[0];
279
+ }
280
+ for (j = 0, len = arguments.length; j < len; j++) {
281
+ a = arguments[j];
282
+ args.unshift(a);
283
+ }
284
+ first = args.pop();
285
+ args.unshift(first);
286
+ return jQuery.extend.apply(this, args);
287
+ };
288
+ difference = function(arr, values) {
289
+ var item, j, len, results;
290
+ results = [];
291
+ for (j = 0, len = arr.length; j < len; j++) {
292
+ item = arr[j];
293
+ if (!contains(values, item)) {
294
+ results.push(item);
295
+ }
296
+ }
297
+ return results;
298
+ };
299
+ functions = function(object) {
300
+ var i, results;
301
+ results = [];
302
+ for (i in object) {
303
+ if (jQuery.isFunction(object[i])) {
304
+ results.push(i);
305
+ }
306
+ }
307
+ return results;
308
+ };
309
+ identity = function(value) {
310
+ return value;
311
+ };
312
+ without = function(array, item) {
313
+ var i, length, newArray;
314
+ newArray = [];
315
+ i = -1;
316
+ length = array.length;
317
+ while (++i < length) {
318
+ if (array[i] !== item) {
319
+ newArray.push(array[i]);
320
+ }
321
+ }
322
+ return newArray;
323
+ };
324
+ Util = {
325
+ hasClass: hasClass,
326
+ addClass: addClass,
327
+ getAttribute: getAttribute,
328
+ setAttribute: setAttribute,
329
+ setAttributes: setAttributes,
330
+ getData: getData,
331
+ setData: setData,
332
+ width: width,
333
+
334
+ /**
335
+ * Return true if all items in list are strings
336
+ * @param {Array} list - an array of items
337
+ */
338
+ allStrings: allStrings,
339
+ isString: isString,
340
+ isArray: jQuery.isArray,
341
+ isEmpty: isEmpty,
342
+
343
+ /**
344
+ * Assign source properties to destination.
345
+ * If the property is an object it is assigned as a whole, overriding the destination object.
346
+ * @param {Object} destination - the object to assign to
347
+ */
348
+ assign: jQuery.extend,
349
+
350
+ /**
351
+ * Recursively assign source properties to destination
352
+ * @param {Object} destination - the object to assign to
353
+ * @param {...Object} [sources] The source objects.
354
+ */
355
+ merge: merge,
356
+
357
+ /**
358
+ * Convert string to camelCase
359
+ * @param {string} string - the string to convert
360
+ * @return {string} in camelCase format
361
+ */
362
+ camelCase: camelCase,
363
+
364
+ /**
365
+ * Convert string to snake_case
366
+ * @param {string} string - the string to convert
367
+ * @return {string} in snake_case format
368
+ */
369
+ snakeCase: snakeCase,
370
+
371
+ /**
372
+ * Create a new copy of the given object, including all internal objects.
373
+ * @param {Object} value - the object to clone
374
+ * @return {Object} a new deep copy of the object
375
+ */
376
+ cloneDeep: cloneDeep,
377
+
378
+ /**
379
+ * Creates a new array from the parameter with "falsey" values removed
380
+ * @param {Array} array - the array to remove values from
381
+ * @return {Array} a new array without falsey values
382
+ */
383
+ compact: compact,
384
+
385
+ /**
386
+ * Check if a given item is included in the given array
387
+ * @param {Array} array - the array to search in
388
+ * @param {*} item - the item to search for
389
+ * @return {boolean} true if the item is included in the array
390
+ */
391
+ contains: contains,
392
+
393
+ /**
394
+ * Assign values from sources if they are not defined in the destination.
395
+ * Once a value is set it does not change
396
+ * @param {Object} destination - the object to assign defaults to
397
+ * @param {...Object} source - the source object(s) to assign defaults from
398
+ * @return {Object} destination after it was modified
399
+ */
400
+ defaults: defaults,
401
+
402
+ /**
403
+ * Returns values in the given array that are not included in the other array
404
+ * @param {Array} arr - the array to select from
405
+ * @param {Array} values - values to filter from arr
406
+ * @return {Array} the filtered values
407
+ */
408
+ difference: difference,
409
+
410
+ /**
411
+ * Returns true if argument is a function.
412
+ * @param {*} value - the value to check
413
+ * @return {boolean} true if the value is a function
414
+ */
415
+ isFunction: jQuery.isFunction,
416
+
417
+ /**
418
+ * Returns a list of all the function names in obj
419
+ * @param {Object} object - the object to inspect
420
+ * @return {Array} a list of functions of object
421
+ */
422
+ functions: functions,
423
+
424
+ /**
425
+ * Returns the provided value. This functions is used as a default predicate function.
426
+ * @param {*} value
427
+ * @return {*} the provided value
428
+ */
429
+ identity: identity,
430
+ isPlainObject: jQuery.isPlainObject,
431
+
432
+ /**
433
+ * Remove leading or trailing spaces from text
434
+ * @param {string} text
435
+ * @return {string} the `text` without leading or trailing spaces
436
+ */
437
+ trim: jQuery.trim,
438
+
439
+ /**
440
+ * Creates a new array without the given item.
441
+ * @param {Array} array - original array
442
+ * @param {*} item - the item to exclude from the new array
443
+ * @return {Array} a new array made of the original array's items except for `item`
444
+ */
445
+ without: without
446
+ };
447
+ return Util;
448
+ });
449
+
450
+ }).call(this);
451
+
452
+ (function() {
453
+ (function(root, factory) {
454
+ if ((typeof define === 'function') && define.amd) {
455
+ return define('configuration',['util'], factory);
456
+ } else if (typeof exports === 'object') {
457
+ return module.exports = factory(require('util'));
458
+ } else {
459
+ root.cloudinary || (root.cloudinary = {});
460
+ return root.cloudinary.Configuration = factory(root.cloudinary.Util);
461
+ }
462
+ })(this, function(Util) {
463
+
464
+ /**
465
+ * Cloudinary configuration class
466
+ */
467
+ var Configuration;
468
+ Configuration = (function() {
469
+
470
+ /**
471
+ * Defaults configuration.
472
+ * @const {Object} Configuration.DEFAULT_CONFIGURATION_PARAMS
473
+ */
474
+ var DEFAULT_CONFIGURATION_PARAMS, ref;
475
+
476
+ DEFAULT_CONFIGURATION_PARAMS = {
477
+ secure: (typeof window !== "undefined" && window !== null ? (ref = window.location) != null ? ref.protocol : void 0 : void 0) === 'https:'
478
+ };
479
+
480
+ Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive_width", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
481
+
482
+
483
+ /**
484
+ * Cloudinary configuration class
485
+ * @constructor Configuration
486
+ * @param {Object} options - configuration parameters
487
+ */
488
+
489
+ function Configuration(options) {
490
+ if (options == null) {
491
+ options = {};
492
+ }
493
+ this.configuration = Util.cloneDeep(options);
494
+ Util.defaults(this.configuration, DEFAULT_CONFIGURATION_PARAMS);
495
+ }
496
+
497
+
498
+ /**
499
+ * Initialize the configuration.
500
+ * The function first tries to retrieve the configuration form the environment and then from the document.
501
+ * @function Configuration#init
502
+ * @return {Configuration} returns this for chaining
503
+ * @see fromDocument
504
+ * @see fromEnvironment
505
+ */
506
+
507
+ Configuration.prototype.init = function() {
508
+ this.fromEnvironment();
509
+ this.fromDocument();
510
+ return this;
511
+ };
512
+
513
+
514
+ /**
515
+ * Set a new configuration item
516
+ * @function Configuration#set
517
+ * @param {string} name - the name of the item to set
518
+ * @param {*} value - the value to be set
519
+ * @return {Configuration}
520
+ *
521
+ */
522
+
523
+ Configuration.prototype.set = function(name, value) {
524
+ this.configuration[name] = value;
525
+ return this;
526
+ };
527
+
528
+
529
+ /**
530
+ * Get the value of a configuration item
531
+ * @function Configuration#get
532
+ * @param {string} name - the name of the item to set
533
+ * @return {*} the configuration item
534
+ */
535
+
536
+ Configuration.prototype.get = function(name) {
537
+ return this.configuration[name];
538
+ };
539
+
540
+ Configuration.prototype.merge = function(config) {
541
+ if (config == null) {
542
+ config = {};
543
+ }
544
+ Util.assign(this.configuration, Util.cloneDeep(config));
545
+ return this;
546
+ };
547
+
548
+
549
+ /**
550
+ * Initialize Cloudinary from HTML meta tags.
551
+ * @function Configuration#fromDocument
552
+ * @return {Configuration}
553
+ * @example <meta name="cloudinary_cloud_name" content="mycloud">
554
+ *
555
+ */
556
+
557
+ Configuration.prototype.fromDocument = function() {
558
+ var el, i, len, meta_elements;
559
+ meta_elements = typeof document !== "undefined" && document !== null ? document.querySelectorAll('meta[name^="cloudinary_"]') : void 0;
560
+ if (meta_elements) {
561
+ for (i = 0, len = meta_elements.length; i < len; i++) {
562
+ el = meta_elements[i];
563
+ this.configuration[el.getAttribute('name').replace('cloudinary_', '')] = el.getAttribute('content');
564
+ }
565
+ }
566
+ return this;
567
+ };
568
+
569
+
570
+ /**
571
+ * Initialize Cloudinary from the `CLOUDINARY_URL` environment variable.
572
+ *
573
+ * This function will only run under Node.js environment.
574
+ * @function Configuration#fromEnvironment
575
+ * @requires Node.js
576
+ */
577
+
578
+ Configuration.prototype.fromEnvironment = function() {
579
+ var cloudinary_url, k, ref1, ref2, uri, v;
580
+ cloudinary_url = typeof process !== "undefined" && process !== null ? (ref1 = process.env) != null ? ref1.CLOUDINARY_URL : void 0 : void 0;
581
+ if (cloudinary_url != null) {
582
+ uri = require('url').parse(cloudinary_url, true);
583
+ this.configuration = {
584
+ cloud_name: uri.host,
585
+ api_key: uri.auth && uri.auth.split(":")[0],
586
+ api_secret: uri.auth && uri.auth.split(":")[1],
587
+ private_cdn: uri.pathname != null,
588
+ secure_distribution: uri.pathname && uri.pathname.substring(1)
589
+ };
590
+ if (uri.query != null) {
591
+ ref2 = uri.query;
592
+ for (k in ref2) {
593
+ v = ref2[k];
594
+ this.configuration[k] = v;
595
+ }
596
+ }
597
+ }
598
+ return this;
599
+ };
600
+
601
+
602
+ /**
603
+ * Create or modify the Cloudinary client configuration
604
+ *
605
+ * Warning: `config()` returns the actual internal configuration object. modifying it will change the configuration.
606
+ *
607
+ * This is a backward compatibility method. For new code, use get(), merge() etc.
608
+ * @function Configuration#config
609
+ * @param {hash|string|boolean} new_config
610
+ * @param {string} new_value
611
+ * @returns {*} configuration, or value
612
+ *
613
+ * @see {@link fromEnvironment} for initialization using environment variables
614
+ * @see {@link fromDocument} for initialization using HTML meta tags
615
+ */
616
+
617
+ Configuration.prototype.config = function(new_config, new_value) {
618
+ switch (false) {
619
+ case new_value === void 0:
620
+ this.set(new_config, new_value);
621
+ return this.configuration;
622
+ case !Util.isString(new_config):
623
+ return this.get(new_config);
624
+ case !Util.isPlainObject(new_config):
625
+ this.merge(new_config);
626
+ return this.configuration;
627
+ default:
628
+ return this.configuration;
629
+ }
630
+ };
631
+
632
+
633
+ /**
634
+ * Returns a copy of the configuration parameters
635
+ * @function Configuration#toOptions
636
+ * @returns {Object} a key:value collection of the configuration parameters
637
+ */
638
+
639
+ Configuration.prototype.toOptions = function() {
640
+ return Util.cloneDeep(this.configuration);
641
+ };
642
+
643
+ return Configuration;
644
+
645
+ })();
646
+ return Configuration;
647
+ });
648
+
649
+ }).call(this);
650
+
651
+ (function() {
652
+ var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
653
+ hasProp = {}.hasOwnProperty;
654
+
655
+ (function(root, factory) {
656
+ if ((typeof define === 'function') && define.amd) {
657
+ return define('parameters',['util', 'transformation', 'require'], factory);
658
+ } else if (typeof exports === 'object') {
659
+ return module.exports = factory(require('util'), require('transformation'), require);
660
+ } else {
661
+ root.cloudinary || (root.cloudinary = {});
662
+ return root.cloudinary.parameters = factory(root.cloudinary.Util, root.cloudinary.Transformation, function() {
663
+ return cloudinary.Transformation;
664
+ });
665
+ }
666
+ })(this, function(Util, Transformation, require) {
667
+ var ArrayParam, Param, RangeParam, RawParam, TransformationParam, parameters;
668
+ Param = (function() {
669
+
670
+ /**
671
+ * Represents a single parameter
672
+ * @class Param
673
+ * @param {string} name - The name of the parameter in snake_case
674
+ * @param {string} short - The name of the serialized form of the parameter.
675
+ * If a value is not provided, the parameter will not be serialized.
676
+ * @param {function} [process=Util.identity ] - Manipulate origValue when value is called
677
+ * @ignore
678
+ */
679
+ function Param(name, short, process) {
680
+ if (process == null) {
681
+ process = Util.identity;
682
+ }
683
+
684
+ /**
685
+ * The name of the parameter in snake_case
686
+ * @member {string} Param#name
687
+ */
688
+ this.name = name;
689
+
690
+ /**
691
+ * The name of the serialized form of the parameter
692
+ * @member {string} Param#short
693
+ */
694
+ this.short = short;
695
+
696
+ /**
697
+ * Manipulate origValue when value is called
698
+ * @member {function} Param#process
699
+ */
700
+ this.process = process;
701
+ }
702
+
703
+
704
+ /**
705
+ * Set a (unprocessed) value for this parameter
706
+ * @function Param#set
707
+ * @param {*} origValue - the value of the parameter
708
+ * @return {Param} self for chaining
709
+ */
710
+
711
+ Param.prototype.set = function(origValue) {
712
+ this.origValue = origValue;
713
+ return this;
714
+ };
715
+
716
+
717
+ /**
718
+ * Generate the serialized form of the parameter
719
+ * @function Param#serialize
720
+ * @return {string} the serialized form of the parameter
721
+ */
722
+
723
+ Param.prototype.serialize = function() {
724
+ var val, valid;
725
+ val = this.value();
726
+ valid = Util.isArray(val) || Util.isPlainObject(val) || Util.isString(val) ? !Util.isEmpty(val) : val != null;
727
+ if ((this.short != null) && valid) {
728
+ return this.short + "_" + val;
729
+ } else {
730
+ return '';
731
+ }
732
+ };
733
+
734
+
735
+ /**
736
+ * Return the processed value of the parameter
737
+ * @function Param#value
738
+ */
739
+
740
+ Param.prototype.value = function() {
741
+ return this.process(this.origValue);
742
+ };
743
+
744
+ Param.norm_color = function(value) {
745
+ return value != null ? value.replace(/^#/, 'rgb:') : void 0;
746
+ };
747
+
748
+ Param.prototype.build_array = function(arg) {
749
+ if (arg == null) {
750
+ arg = [];
751
+ }
752
+ if (Util.isArray(arg)) {
753
+ return arg;
754
+ } else {
755
+ return [arg];
756
+ }
757
+ };
758
+
759
+
760
+ /**
761
+ * Covert value to video codec string.
762
+ *
763
+ * If the parameter is an object,
764
+ * @param {(string|Object)} param - the video codec as either a String or a Hash
765
+ * @return {string} the video codec string in the format codec:profile:level
766
+ * @example
767
+ * vc_[ :profile : [level]]
768
+ * or
769
+ { codec: 'h264', profile: 'basic', level: '3.1' }
770
+ * @ignore
771
+ */
772
+
773
+ Param.process_video_params = function(param) {
774
+ var video;
775
+ switch (param.constructor) {
776
+ case Object:
777
+ video = "";
778
+ if ('codec' in param) {
779
+ video = param['codec'];
780
+ if ('profile' in param) {
781
+ video += ":" + param['profile'];
782
+ if ('level' in param) {
783
+ video += ":" + param['level'];
784
+ }
785
+ }
786
+ }
787
+ return video;
788
+ case String:
789
+ return param;
790
+ default:
791
+ return null;
792
+ }
793
+ };
794
+
795
+ return Param;
796
+
797
+ })();
798
+ ArrayParam = (function(superClass) {
799
+ extend(ArrayParam, superClass);
800
+
801
+
802
+ /**
803
+ * A parameter that represents an array
804
+ * @param {string} name - The name of the parameter in snake_case
805
+ * @param {string} short - The name of the serialized form of the parameter
806
+ * If a value is not provided, the parameter will not be serialized.
807
+ * @param {string} [sep='.'] - The separator to use when joining the array elements together
808
+ * @param {function} [process=Util.identity ] - Manipulate origValue when value is called
809
+ * @class ArrayParam
810
+ * @extends Param
811
+ * @ignore
812
+ */
813
+
814
+ function ArrayParam(name, short, sep, process) {
815
+ if (sep == null) {
816
+ sep = '.';
817
+ }
818
+ this.sep = sep;
819
+ ArrayParam.__super__.constructor.call(this, name, short, process);
820
+ }
821
+
822
+ ArrayParam.prototype.serialize = function() {
823
+ var array, flat, t;
824
+ if (this.short != null) {
825
+ array = this.value();
826
+ if (Util.isEmpty(array)) {
827
+ return '';
828
+ } else {
829
+ flat = (function() {
830
+ var i, len, ref, results;
831
+ ref = this.value();
832
+ results = [];
833
+ for (i = 0, len = ref.length; i < len; i++) {
834
+ t = ref[i];
835
+ if (Util.isFunction(t.serialize)) {
836
+ results.push(t.serialize());
837
+ } else {
838
+ results.push(t);
839
+ }
840
+ }
841
+ return results;
842
+ }).call(this);
843
+ return this.short + "_" + (flat.join(this.sep));
844
+ }
845
+ } else {
846
+ return '';
847
+ }
848
+ };
849
+
850
+ ArrayParam.prototype.set = function(origValue) {
851
+ if ((origValue == null) || Util.isArray(origValue)) {
852
+ return ArrayParam.__super__.set.call(this, origValue);
853
+ } else {
854
+ return ArrayParam.__super__.set.call(this, [origValue]);
855
+ }
856
+ };
857
+
858
+ return ArrayParam;
859
+
860
+ })(Param);
861
+ TransformationParam = (function(superClass) {
862
+ extend(TransformationParam, superClass);
863
+
864
+
865
+ /**
866
+ * A parameter that represents a transformation
867
+ * @param {string} name - The name of the parameter in snake_case
868
+ * @param {string} [short='t'] - The name of the serialized form of the parameter
869
+ * @param {string} [sep='.'] - The separator to use when joining the array elements together
870
+ * @param {function} [process=Util.identity ] - Manipulate origValue when value is called
871
+ * @class TransformationParam
872
+ * @extends Param
873
+ * @ignore
874
+ */
875
+
876
+ function TransformationParam(name, short, sep, process) {
877
+ if (short == null) {
878
+ short = "t";
879
+ }
880
+ if (sep == null) {
881
+ sep = '.';
882
+ }
883
+ this.sep = sep;
884
+ TransformationParam.__super__.constructor.call(this, name, short, process);
885
+ }
886
+
887
+ TransformationParam.prototype.serialize = function() {
888
+ var joined, result, t;
889
+ if (Util.isEmpty(this.value())) {
890
+ return '';
891
+ } else if (Util.allStrings(this.value())) {
892
+ joined = this.value().join(this.sep);
893
+ if (!Util.isEmpty(joined)) {
894
+ return this.short + "_" + joined;
895
+ } else {
896
+ return '';
897
+ }
898
+ } else {
899
+ result = (function() {
900
+ var i, len, ref, results;
901
+ ref = this.value();
902
+ results = [];
903
+ for (i = 0, len = ref.length; i < len; i++) {
904
+ t = ref[i];
905
+ if (t != null) {
906
+ if (Util.isString(t) && !Util.isEmpty(t)) {
907
+ results.push(this.short + "_" + t);
908
+ } else if (Util.isFunction(t.serialize)) {
909
+ results.push(t.serialize());
910
+ } else if (Util.isPlainObject(t) && !Util.isEmpty(t)) {
911
+ Transformation || (Transformation = require('transformation'));
912
+ results.push(new Transformation(t).serialize());
913
+ } else {
914
+ results.push(void 0);
915
+ }
916
+ }
917
+ }
918
+ return results;
919
+ }).call(this);
920
+ return Util.compact(result);
921
+ }
922
+ };
923
+
924
+ TransformationParam.prototype.set = function(origValue1) {
925
+ this.origValue = origValue1;
926
+ if (Util.isArray(this.origValue)) {
927
+ return TransformationParam.__super__.set.call(this, this.origValue);
928
+ } else {
929
+ return TransformationParam.__super__.set.call(this, [this.origValue]);
930
+ }
931
+ };
932
+
933
+ return TransformationParam;
934
+
935
+ })(Param);
936
+ RangeParam = (function(superClass) {
937
+ extend(RangeParam, superClass);
938
+
939
+
940
+ /**
941
+ * A parameter that represents a range
942
+ * @param {string} name - The name of the parameter in snake_case
943
+ * @param {string} short - The name of the serialized form of the parameter
944
+ * If a value is not provided, the parameter will not be serialized.
945
+ * @param {function} [process=norm_range_value ] - Manipulate origValue when value is called
946
+ * @class RangeParam
947
+ * @extends Param
948
+ * @ignore
949
+ */
950
+
951
+ function RangeParam(name, short, process) {
952
+ if (process == null) {
953
+ process = this.norm_range_value;
954
+ }
955
+ RangeParam.__super__.constructor.call(this, name, short, process);
956
+ }
957
+
958
+ RangeParam.norm_range_value = function(value) {
959
+ var modifier, offset;
960
+ offset = String(value).match(new RegExp('^' + offset_any_pattern + '$'));
961
+ if (offset) {
962
+ modifier = offset[5] != null ? 'p' : '';
963
+ value = (offset[1] || offset[4]) + modifier;
964
+ }
965
+ return value;
966
+ };
967
+
968
+ return RangeParam;
969
+
970
+ })(Param);
971
+ RawParam = (function(superClass) {
972
+ extend(RawParam, superClass);
973
+
974
+ function RawParam(name, short, process) {
975
+ if (process == null) {
976
+ process = Util.identity;
977
+ }
978
+ RawParam.__super__.constructor.call(this, name, short, process);
979
+ }
980
+
981
+ RawParam.prototype.serialize = function() {
982
+ return this.value();
983
+ };
984
+
985
+ return RawParam;
986
+
987
+ })(Param);
988
+ parameters = {};
989
+ parameters.Param = Param;
990
+ parameters.ArrayParam = ArrayParam;
991
+ parameters.RangeParam = RangeParam;
992
+ parameters.RawParam = RawParam;
993
+ parameters.TransformationParam = TransformationParam;
994
+ return parameters;
995
+ });
996
+
997
+ }).call(this);
998
+
999
+ (function() {
1000
+ var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
1001
+ hasProp = {}.hasOwnProperty;
1002
+
1003
+ (function(root, factory) {
1004
+ if ((typeof define === 'function') && define.amd) {
1005
+ return define('transformation',['configuration', 'parameters', 'util'], factory);
1006
+ } else if (typeof exports === 'object') {
1007
+ return module.exports = factory(require('configuration'), require('parameters'), require('util'));
1008
+ } else {
1009
+ root.cloudinary || (root.cloudinary = {});
1010
+ return root.cloudinary.Transformation = factory(root.cloudinary.Configuration, root.cloudinary.parameters, root.cloudinary.Util);
1011
+ }
1012
+ })(this, function(Configuration, parameters, Util) {
1013
+ var ArrayParam, Param, RangeParam, RawParam, Transformation, TransformationBase, TransformationParam;
1014
+ Param = parameters.Param;
1015
+ ArrayParam = parameters.ArrayParam;
1016
+ RangeParam = parameters.RangeParam;
1017
+ RawParam = parameters.RawParam;
1018
+ TransformationParam = parameters.TransformationParam;
1019
+ TransformationBase = (function() {
1020
+ var lastArgCallback;
1021
+
1022
+ lastArgCallback = function(args) {
1023
+ var callback;
1024
+ callback = args != null ? args[args.length - 1] : void 0;
1025
+ if (Util.isFunction(callback)) {
1026
+ return callback;
1027
+ } else {
1028
+ return void 0;
1029
+ }
1030
+ };
1031
+
1032
+
1033
+ /**
1034
+ * The base class for transformations.
1035
+ * Members of this class are documented as belonging to the {@link Transformation} class for convenience.
1036
+ * @class TransformationBase
1037
+ */
1038
+
1039
+ function TransformationBase(options) {
1040
+ var chainedTo, m, trans;
1041
+ if (options == null) {
1042
+ options = {};
1043
+ }
1044
+
1045
+ /** @private */
1046
+ chainedTo = void 0;
1047
+
1048
+ /** @private */
1049
+ trans = {};
1050
+
1051
+ /**
1052
+ * Return an options object that can be used to create an identical Transformation
1053
+ * @function Transformation#toOptions
1054
+ * @return {Object} Returns a plain object representing this transformation
1055
+ */
1056
+ this.toOptions = function() {
1057
+ var key, opt, ref, value;
1058
+ opt = {};
1059
+ for (key in trans) {
1060
+ value = trans[key];
1061
+ opt[key] = value.origValue;
1062
+ }
1063
+ ref = this.otherOptions;
1064
+ for (key in ref) {
1065
+ value = ref[key];
1066
+ if (value !== void 0) {
1067
+ opt[key] = value;
1068
+ }
1069
+ }
1070
+ return opt;
1071
+ };
1072
+
1073
+ /**
1074
+ * Set a parent for this object for chaining purposes.
1075
+ *
1076
+ * @function Transformation#setParent
1077
+ * @param {Object} object - the parent to be assigned to
1078
+ * @returns {Transformation} Returns this instance for chaining purposes.
1079
+ */
1080
+ this.setParent = function(object) {
1081
+ chainedTo = object;
1082
+ this.fromOptions(typeof object.toOptions === "function" ? object.toOptions() : void 0);
1083
+ return this;
1084
+ };
1085
+
1086
+ /**
1087
+ * Returns the parent of this object in the chain
1088
+ * @function Transformation#getParent
1089
+ * @protected
1090
+ * @return {Object} Returns the parent of this object if there is any
1091
+ */
1092
+ this.getParent = function() {
1093
+ return chainedTo;
1094
+ };
1095
+
1096
+ /** @protected */
1097
+ this.param = function(value, name, abbr, defaultValue, process) {
1098
+ if (process == null) {
1099
+ if (Util.isFunction(defaultValue)) {
1100
+ process = defaultValue;
1101
+ } else {
1102
+ process = Util.identity;
1103
+ }
1104
+ }
1105
+ trans[name] = new Param(name, abbr, process).set(value);
1106
+ return this;
1107
+ };
1108
+
1109
+ /** @protected */
1110
+ this.rawParam = function(value, name, abbr, defaultValue, process) {
1111
+ if (process == null) {
1112
+ process = Util.identity;
1113
+ }
1114
+ process = lastArgCallback(arguments);
1115
+ trans[name] = new RawParam(name, abbr, process).set(value);
1116
+ return this;
1117
+ };
1118
+
1119
+ /** @protected */
1120
+ this.rangeParam = function(value, name, abbr, defaultValue, process) {
1121
+ if (process == null) {
1122
+ process = Util.identity;
1123
+ }
1124
+ process = lastArgCallback(arguments);
1125
+ trans[name] = new RangeParam(name, abbr, process).set(value);
1126
+ return this;
1127
+ };
1128
+
1129
+ /** @protected */
1130
+ this.arrayParam = function(value, name, abbr, sep, defaultValue, process) {
1131
+ if (sep == null) {
1132
+ sep = ":";
1133
+ }
1134
+ if (defaultValue == null) {
1135
+ defaultValue = [];
1136
+ }
1137
+ if (process == null) {
1138
+ process = Util.identity;
1139
+ }
1140
+ process = lastArgCallback(arguments);
1141
+ trans[name] = new ArrayParam(name, abbr, sep, process).set(value);
1142
+ return this;
1143
+ };
1144
+
1145
+ /** @protected */
1146
+ this.transformationParam = function(value, name, abbr, sep, defaultValue, process) {
1147
+ if (sep == null) {
1148
+ sep = ".";
1149
+ }
1150
+ if (process == null) {
1151
+ process = Util.identity;
1152
+ }
1153
+ process = lastArgCallback(arguments);
1154
+ trans[name] = new TransformationParam(name, abbr, sep, process).set(value);
1155
+ return this;
1156
+ };
1157
+
1158
+ /**
1159
+ * Get the value associated with the given name.
1160
+ * @function Transformation#getValue
1161
+ * @param {string} name - the name of the parameter
1162
+ * @return {*} the processed value associated with the given name
1163
+ * @description Use {@link get}.origValue for the value originally provided for the parameter
1164
+ */
1165
+ this.getValue = function(name) {
1166
+ var ref, ref1;
1167
+ return (ref = (ref1 = trans[name]) != null ? ref1.value() : void 0) != null ? ref : this.otherOptions[name];
1168
+ };
1169
+
1170
+ /**
1171
+ * Get the parameter object for the given parameter name
1172
+ * @function Transformation#get
1173
+ * @param {string} name the name of the transformation parameter
1174
+ * @returns {Param} the param object for the given name, or undefined
1175
+ */
1176
+ this.get = function(name) {
1177
+ return trans[name];
1178
+ };
1179
+
1180
+ /**
1181
+ * Remove a transformation option from the transformation.
1182
+ * @function Transformation#remove
1183
+ * @param {string} name - the name of the option to remove
1184
+ * @return {*} Returns the option that was removed or null if no option by that name was found. The type of the
1185
+ * returned value depends on the value.
1186
+ */
1187
+ this.remove = function(name) {
1188
+ var temp;
1189
+ switch (false) {
1190
+ case trans[name] == null:
1191
+ temp = trans[name];
1192
+ delete trans[name];
1193
+ return temp.origValue;
1194
+ case this.otherOptions[name] == null:
1195
+ temp = this.otherOptions[name];
1196
+ delete this.otherOptions[name];
1197
+ return temp;
1198
+ default:
1199
+ return null;
1200
+ }
1201
+ };
1202
+
1203
+ /**
1204
+ * Return an array of all the keys (option names) in the transformation.
1205
+ * @return {Array<string>} the keys in snakeCase format
1206
+ */
1207
+ this.keys = function() {
1208
+ var key;
1209
+ return ((function() {
1210
+ var results;
1211
+ results = [];
1212
+ for (key in trans) {
1213
+ results.push(Util.snakeCase(key));
1214
+ }
1215
+ return results;
1216
+ })()).sort();
1217
+ };
1218
+
1219
+ /**
1220
+ * Returns a plain object representation of the transformation. Values are processed.
1221
+ * @function Transformation#toPlainObject
1222
+ * @return {Object} the transformation options as plain object
1223
+ */
1224
+ this.toPlainObject = function() {
1225
+ var hash, key;
1226
+ hash = {};
1227
+ for (key in trans) {
1228
+ hash[key] = trans[key].value();
1229
+ if (Util.isPlainObject(hash[key])) {
1230
+ hash[key] = Util.cloneDeep(hash[key]);
1231
+ }
1232
+ }
1233
+ return hash;
1234
+ };
1235
+
1236
+ /**
1237
+ * Complete the current transformation and chain to a new one.
1238
+ * In the URL, transformations are chained together by slashes.
1239
+ * @function Transformation#chain
1240
+ * @return {Transformation} Returns this transformation for chaining
1241
+ * @example
1242
+ * var tr = cloudinary.Transformation.new();
1243
+ * tr.width(10).crop('fit').chain().angle(15).serialize()
1244
+ * // produces "c_fit,w_10/a_15"
1245
+ */
1246
+ this.chain = function() {
1247
+ var tr;
1248
+ tr = new this.constructor(this.toOptions());
1249
+ trans = [];
1250
+ return this.set("transformation", tr);
1251
+ };
1252
+ this.otherOptions = {};
1253
+
1254
+ /**
1255
+ * Transformation Class methods.
1256
+ * This is a list of the parameters defined in Transformation.
1257
+ * Values are camelCased.
1258
+ * @private
1259
+ * @ignore
1260
+ * @type {Array<string>}
1261
+ */
1262
+ this.methods = Util.difference(Util.functions(Transformation.prototype), Util.functions(TransformationBase.prototype));
1263
+
1264
+ /**
1265
+ * Parameters that are filtered out before passing the options to an HTML tag.
1266
+ *
1267
+ * The list of parameters is a combination of `Transformation::methods` and `Configuration::CONFIG_PARAMS`
1268
+ * @const {Array<string>} Transformation.PARAM_NAMES
1269
+ * @private
1270
+ * @ignore
1271
+ * @see toHtmlAttributes
1272
+ */
1273
+ this.PARAM_NAMES = ((function() {
1274
+ var i, len, ref, results;
1275
+ ref = this.methods;
1276
+ results = [];
1277
+ for (i = 0, len = ref.length; i < len; i++) {
1278
+ m = ref[i];
1279
+ results.push(Util.snakeCase(m));
1280
+ }
1281
+ return results;
1282
+ }).call(this)).concat(Configuration.CONFIG_PARAMS);
1283
+ if (!Util.isEmpty(options)) {
1284
+ this.fromOptions(options);
1285
+ }
1286
+ }
1287
+
1288
+
1289
+ /**
1290
+ * Merge the provided options with own's options
1291
+ * @param {Object} [options={}] key-value list of options
1292
+ * @returns {Transformation} Returns this instance for chaining
1293
+ */
1294
+
1295
+ TransformationBase.prototype.fromOptions = function(options) {
1296
+ var key, opt;
1297
+ options || (options = {});
1298
+ if (Util.isString(options) || Util.isArray(options) || options instanceof Transformation) {
1299
+ options = {
1300
+ transformation: options
1301
+ };
1302
+ }
1303
+ options = Util.cloneDeep(options, function(value) {
1304
+ if (value instanceof Transformation) {
1305
+ return new value.constructor(value.toOptions());
1306
+ }
1307
+ });
1308
+ for (key in options) {
1309
+ opt = options[key];
1310
+ this.set(key, opt);
1311
+ }
1312
+ return this;
1313
+ };
1314
+
1315
+
1316
+ /**
1317
+ * Set a parameter.
1318
+ * The parameter name `key` is converted to
1319
+ * @param {string} key - the name of the parameter
1320
+ * @param {*} value - the value of the parameter
1321
+ * @returns {Transformation} Returns this instance for chaining
1322
+ */
1323
+
1324
+ TransformationBase.prototype.set = function(key, value) {
1325
+ var camelKey;
1326
+ camelKey = Util.camelCase(key);
1327
+ if (Util.contains(this.methods, camelKey)) {
1328
+ this[camelKey](value);
1329
+ } else {
1330
+ this.otherOptions[key] = value;
1331
+ }
1332
+ return this;
1333
+ };
1334
+
1335
+ TransformationBase.prototype.hasLayer = function() {
1336
+ return this.getValue("overlay") || this.getValue("underlay");
1337
+ };
1338
+
1339
+
1340
+ /**
1341
+ * Generate a string representation of the transformation.
1342
+ * @function Transformation#serialize
1343
+ * @return {string} Returns the transformation as a string
1344
+ */
1345
+
1346
+ TransformationBase.prototype.serialize = function() {
1347
+ var paramList, ref, resultArray, t, transformationList, transformationString, transformations, value;
1348
+ resultArray = [];
1349
+ paramList = this.keys();
1350
+ transformations = (ref = this.get("transformation")) != null ? ref.serialize() : void 0;
1351
+ paramList = Util.without(paramList, "transformation");
1352
+ transformationList = (function() {
1353
+ var i, len, ref1, results;
1354
+ results = [];
1355
+ for (i = 0, len = paramList.length; i < len; i++) {
1356
+ t = paramList[i];
1357
+ results.push((ref1 = this.get(t)) != null ? ref1.serialize() : void 0);
1358
+ }
1359
+ return results;
1360
+ }).call(this);
1361
+ switch (false) {
1362
+ case !Util.isString(transformations):
1363
+ transformationList.push(transformations);
1364
+ break;
1365
+ case !Util.isArray(transformations):
1366
+ resultArray = transformations;
1367
+ }
1368
+ transformationString = ((function() {
1369
+ var i, len, results;
1370
+ results = [];
1371
+ for (i = 0, len = transformationList.length; i < len; i++) {
1372
+ value = transformationList[i];
1373
+ if (Util.isArray(value) && !Util.isEmpty(value) || !Util.isArray(value) && value) {
1374
+ results.push(value);
1375
+ }
1376
+ }
1377
+ return results;
1378
+ })()).sort().join(',');
1379
+ if (!Util.isEmpty(transformationString)) {
1380
+ resultArray.push(transformationString);
1381
+ }
1382
+ return Util.compact(resultArray).join('/');
1383
+ };
1384
+
1385
+
1386
+ /**
1387
+ * Provide a list of all the valid transformation option names
1388
+ * @function Transformation#listNames
1389
+ * @private
1390
+ * @return {Array<string>} a array of all the valid option names
1391
+ */
1392
+
1393
+ TransformationBase.prototype.listNames = function() {
1394
+ return this.methods;
1395
+ };
1396
+
1397
+
1398
+ /**
1399
+ * Returns attributes for an HTML tag.
1400
+ * @function Cloudinary.toHtmlAttributes
1401
+ * @return PlainObject
1402
+ */
1403
+
1404
+ TransformationBase.prototype.toHtmlAttributes = function() {
1405
+ var height, i, j, k, key, len, len1, options, ref, ref1, ref2, ref3, ref4, value, width;
1406
+ options = {};
1407
+ ref = this.otherOptions;
1408
+ for (key in ref) {
1409
+ value = ref[key];
1410
+ if (!Util.contains(this.PARAM_NAMES, key)) {
1411
+ options[key] = value;
1412
+ }
1413
+ }
1414
+ ref1 = Util.difference(this.keys(), this.PARAM_NAMES);
1415
+ for (i = 0, len = ref1.length; i < len; i++) {
1416
+ key = ref1[i];
1417
+ options[key] = this.get(key).value;
1418
+ }
1419
+ ref2 = this.keys();
1420
+ for (j = 0, len1 = ref2.length; j < len1; j++) {
1421
+ k = ref2[j];
1422
+ if (/^html_/.exec(k)) {
1423
+ options[k.substr(5)] = this.getValue(k);
1424
+ }
1425
+ }
1426
+ if (!(this.hasLayer() || this.getValue("angle") || Util.contains(["fit", "limit", "lfill"], this.getValue("crop")))) {
1427
+ width = (ref3 = this.get("width")) != null ? ref3.origValue : void 0;
1428
+ height = (ref4 = this.get("height")) != null ? ref4.origValue : void 0;
1429
+ if (parseFloat(width) >= 1.0) {
1430
+ if (options['width'] == null) {
1431
+ options['width'] = width;
1432
+ }
1433
+ }
1434
+ if (parseFloat(height) >= 1.0) {
1435
+ if (options['height'] == null) {
1436
+ options['height'] = height;
1437
+ }
1438
+ }
1439
+ }
1440
+ return options;
1441
+ };
1442
+
1443
+ TransformationBase.prototype.isValidParamName = function(name) {
1444
+ return this.methods.indexOf(Util.camelCase(name)) >= 0;
1445
+ };
1446
+
1447
+
1448
+ /**
1449
+ * Delegate to the parent (up the call chain) to produce HTML
1450
+ * @function Transformation#toHtml
1451
+ * @return {string} HTML representation of the parent if possible.
1452
+ * @example
1453
+ * tag = cloudinary.ImageTag.new("sample", {cloud_name: "demo"})
1454
+ * // ImageTag {name: "img", publicId: "sample"}
1455
+ * tag.toHtml()
1456
+ * // <img src="http://res.cloudinary.com/demo/image/upload/sample">
1457
+ * tag.transformation().crop("fit").width(300).toHtml()
1458
+ * // <img src="http://res.cloudinary.com/demo/image/upload/c_fit,w_300/sample">
1459
+ */
1460
+
1461
+ TransformationBase.prototype.toHtml = function() {
1462
+ var ref;
1463
+ return (ref = this.getParent()) != null ? typeof ref.toHtml === "function" ? ref.toHtml() : void 0 : void 0;
1464
+ };
1465
+
1466
+ TransformationBase.prototype.toString = function() {
1467
+ return this.serialize();
1468
+ };
1469
+
1470
+ return TransformationBase;
1471
+
1472
+ })();
1473
+ return Transformation = (function(superClass) {
1474
+ extend(Transformation, superClass);
1475
+
1476
+
1477
+ /**
1478
+ * Represents a single transformation.
1479
+ * @class Transformation
1480
+ * @example
1481
+ * t = new cloudinary.Transformation();
1482
+ * t.angle(20).crop("scale").width("auto");
1483
+ *
1484
+ * // or
1485
+ *
1486
+ * t = new cloudinary.Transformation( {angle: 20, crop: "scale", width: "auto"});
1487
+ */
1488
+
1489
+ function Transformation(options) {
1490
+ if (options == null) {
1491
+ options = {};
1492
+ }
1493
+ Transformation.__super__.constructor.call(this, options);
1494
+ }
1495
+
1496
+
1497
+ /**
1498
+ * Convenience constructor
1499
+ * @param {Object} options
1500
+ * @return {Transformation}
1501
+ * @example cl = cloudinary.Transformation.new( {angle: 20, crop: "scale", width: "auto"})
1502
+ */
1503
+
1504
+ Transformation["new"] = function(args) {
1505
+ return new Transformation(args);
1506
+ };
1507
+
1508
+
1509
+ /*
1510
+ Transformation Parameters
1511
+ */
1512
+
1513
+ Transformation.prototype.angle = function(value) {
1514
+ return this.arrayParam(value, "angle", "a", ".");
1515
+ };
1516
+
1517
+ Transformation.prototype.audioCodec = function(value) {
1518
+ return this.param(value, "audio_codec", "ac");
1519
+ };
1520
+
1521
+ Transformation.prototype.audioFrequency = function(value) {
1522
+ return this.param(value, "audio_frequency", "af");
1523
+ };
1524
+
1525
+ Transformation.prototype.aspectRatio = function(value) {
1526
+ return this.param(value, "aspect_ratio", "ar");
1527
+ };
1528
+
1529
+ Transformation.prototype.background = function(value) {
1530
+ return this.param(value, "background", "b", Param.norm_color);
1531
+ };
1532
+
1533
+ Transformation.prototype.bitRate = function(value) {
1534
+ return this.param(value, "bit_rate", "br");
1535
+ };
1536
+
1537
+ Transformation.prototype.border = function(value) {
1538
+ return this.param(value, "border", "bo", function(border) {
1539
+ if (Util.isPlainObject(border)) {
1540
+ border = Util.assign({}, {
1541
+ color: "black",
1542
+ width: 2
1543
+ }, border);
1544
+ return border.width + "px_solid_" + (Param.norm_color(border.color));
1545
+ } else {
1546
+ return border;
1547
+ }
1548
+ });
1549
+ };
1550
+
1551
+ Transformation.prototype.color = function(value) {
1552
+ return this.param(value, "color", "co", Param.norm_color);
1553
+ };
1554
+
1555
+ Transformation.prototype.colorSpace = function(value) {
1556
+ return this.param(value, "color_space", "cs");
1557
+ };
1558
+
1559
+ Transformation.prototype.crop = function(value) {
1560
+ return this.param(value, "crop", "c");
1561
+ };
1562
+
1563
+ Transformation.prototype.defaultImage = function(value) {
1564
+ return this.param(value, "default_image", "d");
1565
+ };
1566
+
1567
+ Transformation.prototype.delay = function(value) {
1568
+ return this.param(value, "delay", "l");
1569
+ };
1570
+
1571
+ Transformation.prototype.density = function(value) {
1572
+ return this.param(value, "density", "dn");
1573
+ };
1574
+
1575
+ Transformation.prototype.duration = function(value) {
1576
+ return this.rangeParam(value, "duration", "du");
1577
+ };
1578
+
1579
+ Transformation.prototype.dpr = function(value) {
1580
+ return this.param(value, "dpr", "dpr", function(dpr) {
1581
+ dpr = dpr.toString();
1582
+ if (dpr === "auto") {
1583
+ return "1.0";
1584
+ } else if (dpr != null ? dpr.match(/^\d+$/) : void 0) {
1585
+ return dpr + ".0";
1586
+ } else {
1587
+ return dpr;
1588
+ }
1589
+ });
1590
+ };
1591
+
1592
+ Transformation.prototype.effect = function(value) {
1593
+ return this.arrayParam(value, "effect", "e", ":");
1594
+ };
1595
+
1596
+ Transformation.prototype.endOffset = function(value) {
1597
+ return this.rangeParam(value, "end_offset", "eo");
1598
+ };
1599
+
1600
+ Transformation.prototype.fallbackContent = function(value) {
1601
+ return this.param(value, "fallback_content");
1602
+ };
1603
+
1604
+ Transformation.prototype.fetchFormat = function(value) {
1605
+ return this.param(value, "fetch_format", "f");
1606
+ };
1607
+
1608
+ Transformation.prototype.format = function(value) {
1609
+ return this.param(value, "format");
1610
+ };
1611
+
1612
+ Transformation.prototype.flags = function(value) {
1613
+ return this.arrayParam(value, "flags", "fl", ".");
1614
+ };
1615
+
1616
+ Transformation.prototype.gravity = function(value) {
1617
+ return this.param(value, "gravity", "g");
1618
+ };
1619
+
1620
+ Transformation.prototype.height = function(value) {
1621
+ return this.param(value, "height", "h", (function(_this) {
1622
+ return function() {
1623
+ if (_this.getValue("crop") || _this.getValue("overlay") || _this.getValue("underlay")) {
1624
+ return value;
1625
+ } else {
1626
+ return null;
1627
+ }
1628
+ };
1629
+ })(this));
1630
+ };
1631
+
1632
+ Transformation.prototype.htmlHeight = function(value) {
1633
+ return this.param(value, "html_height");
1634
+ };
1635
+
1636
+ Transformation.prototype.htmlWidth = function(value) {
1637
+ return this.param(value, "html_width");
1638
+ };
1639
+
1640
+ Transformation.prototype.offset = function(value) {
1641
+ var end_o, ref, start_o;
1642
+ ref = Util.isFunction(value != null ? value.split : void 0) ? value.split('..') : Util.isArray(value) ? value : [null, null], start_o = ref[0], end_o = ref[1];
1643
+ if (start_o != null) {
1644
+ this.startOffset(start_o);
1645
+ }
1646
+ if (end_o != null) {
1647
+ return this.endOffset(end_o);
1648
+ }
1649
+ };
1650
+
1651
+ Transformation.prototype.opacity = function(value) {
1652
+ return this.param(value, "opacity", "o");
1653
+ };
1654
+
1655
+ Transformation.prototype.overlay = function(value) {
1656
+ return this.param(value, "overlay", "l");
1657
+ };
1658
+
1659
+ Transformation.prototype.page = function(value) {
1660
+ return this.param(value, "page", "pg");
1661
+ };
1662
+
1663
+ Transformation.prototype.poster = function(value) {
1664
+ return this.param(value, "poster");
1665
+ };
1666
+
1667
+ Transformation.prototype.prefix = function(value) {
1668
+ return this.param(value, "prefix", "p");
1669
+ };
1670
+
1671
+ Transformation.prototype.quality = function(value) {
1672
+ return this.param(value, "quality", "q");
1673
+ };
1674
+
1675
+ Transformation.prototype.radius = function(value) {
1676
+ return this.param(value, "radius", "r");
1677
+ };
1678
+
1679
+ Transformation.prototype.rawTransformation = function(value) {
1680
+ return this.rawParam(value, "raw_transformation");
1681
+ };
1682
+
1683
+ Transformation.prototype.size = function(value) {
1684
+ var height, ref, width;
1685
+ if (Util.isFunction(value != null ? value.split : void 0)) {
1686
+ ref = value.split('x'), width = ref[0], height = ref[1];
1687
+ this.width(width);
1688
+ return this.height(height);
1689
+ }
1690
+ };
1691
+
1692
+ Transformation.prototype.sourceTypes = function(value) {
1693
+ return this.param(value, "source_types");
1694
+ };
1695
+
1696
+ Transformation.prototype.sourceTransformation = function(value) {
1697
+ return this.param(value, "source_transformation");
1698
+ };
1699
+
1700
+ Transformation.prototype.startOffset = function(value) {
1701
+ return this.rangeParam(value, "start_offset", "so");
1702
+ };
1703
+
1704
+ Transformation.prototype.transformation = function(value) {
1705
+ return this.transformationParam(value, "transformation", "t");
1706
+ };
1707
+
1708
+ Transformation.prototype.underlay = function(value) {
1709
+ return this.param(value, "underlay", "u");
1710
+ };
1711
+
1712
+ Transformation.prototype.videoCodec = function(value) {
1713
+ return this.param(value, "video_codec", "vc", Param.process_video_params);
1714
+ };
1715
+
1716
+ Transformation.prototype.videoSampling = function(value) {
1717
+ return this.param(value, "video_sampling", "vs");
1718
+ };
1719
+
1720
+ Transformation.prototype.width = function(value) {
1721
+ return this.param(value, "width", "w", (function(_this) {
1722
+ return function() {
1723
+ if (_this.getValue("crop") || _this.getValue("overlay") || _this.getValue("underlay")) {
1724
+ return value;
1725
+ } else {
1726
+ return null;
1727
+ }
1728
+ };
1729
+ })(this));
1730
+ };
1731
+
1732
+ Transformation.prototype.x = function(value) {
1733
+ return this.param(value, "x", "x");
1734
+ };
1735
+
1736
+ Transformation.prototype.y = function(value) {
1737
+ return this.param(value, "y", "y");
1738
+ };
1739
+
1740
+ Transformation.prototype.zoom = function(value) {
1741
+ return this.param(value, "zoom", "z");
1742
+ };
1743
+
1744
+ return Transformation;
1745
+
1746
+ })(TransformationBase);
1747
+ });
1748
+
1749
+ }).call(this);
1750
+
1751
+ (function() {
1752
+ (function(root, factory) {
1753
+ if ((typeof define === 'function') && define.amd) {
1754
+ return define('tags/htmltag',['transformation', 'util'], factory);
1755
+ } else if (typeof exports === 'object') {
1756
+ return module.exports = factory(require('transformation'), require('util'));
1757
+ } else {
1758
+ root.cloudinary || (root.cloudinary = {});
1759
+ return root.cloudinary.HtmlTag = factory(root.cloudinary.Transformation, root.cloudinary.Util);
1760
+ }
1761
+ })(this, function(Transformation, Util) {
1762
+ var HtmlTag;
1763
+ return HtmlTag = (function() {
1764
+
1765
+ /**
1766
+ * Represents an HTML (DOM) tag
1767
+ * @constructor HtmlTag
1768
+ * @param {string} name - the name of the tag
1769
+ * @param {string} [publicId]
1770
+ * @param {Object} options
1771
+ * @example tag = new HtmlTag( 'div', { 'width': 10})
1772
+ */
1773
+ var toAttribute;
1774
+
1775
+ function HtmlTag(name, publicId, options) {
1776
+ var transformation;
1777
+ this.name = name;
1778
+ this.publicId = publicId;
1779
+ if (options == null) {
1780
+ if (Util.isPlainObject(publicId)) {
1781
+ options = publicId;
1782
+ this.publicId = void 0;
1783
+ } else {
1784
+ options = {};
1785
+ }
1786
+ }
1787
+ transformation = new Transformation(options);
1788
+ transformation.setParent(this);
1789
+ this.transformation = function() {
1790
+ return transformation;
1791
+ };
1792
+ }
1793
+
1794
+
1795
+ /**
1796
+ * Convenience constructor
1797
+ * Creates a new instance of an HTML (DOM) tag
1798
+ * @function HtmlTag.new
1799
+ * @param {string} name - the name of the tag
1800
+ * @param {string} [publicId]
1801
+ * @param {Object} options
1802
+ * @return {HtmlTag}
1803
+ * @example tag = HtmlTag.new( 'div', { 'width': 10})
1804
+ */
1805
+
1806
+ HtmlTag["new"] = function(name, publicId, options) {
1807
+ return new this(name, publicId, options);
1808
+ };
1809
+
1810
+
1811
+ /**
1812
+ * Represent the given key and value as an HTML attribute.
1813
+ * @function HtmlTag#toAttribute
1814
+ * @protected
1815
+ * @param {string} key - attribute name
1816
+ * @param {*|boolean} value - the value of the attribute. If the value is boolean `true`, return the key only.
1817
+ * @returns {string} the attribute
1818
+ *
1819
+ */
1820
+
1821
+ toAttribute = function(key, value) {
1822
+ if (!value) {
1823
+ return void 0;
1824
+ } else if (value === true) {
1825
+ return key;
1826
+ } else {
1827
+ return key + "=\"" + value + "\"";
1828
+ }
1829
+ };
1830
+
1831
+
1832
+ /**
1833
+ * combine key and value from the `attr` to generate an HTML tag attributes string.
1834
+ * `Transformation::toHtmlTagOptions` is used to filter out transformation and configuration keys.
1835
+ * @protected
1836
+ * @param {Object} attrs
1837
+ * @return {string} the attributes in the format `'key1="value1" key2="value2"'`
1838
+ * @ignore
1839
+ */
1840
+
1841
+ HtmlTag.prototype.htmlAttrs = function(attrs) {
1842
+ var key, pairs, value;
1843
+ return pairs = ((function() {
1844
+ var results;
1845
+ results = [];
1846
+ for (key in attrs) {
1847
+ value = attrs[key];
1848
+ if (value) {
1849
+ results.push(toAttribute(key, value));
1850
+ }
1851
+ }
1852
+ return results;
1853
+ })()).sort().join(' ');
1854
+ };
1855
+
1856
+
1857
+ /**
1858
+ * Get all options related to this tag.
1859
+ * @function HtmlTag#getOptions
1860
+ * @returns {Object} the options
1861
+ *
1862
+ */
1863
+
1864
+ HtmlTag.prototype.getOptions = function() {
1865
+ return this.transformation().toOptions();
1866
+ };
1867
+
1868
+
1869
+ /**
1870
+ * Get the value of option `name`
1871
+ * @function HtmlTag#getOption
1872
+ * @param {string} name - the name of the option
1873
+ * @returns {*} Returns the value of the option
1874
+ *
1875
+ */
1876
+
1877
+ HtmlTag.prototype.getOption = function(name) {
1878
+ return this.transformation().getValue(name);
1879
+ };
1880
+
1881
+
1882
+ /**
1883
+ * Get the attributes of the tag.
1884
+ * @function HtmlTag#attributes
1885
+ * @returns {Object} attributes
1886
+ */
1887
+
1888
+ HtmlTag.prototype.attributes = function() {
1889
+ return this.transformation().toHtmlAttributes();
1890
+ };
1891
+
1892
+
1893
+ /**
1894
+ * Set a tag attribute named `name` to `value`
1895
+ * @function HtmlTag#setAttr
1896
+ * @param {string} name - the name of the attribute
1897
+ * @param {string} value - the value of the attribute
1898
+ */
1899
+
1900
+ HtmlTag.prototype.setAttr = function(name, value) {
1901
+ this.transformation().set("html_" + name, value);
1902
+ return this;
1903
+ };
1904
+
1905
+
1906
+ /**
1907
+ * Get the value of the tag attribute `name`
1908
+ * @function HtmlTag#getAttr
1909
+ * @param {string} name - the name of the attribute
1910
+ * @returns {*}
1911
+ */
1912
+
1913
+ HtmlTag.prototype.getAttr = function(name) {
1914
+ return this.attributes()["html_" + name] || this.attributes()[name];
1915
+ };
1916
+
1917
+
1918
+ /**
1919
+ * Remove the tag attributed named `name`
1920
+ * @function HtmlTag#removeAttr
1921
+ * @param {string} name - the name of the attribute
1922
+ * @returns {*}
1923
+ */
1924
+
1925
+ HtmlTag.prototype.removeAttr = function(name) {
1926
+ var ref;
1927
+ return (ref = this.transformation().remove("html_" + name)) != null ? ref : this.transformation().remove(name);
1928
+ };
1929
+
1930
+
1931
+ /**
1932
+ * @function HtmlTag#content
1933
+ * @protected
1934
+ * @ignore
1935
+ */
1936
+
1937
+ HtmlTag.prototype.content = function() {
1938
+ return "";
1939
+ };
1940
+
1941
+
1942
+ /**
1943
+ * @function HtmlTag#openTag
1944
+ * @protected
1945
+ * @ignore
1946
+ */
1947
+
1948
+ HtmlTag.prototype.openTag = function() {
1949
+ return "<" + this.name + " " + (this.htmlAttrs(this.attributes())) + ">";
1950
+ };
1951
+
1952
+
1953
+ /**
1954
+ * @function HtmlTag#closeTag
1955
+ * @protected
1956
+ * @ignore
1957
+ */
1958
+
1959
+ HtmlTag.prototype.closeTag = function() {
1960
+ return "</" + this.name + ">";
1961
+ };
1962
+
1963
+
1964
+ /**
1965
+ * Generates an HTML representation of the tag.
1966
+ * @function HtmlTag#toHtml
1967
+ * @returns {string} Returns HTML in string format
1968
+ */
1969
+
1970
+ HtmlTag.prototype.toHtml = function() {
1971
+ return this.openTag() + this.content() + this.closeTag();
1972
+ };
1973
+
1974
+
1975
+ /**
1976
+ * Creates a DOM object representing the tag.
1977
+ * @function HtmlTag#toDOM
1978
+ * @returns {Element}
1979
+ */
1980
+
1981
+ HtmlTag.prototype.toDOM = function() {
1982
+ var element, name, ref, value;
1983
+ if (!Util.isFunction(typeof document !== "undefined" && document !== null ? document.createElement : void 0)) {
1984
+ throw "Can't create DOM if document is not present!";
1985
+ }
1986
+ element = document.createElement(this.name);
1987
+ ref = this.attributes();
1988
+ for (name in ref) {
1989
+ value = ref[name];
1990
+ element[name] = value;
1991
+ }
1992
+ return element;
1993
+ };
1994
+
1995
+ return HtmlTag;
1996
+
1997
+ })();
1998
+ });
1999
+
2000
+ }).call(this);
2001
+
2002
+ (function() {
2003
+ var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
2004
+ hasProp = {}.hasOwnProperty;
2005
+
2006
+ (function(root, factory) {
2007
+ if ((typeof define === 'function') && define.amd) {
2008
+ return define('tags/videotag',['tags/htmltag', 'util', 'cloudinary', 'require'], factory);
2009
+ } else if (typeof exports === 'object') {
2010
+ return module.exports = factory(require('tags/htmltag'), require('util'), require('cloudinary'), require);
2011
+ } else {
2012
+ root.cloudinary || (root.cloudinary = {});
2013
+ return root.cloudinary.VideoTag = factory(root.cloudinary.HtmlTag, root.cloudinary.Util, root.cloudinary.Cloudinary, function() {
2014
+ return root.cloudinary.Cloudinary;
2015
+ });
2016
+ }
2017
+ })(this, function(HtmlTag, Util, Cloudinary, require) {
2018
+ var VideoTag;
2019
+ return VideoTag = (function(superClass) {
2020
+ var DEFAULT_POSTER_OPTIONS, DEFAULT_VIDEO_SOURCE_TYPES, VIDEO_TAG_PARAMS;
2021
+
2022
+ extend(VideoTag, superClass);
2023
+
2024
+ VIDEO_TAG_PARAMS = ['source_types', 'source_transformation', 'fallback_content', 'poster'];
2025
+
2026
+ DEFAULT_VIDEO_SOURCE_TYPES = ['webm', 'mp4', 'ogv'];
2027
+
2028
+ DEFAULT_POSTER_OPTIONS = {
2029
+ format: 'jpg',
2030
+ resource_type: 'video'
2031
+ };
2032
+
2033
+
2034
+ /**
2035
+ * Creates an HTML (DOM) Video tag using Cloudinary as the source.
2036
+ * @constructor VideoTag
2037
+ * @extends HtmlTag
2038
+ * @param {string} [publicId]
2039
+ * @param {Object} [options]
2040
+ */
2041
+
2042
+ function VideoTag(publicId, options) {
2043
+ if (options == null) {
2044
+ options = {};
2045
+ }
2046
+ Cloudinary || (Cloudinary = require('cloudinary'));
2047
+ options = Util.defaults({}, options, Cloudinary.DEFAULT_VIDEO_PARAMS);
2048
+ VideoTag.__super__.constructor.call(this, "video", publicId.replace(/\.(mp4|ogv|webm)$/, ''), options);
2049
+ }
2050
+
2051
+
2052
+ /**
2053
+ * Set the transformation to apply on each source
2054
+ * @function VideoTag#setSourceTransformation
2055
+ * @param {Object} an object with pairs of source type and source transformation
2056
+ * @returns {VideoTag} Returns this instance for chaining purposes.
2057
+ */
2058
+
2059
+ VideoTag.prototype.setSourceTransformation = function(value) {
2060
+ this.transformation().sourceTransformation(value);
2061
+ return this;
2062
+ };
2063
+
2064
+
2065
+ /**
2066
+ * Set the source types to include in the video tag
2067
+ * @function VideoTag#setSourceTypes
2068
+ * @param {Array<string>} an array of source types
2069
+ * @returns {VideoTag} Returns this instance for chaining purposes.
2070
+ */
2071
+
2072
+ VideoTag.prototype.setSourceTypes = function(value) {
2073
+ this.transformation().sourceTypes(value);
2074
+ return this;
2075
+ };
2076
+
2077
+
2078
+ /**
2079
+ * Set the poster to be used in the video tag
2080
+ * @function VideoTag#setPoster
2081
+ * @param {string|Object} value
2082
+ * - string: a URL to use for the poster
2083
+ * - Object: transformation parameters to apply to the poster. May optionally include a public_id to use instead of the video public_id.
2084
+ * @returns {VideoTag} Returns this instance for chaining purposes.
2085
+ */
2086
+
2087
+ VideoTag.prototype.setPoster = function(value) {
2088
+ this.transformation().poster(value);
2089
+ return this;
2090
+ };
2091
+
2092
+
2093
+ /**
2094
+ * Set the content to use as fallback in the video tag
2095
+ * @function VideoTag#setFallbackContent
2096
+ * @param {string} value - the content to use, in HTML format
2097
+ * @returns {VideoTag} Returns this instance for chaining purposes.
2098
+ */
2099
+
2100
+ VideoTag.prototype.setFallbackContent = function(value) {
2101
+ this.transformation().fallbackContent(value);
2102
+ return this;
2103
+ };
2104
+
2105
+ VideoTag.prototype.content = function() {
2106
+ var cld, fallback, innerTags, mimeType, sourceTransformation, sourceTypes, src, srcType, transformation, videoType;
2107
+ sourceTypes = this.transformation().getValue('source_types');
2108
+ sourceTransformation = this.transformation().getValue('source_transformation');
2109
+ fallback = this.transformation().getValue('fallback_content');
2110
+ Cloudinary || (Cloudinary = require('cloudinary'));
2111
+ if (Util.isArray(sourceTypes)) {
2112
+ cld = new Cloudinary(this.getOptions());
2113
+ innerTags = (function() {
2114
+ var i, len, results;
2115
+ results = [];
2116
+ for (i = 0, len = sourceTypes.length; i < len; i++) {
2117
+ srcType = sourceTypes[i];
2118
+ transformation = sourceTransformation[srcType] || {};
2119
+ src = cld.url("" + this.publicId, Util.defaults({}, transformation, {
2120
+ resource_type: 'video',
2121
+ format: srcType
2122
+ }));
2123
+ videoType = srcType === 'ogv' ? 'ogg' : srcType;
2124
+ mimeType = 'video/' + videoType;
2125
+ results.push("<source " + (this.htmlAttrs({
2126
+ src: src,
2127
+ type: mimeType
2128
+ })) + ">");
2129
+ }
2130
+ return results;
2131
+ }).call(this);
2132
+ } else {
2133
+ innerTags = [];
2134
+ }
2135
+ return innerTags.join('') + fallback;
2136
+ };
2137
+
2138
+ VideoTag.prototype.attributes = function() {
2139
+ var a, attr, defaults, i, len, poster, ref, ref1, sourceTypes;
2140
+ Cloudinary || (Cloudinary = require('cloudinary'));
2141
+ sourceTypes = this.getOption('source_types');
2142
+ poster = (ref = this.getOption('poster')) != null ? ref : {};
2143
+ if (Util.isPlainObject(poster)) {
2144
+ defaults = poster.public_id != null ? Cloudinary.DEFAULT_IMAGE_PARAMS : DEFAULT_POSTER_OPTIONS;
2145
+ poster = new Cloudinary(this.getOptions()).url((ref1 = poster.public_id) != null ? ref1 : this.publicId, Util.defaults({}, poster, defaults));
2146
+ }
2147
+ attr = VideoTag.__super__.attributes.call(this) || [];
2148
+ for (i = 0, len = attr.length; i < len; i++) {
2149
+ a = attr[i];
2150
+ if (!Util.contains(VIDEO_TAG_PARAMS)) {
2151
+ attr = a;
2152
+ }
2153
+ }
2154
+ if (!Util.isArray(sourceTypes)) {
2155
+ attr["src"] = new Cloudinary(this.getOptions()).url(this.publicId, {
2156
+ resource_type: 'video',
2157
+ format: sourceTypes
2158
+ });
2159
+ }
2160
+ if (poster != null) {
2161
+ attr["poster"] = poster;
2162
+ }
2163
+ return attr;
2164
+ };
2165
+
2166
+ return VideoTag;
2167
+
2168
+ })(HtmlTag);
2169
+ });
2170
+
2171
+ }).call(this);
2172
+
2173
+ (function() {
2174
+ (function(root, factory) {
2175
+ var require;
2176
+ if ((typeof define === 'function') && define.amd) {
2177
+ return define('cloudinary',['utf8_encode', 'crc32', 'util', 'transformation', 'configuration', 'tags/imagetag', 'tags/videotag', 'require'], factory);
2178
+ } else if (typeof exports === 'object') {
2179
+ return module.exports = factory(require('utf8_encode'), require('crc32'), require('util'), require('transformation'), require('configuration'), require('tags/imagetag'), require('tags/videotag'), require);
2180
+ } else {
2181
+ root.cloudinary || (root.cloudinary = {});
2182
+
2183
+ /**
2184
+ * Resolves circular dependency
2185
+ * @private
2186
+ */
2187
+ require = function(name) {
2188
+ switch (name) {
2189
+ case 'tags/imagetag':
2190
+ return root.cloudinary.ImageTag;
2191
+ case 'tags/videotag':
2192
+ return root.cloudinary.VideoTag;
2193
+ }
2194
+ };
2195
+ return root.cloudinary.Cloudinary = factory(root.cloudinary.utf8_encode, root.cloudinary.crc32, root.cloudinary.Util, root.cloudinary.Transformation, root.cloudinary.Configuration, root.cloudinary.ImageTag, root.cloudinary.VideoTag, require);
2196
+ }
2197
+ })(this, function(utf8_encode, crc32, Util, Transformation, Configuration, ImageTag, VideoTag, require) {
2198
+
2199
+ /**
2200
+ * Main Cloudinary class
2201
+ */
2202
+ var Cloudinary;
2203
+ return Cloudinary = (function() {
2204
+ var AKAMAI_SHARED_CDN, CF_SHARED_CDN, DEFAULT_POSTER_OPTIONS, DEFAULT_VIDEO_SOURCE_TYPES, OLD_AKAMAI_SHARED_CDN, SHARED_CDN, VERSION, absolutize, applyBreakpoints, cdnSubdomainNumber, closestAbove, cloudinaryUrlPrefix, defaultBreakpoints, finalizeResourceType, parentWidth;
2205
+
2206
+ VERSION = "2.0.3";
2207
+
2208
+ CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
2209
+
2210
+ OLD_AKAMAI_SHARED_CDN = "cloudinary-a.akamaihd.net";
2211
+
2212
+ AKAMAI_SHARED_CDN = "res.cloudinary.com";
2213
+
2214
+ SHARED_CDN = AKAMAI_SHARED_CDN;
2215
+
2216
+ DEFAULT_POSTER_OPTIONS = {
2217
+ format: 'jpg',
2218
+ resource_type: 'video'
2219
+ };
2220
+
2221
+ DEFAULT_VIDEO_SOURCE_TYPES = ['webm', 'mp4', 'ogv'];
2222
+
2223
+
2224
+ /**
2225
+ * @const {Object} Cloudinary.DEFAULT_IMAGE_PARAMS
2226
+ * Defaults values for image parameters.
2227
+ *
2228
+ * (Previously defined using option_consume() )
2229
+ */
2230
+
2231
+ Cloudinary.DEFAULT_IMAGE_PARAMS = {
2232
+ resource_type: "image",
2233
+ transformation: [],
2234
+ type: 'upload'
2235
+ };
2236
+
2237
+
2238
+ /**
2239
+ * Defaults values for video parameters.
2240
+ * @const {Object} Cloudinary.DEFAULT_VIDEO_PARAMS
2241
+ * (Previously defined using option_consume() )
2242
+ */
2243
+
2244
+ Cloudinary.DEFAULT_VIDEO_PARAMS = {
2245
+ fallback_content: '',
2246
+ resource_type: "video",
2247
+ source_transformation: {},
2248
+ source_types: DEFAULT_VIDEO_SOURCE_TYPES,
2249
+ transformation: [],
2250
+ type: 'upload'
2251
+ };
2252
+
2253
+
2254
+ /**
2255
+ * Main Cloudinary class
2256
+ * @class Cloudinary
2257
+ * @param {Object} options - options to configure Cloudinary
2258
+ * @see Configuration for more details
2259
+ * @example
2260
+ *var cl = new cloudinary.Cloudinary( { cloud_name: "mycloud"});
2261
+ *var imgTag = cl.image("myPicID");
2262
+ */
2263
+
2264
+ function Cloudinary(options) {
2265
+ var configuration;
2266
+ this.devicePixelRatioCache = {};
2267
+ this.responsiveConfig = {};
2268
+ this.responsiveResizeInitialized = false;
2269
+ configuration = new cloudinary.Configuration(options);
2270
+ this.config = function(newConfig, newValue) {
2271
+ return configuration.config(newConfig, newValue);
2272
+ };
2273
+
2274
+ /**
2275
+ * Use \<meta\> tags in the document to configure this Cloudinary instance.
2276
+ * @return {Cloudinary} this for chaining
2277
+ */
2278
+ this.fromDocument = function() {
2279
+ configuration.fromDocument();
2280
+ return this;
2281
+ };
2282
+
2283
+ /**
2284
+ * Use environment variables to configure this Cloudinary instance.
2285
+ * @return {Cloudinary} this for chaining
2286
+ */
2287
+ this.fromEnvironment = function() {
2288
+ configuration.fromEnvironment();
2289
+ return this;
2290
+ };
2291
+
2292
+ /**
2293
+ * Initialize configuration.
2294
+ * @function Cloudinary#init
2295
+ * @see Configuration#init
2296
+ * @return {Cloudinary} this for chaining
2297
+ */
2298
+ this.init = function() {
2299
+ configuration.init();
2300
+ return this;
2301
+ };
2302
+ }
2303
+
2304
+
2305
+ /**
2306
+ * Convenience constructor
2307
+ * @param {Object} options
2308
+ * @return {Cloudinary}
2309
+ * @example cl = cloudinary.Cloudinary.new( { cloud_name: "mycloud"})
2310
+ */
2311
+
2312
+ Cloudinary["new"] = function(options) {
2313
+ return new this(options);
2314
+ };
2315
+
2316
+
2317
+ /**
2318
+ * Return the resource type and action type based on the given configuration
2319
+ * @function Cloudinary#finalizeResourceType
2320
+ * @param {Object|string} resourceType
2321
+ * @param {string} [type='upload']
2322
+ * @param {string} [urlSuffix]
2323
+ * @param {boolean} [useRootPath]
2324
+ * @param {boolean} [shorten]
2325
+ * @returns {string} resource_type/type
2326
+ * @ignore
2327
+ */
2328
+
2329
+ finalizeResourceType = function(resourceType, type, urlSuffix, useRootPath, shorten) {
2330
+ var options;
2331
+ if (Util.isPlainObject(resourceType)) {
2332
+ options = resourceType;
2333
+ resourceType = options.resource_type;
2334
+ type = options.type;
2335
+ urlSuffix = options.url_suffix;
2336
+ useRootPath = options.use_root_path;
2337
+ shorten = options.shorten;
2338
+ }
2339
+ if (type == null) {
2340
+ type = 'upload';
2341
+ }
2342
+ if (urlSuffix != null) {
2343
+ if (resourceType === 'image' && type === 'upload') {
2344
+ resourceType = "images";
2345
+ type = null;
2346
+ } else if (resourceType === 'raw' && type === 'upload') {
2347
+ resourceType = 'files';
2348
+ type = null;
2349
+ } else {
2350
+ throw new Error("URL Suffix only supported for image/upload and raw/upload");
2351
+ }
2352
+ }
2353
+ if (useRootPath) {
2354
+ if (resourceType === 'image' && type === 'upload' || resourceType === "images") {
2355
+ resourceType = null;
2356
+ type = null;
2357
+ } else {
2358
+ throw new Error("Root path only supported for image/upload");
2359
+ }
2360
+ }
2361
+ if (shorten && resourceType === 'image' && type === 'upload') {
2362
+ resourceType = 'iu';
2363
+ type = null;
2364
+ }
2365
+ return [resourceType, type].join("/");
2366
+ };
2367
+
2368
+ absolutize = function(url) {
2369
+ var prefix;
2370
+ if (!url.match(/^https?:\//)) {
2371
+ prefix = document.location.protocol + '//' + document.location.host;
2372
+ if (url[0] === '?') {
2373
+ prefix += document.location.pathname;
2374
+ } else if (url[0] !== '/') {
2375
+ prefix += document.location.pathname.replace(/\/[^\/]*$/, '/');
2376
+ }
2377
+ url = prefix + url;
2378
+ }
2379
+ return url;
2380
+ };
2381
+
2382
+
2383
+ /**
2384
+ * Generate an resource URL.
2385
+ * @function Cloudinary#url
2386
+ * @param {string} publicId - the public ID of the resource
2387
+ * @param {Object} [options] - options for the tag and transformations, possible values include all {@link Transformation} parameters
2388
+ * and {@link Configuration} parameters
2389
+ * @param {string} [options.type='upload'] - the classification of the resource
2390
+ * @param {Object} [options.resource_type='image'] - the type of the resource
2391
+ * @return {string} The resource URL
2392
+ */
2393
+
2394
+ Cloudinary.prototype.url = function(publicId, options) {
2395
+ var prefix, ref, resourceTypeAndType, transformation, transformationString, url, version;
2396
+ if (options == null) {
2397
+ options = {};
2398
+ }
2399
+ if (!publicId) {
2400
+ return publicId;
2401
+ }
2402
+ options = Util.defaults({}, options, this.config(), Cloudinary.DEFAULT_IMAGE_PARAMS);
2403
+ if (options.type === 'fetch') {
2404
+ options.fetch_format = options.fetch_format || options.format;
2405
+ publicId = absolutize(publicId);
2406
+ }
2407
+ transformation = new Transformation(options);
2408
+ transformationString = transformation.serialize();
2409
+ if (!options.cloud_name) {
2410
+ throw 'Unknown cloud_name';
2411
+ }
2412
+ if (options.url_suffix && !options.private_cdn) {
2413
+ throw 'URL Suffix only supported in private CDN';
2414
+ }
2415
+ if (publicId.search('/') >= 0 && !publicId.match(/^v[0-9]+/) && !publicId.match(/^https?:\//) && !((ref = options.version) != null ? ref.toString() : void 0)) {
2416
+ options.version = 1;
2417
+ }
2418
+ if (publicId.match(/^https?:/)) {
2419
+ if (options.type === 'upload' || options.type === 'asset') {
2420
+ url = publicId;
2421
+ } else {
2422
+ publicId = encodeURIComponent(publicId).replace(/%3A/g, ':').replace(/%2F/g, '/');
2423
+ }
2424
+ } else {
2425
+ publicId = encodeURIComponent(decodeURIComponent(publicId)).replace(/%3A/g, ':').replace(/%2F/g, '/');
2426
+ if (options.url_suffix) {
2427
+ if (options.url_suffix.match(/[\.\/]/)) {
2428
+ throw 'url_suffix should not include . or /';
2429
+ }
2430
+ publicId = publicId + '/' + options.url_suffix;
2431
+ }
2432
+ if (options.format) {
2433
+ if (!options.trust_public_id) {
2434
+ publicId = publicId.replace(/\.(jpg|png|gif|webp)$/, '');
2435
+ }
2436
+ publicId = publicId + '.' + options.format;
2437
+ }
2438
+ }
2439
+ prefix = cloudinaryUrlPrefix(publicId, options);
2440
+ resourceTypeAndType = finalizeResourceType(options.resource_type, options.type, options.url_suffix, options.use_root_path, options.shorten);
2441
+ version = options.version ? 'v' + options.version : '';
2442
+ return url || Util.compact([prefix, resourceTypeAndType, transformationString, version, publicId]).join('/').replace(/([^:])\/+/g, '$1/');
2443
+ };
2444
+
2445
+
2446
+ /**
2447
+ * Generate an video resource URL.
2448
+ * @function Cloudinary#video_url
2449
+ * @param {string} publicId - the public ID of the resource
2450
+ * @param {Object} [options] - options for the tag and transformations, possible values include all {@link Transformation} parameters
2451
+ * and {@link Configuration} parameters
2452
+ * @param {string} [options.type='upload'] - the classification of the resource
2453
+ * @return {string} The video URL
2454
+ */
2455
+
2456
+ Cloudinary.prototype.video_url = function(publicId, options) {
2457
+ options = Util.assign({
2458
+ resource_type: 'video'
2459
+ }, options);
2460
+ return this.url(publicId, options);
2461
+ };
2462
+
2463
+
2464
+ /**
2465
+ * Generate an video thumbnail URL.
2466
+ * @function Cloudinary#video_thumbnail_url
2467
+ * @param {string} publicId - the public ID of the resource
2468
+ * @param {Object} [options] - options for the tag and transformations, possible values include all {@link Transformation} parameters
2469
+ * and {@link Configuration} parameters
2470
+ * @param {string} [options.type='upload'] - the classification of the resource
2471
+ * @return {string} The video thumbnail URL
2472
+ */
2473
+
2474
+ Cloudinary.prototype.video_thumbnail_url = function(publicId, options) {
2475
+ options = Util.assign({}, DEFAULT_POSTER_OPTIONS, options);
2476
+ return this.url(publicId, options);
2477
+ };
2478
+
2479
+
2480
+ /**
2481
+ * Generate a string representation of the provided transformation options.
2482
+ * @function Cloudinary#transformation_string
2483
+ * @param {Object} options - the transformation options
2484
+ * @returns {string} The transformation string
2485
+ */
2486
+
2487
+ Cloudinary.prototype.transformation_string = function(options) {
2488
+ return new Transformation(options).serialize();
2489
+ };
2490
+
2491
+
2492
+ /**
2493
+ * Generate an image tag.
2494
+ * @function Cloudinary#image
2495
+ * @param {string} publicId - the public ID of the image
2496
+ * @param {Object} [options] - options for the tag and transformations
2497
+ * @return {HTMLImageElement} an image tag element
2498
+ */
2499
+
2500
+ Cloudinary.prototype.image = function(publicId, options) {
2501
+ var img, tag_options;
2502
+ if (options == null) {
2503
+ options = {};
2504
+ }
2505
+ tag_options = Util.assign({
2506
+ src: ''
2507
+ }, options);
2508
+ img = this.imageTag(publicId, tag_options).toDOM();
2509
+ Util.setData(img, 'src-cache', this.url(publicId, options));
2510
+ this.cloudinary_update(img, options);
2511
+ return img;
2512
+ };
2513
+
2514
+
2515
+ /**
2516
+ * Creates a new ImageTag instance, configured using this own's configuration.
2517
+ * @function Cloudinary#imageTag
2518
+ * @param {string} publicId - the public ID of the resource
2519
+ * @param {Object} options - additional options to pass to the new ImageTag instance
2520
+ * @return {ImageTag} An ImageTag that is attached (chained) to this Cloudinary instance
2521
+ */
2522
+
2523
+ Cloudinary.prototype.imageTag = function(publicId, options) {
2524
+ options = Util.defaults({}, options, this.config());
2525
+ ImageTag || (ImageTag = require('tags/imagetag'));
2526
+ return new ImageTag(publicId, options);
2527
+ };
2528
+
2529
+
2530
+ /**
2531
+ * Generate an image tag for the video thumbnail.
2532
+ * @function Cloudinary#video_thumbnail
2533
+ * @param {string} publicId - the public ID of the video
2534
+ * @param {Object} [options] - options for the tag and transformations
2535
+ * @return {HTMLImageElement} An image tag element
2536
+ */
2537
+
2538
+ Cloudinary.prototype.video_thumbnail = function(publicId, options) {
2539
+ return this.image(publicId, Util.merge({}, DEFAULT_POSTER_OPTIONS, options));
2540
+ };
2541
+
2542
+
2543
+ /**
2544
+ * @function Cloudinary#facebook_profile_image
2545
+ * @param {string} publicId - the public ID of the image
2546
+ * @param {Object} [options] - options for the tag and transformations
2547
+ * @return {HTMLImageElement} an image tag element
2548
+ */
2549
+
2550
+ Cloudinary.prototype.facebook_profile_image = function(publicId, options) {
2551
+ return this.image(publicId, Util.assign({
2552
+ type: 'facebook'
2553
+ }, options));
2554
+ };
2555
+
2556
+
2557
+ /**
2558
+ * @function Cloudinary#twitter_profile_image
2559
+ * @param {string} publicId - the public ID of the image
2560
+ * @param {Object} [options] - options for the tag and transformations
2561
+ * @return {HTMLImageElement} an image tag element
2562
+ */
2563
+
2564
+ Cloudinary.prototype.twitter_profile_image = function(publicId, options) {
2565
+ return this.image(publicId, Util.assign({
2566
+ type: 'twitter'
2567
+ }, options));
2568
+ };
2569
+
2570
+
2571
+ /**
2572
+ * @function Cloudinary#twitter_name_profile_image
2573
+ * @param {string} publicId - the public ID of the image
2574
+ * @param {Object} [options] - options for the tag and transformations
2575
+ * @return {HTMLImageElement} an image tag element
2576
+ */
2577
+
2578
+ Cloudinary.prototype.twitter_name_profile_image = function(publicId, options) {
2579
+ return this.image(publicId, Util.assign({
2580
+ type: 'twitter_name'
2581
+ }, options));
2582
+ };
2583
+
2584
+
2585
+ /**
2586
+ * @function Cloudinary#gravatar_image
2587
+ * @param {string} publicId - the public ID of the image
2588
+ * @param {Object} [options] - options for the tag and transformations
2589
+ * @return {HTMLImageElement} an image tag element
2590
+ */
2591
+
2592
+ Cloudinary.prototype.gravatar_image = function(publicId, options) {
2593
+ return this.image(publicId, Util.assign({
2594
+ type: 'gravatar'
2595
+ }, options));
2596
+ };
2597
+
2598
+
2599
+ /**
2600
+ * @function Cloudinary#fetch_image
2601
+ * @param {string} publicId - the public ID of the image
2602
+ * @param {Object} [options] - options for the tag and transformations
2603
+ * @return {HTMLImageElement} an image tag element
2604
+ */
2605
+
2606
+ Cloudinary.prototype.fetch_image = function(publicId, options) {
2607
+ return this.image(publicId, Util.assign({
2608
+ type: 'fetch'
2609
+ }, options));
2610
+ };
2611
+
2612
+
2613
+ /**
2614
+ * @function Cloudinary#video
2615
+ * @param {string} publicId - the public ID of the image
2616
+ * @param {Object} [options] - options for the tag and transformations
2617
+ * @return {HTMLImageElement} an image tag element
2618
+ */
2619
+
2620
+ Cloudinary.prototype.video = function(publicId, options) {
2621
+ if (options == null) {
2622
+ options = {};
2623
+ }
2624
+ return this.videoTag(publicId, options).toHtml();
2625
+ };
2626
+
2627
+
2628
+ /**
2629
+ * Creates a new VideoTag instance, configured using this own's configuration.
2630
+ * @function Cloudinary#videoTag
2631
+ * @param {string} publicId - the public ID of the resource
2632
+ * @param {Object} options - additional options to pass to the new VideoTag instance
2633
+ * @return {VideoTag} A VideoTag that is attached (chained) to this Cloudinary instance
2634
+ */
2635
+
2636
+ Cloudinary.prototype.videoTag = function(publicId, options) {
2637
+ VideoTag || (VideoTag = require('tags/videotag'));
2638
+ options = Util.defaults({}, options, this.config());
2639
+ return new VideoTag(publicId, options);
2640
+ };
2641
+
2642
+
2643
+ /**
2644
+ * Generate the URL of the sprite image
2645
+ * @function Cloudinary#sprite_css
2646
+ * @param {string} publicId - the public ID of the resource
2647
+ * @param {Object} [options] - options for the tag and transformations
2648
+ * @see {@link http://cloudinary.com/documentation/sprite_generation Sprite generation}
2649
+ */
2650
+
2651
+ Cloudinary.prototype.sprite_css = function(publicId, options) {
2652
+ options = Util.assign({
2653
+ type: 'sprite'
2654
+ }, options);
2655
+ if (!publicId.match(/.css$/)) {
2656
+ options.format = 'css';
2657
+ }
2658
+ return this.url(publicId, options);
2659
+ };
2660
+
2661
+
2662
+ /**
2663
+ * @function Cloudinary#responsive
2664
+ */
2665
+
2666
+ Cloudinary.prototype.responsive = function(options) {
2667
+ var ref, ref1, responsiveResize, timeout;
2668
+ this.responsiveConfig = Util.merge(this.responsiveConfig || {}, options);
2669
+ this.cloudinary_update('img.cld-responsive, img.cld-hidpi', this.responsiveConfig);
2670
+ responsiveResize = (ref = (ref1 = this.responsiveConfig['responsive_resize']) != null ? ref1 : this.config('responsive_resize')) != null ? ref : true;
2671
+ if (responsiveResize && !this.responsiveResizeInitialized) {
2672
+ this.responsiveConfig.resizing = this.responsiveResizeInitialized = true;
2673
+ timeout = null;
2674
+ return window.addEventListener('resize', (function(_this) {
2675
+ return function() {
2676
+ var debounce, ref2, ref3, reset, run, wait;
2677
+ debounce = (ref2 = (ref3 = _this.responsiveConfig['responsive_debounce']) != null ? ref3 : _this.config('responsive_debounce')) != null ? ref2 : 100;
2678
+ reset = function() {
2679
+ if (timeout) {
2680
+ clearTimeout(timeout);
2681
+ return timeout = null;
2682
+ }
2683
+ };
2684
+ run = function() {
2685
+ return _this.cloudinary_update('img.cld-responsive', _this.responsiveConfig);
2686
+ };
2687
+ wait = function() {
2688
+ reset();
2689
+ return setTimeout((function() {
2690
+ reset();
2691
+ return run();
2692
+ }), debounce);
2693
+ };
2694
+ if (debounce) {
2695
+ return wait();
2696
+ } else {
2697
+ return run();
2698
+ }
2699
+ };
2700
+ })(this));
2701
+ }
2702
+ };
2703
+
2704
+
2705
+ /**
2706
+ * @function Cloudinary#calc_breakpoint
2707
+ * @private
2708
+ * @ignore
2709
+ */
2710
+
2711
+ Cloudinary.prototype.calc_breakpoint = function(element, width) {
2712
+ var breakpoints, point;
2713
+ breakpoints = Util.getData(element, 'breakpoints') || Util.getData(element, 'stoppoints') || this.config('breakpoints') || this.config('stoppoints') || defaultBreakpoints;
2714
+ if (Util.isFunction(breakpoints)) {
2715
+ return breakpoints(width);
2716
+ } else {
2717
+ if (Util.isString(breakpoints)) {
2718
+ breakpoints = ((function() {
2719
+ var j, len, ref, results;
2720
+ ref = breakpoints.split(',');
2721
+ results = [];
2722
+ for (j = 0, len = ref.length; j < len; j++) {
2723
+ point = ref[j];
2724
+ results.push(parseInt(point));
2725
+ }
2726
+ return results;
2727
+ })()).sort(function(a, b) {
2728
+ return a - b;
2729
+ });
2730
+ }
2731
+ return closestAbove(breakpoints, width);
2732
+ }
2733
+ };
2734
+
2735
+
2736
+ /**
2737
+ * @function Cloudinary#calc_stoppoint
2738
+ * @deprecated Use {@link calc_breakpoint} instead.
2739
+ * @private
2740
+ * @ignore
2741
+ */
2742
+
2743
+ Cloudinary.prototype.calc_stoppoint = Cloudinary.prototype.calc_breakpoint;
2744
+
2745
+
2746
+ /**
2747
+ * @function Cloudinary#device_pixel_ratio
2748
+ */
2749
+
2750
+ Cloudinary.prototype.device_pixel_ratio = function() {
2751
+ var dpr, dprString, dprUsed;
2752
+ dpr = (typeof window !== "undefined" && window !== null ? window.devicePixelRatio : void 0) || 1;
2753
+ dprString = this.devicePixelRatioCache[dpr];
2754
+ if (!dprString) {
2755
+ dprUsed = closestAbove(this.supported_dpr_values, dpr);
2756
+ dprString = dprUsed.toString();
2757
+ if (dprString.match(/^\d+$/)) {
2758
+ dprString += '.0';
2759
+ }
2760
+ this.devicePixelRatioCache[dpr] = dprString;
2761
+ }
2762
+ return dprString;
2763
+ };
2764
+
2765
+ Cloudinary.prototype.supported_dpr_values = [0.75, 1.0, 1.3, 1.5, 2.0, 3.0];
2766
+
2767
+ defaultBreakpoints = function(width) {
2768
+ return 10 * Math.ceil(width / 10);
2769
+ };
2770
+
2771
+ closestAbove = function(list, value) {
2772
+ var i;
2773
+ i = list.length - 2;
2774
+ while (i >= 0 && list[i] >= value) {
2775
+ i--;
2776
+ }
2777
+ return list[i + 1];
2778
+ };
2779
+
2780
+ cdnSubdomainNumber = function(publicId) {
2781
+ return crc32(publicId) % 5 + 1;
2782
+ };
2783
+
2784
+ cloudinaryUrlPrefix = function(publicId, options) {
2785
+ var cdnPart, host, path, protocol, ref, ref1, subdomain;
2786
+ if (((ref = options.cloud_name) != null ? ref.indexOf("/") : void 0) === 0) {
2787
+ return '/res' + options.cloud_name;
2788
+ }
2789
+ protocol = "http://";
2790
+ cdnPart = "";
2791
+ subdomain = "res";
2792
+ host = ".cloudinary.com";
2793
+ path = "/" + options.cloud_name;
2794
+ if (options.protocol) {
2795
+ protocol = options.protocol + '//';
2796
+ } else if ((typeof window !== "undefined" && window !== null ? (ref1 = window.location) != null ? ref1.protocol : void 0 : void 0) === 'file:') {
2797
+ protocol = 'file://';
2798
+ }
2799
+ if (options.private_cdn) {
2800
+ cdnPart = options.cloud_name + "-";
2801
+ path = "";
2802
+ }
2803
+ if (options.cdn_subdomain) {
2804
+ subdomain = "res-" + cdnSubdomainNumber(publicId);
2805
+ }
2806
+ if (options.secure) {
2807
+ protocol = "https://";
2808
+ if (options.secure_cdn_subdomain === false) {
2809
+ subdomain = "res";
2810
+ }
2811
+ if ((options.secure_distribution != null) && options.secure_distribution !== OLD_AKAMAI_SHARED_CDN && options.secure_distribution !== SHARED_CDN) {
2812
+ cdnPart = "";
2813
+ subdomain = "";
2814
+ host = options.secure_distribution;
2815
+ }
2816
+ } else if (options.cname) {
2817
+ protocol = "http://";
2818
+ cdnPart = "";
2819
+ subdomain = options.cdn_subdomain ? 'a' + ((crc32(publicId) % 5) + 1) + '.' : '';
2820
+ host = options.cname;
2821
+ }
2822
+ return [protocol, cdnPart, subdomain, host, path].join("");
2823
+ };
2824
+
2825
+
2826
+ /**
2827
+ * Finds all `img` tags under each node and sets it up to provide the image through Cloudinary
2828
+ * @function Cloudinary#processImageTags
2829
+ */
2830
+
2831
+ Cloudinary.prototype.processImageTags = function(nodes, options) {
2832
+ var images, imgOptions, node, publicId, url;
2833
+ if (options == null) {
2834
+ options = {};
2835
+ }
2836
+ options = Util.defaults({}, options, this.config());
2837
+ images = (function() {
2838
+ var j, len, ref, results;
2839
+ results = [];
2840
+ for (j = 0, len = nodes.length; j < len; j++) {
2841
+ node = nodes[j];
2842
+ if (!(((ref = node.tagName) != null ? ref.toUpperCase() : void 0) === 'IMG')) {
2843
+ continue;
2844
+ }
2845
+ imgOptions = Util.assign({
2846
+ width: node.getAttribute('width'),
2847
+ height: node.getAttribute('height'),
2848
+ src: node.getAttribute('src')
2849
+ }, options);
2850
+ publicId = imgOptions['source'] || imgOptions['src'];
2851
+ delete imgOptions['source'];
2852
+ delete imgOptions['src'];
2853
+ url = this.url(publicId, imgOptions);
2854
+ imgOptions = new Transformation(imgOptions).toHtmlAttributes();
2855
+ Util.setData(node, 'src-cache', url);
2856
+ node.setAttribute('width', imgOptions.width);
2857
+ results.push(node.setAttribute('height', imgOptions.height));
2858
+ }
2859
+ return results;
2860
+ }).call(this);
2861
+ this.cloudinary_update(images, options);
2862
+ return this;
2863
+ };
2864
+
2865
+ applyBreakpoints = function(tag, width, options) {
2866
+ var ref, ref1, ref2, ref3, responsive_use_breakpoints;
2867
+ responsive_use_breakpoints = (ref = (ref1 = (ref2 = (ref3 = options['responsive_use_breakpoints']) != null ? ref3 : options['responsive_use_stoppoints']) != null ? ref2 : this.config('responsive_use_breakpoints')) != null ? ref1 : this.config('responsive_use_stoppoints')) != null ? ref : 'resize';
2868
+ if ((!responsive_use_breakpoints) || (responsive_use_breakpoints === 'resize' && !options.resizing)) {
2869
+ return width;
2870
+ } else {
2871
+ return this.calc_breakpoint(tag, width);
2872
+ }
2873
+ };
2874
+
2875
+ parentWidth = function(element) {
2876
+ var containerWidth;
2877
+ containerWidth = 0;
2878
+ while (((element = element != null ? element.parentNode : void 0) instanceof Element) && !containerWidth) {
2879
+ containerWidth = Util.width(element);
2880
+ }
2881
+ return containerWidth;
2882
+ };
2883
+
2884
+
2885
+ /**
2886
+ * Update hidpi (dpr_auto) and responsive (w_auto) fields according to the current container size and the device pixel ratio.
2887
+ * Only images marked with the cld-responsive class have w_auto updated.
2888
+ * @function Cloudinary#cloudinary_update
2889
+ * @param {(Array|string|NodeList)} elements - the elements to modify
2890
+ * @param {Object} options
2891
+ * @param {boolean|string} [options.responsive_use_breakpoints='resize']
2892
+ * - when `true`, always use breakpoints for width
2893
+ * - when `"resize"` use exact width on first render and breakpoints on resize (default)
2894
+ * - when `false` always use exact width
2895
+ * @param {boolean} [options.responsive] - if `true`, enable responsive on this element. Can be done by adding cld-responsive.
2896
+ * @param {boolean} [options.responsive_preserve_height] - if set to true, original css height is preserved.
2897
+ * Should only be used if the transformation supports different aspect ratios.
2898
+ */
2899
+
2900
+ Cloudinary.prototype.cloudinary_update = function(elements, options) {
2901
+ var containerWidth, imageWidth, j, len, ref, requestedWidth, setUrl, src, tag;
2902
+ if (options == null) {
2903
+ options = {};
2904
+ }
2905
+ elements = (function() {
2906
+ switch (false) {
2907
+ case !Util.isArray(elements):
2908
+ return elements;
2909
+ case elements.constructor.name !== "NodeList":
2910
+ return elements;
2911
+ case !Util.isString(elements):
2912
+ return document.querySelectorAll(elements);
2913
+ default:
2914
+ return [elements];
2915
+ }
2916
+ })();
2917
+ for (j = 0, len = elements.length; j < len; j++) {
2918
+ tag = elements[j];
2919
+ if (!((ref = tag.tagName) != null ? ref.match(/img/i) : void 0)) {
2920
+ continue;
2921
+ }
2922
+ setUrl = true;
2923
+ if (options.responsive) {
2924
+ Util.addClass(tag, "cld-responsive");
2925
+ }
2926
+ src = Util.getData(tag, 'src-cache') || Util.getData(tag, 'src');
2927
+ if (!Util.isEmpty(src)) {
2928
+ src = src.replace(/\bdpr_(1\.0|auto)\b/g, 'dpr_' + this.device_pixel_ratio());
2929
+ if (Util.hasClass(tag, 'cld-responsive') && /\bw_auto\b/.exec(src)) {
2930
+ containerWidth = parentWidth(tag);
2931
+ if (containerWidth !== 0) {
2932
+ requestedWidth = applyBreakpoints.call(this, tag, containerWidth, options);
2933
+ imageWidth = Util.getData(tag, 'width') || 0;
2934
+ if (requestedWidth > imageWidth) {
2935
+ imageWidth = requestedWidth;
2936
+ }
2937
+ Util.setData(tag, 'width', requestedWidth);
2938
+ src = src.replace(/\bw_auto\b/g, 'w_' + imageWidth);
2939
+ Util.setAttribute(tag, 'width', null);
2940
+ if (!options.responsive_preserve_height) {
2941
+ Util.setAttribute(tag, 'height', null);
2942
+ }
2943
+ } else {
2944
+ setUrl = false;
2945
+ }
2946
+ }
2947
+ if (setUrl) {
2948
+ Util.setAttribute(tag, 'src', src);
2949
+ }
2950
+ }
2951
+ }
2952
+ return this;
2953
+ };
2954
+
2955
+
2956
+ /**
2957
+ * Provide a transformation object, initialized with own's options, for chaining purposes.
2958
+ * @function Cloudinary#transformation
2959
+ * @param {Object} options
2960
+ * @return {Transformation}
2961
+ */
2962
+
2963
+ Cloudinary.prototype.transformation = function(options) {
2964
+ return Transformation["new"](this.config()).fromOptions(options).setParent(this);
2965
+ };
2966
+
2967
+ return Cloudinary;
2968
+
2969
+ })();
2970
+ });
2971
+
2972
+ }).call(this);
2973
+
2974
+ (function() {
2975
+ var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
2976
+ hasProp = {}.hasOwnProperty;
2977
+
2978
+ (function(root, factory) {
2979
+ if ((typeof define === 'function') && define.amd) {
2980
+ return define('tags/imagetag',['tags/htmltag', 'cloudinary', 'require'], factory);
2981
+ } else if (typeof exports === 'object') {
2982
+ return module.exports = factory(require('tags/htmltag'), require('cloudinary'), require);
2983
+ } else {
2984
+ root.cloudinary || (root.cloudinary = {});
2985
+ return root.cloudinary.ImageTag = factory(root.cloudinary.HtmlTag, root.cloudinary.Cloudinary, function() {
2986
+ return root.cloudinary.Cloudinary;
2987
+ });
2988
+ }
2989
+ })(this, function(HtmlTag, Cloudinary, require) {
2990
+ var ImageTag;
2991
+ return ImageTag = (function(superClass) {
2992
+ extend(ImageTag, superClass);
2993
+
2994
+
2995
+ /**
2996
+ * Creates an HTML (DOM) Image tag using Cloudinary as the source.
2997
+ * @constructor ImageTag
2998
+ * @extends HtmlTag
2999
+ * @param {string} [publicId]
3000
+ * @param {Object} [options]
3001
+ */
3002
+
3003
+ function ImageTag(publicId, options) {
3004
+ if (options == null) {
3005
+ options = {};
3006
+ }
3007
+ ImageTag.__super__.constructor.call(this, "img", publicId, options);
3008
+ }
3009
+
3010
+
3011
+ /** @override */
3012
+
3013
+ ImageTag.prototype.closeTag = function() {
3014
+ return "";
3015
+ };
3016
+
3017
+
3018
+ /** @override */
3019
+
3020
+ ImageTag.prototype.attributes = function() {
3021
+ var attr;
3022
+ Cloudinary || (Cloudinary = require('cloudinary'));
3023
+ attr = ImageTag.__super__.attributes.call(this) || [];
3024
+ if (attr['src'] == null) {
3025
+ attr['src'] = new Cloudinary(this.getOptions()).url(this.publicId);
3026
+ }
3027
+ return attr;
3028
+ };
3029
+
3030
+ return ImageTag;
3031
+
3032
+ })(HtmlTag);
3033
+ });
3034
+
3035
+ }).call(this);
3036
+
3037
+ (function() {
3038
+ var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
3039
+ hasProp = {}.hasOwnProperty;
3040
+
3041
+ (function(root, factory) {
3042
+ if ((typeof define === 'function') && define.amd) {
3043
+ return define('cloudinaryjquery',['jquery', 'util', 'transformation', 'cloudinary'], factory);
3044
+ } else if (typeof exports === 'object') {
3045
+ return module.exports = factory(require('jquery'), require('util'), require('transformation'), require('cloudinary'));
3046
+ } else {
3047
+ root.cloudinary || (root.cloudinary = {});
3048
+ return root.cloudinary.CloudinaryJQuery = factory(jQuery, root.cloudinary.Util, root.cloudinary.Transformation, root.cloudinary.Cloudinary);
3049
+ }
3050
+ })(this, function(jQuery, Util, Transformation, Cloudinary) {
3051
+ var CloudinaryJQuery, webp;
3052
+ CloudinaryJQuery = (function(superClass) {
3053
+ extend(CloudinaryJQuery, superClass);
3054
+
3055
+
3056
+ /**
3057
+ * Cloudinary class with jQuery support
3058
+ * @constructor CloudinaryJQuery
3059
+ * @extends Cloudinary
3060
+ */
3061
+
3062
+ function CloudinaryJQuery(options) {
3063
+ CloudinaryJQuery.__super__.constructor.call(this, options);
3064
+ }
3065
+
3066
+
3067
+ /**
3068
+ * @override
3069
+ */
3070
+
3071
+ CloudinaryJQuery.prototype.image = function(publicId, options) {
3072
+ var img, tag_options, url;
3073
+ if (options == null) {
3074
+ options = {};
3075
+ }
3076
+ tag_options = Util.merge({
3077
+ src: ''
3078
+ }, options);
3079
+ img = this.imageTag(publicId, tag_options).toHtml();
3080
+ url = this.url(publicId, options);
3081
+ return jQuery(img).data('src-cache', url).cloudinary_update(options);
3082
+ };
3083
+
3084
+
3085
+ /**
3086
+ * @override
3087
+ */
3088
+
3089
+ CloudinaryJQuery.prototype.responsive = function(options) {
3090
+ var ref, ref1, responsiveConfig, responsiveResizeInitialized, responsive_resize, timeout;
3091
+ responsiveConfig = jQuery.extend(responsiveConfig || {}, options);
3092
+ jQuery('img.cld-responsive, img.cld-hidpi').cloudinary_update(responsiveConfig);
3093
+ responsive_resize = (ref = (ref1 = responsiveConfig['responsive_resize']) != null ? ref1 : this.config('responsive_resize')) != null ? ref : true;
3094
+ if (responsive_resize && !responsiveResizeInitialized) {
3095
+ responsiveConfig.resizing = responsiveResizeInitialized = true;
3096
+ timeout = null;
3097
+ return jQuery(window).on('resize', (function(_this) {
3098
+ return function() {
3099
+ var debounce, ref2, ref3, reset, run, wait;
3100
+ debounce = (ref2 = (ref3 = responsiveConfig['responsive_debounce']) != null ? ref3 : _this.config('responsive_debounce')) != null ? ref2 : 100;
3101
+ reset = function() {
3102
+ if (timeout) {
3103
+ clearTimeout(timeout);
3104
+ return timeout = null;
3105
+ }
3106
+ };
3107
+ run = function() {
3108
+ return jQuery('img.cld-responsive').cloudinary_update(responsiveConfig);
3109
+ };
3110
+ wait = function() {
3111
+ reset();
3112
+ return setTimeout((function() {
3113
+ reset();
3114
+ return run();
3115
+ }), debounce);
3116
+ };
3117
+ if (debounce) {
3118
+ return wait();
3119
+ } else {
3120
+ return run();
3121
+ }
3122
+ };
3123
+ })(this));
3124
+ }
3125
+ };
3126
+
3127
+ return CloudinaryJQuery;
3128
+
3129
+ })(Cloudinary);
3130
+
3131
+ /**
3132
+ * The following methods are provided through the jQuery class
3133
+ * @class jQuery
3134
+ */
3135
+
3136
+ /**
3137
+ * Convert all img tags in the collection to utilize Cloudinary.
3138
+ * @function jQuery#cloudinary
3139
+ * @param {Object} [options] - options for the tag and transformations
3140
+ * @returns {jQuery}
3141
+ */
3142
+ jQuery.fn.cloudinary = function(options) {
3143
+ this.filter('img').each(function() {
3144
+ var img_options, public_id, url;
3145
+ img_options = jQuery.extend({
3146
+ width: jQuery(this).attr('width'),
3147
+ height: jQuery(this).attr('height'),
3148
+ src: jQuery(this).attr('src')
3149
+ }, jQuery(this).data(), options);
3150
+ public_id = img_options.source || img_options.src;
3151
+ delete img_options.source;
3152
+ delete img_options.src;
3153
+ url = jQuery.cloudinary.url(public_id, img_options);
3154
+ img_options = new Transformation(img_options).toHtmlAttributes();
3155
+ return jQuery(this).data('src-cache', url).attr({
3156
+ width: img_options.width,
3157
+ height: img_options.height
3158
+ });
3159
+ }).cloudinary_update(options);
3160
+ return this;
3161
+ };
3162
+
3163
+ /**
3164
+ * Update hidpi (dpr_auto) and responsive (w_auto) fields according to the current container size and the device pixel ratio.
3165
+ * Only images marked with the cld-responsive class have w_auto updated.
3166
+ * options:
3167
+ * - responsive_use_stoppoints:
3168
+ * - true - always use stoppoints for width
3169
+ * - "resize" - use exact width on first render and stoppoints on resize (default)
3170
+ * - false - always use exact width
3171
+ * - responsive:
3172
+ * - true - enable responsive on this element. Can be done by adding cld-responsive.
3173
+ * Note that jQuery.cloudinary.responsive() should be called once on the page.
3174
+ * - responsive_preserve_height: if set to true, original css height is perserved. Should only be used if the transformation supports different aspect ratios.
3175
+ */
3176
+ jQuery.fn.cloudinary_update = function(options) {
3177
+ if (options == null) {
3178
+ options = {};
3179
+ }
3180
+ $.cloudinary.cloudinary_update(this.filter('img').toArray(), options);
3181
+ return this;
3182
+ };
3183
+ webp = null;
3184
+
3185
+ /**
3186
+ * @function jQuery#webpify
3187
+ */
3188
+ jQuery.fn.webpify = function(options, webp_options) {
3189
+ var that, webp_canary;
3190
+ if (options == null) {
3191
+ options = {};
3192
+ }
3193
+ that = this;
3194
+ webp_options = webp_options != null ? webp_options : options;
3195
+ if (!webp) {
3196
+ webp = jQuery.Deferred();
3197
+ webp_canary = new Image;
3198
+ webp_canary.onerror = webp.reject;
3199
+ webp_canary.onload = webp.resolve;
3200
+ webp_canary.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMwAgSSNtse/cXjxyCCmrYNWPwmHRH9jwMA';
3201
+ }
3202
+ jQuery(function() {
3203
+ return webp.done(function() {
3204
+ return jQuery(that).cloudinary(jQuery.extend({}, webp_options, {
3205
+ format: 'webp'
3206
+ }));
3207
+ }).fail(function() {
3208
+ return jQuery(that).cloudinary(options);
3209
+ });
3210
+ });
3211
+ return this;
3212
+ };
3213
+ jQuery.fn.fetchify = function(options) {
3214
+ return this.cloudinary(jQuery.extend(options, {
3215
+ 'type': 'fetch'
3216
+ }));
3217
+ };
3218
+ jQuery.cloudinary = new CloudinaryJQuery();
3219
+ jQuery.cloudinary.fromDocument();
3220
+ return CloudinaryJQuery;
3221
+ });
3222
+
3223
+ }).call(this);
3224
+
3225
+
3226
+ /**
3227
+ * This module extends CloudinaryJquery to support jQuery File Upload
3228
+ */
3229
+
3230
+ (function() {
3231
+ (function(root, factory) {
3232
+ if ((typeof define === 'function') && define.amd) {
3233
+ return define('jquery-file-upload',['jquery', 'util', 'cloudinaryjquery', 'jquery.ui.widget', 'jquery.iframe-transport', 'jquery.fileupload'], factory);
3234
+ } else if (typeof exports === 'object') {
3235
+ return module.exports = factory(require('jquery'), require('util'), require('cloudinaryjquery'));
3236
+ } else {
3237
+ root.cloudinary.CloudinaryJQuery = factory(jQuery, root.cloudinary.Util, root.cloudinary.CloudinaryJQuery);
3238
+ $(function() {
3239
+ if ($.fn.cloudinary_fileupload !== void 0) {
3240
+ return $('input.cloudinary-fileupload[type=file]').cloudinary_fileupload();
3241
+ }
3242
+ });
3243
+ return root.cloudinary.CloudinaryJQuery;
3244
+ }
3245
+ })(this, function(jQuery, Util, CloudinaryJQuery) {
3246
+
3247
+ /**
3248
+ * Delete a resource using the upload token
3249
+ * @function CloudinaryJQuery#delete_by_token
3250
+ * @param {string} delete_token - the delete token
3251
+ * @param {Object} [options]
3252
+ * @param {string} [options.url] - an alternative URL to use for the API
3253
+ * @param {string} [options.cloud_name] - an alternative cloud_name to use. This parameter is ignored if `options.url` is provided.
3254
+ */
3255
+ CloudinaryJQuery.prototype.delete_by_token = function(delete_token, options) {
3256
+ var cloud_name, dataType, url;
3257
+ options = options || {};
3258
+ url = options.url;
3259
+ if (!url) {
3260
+ cloud_name = options.cloud_name || jQuery.cloudinary.config().cloud_name;
3261
+ url = 'https://api.cloudinary.com/v1_1/' + cloud_name + '/delete_by_token';
3262
+ }
3263
+ dataType = jQuery.support.xhrFileUpload ? 'json' : 'iframe json';
3264
+ return jQuery.ajax({
3265
+ url: url,
3266
+ method: 'POST',
3267
+ data: {
3268
+ token: delete_token
3269
+ },
3270
+ headers: {
3271
+ 'X-Requested-With': 'XMLHttpRequest'
3272
+ },
3273
+ dataType: dataType
3274
+ });
3275
+ };
3276
+
3277
+ /**
3278
+ * Creates an `input` tag and sets it up to upload files to cloudinary
3279
+ * @function CloudinaryJQuery#unsigned_upload_tag
3280
+ * @param {string}
3281
+ */
3282
+ CloudinaryJQuery.prototype.unsigned_upload_tag = function(upload_preset, upload_params, options) {
3283
+ return jQuery('<input/>').attr({
3284
+ type: 'file',
3285
+ name: 'file'
3286
+ }).unsigned_cloudinary_upload(upload_preset, upload_params, options);
3287
+ };
3288
+
3289
+ /**
3290
+ * Initialize the jQuery File Upload plugin to upload to Cloudinary
3291
+ * @function jQuery#cloudinary_fileupload
3292
+ * @param {Object} options
3293
+ * @returns {jQuery}
3294
+ */
3295
+ jQuery.fn.cloudinary_fileupload = function(options) {
3296
+ var cloud_name, initializing, resource_type, type, upload_url;
3297
+ initializing = !this.data('blueimpFileupload');
3298
+ if (initializing) {
3299
+ options = jQuery.extend({
3300
+ maxFileSize: 20000000,
3301
+ dataType: 'json',
3302
+ headers: {
3303
+ 'X-Requested-With': 'XMLHttpRequest'
3304
+ }
3305
+ }, options);
3306
+ }
3307
+ this.fileupload(options);
3308
+ if (initializing) {
3309
+ this.bind('fileuploaddone', function(e, data) {
3310
+ var add_field, field, multiple, upload_info;
3311
+ if (data.result.error) {
3312
+ return;
3313
+ }
3314
+ data.result.path = ['v', data.result.version, '/', data.result.public_id, data.result.format ? '.' + data.result.format : ''].join('');
3315
+ if (data.cloudinaryField && data.form.length > 0) {
3316
+ upload_info = [data.result.resource_type, data.result.type, data.result.path].join('/') + '#' + data.result.signature;
3317
+ multiple = jQuery(e.target).prop('multiple');
3318
+ add_field = function() {
3319
+ return jQuery('<input/>').attr({
3320
+ type: 'hidden',
3321
+ name: data.cloudinaryField
3322
+ }).val(upload_info).appendTo(data.form);
3323
+ };
3324
+ if (multiple) {
3325
+ add_field();
3326
+ } else {
3327
+ field = jQuery(data.form).find('input[name="' + data.cloudinaryField + '"]');
3328
+ if (field.length > 0) {
3329
+ field.val(upload_info);
3330
+ } else {
3331
+ add_field();
3332
+ }
3333
+ }
3334
+ }
3335
+ return jQuery(e.target).trigger('cloudinarydone', data);
3336
+ });
3337
+ this.bind('fileuploadsend', function(e, data) {
3338
+ return data.headers['X-Unique-Upload-Id'] = (Math.random() * 10000000000).toString(16);
3339
+ });
3340
+ this.bind('fileuploadstart', function(e) {
3341
+ return jQuery(e.target).trigger('cloudinarystart');
3342
+ });
3343
+ this.bind('fileuploadstop', function(e) {
3344
+ return jQuery(e.target).trigger('cloudinarystop');
3345
+ });
3346
+ this.bind('fileuploadprogress', function(e, data) {
3347
+ return jQuery(e.target).trigger('cloudinaryprogress', data);
3348
+ });
3349
+ this.bind('fileuploadprogressall', function(e, data) {
3350
+ return jQuery(e.target).trigger('cloudinaryprogressall', data);
3351
+ });
3352
+ this.bind('fileuploadfail', function(e, data) {
3353
+ return jQuery(e.target).trigger('cloudinaryfail', data);
3354
+ });
3355
+ this.bind('fileuploadalways', function(e, data) {
3356
+ return jQuery(e.target).trigger('cloudinaryalways', data);
3357
+ });
3358
+ if (!this.fileupload('option').url) {
3359
+ cloud_name = options.cloud_name || jQuery.cloudinary.config().cloud_name;
3360
+ resource_type = options.resource_type || 'auto';
3361
+ type = options.type || 'upload';
3362
+ upload_url = 'https://api.cloudinary.com/v1_1/' + cloud_name + '/' + resource_type + '/' + type;
3363
+ this.fileupload('option', 'url', upload_url);
3364
+ }
3365
+ }
3366
+ return this;
3367
+ };
3368
+
3369
+ /**
3370
+ * Add a file to upload
3371
+ * @function jQuery#cloudinary_upload_url
3372
+ * @param {string} remote_url - the url to add
3373
+ * @returns {jQuery}
3374
+ */
3375
+ jQuery.fn.cloudinary_upload_url = function(remote_url) {
3376
+ this.fileupload('option', 'formData').file = remote_url;
3377
+ this.fileupload('add', {
3378
+ files: [remote_url]
3379
+ });
3380
+ delete this.fileupload('option', 'formData').file;
3381
+ return this;
3382
+ };
3383
+
3384
+ /**
3385
+ * Initialize the jQuery File Upload plugin to upload to Cloudinary using unsigned upload
3386
+ * @function jQuery#unsigned_cloudinary_upload
3387
+ * @param {string} upload_preset - the upload preset to use
3388
+ * @param {Object} [upload_params] - parameters that should be past to the server
3389
+ * @param {Object} [options]
3390
+ * @returns {jQuery}
3391
+ */
3392
+ jQuery.fn.unsigned_cloudinary_upload = function(upload_preset, upload_params, options) {
3393
+ var attr, attrs_to_move, html_options, i, key, value;
3394
+ if (upload_params == null) {
3395
+ upload_params = {};
3396
+ }
3397
+ if (options == null) {
3398
+ options = {};
3399
+ }
3400
+ upload_params = Util.cloneDeep(upload_params);
3401
+ options = Util.cloneDeep(options);
3402
+ attrs_to_move = ['cloud_name', 'resource_type', 'type'];
3403
+ i = 0;
3404
+ while (i < attrs_to_move.length) {
3405
+ attr = attrs_to_move[i];
3406
+ if (upload_params[attr]) {
3407
+ options[attr] = upload_params[attr];
3408
+ delete upload_params[attr];
3409
+ }
3410
+ i++;
3411
+ }
3412
+ for (key in upload_params) {
3413
+ value = upload_params[key];
3414
+ if (Util.isPlainObject(value)) {
3415
+ upload_params[key] = jQuery.map(value, function(v, k) {
3416
+ return k + '=' + v;
3417
+ }).join('|');
3418
+ } else if (Util.isArray(value)) {
3419
+ if (value.length > 0 && jQuery.isArray(value[0])) {
3420
+ upload_params[key] = jQuery.map(value, function(array_value) {
3421
+ return array_value.join(',');
3422
+ }).join('|');
3423
+ } else {
3424
+ upload_params[key] = value.join(',');
3425
+ }
3426
+ }
3427
+ }
3428
+ if (!upload_params.callback) {
3429
+ upload_params.callback = '/cloudinary_cors.html';
3430
+ }
3431
+ upload_params.upload_preset = upload_preset;
3432
+ options.formData = upload_params;
3433
+ if (options.cloudinary_field) {
3434
+ options.cloudinaryField = options.cloudinary_field;
3435
+ delete options.cloudinary_field;
3436
+ }
3437
+ html_options = options.html || {};
3438
+ html_options["class"] = Util.trim("cloudinary_fileupload " + (html_options["class"] || ''));
3439
+ if (options.multiple) {
3440
+ html_options.multiple = true;
3441
+ }
3442
+ this.attr(html_options).cloudinary_fileupload(options);
3443
+ return this;
3444
+ };
3445
+ jQuery.cloudinary = new CloudinaryJQuery();
3446
+ return CloudinaryJQuery;
3447
+ });
3448
+
3449
+ }).call(this);
3450
+
3451
+
3452
+ /**
3453
+ * Creates the namespace for Cloudinary
3454
+ */
3455
+
3456
+ (function() {
3457
+ (function(root, factory) {
3458
+ if ((typeof define === 'function') && define.amd) {
3459
+ return define('cloudinary-jquery-file-upload-full',['utf8_encode', 'crc32', 'util', 'transformation', 'configuration', 'tags/htmltag', 'tags/imagetag', 'tags/videotag', 'cloudinary', 'cloudinaryjquery', 'jquery-file-upload'], factory);
3460
+ } else if (typeof exports === 'object') {
3461
+ return module.exports = factory(require('utf8_encode'), require('crc32'), require('util'), require('transformation'), require('configuration'), require('tags/htmltag'), require('tags/imagetag'), require('tags/videotag'), require('cloudinary'), require('cloudinaryjquery'), require('jquery-file-upload'));
3462
+ } else {
3463
+ root.cloudinary || (root.cloudinary = {});
3464
+ return root.cloudinary = factory(root.cloudinary.utf8_encode, root.cloudinary.crc32, root.cloudinary.Util, root.cloudinary.Transformation, root.cloudinary.Configuration, root.cloudinary.HtmlTag, root.cloudinary.ImageTag, root.cloudinary.VideoTag, root.cloudinary.Cloudinary, root.cloudinary.CloudinaryJQuery);
3465
+ }
3466
+ })(this, function(utf8_encode, crc32, Util, Transformation, Configuration, HtmlTag, ImageTag, VideoTag, Cloudinary, CloudinaryJQuery) {
3467
+ return {
3468
+ utf8_encode: utf8_encode,
3469
+ crc32: crc32,
3470
+ Util: Util,
3471
+ Transformation: Transformation,
3472
+ Configuration: Configuration,
3473
+ HtmlTag: HtmlTag,
3474
+ ImageTag: ImageTag,
3475
+ VideoTag: VideoTag,
3476
+ Cloudinary: Cloudinary,
3477
+ CloudinaryJQuery: CloudinaryJQuery
3478
+ };
3479
+ });
3480
+
3481
+ }).call(this);
3482
+