Kraken.io Image Optimizer - Version 2.0.0

Version Description

  • Please read! Kraken.io settings have now moved to an own section (Settings->Kraken.io), in order to reduce clutter in Media Settings, and to accomodate new features on the way.
  • Advanced settings grouped in "Advanced Settings" section of settings page.
  • Direct link to Kraken.io settings from Kraken.io in the plugins section.
  • Updated screenshots.
  • WordPress version compatibility bumped to 4.2.
Download this release

Release Info

Developer karim79
Plugin Icon 128x128 Kraken.io Image Optimizer
Version 2.0.0
Comparing to
See all releases

Code changes from version 1.0.9.1 to 2.0.0

Files changed (8) hide show
  1. css/admin.css +52 -0
  2. css/dist/kraken.min.css +1 -0
  3. css/tipsy.css +2 -2
  4. js/ajax.js +15 -0
  5. js/dist/kraken.min.js +1 -1
  6. kraken.php +178 -113
  7. lib/Kraken.php +1 -1
  8. readme.txt +36 -17
css/admin.css CHANGED
@@ -179,6 +179,12 @@ small.krakenReset {
179
  background: url('https://kraken-nekkraug.netdna-ssl.com/assets/images/spinner.gif') no-repeat 0 0;
180
  background-size: 10px;
181
  }
 
 
 
 
 
 
182
  small.krakenWhatsThis {
183
  font-size: 9px;
184
  }
@@ -188,4 +194,50 @@ span.kraken-reset-all {
188
  span.kraken-reset-all.enabled {
189
  text-decoration: underline;
190
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  }
179
  background: url('https://kraken-nekkraug.netdna-ssl.com/assets/images/spinner.gif') no-repeat 0 0;
180
  background-size: 10px;
181
  }
182
+ h1.kraken-admin-section-title {
183
+ margin-bottom: 30px;
184
+ }
185
+ .kraken_show_reset {
186
+ margin-right: 11px;
187
+ }
188
  small.krakenWhatsThis {
189
  font-size: 9px;
190
  }
194
  span.kraken-reset-all.enabled {
195
  text-decoration: underline;
196
  cursor: pointer;
197
+ }
198
+ td.krakenAdvancedSettings {
199
+ padding: 0;
200
+ }
201
+ td.krakenAdvancedSettingsDescription {
202
+ padding: 0;
203
+ padding-bottom: 10px;
204
+ }
205
+ td.krakenAdvancedSettings h3 {
206
+ margin-bottom: 2px;
207
+ }
208
+ td.krakenAdvancedSettings h3 > .kraken-advanced-settings-label:hover {
209
+ cursor: pointer;
210
+ color: #45bbe6;
211
+ -webkit-user-select: none;
212
+ -khtml-user-select: none;
213
+ -moz-user-select: none;
214
+ -ms-user-select: none;
215
+ user-select: none;
216
+ }
217
+ td.krakenAdvancedSettings h3 span.kraken-advanced-toggle {
218
+ color: #45bbe6;
219
+ font-size: 10px;
220
+ }
221
+ .kraken-plus-minus {
222
+ cursor: pointer;
223
+ line-height: 24px;
224
+ display: inline-block;
225
+ width: 20px;
226
+ -webkit-user-select: none;
227
+ -khtml-user-select: none;
228
+ -moz-user-select: none;
229
+ -ms-user-select: none;
230
+ user-select: none;
231
+ }
232
+ .kraken-advanced-settings {
233
+ display: none;
234
+ }
235
+ #krakenSettings .form-table {
236
+ margin-bottom: 30px;
237
+ }
238
+ #krakenSettings .form-table th {
239
+ width: 370px;
240
+ }
241
+ .kraken.error.settings-error, .kraken.updated.settings-error {
242
+ margin-bottom: 30px;
243
  }
css/dist/kraken.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .tipsy-ne .tipsy-arrow,.tipsy-nw .tipsy-arrow{border-top:none;top:0;border-bottom-style:solid}.tipsy-inner,td.kraken-krakedsize{text-align:left}.kraken-plus-minus,td.krakenAdvancedSettings h3>.kraken-advanced-settings-label:hover{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-khtml-user-select:none}.kraken-modal{display:none;width:600px;background:#fff;padding:15px 30px;border-radius:8px;-webkit-box-shadow:0 0 10px #000;-moz-box-shadow:0 0 10px #000;-o-box-shadow:0 0 10px #000;-ms-box-shadow:0 0 10px #000;box-shadow:0 0 10px #000}.kraken-modal,.kraken-modal-spinner{-o-border-radius:8px;-ms-border-radius:8px;-webkit-border-radius:8px;-moz-border-radius:8px}.kraken-modal-spinner{display:none;width:64px;height:64px;position:fixed;top:50%;left:50%;margin-right:-32px;margin-top:-32px;background:url(spinner.gif)center center no-repeat #111;border-radius:8px}.tipsy{font-size:10px;position:absolute;padding:5px;z-index:100000}.tipsy-inner{background-color:#000;color:#FFF;max-width:300px;padding:5px 8px 4px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:0 0 5px #000;-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000}.head_cell,.head_file_name,.item_file_name{height:20px;padding-top:5px}.tipsy-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.tipsy-arrow-n{border-bottom-color:#000}.tipsy-arrow-s{border-top-color:#000}.tipsy-arrow-e{border-left-color:#000}.tipsy-n .tipsy-arrow,.tipsy-ne .tipsy-arrow,.tipsy-nw .tipsy-arrow,.tipsy-s .tipsy-arrow,.tipsy-se .tipsy-arrow,.tipsy-sw .tipsy-arrow{border-left-color:transparent}.tipsy-arrow-w{border-right-color:#000}.tipsy-n .tipsy-arrow,.tipsy-ne .tipsy-arrow,.tipsy-nw .tipsy-arrow,.tipsy-s .tipsy-arrow,.tipsy-se .tipsy-arrow,.tipsy-sw .tipsy-arrow{border-right-color:transparent}.tipsy-n .tipsy-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none}.tipsy-nw .tipsy-arrow{left:10px}.tipsy-ne .tipsy-arrow{right:10px}.tipsy-s .tipsy-arrow,.tipsy-se .tipsy-arrow,.tipsy-sw .tipsy-arrow{border-bottom:none;border-top-style:solid}.tipsy-e .tipsy-arrow,.tipsy-w .tipsy-arrow{border-bottom-color:transparent;top:50%;border-top-color:transparent}.tipsy-s .tipsy-arrow{bottom:0;left:50%;margin-left:-5px}.tipsy-sw .tipsy-arrow{bottom:0;left:10px}.tipsy-se .tipsy-arrow{bottom:0;right:10px}.tipsy-e .tipsy-arrow{right:0;margin-top:-5px;border-left-style:solid;border-right:none}.tipsy-w .tipsy-arrow{left:0;margin-top:-5px;border-right-style:solid;border-left:none}.item_cell,.item_file_name{background-color:#F8F8F8;margin-top:5px}.head_cell{float:left;width:10em;background-color:#F0F0F0}.head_file_name{float:left;width:30em;background-color:#F0F0F0;padding-left:2px}.item_cell{float:left;width:10em;height:20px;padding-top:5px}.item_file_name{float:left;width:30em;padding-left:2px}.apiInvalid,.apiValid{position:absolute;width:16px}#kraken_loading{float:left;clear:left}.kraken_req,.kraken_req_bulk{border:1px solid #efab00;color:#222;padding:3px 8px 4px;font-size:11px;text-shadow:0 1px 0 rgba(255,255,255,.5);background:#ffc942;background-image:-webkit-gradient(linear,left top,left bottom,from(#ffc942),to(#efab00));background-image:-webkit-linear-gradient(top,#ffc942,#efab00);background-image:-moz-linear-gradient(top,#ffc942,#efab00);background-image:-o-linear-gradient(top,#ffc942,#efab00);background-image:linear-gradient(to bottom,#ffc942,#efab00);-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;cursor:pointer;font-weight:700}.krakenBulkSpinner,.krakenSpinner,.resetSpinner{background:url(https://kraken-nekkraug.netdna-ssl.com/assets/images/spinner.gif)no-repeat}.kraken_req_bulk{font-size:16px}.buttonWrap{position:relative;margin-bottom:5px}.apiValid{left:0;display:inline-block;height:16px;top:3px}.apiInvalid{left:0;display:inline-block;height:16px;top:2px}p.apiStatus{padding-left:26px;position:relative;width:400px}.krakenSpinner{display:none;position:absolute;width:16px;height:16px;top:5px}.krakenBulkSpinner{display:none;padding:0;margin:0;width:16px;height:16px}.krakenError,.noSavings{margin-left:2px}.kraken-bulk-small,.kraken-plus-minus,.radiosWrap,.resetSpinner,.visible{display:inline-block}.krakenErrorWrap{margin-top:10px;margin-bottom:4px}.krakenError{font-weight:700;color:#dd3d36}.krakenBulkHeader{font-size:16px;margin-bottom:10px;font-weight:700}#kraken-bulk-modal{position:absolute!important;top:100px;width:785px}#kraken-bulk-modal label{margin-bottom:11px}#kraken-bulk{width:780px;margin:0 auto 10px;border-spacing:1px;border-collapse:separate}.kraken-bulk-header td{font-weight:700;font-size:14px;padding:4px 0 4px 2px}tr.kraken-item-row td{padding:2px;height:20px}span.kraken-bulk-choose-type{font-weight:700;margin-right:5px}#kraken-bulk-type-lossy{margin-right:5px}.close-kraken-bulk{font-size:12px;margin-left:10px;font-weight:700;cursor:pointer}.radiosWrap{margin:0 0 5px 4px}.kraken-bulk-small{font-size:12px;margin:0 0 4px 4px}small.krakenReset{text-decoration:underline;cursor:pointer}.resetSpinner{margin-right:3px;margin-top:4px;vertical-align:baseline;width:10px;height:10px;background-size:10px}h1.kraken-admin-section-title{margin-bottom:30px}.kraken_show_reset{margin-right:11px}small.krakenWhatsThis{font-size:9px}span.kraken-reset-all{font-size:11px}span.kraken-reset-all.enabled{text-decoration:underline;cursor:pointer}td.krakenAdvancedSettings{padding:0}td.krakenAdvancedSettingsDescription{padding:0 0 10px}td.krakenAdvancedSettings h3{margin-bottom:2px}#krakenSettings .form-table,.kraken.error.settings-error,.kraken.updated.settings-error{margin-bottom:30px}td.krakenAdvancedSettings h3>.kraken-advanced-settings-label:hover{cursor:pointer;color:#45bbe6;user-select:none}td.krakenAdvancedSettings h3 span.kraken-advanced-toggle{color:#45bbe6;font-size:10px}.kraken-plus-minus{cursor:pointer;line-height:24px;width:20px;user-select:none}.kraken-advanced-settings{display:none}#krakenSettings .form-table th{width:370px}
css/tipsy.css CHANGED
@@ -1,11 +1,11 @@
1
  .tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
2
- .tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; }
3
 
4
  /* Rounded corners */
5
  .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
6
 
7
  /* Uncomment for shadow */
8
- /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
9
 
10
  .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
11
 
1
  .tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
2
+ .tipsy-inner { background-color: #000; color: #FFF; max-width: 300px; padding: 5px 8px 4px 8px; text-align: left; }
3
 
4
  /* Rounded corners */
5
  .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
6
 
7
  /* Uncomment for shadow */
8
+ .tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }
9
 
10
  .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
11
 
js/ajax.js CHANGED
@@ -405,6 +405,21 @@ jQuery(document).ready(function($) {
405
  });
406
  });
407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
 
409
  $('body').on("click", ".kraken_req", function(e) {
410
  e.preventDefault();
405
  });
406
  });
407
 
408
+ $('.krakenAdvancedSettings h3').on('click', function () {
409
+ var $rows = $('.kraken-advanced-settings');
410
+ var $plusMinus = $('.kraken-plus-minus');
411
+ if ($rows.is(':visible')) {
412
+ $rows.hide();
413
+ $plusMinus
414
+ .removeClass('dashicons-arrow-down')
415
+ .addClass('dashicons-arrow-right');
416
+ } else {
417
+ $rows.show();
418
+ $plusMinus
419
+ .removeClass('dashicons-arrow-right')
420
+ .addClass('dashicons-arrow-down');
421
+ }
422
+ });
423
 
424
  $('body').on("click", ".kraken_req", function(e) {
425
  e.preventDefault();
js/dist/kraken.min.js CHANGED
@@ -1,3 +1,3 @@
1
  !function(){function only_once(fn){var called=!1;return function(){if(called)throw new Error("Callback was already called.");called=!0,fn.apply(root,arguments)}}var root,previous_async,async={};root=this,null!=root&&(previous_async=root.async),async.noConflict=function(){return root.async=previous_async,async};var _each=function(arr,iterator){if(arr.forEach)return arr.forEach(iterator);for(var i=0;i<arr.length;i+=1)iterator(arr[i],i,arr)},_map=function(arr,iterator){if(arr.map)return arr.map(iterator);var results=[];return _each(arr,function(x,i,a){results.push(iterator(x,i,a))}),results},_reduce=function(arr,iterator,memo){return arr.reduce?arr.reduce(iterator,memo):(_each(arr,function(x,i,a){memo=iterator(memo,x,i,a)}),memo)},_keys=function(obj){if(Object.keys)return Object.keys(obj);var keys=[];for(var k in obj)obj.hasOwnProperty(k)&&keys.push(k);return keys};"undefined"!=typeof process&&process.nextTick?(async.nextTick=process.nextTick,"undefined"!=typeof setImmediate?async.setImmediate=function(fn){setImmediate(fn)}:async.setImmediate=async.nextTick):"function"==typeof setImmediate?(async.nextTick=function(fn){setImmediate(fn)},async.setImmediate=async.nextTick):(async.nextTick=function(fn){setTimeout(fn,0)},async.setImmediate=async.nextTick),async.each=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0;_each(arr,function(x){iterator(x,only_once(function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length&&callback(null))}))})},async.forEach=async.each,async.eachSeries=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0,iterate=function(){iterator(arr[completed],function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length?callback(null):iterate())})};iterate()},async.forEachSeries=async.eachSeries,async.eachLimit=function(arr,limit,iterator,callback){var fn=_eachLimit(limit);fn.apply(null,[arr,iterator,callback])},async.forEachLimit=async.eachLimit;var _eachLimit=function(limit){return function(arr,iterator,callback){if(callback=callback||function(){},!arr.length||0>=limit)return callback();var completed=0,started=0,running=0;!function replenish(){if(completed>=arr.length)return callback();for(;limit>running&&started<arr.length;)started+=1,running+=1,iterator(arr[started-1],function(err){err?(callback(err),callback=function(){}):(completed+=1,running-=1,completed>=arr.length?callback():replenish())})}()}},doParallel=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.each].concat(args))}},doParallelLimit=function(limit,fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[_eachLimit(limit)].concat(args))}},doSeries=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.eachSeries].concat(args))}},_asyncMap=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(err,v){results[x.index]=v,callback(err)})},function(err){callback(err,results)})};async.map=doParallel(_asyncMap),async.mapSeries=doSeries(_asyncMap),async.mapLimit=function(arr,limit,iterator,callback){return _mapLimit(limit)(arr,iterator,callback)};var _mapLimit=function(limit){return doParallelLimit(limit,_asyncMap)};async.reduce=function(arr,memo,iterator,callback){async.eachSeries(arr,function(x,callback){iterator(memo,x,function(err,v){memo=v,callback(err)})},function(err){callback(err,memo)})},async.inject=async.reduce,async.foldl=async.reduce,async.reduceRight=function(arr,memo,iterator,callback){var reversed=_map(arr,function(x){return x}).reverse();async.reduce(reversed,memo,iterator,callback)},async.foldr=async.reduceRight;var _filter=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v&&results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.filter=doParallel(_filter),async.filterSeries=doSeries(_filter),async.select=async.filter,async.selectSeries=async.filterSeries;var _reject=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v||results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.reject=doParallel(_reject),async.rejectSeries=doSeries(_reject);var _detect=function(eachfn,arr,iterator,main_callback){eachfn(arr,function(x,callback){iterator(x,function(result){result?(main_callback(x),main_callback=function(){}):callback()})},function(err){main_callback()})};async.detect=doParallel(_detect),async.detectSeries=doSeries(_detect),async.some=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v&&(main_callback(!0),main_callback=function(){}),callback()})},function(err){main_callback(!1)})},async.any=async.some,async.every=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v||(main_callback(!1),main_callback=function(){}),callback()})},function(err){main_callback(!0)})},async.all=async.every,async.sortBy=function(arr,iterator,callback){async.map(arr,function(x,callback){iterator(x,function(err,criteria){err?callback(err):callback(null,{value:x,criteria:criteria})})},function(err,results){if(err)return callback(err);var fn=function(left,right){var a=left.criteria,b=right.criteria;return b>a?-1:a>b?1:0};callback(null,_map(results.sort(fn),function(x){return x.value}))})},async.auto=function(tasks,callback){callback=callback||function(){};var keys=_keys(tasks);if(!keys.length)return callback(null);var results={},listeners=[],addListener=function(fn){listeners.unshift(fn)},removeListener=function(fn){for(var i=0;i<listeners.length;i+=1)if(listeners[i]===fn)return void listeners.splice(i,1)},taskComplete=function(){_each(listeners.slice(0),function(fn){fn()})};addListener(function(){_keys(results).length===keys.length&&(callback(null,results),callback=function(){})}),_each(keys,function(k){var task=tasks[k]instanceof Function?[tasks[k]]:tasks[k],taskCallback=function(err){var args=Array.prototype.slice.call(arguments,1);if(args.length<=1&&(args=args[0]),err){var safeResults={};_each(_keys(results),function(rkey){safeResults[rkey]=results[rkey]}),safeResults[k]=args,callback(err,safeResults),callback=function(){}}else results[k]=args,async.setImmediate(taskComplete)},requires=task.slice(0,Math.abs(task.length-1))||[],ready=function(){return _reduce(requires,function(a,x){return a&&results.hasOwnProperty(x)},!0)&&!results.hasOwnProperty(k)};if(ready())task[task.length-1](taskCallback,results);else{var listener=function(){ready()&&(removeListener(listener),task[task.length-1](taskCallback,results))};addListener(listener)}})},async.waterfall=function(tasks,callback){if(callback=callback||function(){},tasks.constructor!==Array){var err=new Error("First argument to waterfall must be an array of functions");return callback(err)}if(!tasks.length)return callback();var wrapIterator=function(iterator){return function(err){if(err)callback.apply(null,arguments),callback=function(){};else{var args=Array.prototype.slice.call(arguments,1),next=iterator.next();args.push(next?wrapIterator(next):callback),async.setImmediate(function(){iterator.apply(null,args)})}}};wrapIterator(async.iterator(tasks))()};var _parallel=function(eachfn,tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)eachfn.map(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};eachfn.each(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}};async.parallel=function(tasks,callback){_parallel({map:async.map,each:async.each},tasks,callback)},async.parallelLimit=function(tasks,limit,callback){_parallel({map:_mapLimit(limit),each:_eachLimit(limit)},tasks,callback)},async.series=function(tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)async.mapSeries(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};async.eachSeries(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}},async.iterator=function(tasks){var makeCallback=function(index){var fn=function(){return tasks.length&&tasks[index].apply(null,arguments),fn.next()};return fn.next=function(){return index<tasks.length-1?makeCallback(index+1):null},fn};return makeCallback(0)},async.apply=function(fn){var args=Array.prototype.slice.call(arguments,1);return function(){return fn.apply(null,args.concat(Array.prototype.slice.call(arguments)))}};var _concat=function(eachfn,arr,fn,callback){var r=[];eachfn(arr,function(x,cb){fn(x,function(err,y){r=r.concat(y||[]),cb(err)})},function(err){callback(err,r)})};async.concat=doParallel(_concat),async.concatSeries=doSeries(_concat),async.whilst=function(test,iterator,callback){test()?iterator(function(err){return err?callback(err):void async.whilst(test,iterator,callback)}):callback()},async.doWhilst=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?async.doWhilst(iterator,test,callback):callback())})},async.until=function(test,iterator,callback){test()?callback():iterator(function(err){return err?callback(err):void async.until(test,iterator,callback)})},async.doUntil=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?callback():async.doUntil(iterator,test,callback))})},async.queue=function(worker,concurrency){function _insert(q,data,pos,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){var item={data:task,callback:"function"==typeof callback?callback:null};pos?q.tasks.unshift(item):q.tasks.push(item),q.saturated&&q.tasks.length===concurrency&&q.saturated(),async.setImmediate(q.process)})}void 0===concurrency&&(concurrency=1);var workers=0,q={tasks:[],concurrency:concurrency,saturated:null,empty:null,drain:null,push:function(data,callback){_insert(q,data,!1,callback)},unshift:function(data,callback){_insert(q,data,!0,callback)},process:function(){if(workers<q.concurrency&&q.tasks.length){var task=q.tasks.shift();q.empty&&0===q.tasks.length&&q.empty(),workers+=1;var next=function(){workers-=1,task.callback&&task.callback.apply(task,arguments),q.drain&&q.tasks.length+workers===0&&q.drain(),q.process()},cb=only_once(next);worker(task.data,cb)}},length:function(){return q.tasks.length},running:function(){return workers}};return q},async.cargo=function(worker,payload){var working=!1,tasks=[],cargo={tasks:tasks,payload:payload,saturated:null,empty:null,drain:null,push:function(data,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){tasks.push({data:task,callback:"function"==typeof callback?callback:null}),cargo.saturated&&tasks.length===payload&&cargo.saturated()}),async.setImmediate(cargo.process)},process:function process(){if(!working){if(0===tasks.length)return void(cargo.drain&&cargo.drain());var ts="number"==typeof payload?tasks.splice(0,payload):tasks.splice(0),ds=_map(ts,function(task){return task.data});cargo.empty&&cargo.empty(),working=!0,worker(ds,function(){working=!1;var args=arguments;_each(ts,function(data){data.callback&&data.callback.apply(null,args)}),process()})}},length:function(){return tasks.length},running:function(){return working}};return cargo};var _console_fn=function(name){return function(fn){var args=Array.prototype.slice.call(arguments,1);fn.apply(null,args.concat([function(err){var args=Array.prototype.slice.call(arguments,1);"undefined"!=typeof console&&(err?console.error&&console.error(err):console[name]&&_each(args,function(x){console[name](x)}))}]))}};async.log=_console_fn("log"),async.dir=_console_fn("dir"),async.memoize=function(fn,hasher){var memo={},queues={};hasher=hasher||function(x){return x};var memoized=function(){var args=Array.prototype.slice.call(arguments),callback=args.pop(),key=hasher.apply(null,args);key in memo?callback.apply(null,memo[key]):key in queues?queues[key].push(callback):(queues[key]=[callback],fn.apply(null,args.concat([function(){memo[key]=arguments;var q=queues[key];delete queues[key];for(var i=0,l=q.length;l>i;i++)q[i].apply(null,arguments)}])))};return memoized.memo=memo,memoized.unmemoized=fn,memoized},async.unmemoize=function(fn){return function(){return(fn.unmemoized||fn).apply(null,arguments)}},async.times=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.map(counter,iterator,callback)},async.timesSeries=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.mapSeries(counter,iterator,callback)},async.compose=function(){var fns=Array.prototype.reverse.call(arguments);return function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();async.reduce(fns,args,function(newargs,fn,cb){fn.apply(that,newargs.concat([function(){var err=arguments[0],nextargs=Array.prototype.slice.call(arguments,1);cb(err,nextargs)}]))},function(err,results){callback.apply(that,[err].concat(results))})}};var _applyEach=function(eachfn,fns){var go=function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();return eachfn(fns,function(fn,cb){fn.apply(that,args.concat([cb]))},callback)};if(arguments.length>2){var args=Array.prototype.slice.call(arguments,2);return go.apply(this,args)}return go};async.applyEach=doParallel(_applyEach),async.applyEachSeries=doSeries(_applyEach),async.forever=function(fn,callback){function next(err){if(err){if(callback)return callback(err);throw err}fn(next)}next()},"undefined"!=typeof define&&define.amd?define([],function(){return async}):"undefined"!=typeof module&&module.exports?module.exports=async:root.async=async}(),function($){function maybeCall(thing,ctx){return"function"==typeof thing?thing.call(ctx):thing}function isElementInDOM(ele){for(;ele=ele.parentNode;)if(ele==document)return!0;return!1}function Tipsy(element,options){this.$element=$(element),this.options=options,this.enabled=!0,this.fixTitle()}Tipsy.prototype={show:function(){var title=this.getTitle();if(title&&this.enabled){var $tip=this.tip();$tip.find(".tipsy-inner")[this.options.html?"html":"text"](title),$tip[0].className="tipsy",$tip.remove().css({top:0,left:0,visibility:"hidden",display:"block"}).prependTo(document.body);var tp,pos=$.extend({},this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight}),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight,gravity=maybeCall(this.options.gravity,this.$element[0]);switch(gravity.charAt(0)){case"n":tp={top:pos.top+pos.height+this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"s":tp={top:pos.top-actualHeight-this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"e":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth-this.options.offset};break;case"w":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width+this.options.offset}}2==gravity.length&&("w"==gravity.charAt(1)?tp.left=pos.left+pos.width/2-15:tp.left=pos.left+pos.width/2-actualWidth+15),$tip.css(tp).addClass("tipsy-"+gravity),$tip.find(".tipsy-arrow")[0].className="tipsy-arrow tipsy-arrow-"+gravity.charAt(0),this.options.className&&$tip.addClass(maybeCall(this.options.className,this.$element[0])),this.options.fade?$tip.stop().css({opacity:0,display:"block",visibility:"visible"}).animate({opacity:this.options.opacity}):$tip.css({visibility:"visible",opacity:this.options.opacity})}},hide:function(){this.options.fade?this.tip().stop().fadeOut(function(){$(this).remove()}):this.tip().remove()},fixTitle:function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("original-title"))&&$e.attr("original-title",$e.attr("title")||"").removeAttr("title")},getTitle:function(){var title,$e=this.$element,o=this.options;this.fixTitle();var title,o=this.options;return"string"==typeof o.title?title=$e.attr("title"==o.title?"original-title":o.title):"function"==typeof o.title&&(title=o.title.call($e[0])),title=(""+title).replace(/(^\s*|\s*$)/,""),title||o.fallback},tip:function(){return this.$tip||(this.$tip=$('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>'),this.$tip.data("tipsy-pointee",this.$element[0])),this.$tip},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled}},$.fn.tipsy=function(options){function get(ele){var tipsy=$.data(ele,"tipsy");return tipsy||(tipsy=new Tipsy(ele,$.fn.tipsy.elementOptions(ele,options)),$.data(ele,"tipsy",tipsy)),tipsy}function enter(){var tipsy=get(this);tipsy.hoverState="in",0==options.delayIn?tipsy.show():(tipsy.fixTitle(),setTimeout(function(){"in"==tipsy.hoverState&&tipsy.show()},options.delayIn))}function leave(){var tipsy=get(this);tipsy.hoverState="out",0==options.delayOut?tipsy.hide():setTimeout(function(){"out"==tipsy.hoverState&&tipsy.hide()},options.delayOut)}if(options===!0)return this.data("tipsy");if("string"==typeof options){var tipsy=this.data("tipsy");return tipsy&&tipsy[options](),this}if(options=$.extend({},$.fn.tipsy.defaults,options),options.live||this.each(function(){get(this)}),"manual"!=options.trigger){var binder=options.live?"live":"bind",eventIn="hover"==options.trigger?"mouseenter":"focus",eventOut="hover"==options.trigger?"mouseleave":"blur";this[binder](eventIn,enter)[binder](eventOut,leave)}return this},$.fn.tipsy.defaults={className:null,delayIn:0,delayOut:0,fade:!1,fallback:"",gravity:"n",html:!1,live:!1,offset:0,opacity:.8,title:"title",trigger:"hover"},$.fn.tipsy.revalidate=function(){$(".tipsy").each(function(){var pointee=$.data(this,"tipsy-pointee");pointee&&isElementInDOM(pointee)||$(this).remove()})},$.fn.tipsy.elementOptions=function(ele,options){return $.metadata?$.extend({},options,$(ele).metadata()):options},$.fn.tipsy.autoNS=function(){return $(this).offset().top>$(document).scrollTop()+$(window).height()/2?"s":"n"},$.fn.tipsy.autoWE=function(){return $(this).offset().left>$(document).scrollLeft()+$(window).width()/2?"e":"w"},$.fn.tipsy.autoBounds=function(margin,prefer){return function(){var dir={ns:prefer[0],ew:prefer.length>1?prefer[1]:!1},boundTop=$(document).scrollTop()+margin,boundLeft=$(document).scrollLeft()+margin,$this=$(this);return $this.offset().top<boundTop&&(dir.ns="n"),$this.offset().left<boundLeft&&(dir.ew="w"),$(window).width()+$(document).scrollLeft()-$this.offset().left<margin&&(dir.ew="e"),$(window).height()+$(document).scrollTop()-$this.offset().top<margin&&(dir.ns="s"),dir.ns+(dir.ew?dir.ew:"")}}}(jQuery),function($){var current=null;$.kmodal=function(el,options){$.kmodal.close();var remove,target;if(this.$body=$("body"),this.options=$.extend({},$.kmodal.defaults,options),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),el.is("a"))if(target=el.attr("href"),/^#/.test(target)){if(this.$elm=$(target),1!==this.$elm.length)return null;this.open()}else this.$elm=$("<div>"),this.$body.append(this.$elm),remove=function(event,modal){modal.elm.remove()},this.showSpinner(),el.trigger($.kmodal.AJAX_SEND),$.get(target).done(function(html){current&&(el.trigger($.kmodal.AJAX_SUCCESS),current.$elm.empty().append(html).on($.kmodal.CLOSE,remove),current.hideSpinner(),current.open(),el.trigger($.kmodal.AJAX_COMPLETE))}).fail(function(){el.trigger($.kmodal.AJAX_FAIL),current.hideSpinner(),el.trigger($.kmodal.AJAX_COMPLETE)});else this.$elm=el,this.$body.append(this.$elm),this.open()},$.kmodal.prototype={constructor:$.kmodal,open:function(){var m=this;this.options.doFade?(this.block(),setTimeout(function(){m.show()},this.options.fadeDuration*this.options.fadeDelay)):(this.block(),this.show()),this.options.escapeClose&&$(document).on("keydown.modal",function(event){27==event.which&&$.kmodal.close()}),this.options.clickClose&&this.blocker.click($.kmodal.close)},close:function(){this.unblock(),this.hide(),$(document).off("keydown.modal")},block:function(){var initialOpacity=this.options.doFade?0:this.options.opacity;this.$elm.trigger($.kmodal.BEFORE_BLOCK,[this._ctx()]),this.blocker=$('<div class="jquery-modal blocker"></div>').css({top:0,right:0,bottom:0,left:0,width:"100%",height:"100%",position:"fixed",zIndex:this.options.zIndex,background:this.options.overlay,opacity:initialOpacity}),this.$body.append(this.blocker),this.options.doFade&&this.blocker.animate({opacity:this.options.opacity},this.options.fadeDuration),this.$elm.trigger($.kmodal.BLOCK,[this._ctx()])},unblock:function(){this.options.doFade?this.blocker.fadeOut(this.options.fadeDuration,function(){$(this).remove()}):this.blocker.remove()},show:function(){this.$elm.trigger($.kmodal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=$('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass+" current"),this.center(),this.options.doFade?this.$elm.fadeIn(this.options.fadeDuration):this.$elm.show(),this.$elm.trigger($.kmodal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger($.kmodal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove(),this.$elm.removeClass("current"),this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration):this.$elm.hide(),this.$elm.trigger($.kmodal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||$('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},center:function(){this.$elm.css({position:"fixed",top:"50%",left:"50%",marginTop:-(this.$elm.outerHeight()/2),marginLeft:-(this.$elm.outerWidth()/2),zIndex:this.options.zIndex+1})},_ctx:function(){return{elm:this.$elm,blocker:this.blocker,options:this.options}}},$.kmodal.prototype.resize=$.kmodal.prototype.center,$.kmodal.close=function(event){if(current){event&&event.preventDefault(),current.close();var that=current.$elm;return current=null,that}},$.kmodal.resize=function(){current&&current.resize()},$.kmodal.isActive=function(){return current?!0:!1},$.kmodal.defaults={overlay:"#000",opacity:.75,zIndex:1,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"kraken-modal",spinnerHtml:null,showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},$.kmodal.BEFORE_BLOCK="modal:before-block",$.kmodal.BLOCK="modal:block",$.kmodal.BEFORE_OPEN="modal:before-open",$.kmodal.OPEN="modal:open",$.kmodal.BEFORE_CLOSE="modal:before-close",$.kmodal.CLOSE="modal:close",$.kmodal.AJAX_SEND="modal:ajax:send",$.kmodal.AJAX_SUCCESS="modal:ajax:success",$.kmodal.AJAX_FAIL="modal:ajax:fail",$.kmodal.AJAX_COMPLETE="modal:ajax:complete",$.fn.kmodal=function(options){return 1===this.length&&(current=new $.kmodal(this,options)),this},$(document).on("click.modal",'a[rel="modal:close"]',$.kmodal.close),$(document).on("click.modal",'a[rel="modal:open"]',function(event){event.preventDefault(),$(this).kmodal()})}(jQuery),jQuery(document).ready(function($){$(".krakenWhatsThis").tipsy({fade:!0,gravity:"w"});var data={action:"kraken_request"},errorTpl='<div class="krakenErrorWrap"><a class="krakenError">Failed! Hover here</a></div>',$btnApplyBulkAction=$("#doaction"),$btnApplyBulkAction2=$("#doaction2"),$topBulkActionDropdown=$(".tablenav.top .bulkactions select[name='action']"),$bottomBulkActionDropdown=$(".tablenav.bottom .bulkactions select[name='action2']"),requestSuccess=function(data,textStatus,jqXHR){var $button=$(this),$parent=$(this).parent(),$cell=$(this).closest("td");if(data.success&&"undefined"==typeof data.error){$button.text("Image optimized");var originalSize=(data.type,data.kraked_size,data.original_size),$originalSizeColumn=(data.savings_percent,$(this).parent().prev("td.original_size"));$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),$(this).replaceWith(data.html),$originalSizeColumn.html(originalSize),$parent.remove()})}else if(data.error){var $error=$(errorTpl).attr("title",data.error);$parent.closest("td").find(".krakenErrorWrap").remove(),$parent.after($error),$error.tipsy({fade:!0,gravity:"e"}),$button.text("Retry request").removeAttr("disabled").css({opacity:1})}},requestFail=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled")},requestComplete=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled"),$(this).parent().find(".krakenSpinner").css("display","none")},opts='<option value="kraken-bulk-lossy">Krak \'em all</option>';$topBulkActionDropdown.find("option:last-child").before(opts),$bottomBulkActionDropdown.find("option:last-child").before(opts);var getBulkImageData=function(){var $rows=$("tr[id^='post-']"),$row=null,postId=0,$krakBtn=null,btnData={},originalSize="",rv=[];return $rows.each(function(){$row=$(this),postId=this.id.replace(/^\D+/g,""),$row.find("input[type='checkbox'][value='"+postId+"']:checked").length&&($krakBtn=$row.find(".kraken_req"),$krakBtn.length&&(btnData=$krakBtn.data(),originalSize=$.trim($row.find("td.original_size").text()),btnData.originalSize=originalSize,rv.push(btnData)))}),rv},renderBulkImageSummary=function(bulkImageData){var modalOptions={zIndex:4,escapeClose:!0,clickClose:!1,closeText:"close",showClose:!1},setting=kraken_settings.api_lossy,nImages=bulkImageData.length,header='<p class="krakenBulkHeader">Kraken Bulk Image Optimization</p>',krakEmAll='<button class="kraken_req_bulk">Krak \'em all</button>',typeRadios='<span class="radiosWrap"><span class="kraken-bulk-choose-type">Choose:</span><input type="radio" id="kraken-bulk-type-lossy" value="Lossy" name="kraken-bulk-type"/><label for="kraken-bulk-type-lossy">Lossy</label>&nbsp;<input type="radio" id="kraken-bulk-type-lossless" value="Lossless" name="kraken-bulk-type"/><label for="kraken-bulk-type-lossless">Lossless</label></span>',$modal=$('<div id="kraken-bulk-modal" class="kraken-modal"></div>').html(header).append(typeRadios).append('<br /><small class="kraken-bulk-small">The following <strong>'+nImages+'</strong> images will be optimized by Kraken.io using the <strong class="bulkSetting">'+setting+"</strong> setting:</small><br />").appendTo("body").kmodal(modalOptions).bind($.kmodal.BEFORE_CLOSE,function(event,modal){}).bind($.kmodal.OPEN,function(event,modal){}).bind($.kmodal.CLOSE,function(event,modal){$("#kraken-bulk-modal").remove()}).css({top:"10px",marginTop:"40px"});"lossy"===setting?$("#kraken-bulk-type-lossy").attr("checked",!0):$("#kraken-bulk-type-lossless").attr("checked",!0),$bulkSettingSpan=$(".bulkSetting"),$("input[name='kraken-bulk-type']").change(function(){var text="kraken-bulk-type-lossy"===this.id?"lossy":"lossless";$bulkSettingSpan.text(text)}),$(".jquery-modal.blocker").click(function(e){return!1}),$("#menu-media ul.wp-submenu").css({"z-index":1});var $table=$('<table id="kraken-bulk"></table>'),$headerRow=$('<tr class="kraken-bulk-header"><td>File</td><td style="width:120px">Original Size</td><td style="width:120px">Kraked Size</td><td style="width:120px">Savings</td><td style="width:120px">% Savings</td></tr>');$table.append($headerRow),$.each(bulkImageData,function(index,element){$table.append('<tr class="kraken-item-row" data-krakenbulkid="'+element.id+'"><td class="kraken-filename">'+element.filename+'</td><td class="kraken-originalsize">'+element.originalSize+'</td><td class="kraken-krakedsize"><span class="krakenBulkSpinner hidden"></span></td><td class="kraken-savings"></td><td class="kraken-savingsPercent"></td></tr>')}),$modal.append($table).append(krakEmAll).append('<span class="close-kraken-bulk">Close Window</span>'),$(".close-kraken-bulk").click(function(){$.kmodal.close()}),nImages||$(".kraken_req_bulk").attr("disabled",!0).css({opacity:.5})},bulkAction=function(bulkImageData){$bulkTable=$("#kraken-bulk");var jqxhr=null,q=async.queue(function(task,callback){var id=task.id,$row=(task.filename,$bulkTable.find("tr[data-krakenbulkid='"+id+"']")),$krakedSizeColumn=$row.find(".kraken-krakedsize"),$spinner=$krakedSizeColumn.find(".krakenBulkSpinner").css({display:"inline-block"}),$savingsPercentColumn=$row.find(".kraken-savingsPercent"),$savingsBytesColumn=$row.find(".kraken-savings");jqxhr=$.ajax({url:ajax_object.ajax_url,data:{action:"kraken_request",id:id,type:$("input[name='kraken-bulk-type']:checked").val().toLowerCase()},type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){if(data.success&&"undefined"==typeof data.error){var type=data.type,originalSize=data.original_size,krakedSize=data.kraked_size,savingsPercent=data.savings_percent,savingsBytes=data.saved_bytes;$krakedSizeColumn.text(krakedSize),$savingsPercentColumn.text(savingsPercent),$savingsBytesColumn.text(savingsBytes);var $button=$("button[id='krakenid-"+id+"']"),$parent=$button.parent(),$cell=$button.closest("td"),$originalSizeColumn=$button.parent().prev("td.original_size");$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),krakedData="<strong>"+krakedSize+"</strong><br /><small>Type:&nbsp;"+type+"</small><br /><small>Savings: "+savingsPercent+"</small>","undefined"!=typeof data.thumbs_data&&(krakedData+="<br /><small>"+data.thumbs_data.length+" thumbs optimized</small>"),$(this).replaceWith(krakedData),$originalSizeColumn.html(originalSize),$parent.remove()})}else data.error&&"This image can not be optimized any further"===data.error&&$krakedSizeColumn.text("No savings found.")}).fail(function(){}).always(function(){$spinner.css({display:"none"}),callback()})},kraken_settings.bulk_async_limit);q.drain=function(){$(".kraken_req_bulk").removeAttr("disabled").css({opacity:1}).text("Done").unbind("click").click(function(){$.kmodal.close()})},q.push(bulkImageData,function(err){})};$btnApplyBulkAction.add($btnApplyBulkAction2).click(function(e){if("kraken-bulk-lossy"===$(this).prev("select").val()){e.preventDefault();var bulkImageData=getBulkImageData();renderBulkImageSummary(bulkImageData),$(".kraken_req_bulk").click(function(e){e.preventDefault(),$(this).attr("disabled",!0).css({opacity:.5}),bulkAction(bulkImageData)})}}),$("body").on("click","small.krakenReset",function(e){e.preventDefault();var $resetButton=$(this),resetData={action:"kraken_reset"};resetData.id=$(this).data("id");var $spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){"undefined"!==data.success&&$resetButton.closest(".kraked_size.column-kraked_size").hide().html(data.html).fadeIn().prev(".original_size.column-original_size").html(data.original_size)})}),$("body").on("click",".kraken-reset-all",function(e){e.preventDefault();var reset=confirm("This will immediately remove all Kraken metadata associated with your images. \n\nAre you sure you want to do this?");if(reset){var $resetButton=$(this);$resetButton.text("Resetting images, pleaes wait...").attr("disabled",!0);
2
 
3
- var resetData={action:"kraken_reset_all"},$spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);{$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){$spinner.remove(),$resetButton.text("Your images have been reset.").removeAttr("disabled").removeClass("enabled")})}}}),$("body").on("click",".kraken_req",function(e){e.preventDefault();var $button=$(this),$parent=$(this).parent();data.id=$(this).data("id"),$button.text("Optimizing image...").attr("disabled",!0).css({opacity:.5}),$parent.find(".krakenSpinner").css("display","inline");$.ajax({url:ajax_object.ajax_url,data:data,type:"post",dataType:"json",timeout:36e4,context:$button}).done(requestSuccess).fail(requestFail).always(requestComplete)})});
1
  !function(){function only_once(fn){var called=!1;return function(){if(called)throw new Error("Callback was already called.");called=!0,fn.apply(root,arguments)}}var root,previous_async,async={};root=this,null!=root&&(previous_async=root.async),async.noConflict=function(){return root.async=previous_async,async};var _each=function(arr,iterator){if(arr.forEach)return arr.forEach(iterator);for(var i=0;i<arr.length;i+=1)iterator(arr[i],i,arr)},_map=function(arr,iterator){if(arr.map)return arr.map(iterator);var results=[];return _each(arr,function(x,i,a){results.push(iterator(x,i,a))}),results},_reduce=function(arr,iterator,memo){return arr.reduce?arr.reduce(iterator,memo):(_each(arr,function(x,i,a){memo=iterator(memo,x,i,a)}),memo)},_keys=function(obj){if(Object.keys)return Object.keys(obj);var keys=[];for(var k in obj)obj.hasOwnProperty(k)&&keys.push(k);return keys};"undefined"!=typeof process&&process.nextTick?(async.nextTick=process.nextTick,"undefined"!=typeof setImmediate?async.setImmediate=function(fn){setImmediate(fn)}:async.setImmediate=async.nextTick):"function"==typeof setImmediate?(async.nextTick=function(fn){setImmediate(fn)},async.setImmediate=async.nextTick):(async.nextTick=function(fn){setTimeout(fn,0)},async.setImmediate=async.nextTick),async.each=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0;_each(arr,function(x){iterator(x,only_once(function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length&&callback(null))}))})},async.forEach=async.each,async.eachSeries=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0,iterate=function(){iterator(arr[completed],function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length?callback(null):iterate())})};iterate()},async.forEachSeries=async.eachSeries,async.eachLimit=function(arr,limit,iterator,callback){var fn=_eachLimit(limit);fn.apply(null,[arr,iterator,callback])},async.forEachLimit=async.eachLimit;var _eachLimit=function(limit){return function(arr,iterator,callback){if(callback=callback||function(){},!arr.length||0>=limit)return callback();var completed=0,started=0,running=0;!function replenish(){if(completed>=arr.length)return callback();for(;limit>running&&started<arr.length;)started+=1,running+=1,iterator(arr[started-1],function(err){err?(callback(err),callback=function(){}):(completed+=1,running-=1,completed>=arr.length?callback():replenish())})}()}},doParallel=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.each].concat(args))}},doParallelLimit=function(limit,fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[_eachLimit(limit)].concat(args))}},doSeries=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.eachSeries].concat(args))}},_asyncMap=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(err,v){results[x.index]=v,callback(err)})},function(err){callback(err,results)})};async.map=doParallel(_asyncMap),async.mapSeries=doSeries(_asyncMap),async.mapLimit=function(arr,limit,iterator,callback){return _mapLimit(limit)(arr,iterator,callback)};var _mapLimit=function(limit){return doParallelLimit(limit,_asyncMap)};async.reduce=function(arr,memo,iterator,callback){async.eachSeries(arr,function(x,callback){iterator(memo,x,function(err,v){memo=v,callback(err)})},function(err){callback(err,memo)})},async.inject=async.reduce,async.foldl=async.reduce,async.reduceRight=function(arr,memo,iterator,callback){var reversed=_map(arr,function(x){return x}).reverse();async.reduce(reversed,memo,iterator,callback)},async.foldr=async.reduceRight;var _filter=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v&&results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.filter=doParallel(_filter),async.filterSeries=doSeries(_filter),async.select=async.filter,async.selectSeries=async.filterSeries;var _reject=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v||results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.reject=doParallel(_reject),async.rejectSeries=doSeries(_reject);var _detect=function(eachfn,arr,iterator,main_callback){eachfn(arr,function(x,callback){iterator(x,function(result){result?(main_callback(x),main_callback=function(){}):callback()})},function(err){main_callback()})};async.detect=doParallel(_detect),async.detectSeries=doSeries(_detect),async.some=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v&&(main_callback(!0),main_callback=function(){}),callback()})},function(err){main_callback(!1)})},async.any=async.some,async.every=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v||(main_callback(!1),main_callback=function(){}),callback()})},function(err){main_callback(!0)})},async.all=async.every,async.sortBy=function(arr,iterator,callback){async.map(arr,function(x,callback){iterator(x,function(err,criteria){err?callback(err):callback(null,{value:x,criteria:criteria})})},function(err,results){if(err)return callback(err);var fn=function(left,right){var a=left.criteria,b=right.criteria;return b>a?-1:a>b?1:0};callback(null,_map(results.sort(fn),function(x){return x.value}))})},async.auto=function(tasks,callback){callback=callback||function(){};var keys=_keys(tasks);if(!keys.length)return callback(null);var results={},listeners=[],addListener=function(fn){listeners.unshift(fn)},removeListener=function(fn){for(var i=0;i<listeners.length;i+=1)if(listeners[i]===fn)return void listeners.splice(i,1)},taskComplete=function(){_each(listeners.slice(0),function(fn){fn()})};addListener(function(){_keys(results).length===keys.length&&(callback(null,results),callback=function(){})}),_each(keys,function(k){var task=tasks[k]instanceof Function?[tasks[k]]:tasks[k],taskCallback=function(err){var args=Array.prototype.slice.call(arguments,1);if(args.length<=1&&(args=args[0]),err){var safeResults={};_each(_keys(results),function(rkey){safeResults[rkey]=results[rkey]}),safeResults[k]=args,callback(err,safeResults),callback=function(){}}else results[k]=args,async.setImmediate(taskComplete)},requires=task.slice(0,Math.abs(task.length-1))||[],ready=function(){return _reduce(requires,function(a,x){return a&&results.hasOwnProperty(x)},!0)&&!results.hasOwnProperty(k)};if(ready())task[task.length-1](taskCallback,results);else{var listener=function(){ready()&&(removeListener(listener),task[task.length-1](taskCallback,results))};addListener(listener)}})},async.waterfall=function(tasks,callback){if(callback=callback||function(){},tasks.constructor!==Array){var err=new Error("First argument to waterfall must be an array of functions");return callback(err)}if(!tasks.length)return callback();var wrapIterator=function(iterator){return function(err){if(err)callback.apply(null,arguments),callback=function(){};else{var args=Array.prototype.slice.call(arguments,1),next=iterator.next();args.push(next?wrapIterator(next):callback),async.setImmediate(function(){iterator.apply(null,args)})}}};wrapIterator(async.iterator(tasks))()};var _parallel=function(eachfn,tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)eachfn.map(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};eachfn.each(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}};async.parallel=function(tasks,callback){_parallel({map:async.map,each:async.each},tasks,callback)},async.parallelLimit=function(tasks,limit,callback){_parallel({map:_mapLimit(limit),each:_eachLimit(limit)},tasks,callback)},async.series=function(tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)async.mapSeries(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};async.eachSeries(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}},async.iterator=function(tasks){var makeCallback=function(index){var fn=function(){return tasks.length&&tasks[index].apply(null,arguments),fn.next()};return fn.next=function(){return index<tasks.length-1?makeCallback(index+1):null},fn};return makeCallback(0)},async.apply=function(fn){var args=Array.prototype.slice.call(arguments,1);return function(){return fn.apply(null,args.concat(Array.prototype.slice.call(arguments)))}};var _concat=function(eachfn,arr,fn,callback){var r=[];eachfn(arr,function(x,cb){fn(x,function(err,y){r=r.concat(y||[]),cb(err)})},function(err){callback(err,r)})};async.concat=doParallel(_concat),async.concatSeries=doSeries(_concat),async.whilst=function(test,iterator,callback){test()?iterator(function(err){return err?callback(err):void async.whilst(test,iterator,callback)}):callback()},async.doWhilst=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?async.doWhilst(iterator,test,callback):callback())})},async.until=function(test,iterator,callback){test()?callback():iterator(function(err){return err?callback(err):void async.until(test,iterator,callback)})},async.doUntil=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?callback():async.doUntil(iterator,test,callback))})},async.queue=function(worker,concurrency){function _insert(q,data,pos,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){var item={data:task,callback:"function"==typeof callback?callback:null};pos?q.tasks.unshift(item):q.tasks.push(item),q.saturated&&q.tasks.length===concurrency&&q.saturated(),async.setImmediate(q.process)})}void 0===concurrency&&(concurrency=1);var workers=0,q={tasks:[],concurrency:concurrency,saturated:null,empty:null,drain:null,push:function(data,callback){_insert(q,data,!1,callback)},unshift:function(data,callback){_insert(q,data,!0,callback)},process:function(){if(workers<q.concurrency&&q.tasks.length){var task=q.tasks.shift();q.empty&&0===q.tasks.length&&q.empty(),workers+=1;var next=function(){workers-=1,task.callback&&task.callback.apply(task,arguments),q.drain&&q.tasks.length+workers===0&&q.drain(),q.process()},cb=only_once(next);worker(task.data,cb)}},length:function(){return q.tasks.length},running:function(){return workers}};return q},async.cargo=function(worker,payload){var working=!1,tasks=[],cargo={tasks:tasks,payload:payload,saturated:null,empty:null,drain:null,push:function(data,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){tasks.push({data:task,callback:"function"==typeof callback?callback:null}),cargo.saturated&&tasks.length===payload&&cargo.saturated()}),async.setImmediate(cargo.process)},process:function process(){if(!working){if(0===tasks.length)return void(cargo.drain&&cargo.drain());var ts="number"==typeof payload?tasks.splice(0,payload):tasks.splice(0),ds=_map(ts,function(task){return task.data});cargo.empty&&cargo.empty(),working=!0,worker(ds,function(){working=!1;var args=arguments;_each(ts,function(data){data.callback&&data.callback.apply(null,args)}),process()})}},length:function(){return tasks.length},running:function(){return working}};return cargo};var _console_fn=function(name){return function(fn){var args=Array.prototype.slice.call(arguments,1);fn.apply(null,args.concat([function(err){var args=Array.prototype.slice.call(arguments,1);"undefined"!=typeof console&&(err?console.error&&console.error(err):console[name]&&_each(args,function(x){console[name](x)}))}]))}};async.log=_console_fn("log"),async.dir=_console_fn("dir"),async.memoize=function(fn,hasher){var memo={},queues={};hasher=hasher||function(x){return x};var memoized=function(){var args=Array.prototype.slice.call(arguments),callback=args.pop(),key=hasher.apply(null,args);key in memo?callback.apply(null,memo[key]):key in queues?queues[key].push(callback):(queues[key]=[callback],fn.apply(null,args.concat([function(){memo[key]=arguments;var q=queues[key];delete queues[key];for(var i=0,l=q.length;l>i;i++)q[i].apply(null,arguments)}])))};return memoized.memo=memo,memoized.unmemoized=fn,memoized},async.unmemoize=function(fn){return function(){return(fn.unmemoized||fn).apply(null,arguments)}},async.times=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.map(counter,iterator,callback)},async.timesSeries=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.mapSeries(counter,iterator,callback)},async.compose=function(){var fns=Array.prototype.reverse.call(arguments);return function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();async.reduce(fns,args,function(newargs,fn,cb){fn.apply(that,newargs.concat([function(){var err=arguments[0],nextargs=Array.prototype.slice.call(arguments,1);cb(err,nextargs)}]))},function(err,results){callback.apply(that,[err].concat(results))})}};var _applyEach=function(eachfn,fns){var go=function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();return eachfn(fns,function(fn,cb){fn.apply(that,args.concat([cb]))},callback)};if(arguments.length>2){var args=Array.prototype.slice.call(arguments,2);return go.apply(this,args)}return go};async.applyEach=doParallel(_applyEach),async.applyEachSeries=doSeries(_applyEach),async.forever=function(fn,callback){function next(err){if(err){if(callback)return callback(err);throw err}fn(next)}next()},"undefined"!=typeof define&&define.amd?define([],function(){return async}):"undefined"!=typeof module&&module.exports?module.exports=async:root.async=async}(),function($){function maybeCall(thing,ctx){return"function"==typeof thing?thing.call(ctx):thing}function isElementInDOM(ele){for(;ele=ele.parentNode;)if(ele==document)return!0;return!1}function Tipsy(element,options){this.$element=$(element),this.options=options,this.enabled=!0,this.fixTitle()}Tipsy.prototype={show:function(){var title=this.getTitle();if(title&&this.enabled){var $tip=this.tip();$tip.find(".tipsy-inner")[this.options.html?"html":"text"](title),$tip[0].className="tipsy",$tip.remove().css({top:0,left:0,visibility:"hidden",display:"block"}).prependTo(document.body);var tp,pos=$.extend({},this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight}),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight,gravity=maybeCall(this.options.gravity,this.$element[0]);switch(gravity.charAt(0)){case"n":tp={top:pos.top+pos.height+this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"s":tp={top:pos.top-actualHeight-this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"e":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth-this.options.offset};break;case"w":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width+this.options.offset}}2==gravity.length&&("w"==gravity.charAt(1)?tp.left=pos.left+pos.width/2-15:tp.left=pos.left+pos.width/2-actualWidth+15),$tip.css(tp).addClass("tipsy-"+gravity),$tip.find(".tipsy-arrow")[0].className="tipsy-arrow tipsy-arrow-"+gravity.charAt(0),this.options.className&&$tip.addClass(maybeCall(this.options.className,this.$element[0])),this.options.fade?$tip.stop().css({opacity:0,display:"block",visibility:"visible"}).animate({opacity:this.options.opacity}):$tip.css({visibility:"visible",opacity:this.options.opacity})}},hide:function(){this.options.fade?this.tip().stop().fadeOut(function(){$(this).remove()}):this.tip().remove()},fixTitle:function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("original-title"))&&$e.attr("original-title",$e.attr("title")||"").removeAttr("title")},getTitle:function(){var title,$e=this.$element,o=this.options;this.fixTitle();var title,o=this.options;return"string"==typeof o.title?title=$e.attr("title"==o.title?"original-title":o.title):"function"==typeof o.title&&(title=o.title.call($e[0])),title=(""+title).replace(/(^\s*|\s*$)/,""),title||o.fallback},tip:function(){return this.$tip||(this.$tip=$('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>'),this.$tip.data("tipsy-pointee",this.$element[0])),this.$tip},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled}},$.fn.tipsy=function(options){function get(ele){var tipsy=$.data(ele,"tipsy");return tipsy||(tipsy=new Tipsy(ele,$.fn.tipsy.elementOptions(ele,options)),$.data(ele,"tipsy",tipsy)),tipsy}function enter(){var tipsy=get(this);tipsy.hoverState="in",0==options.delayIn?tipsy.show():(tipsy.fixTitle(),setTimeout(function(){"in"==tipsy.hoverState&&tipsy.show()},options.delayIn))}function leave(){var tipsy=get(this);tipsy.hoverState="out",0==options.delayOut?tipsy.hide():setTimeout(function(){"out"==tipsy.hoverState&&tipsy.hide()},options.delayOut)}if(options===!0)return this.data("tipsy");if("string"==typeof options){var tipsy=this.data("tipsy");return tipsy&&tipsy[options](),this}if(options=$.extend({},$.fn.tipsy.defaults,options),options.live||this.each(function(){get(this)}),"manual"!=options.trigger){var binder=options.live?"live":"bind",eventIn="hover"==options.trigger?"mouseenter":"focus",eventOut="hover"==options.trigger?"mouseleave":"blur";this[binder](eventIn,enter)[binder](eventOut,leave)}return this},$.fn.tipsy.defaults={className:null,delayIn:0,delayOut:0,fade:!1,fallback:"",gravity:"n",html:!1,live:!1,offset:0,opacity:.8,title:"title",trigger:"hover"},$.fn.tipsy.revalidate=function(){$(".tipsy").each(function(){var pointee=$.data(this,"tipsy-pointee");pointee&&isElementInDOM(pointee)||$(this).remove()})},$.fn.tipsy.elementOptions=function(ele,options){return $.metadata?$.extend({},options,$(ele).metadata()):options},$.fn.tipsy.autoNS=function(){return $(this).offset().top>$(document).scrollTop()+$(window).height()/2?"s":"n"},$.fn.tipsy.autoWE=function(){return $(this).offset().left>$(document).scrollLeft()+$(window).width()/2?"e":"w"},$.fn.tipsy.autoBounds=function(margin,prefer){return function(){var dir={ns:prefer[0],ew:prefer.length>1?prefer[1]:!1},boundTop=$(document).scrollTop()+margin,boundLeft=$(document).scrollLeft()+margin,$this=$(this);return $this.offset().top<boundTop&&(dir.ns="n"),$this.offset().left<boundLeft&&(dir.ew="w"),$(window).width()+$(document).scrollLeft()-$this.offset().left<margin&&(dir.ew="e"),$(window).height()+$(document).scrollTop()-$this.offset().top<margin&&(dir.ns="s"),dir.ns+(dir.ew?dir.ew:"")}}}(jQuery),function($){var current=null;$.kmodal=function(el,options){$.kmodal.close();var remove,target;if(this.$body=$("body"),this.options=$.extend({},$.kmodal.defaults,options),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),el.is("a"))if(target=el.attr("href"),/^#/.test(target)){if(this.$elm=$(target),1!==this.$elm.length)return null;this.open()}else this.$elm=$("<div>"),this.$body.append(this.$elm),remove=function(event,modal){modal.elm.remove()},this.showSpinner(),el.trigger($.kmodal.AJAX_SEND),$.get(target).done(function(html){current&&(el.trigger($.kmodal.AJAX_SUCCESS),current.$elm.empty().append(html).on($.kmodal.CLOSE,remove),current.hideSpinner(),current.open(),el.trigger($.kmodal.AJAX_COMPLETE))}).fail(function(){el.trigger($.kmodal.AJAX_FAIL),current.hideSpinner(),el.trigger($.kmodal.AJAX_COMPLETE)});else this.$elm=el,this.$body.append(this.$elm),this.open()},$.kmodal.prototype={constructor:$.kmodal,open:function(){var m=this;this.options.doFade?(this.block(),setTimeout(function(){m.show()},this.options.fadeDuration*this.options.fadeDelay)):(this.block(),this.show()),this.options.escapeClose&&$(document).on("keydown.modal",function(event){27==event.which&&$.kmodal.close()}),this.options.clickClose&&this.blocker.click($.kmodal.close)},close:function(){this.unblock(),this.hide(),$(document).off("keydown.modal")},block:function(){var initialOpacity=this.options.doFade?0:this.options.opacity;this.$elm.trigger($.kmodal.BEFORE_BLOCK,[this._ctx()]),this.blocker=$('<div class="jquery-modal blocker"></div>').css({top:0,right:0,bottom:0,left:0,width:"100%",height:"100%",position:"fixed",zIndex:this.options.zIndex,background:this.options.overlay,opacity:initialOpacity}),this.$body.append(this.blocker),this.options.doFade&&this.blocker.animate({opacity:this.options.opacity},this.options.fadeDuration),this.$elm.trigger($.kmodal.BLOCK,[this._ctx()])},unblock:function(){this.options.doFade?this.blocker.fadeOut(this.options.fadeDuration,function(){$(this).remove()}):this.blocker.remove()},show:function(){this.$elm.trigger($.kmodal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=$('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass+" current"),this.center(),this.options.doFade?this.$elm.fadeIn(this.options.fadeDuration):this.$elm.show(),this.$elm.trigger($.kmodal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger($.kmodal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove(),this.$elm.removeClass("current"),this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration):this.$elm.hide(),this.$elm.trigger($.kmodal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||$('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},center:function(){this.$elm.css({position:"fixed",top:"50%",left:"50%",marginTop:-(this.$elm.outerHeight()/2),marginLeft:-(this.$elm.outerWidth()/2),zIndex:this.options.zIndex+1})},_ctx:function(){return{elm:this.$elm,blocker:this.blocker,options:this.options}}},$.kmodal.prototype.resize=$.kmodal.prototype.center,$.kmodal.close=function(event){if(current){event&&event.preventDefault(),current.close();var that=current.$elm;return current=null,that}},$.kmodal.resize=function(){current&&current.resize()},$.kmodal.isActive=function(){return current?!0:!1},$.kmodal.defaults={overlay:"#000",opacity:.75,zIndex:1,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"kraken-modal",spinnerHtml:null,showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},$.kmodal.BEFORE_BLOCK="modal:before-block",$.kmodal.BLOCK="modal:block",$.kmodal.BEFORE_OPEN="modal:before-open",$.kmodal.OPEN="modal:open",$.kmodal.BEFORE_CLOSE="modal:before-close",$.kmodal.CLOSE="modal:close",$.kmodal.AJAX_SEND="modal:ajax:send",$.kmodal.AJAX_SUCCESS="modal:ajax:success",$.kmodal.AJAX_FAIL="modal:ajax:fail",$.kmodal.AJAX_COMPLETE="modal:ajax:complete",$.fn.kmodal=function(options){return 1===this.length&&(current=new $.kmodal(this,options)),this},$(document).on("click.modal",'a[rel="modal:close"]',$.kmodal.close),$(document).on("click.modal",'a[rel="modal:open"]',function(event){event.preventDefault(),$(this).kmodal()})}(jQuery),jQuery(document).ready(function($){$(".krakenWhatsThis").tipsy({fade:!0,gravity:"w"});var data={action:"kraken_request"},errorTpl='<div class="krakenErrorWrap"><a class="krakenError">Failed! Hover here</a></div>',$btnApplyBulkAction=$("#doaction"),$btnApplyBulkAction2=$("#doaction2"),$topBulkActionDropdown=$(".tablenav.top .bulkactions select[name='action']"),$bottomBulkActionDropdown=$(".tablenav.bottom .bulkactions select[name='action2']"),requestSuccess=function(data,textStatus,jqXHR){var $button=$(this),$parent=$(this).parent(),$cell=$(this).closest("td");if(data.success&&"undefined"==typeof data.error){$button.text("Image optimized");var originalSize=(data.type,data.kraked_size,data.original_size),$originalSizeColumn=(data.savings_percent,$(this).parent().prev("td.original_size"));$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),$(this).replaceWith(data.html),$originalSizeColumn.html(originalSize),$parent.remove()})}else if(data.error){var $error=$(errorTpl).attr("title",data.error);$parent.closest("td").find(".krakenErrorWrap").remove(),$parent.after($error),$error.tipsy({fade:!0,gravity:"e"}),$button.text("Retry request").removeAttr("disabled").css({opacity:1})}},requestFail=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled")},requestComplete=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled"),$(this).parent().find(".krakenSpinner").css("display","none")},opts='<option value="kraken-bulk-lossy">Krak \'em all</option>';$topBulkActionDropdown.find("option:last-child").before(opts),$bottomBulkActionDropdown.find("option:last-child").before(opts);var getBulkImageData=function(){var $rows=$("tr[id^='post-']"),$row=null,postId=0,$krakBtn=null,btnData={},originalSize="",rv=[];return $rows.each(function(){$row=$(this),postId=this.id.replace(/^\D+/g,""),$row.find("input[type='checkbox'][value='"+postId+"']:checked").length&&($krakBtn=$row.find(".kraken_req"),$krakBtn.length&&(btnData=$krakBtn.data(),originalSize=$.trim($row.find("td.original_size").text()),btnData.originalSize=originalSize,rv.push(btnData)))}),rv},renderBulkImageSummary=function(bulkImageData){var modalOptions={zIndex:4,escapeClose:!0,clickClose:!1,closeText:"close",showClose:!1},setting=kraken_settings.api_lossy,nImages=bulkImageData.length,header='<p class="krakenBulkHeader">Kraken Bulk Image Optimization</p>',krakEmAll='<button class="kraken_req_bulk">Krak \'em all</button>',typeRadios='<span class="radiosWrap"><span class="kraken-bulk-choose-type">Choose:</span><input type="radio" id="kraken-bulk-type-lossy" value="Lossy" name="kraken-bulk-type"/><label for="kraken-bulk-type-lossy">Lossy</label>&nbsp;<input type="radio" id="kraken-bulk-type-lossless" value="Lossless" name="kraken-bulk-type"/><label for="kraken-bulk-type-lossless">Lossless</label></span>',$modal=$('<div id="kraken-bulk-modal" class="kraken-modal"></div>').html(header).append(typeRadios).append('<br /><small class="kraken-bulk-small">The following <strong>'+nImages+'</strong> images will be optimized by Kraken.io using the <strong class="bulkSetting">'+setting+"</strong> setting:</small><br />").appendTo("body").kmodal(modalOptions).bind($.kmodal.BEFORE_CLOSE,function(event,modal){}).bind($.kmodal.OPEN,function(event,modal){}).bind($.kmodal.CLOSE,function(event,modal){$("#kraken-bulk-modal").remove()}).css({top:"10px",marginTop:"40px"});"lossy"===setting?$("#kraken-bulk-type-lossy").attr("checked",!0):$("#kraken-bulk-type-lossless").attr("checked",!0),$bulkSettingSpan=$(".bulkSetting"),$("input[name='kraken-bulk-type']").change(function(){var text="kraken-bulk-type-lossy"===this.id?"lossy":"lossless";$bulkSettingSpan.text(text)}),$(".jquery-modal.blocker").click(function(e){return!1}),$("#menu-media ul.wp-submenu").css({"z-index":1});var $table=$('<table id="kraken-bulk"></table>'),$headerRow=$('<tr class="kraken-bulk-header"><td>File</td><td style="width:120px">Original Size</td><td style="width:120px">Kraked Size</td><td style="width:120px">Savings</td><td style="width:120px">% Savings</td></tr>');$table.append($headerRow),$.each(bulkImageData,function(index,element){$table.append('<tr class="kraken-item-row" data-krakenbulkid="'+element.id+'"><td class="kraken-filename">'+element.filename+'</td><td class="kraken-originalsize">'+element.originalSize+'</td><td class="kraken-krakedsize"><span class="krakenBulkSpinner hidden"></span></td><td class="kraken-savings"></td><td class="kraken-savingsPercent"></td></tr>')}),$modal.append($table).append(krakEmAll).append('<span class="close-kraken-bulk">Close Window</span>'),$(".close-kraken-bulk").click(function(){$.kmodal.close()}),nImages||$(".kraken_req_bulk").attr("disabled",!0).css({opacity:.5})},bulkAction=function(bulkImageData){$bulkTable=$("#kraken-bulk");var jqxhr=null,q=async.queue(function(task,callback){var id=task.id,$row=(task.filename,$bulkTable.find("tr[data-krakenbulkid='"+id+"']")),$krakedSizeColumn=$row.find(".kraken-krakedsize"),$spinner=$krakedSizeColumn.find(".krakenBulkSpinner").css({display:"inline-block"}),$savingsPercentColumn=$row.find(".kraken-savingsPercent"),$savingsBytesColumn=$row.find(".kraken-savings");jqxhr=$.ajax({url:ajax_object.ajax_url,data:{action:"kraken_request",id:id,type:$("input[name='kraken-bulk-type']:checked").val().toLowerCase()},type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){if(data.success&&"undefined"==typeof data.error){var type=data.type,originalSize=data.original_size,krakedSize=data.kraked_size,savingsPercent=data.savings_percent,savingsBytes=data.saved_bytes;$krakedSizeColumn.text(krakedSize),$savingsPercentColumn.text(savingsPercent),$savingsBytesColumn.text(savingsBytes);var $button=$("button[id='krakenid-"+id+"']"),$parent=$button.parent(),$cell=$button.closest("td"),$originalSizeColumn=$button.parent().prev("td.original_size");$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),krakedData="<strong>"+krakedSize+"</strong><br /><small>Type:&nbsp;"+type+"</small><br /><small>Savings: "+savingsPercent+"</small>","undefined"!=typeof data.thumbs_data&&(krakedData+="<br /><small>"+data.thumbs_data.length+" thumbs optimized</small>"),$(this).replaceWith(krakedData),$originalSizeColumn.html(originalSize),$parent.remove()})}else data.error&&"This image can not be optimized any further"===data.error&&$krakedSizeColumn.text("No savings found.")}).fail(function(){}).always(function(){$spinner.css({display:"none"}),callback()})},kraken_settings.bulk_async_limit);q.drain=function(){$(".kraken_req_bulk").removeAttr("disabled").css({opacity:1}).text("Done").unbind("click").click(function(){$.kmodal.close()})},q.push(bulkImageData,function(err){})};$btnApplyBulkAction.add($btnApplyBulkAction2).click(function(e){if("kraken-bulk-lossy"===$(this).prev("select").val()){e.preventDefault();var bulkImageData=getBulkImageData();renderBulkImageSummary(bulkImageData),$(".kraken_req_bulk").click(function(e){e.preventDefault(),$(this).attr("disabled",!0).css({opacity:.5}),bulkAction(bulkImageData)})}}),$("body").on("click","small.krakenReset",function(e){e.preventDefault();var $resetButton=$(this),resetData={action:"kraken_reset"};resetData.id=$(this).data("id");var $spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){"undefined"!==data.success&&$resetButton.closest(".kraked_size.column-kraked_size").hide().html(data.html).fadeIn().prev(".original_size.column-original_size").html(data.original_size)})}),$("body").on("click",".kraken-reset-all",function(e){e.preventDefault();var reset=confirm("This will immediately remove all Kraken metadata associated with your images. \n\nAre you sure you want to do this?");if(reset){var $resetButton=$(this);$resetButton.text("Resetting images, pleaes wait...").attr("disabled",!0);
2
 
3
+ var resetData={action:"kraken_reset_all"},$spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);{$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){$spinner.remove(),$resetButton.text("Your images have been reset.").removeAttr("disabled").removeClass("enabled")})}}}),$(".krakenAdvancedSettings h3").on("click",function(){var $rows=$(".kraken-advanced-settings"),$plusMinus=$(".kraken-plus-minus");$rows.is(":visible")?($rows.hide(),$plusMinus.removeClass("dashicons-arrow-down").addClass("dashicons-arrow-right")):($rows.show(),$plusMinus.removeClass("dashicons-arrow-right").addClass("dashicons-arrow-down"))}),$("body").on("click",".kraken_req",function(e){e.preventDefault();var $button=$(this),$parent=$(this).parent();data.id=$(this).data("id"),$button.text("Optimizing image...").attr("disabled",!0).css({opacity:.5}),$parent.find(".krakenSpinner").css("display","inline");$.ajax({url:ajax_object.ajax_url,data:data,type:"post",dataType:"json",timeout:36e4,context:$button}).done(requestSuccess).fail(requestFail).always(requestComplete)})});
kraken.php CHANGED
@@ -21,8 +21,8 @@
21
  * Plugin URI: http://wordpress.org/plugins/kraken-image-optimizer/
22
  * Description: This plugin allows you to optimize your WordPress images through the Kraken API, the world's most advanced image optimization solution.
23
  * Author: Karim Salman
24
- * Version: 1.0.9.1
25
- * Stable Tag: 1.0.9.1
26
  * Author URI: https://kraken.io
27
  * License GPL2
28
  */
@@ -41,99 +41,206 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
41
 
42
  private $optimization_type = 'lossy';
43
 
44
- public static $kraken_plugin_version = '1.0.9.1';
45
 
46
  function __construct() {
47
  $plugin_dir_path = dirname( __FILE__ );
48
  require_once( $plugin_dir_path . '/lib/Kraken.php' );
49
  $this->kraken_settings = get_option( '_kraken_options' );
50
  $this->optimization_type = $this->kraken_settings['api_lossy'];
51
- add_action( 'admin_init', array( &$this, 'admin_init' ) );
52
  add_action( 'admin_enqueue_scripts', array( &$this, 'my_enqueue' ) );
53
  add_action( 'wp_ajax_kraken_reset', array( &$this, 'kraken_media_library_reset' ) );
54
  add_action( 'wp_ajax_kraken_request', array( &$this, 'kraken_media_library_ajax_callback' ) );
55
  add_action( 'wp_ajax_kraken_reset_all', array( &$this, 'kraken_media_library_reset_all' ) );
56
  add_action( 'manage_media_custom_column', array( &$this, 'fill_media_columns' ), 10, 2 );
57
  add_filter( 'manage_media_columns', array( &$this, 'add_media_columns') );
58
-
59
  if ( ( !empty( $this->kraken_settings ) && !empty( $this->kraken_settings['auto_optimize'] ) ) || !isset( $this->kraken_settings['auto_optimize'] ) ) {
60
  add_filter( 'wp_generate_attachment_metadata', array( &$this, 'optimize_thumbnails') );
61
  add_action( 'add_attachment', array( &$this, 'kraken_media_uploader_callback' ) );
62
  }
 
63
  }
64
 
65
- /*
66
- * Adds kraken fields and settings to Settings->Media settings page
67
- */
68
- function admin_init() {
69
 
70
- add_settings_section( 'kraken_image_optimizer', 'Kraken Image Optimizer', array( &$this, 'show_kraken_image_optimizer' ), 'media' );
71
 
72
- register_setting(
73
- 'media',
74
- '_kraken_options',
75
- array( &$this, 'validate_options' )
76
  );
 
 
77
 
78
- add_settings_field(
79
- 'kraken_api_key',
80
- 'API Key:',
81
- array( &$this, 'show_api_key' ),
82
- 'media',
83
- 'kraken_image_optimizer'
84
- );
85
 
86
- add_settings_field(
87
- 'kraken_api_secret',
88
- 'API Secret:',
89
- array( &$this, 'show_api_secret' ),
90
- 'media',
91
- 'kraken_image_optimizer'
92
- );
93
 
94
- add_settings_field(
95
- 'kraken_lossy',
96
- 'Optimization Type:',
97
- array( &$this, 'show_lossy' ),
98
- 'media',
99
- 'kraken_image_optimizer'
100
- );
 
 
101
 
102
- add_settings_field(
103
- 'kraken_auto_optimize',
104
- 'Automatically optimize uploads:',
105
- array( &$this, 'show_auto_optimize' ),
106
- 'media',
107
- 'kraken_image_optimizer'
108
- );
109
 
110
- add_settings_field(
111
- 'kraken_show_reset',
112
- 'Show Reset field: <small class="krakenWhatsThis" title="Checking this option will add a Reset button in the Kraked Size column for each optimized image. Resetting an image will remove the metadata associated with it, effectively making your blog forget that it had been optimized in the first place, allowing further optimization.">what\'s this?</small>',
113
- array( &$this, 'show_reset_field' ),
114
- 'media',
115
- 'kraken_image_optimizer'
116
- );
117
-
118
- add_settings_field(
119
- 'bulk_async_limit',
120
- 'Bulk Concurrency: <small class="krakenWhatsThis" title="This settings defines how many images can be processed at the same time using the bulk optimizer. The recommended value is 4. For blogs on very small hosting plans, or with reduced connectivity, a lower number might be necessary to avoid hitting request limits.">what\'s this?</small>',
121
- array( &$this, 'show_bulk_async_limit' ),
122
- 'media',
123
- 'kraken_image_optimizer'
124
- );
125
 
126
- add_settings_field(
127
- 'credentials_valid',
128
- 'API status:',
129
- array( &$this, 'show_credentials_validity' ),
130
- 'media',
131
- 'kraken_image_optimizer'
132
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  }
134
 
135
  function my_enqueue( $hook ) {
136
- if ( $hook == 'options-media.php' || $hook == 'upload.php') {
137
  wp_enqueue_script( 'jquery' );
138
  if ( KRAKEN_DEV_MODE === true ) {
139
  wp_enqueue_script( 'async-js', plugins_url( '/js/async.js', __FILE__ ) );
@@ -142,14 +249,15 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
142
  wp_enqueue_script( 'ajax-script', plugins_url( '/js/ajax.js', __FILE__ ), array( 'jquery' ) );
143
  wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
144
  wp_localize_script( 'ajax-script', 'kraken_settings', $this->kraken_settings );
 
 
 
145
  } else {
146
  wp_enqueue_script( 'kraken-js', plugins_url( '/js/dist/kraken.min.js', __FILE__ ), array( 'jquery' ) );
147
  wp_localize_script( 'kraken-js', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
148
- wp_localize_script( 'kraken-js', 'kraken_settings', $this->kraken_settings );
 
149
  }
150
- wp_enqueue_style( 'kraken_admin_style', plugins_url( 'css/admin.css', __FILE__ ) );
151
- wp_enqueue_style( 'tipsy-style', plugins_url( 'css/tipsy.css', __FILE__ ) );
152
- wp_enqueue_style( 'modal-style', plugins_url( 'css/jquery.modal.css', __FILE__ ) );
153
  }
154
  }
155
 
@@ -383,49 +491,6 @@ EOD;
383
  echo '<a href="http://kraken.io" title="Visit Kraken.io Homepage">Kraken.io</a> API settings';
384
  }
385
 
386
- function validate_options( $input ) {
387
- $valid = array();
388
- $error = '';
389
- $valid['api_lossy'] = $input['api_lossy'];
390
- $valid['auto_optimize'] = isset( $input['auto_optimize'] )? 1 : 0;
391
- $valid['show_reset'] = isset( $input['show_reset'] ) ? $input['show_reset'] : 0;
392
- $valid['bulk_async_limit'] = isset( $input['bulk_async_limit'] ) ? $input['bulk_async_limit'] : 4;
393
-
394
-
395
- if ( !function_exists( 'curl_exec' ) ) {
396
- $error = 'cURL not available. Kraken Image Optimizer requires cURL in order to communicate with Kraken.io servers. <br /> Please ask your system administrator or host to install PHP cURL, or contact support@kraken.io for advice';
397
- } else {
398
- $status = $this->get_api_status( $input['api_key'], $input['api_secret'] );
399
-
400
- if ( $status !== false ) {
401
-
402
- if ( isset($status['active']) && $status['active'] === true ) {
403
- if ( $status['plan_name'] === 'Developers' ) {
404
- $error = 'Developer API credentials cannot be used with this plugin.';
405
- } else {
406
- $valid['api_key'] = $input['api_key'];
407
- $valid['api_secret'] = $input['api_secret'];
408
- }
409
- } else {
410
- $error = 'There is a problem with your credentials. Please check them from your Kraken.io account.';
411
- }
412
-
413
- } else {
414
- $error = 'Please enter a valid Kraken.io API key and secret';
415
- }
416
- }
417
-
418
- if ( !empty( $error) ) {
419
- add_settings_error(
420
- 'media',
421
- 'api_key_error',
422
- $error,
423
- 'error'
424
- );
425
- }
426
- return $valid;
427
- }
428
-
429
  function show_api_key() {
430
  $settings = $this->kraken_settings;
431
  $value = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
@@ -470,7 +535,7 @@ EOD;
470
  $show_reset = isset( $options['show_reset'] ) ? $options['show_reset'] : 0;
471
  ?>
472
  <input type="checkbox" id="show_reset" name="_kraken_options[show_reset]" value="1" <?php checked( 1, $show_reset, true ); ?>/>
473
- &nbsp;&nbsp;&nbsp;&nbsp;<span class="kraken-reset-all enabled">Reset All Images</span>
474
  <?php
475
  }
476
 
21
  * Plugin URI: http://wordpress.org/plugins/kraken-image-optimizer/
22
  * Description: This plugin allows you to optimize your WordPress images through the Kraken API, the world's most advanced image optimization solution.
23
  * Author: Karim Salman
24
+ * Version: 2.0.0
25
+ * Stable Tag: 2.0.0
26
  * Author URI: https://kraken.io
27
  * License GPL2
28
  */
41
 
42
  private $optimization_type = 'lossy';
43
 
44
+ public static $kraken_plugin_version = '2.0.0';
45
 
46
  function __construct() {
47
  $plugin_dir_path = dirname( __FILE__ );
48
  require_once( $plugin_dir_path . '/lib/Kraken.php' );
49
  $this->kraken_settings = get_option( '_kraken_options' );
50
  $this->optimization_type = $this->kraken_settings['api_lossy'];
 
51
  add_action( 'admin_enqueue_scripts', array( &$this, 'my_enqueue' ) );
52
  add_action( 'wp_ajax_kraken_reset', array( &$this, 'kraken_media_library_reset' ) );
53
  add_action( 'wp_ajax_kraken_request', array( &$this, 'kraken_media_library_ajax_callback' ) );
54
  add_action( 'wp_ajax_kraken_reset_all', array( &$this, 'kraken_media_library_reset_all' ) );
55
  add_action( 'manage_media_custom_column', array( &$this, 'fill_media_columns' ), 10, 2 );
56
  add_filter( 'manage_media_columns', array( &$this, 'add_media_columns') );
57
+ add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array( &$this, 'add_settings_link' ) );
58
  if ( ( !empty( $this->kraken_settings ) && !empty( $this->kraken_settings['auto_optimize'] ) ) || !isset( $this->kraken_settings['auto_optimize'] ) ) {
59
  add_filter( 'wp_generate_attachment_metadata', array( &$this, 'optimize_thumbnails') );
60
  add_action( 'add_attachment', array( &$this, 'kraken_media_uploader_callback' ) );
61
  }
62
+ add_action( 'admin_menu', array( &$this, 'kraken_menu' ) );
63
  }
64
 
65
+ function kraken_menu() {
66
+ add_options_page( 'Kraken Image Optimizer Settings', 'Kraken.io', 'manage_options', 'wp-krakenio', array( &$this, 'kraken_settings_page' ) );
67
+ }
 
68
 
 
69
 
70
+ function add_settings_link ( $links ) {
71
+ $mylinks = array(
72
+ '<a href="' . admin_url( 'options-general.php?page=wp-krakenio' ) . '">Settings</a>',
 
73
  );
74
+ return array_merge( $links, $mylinks );
75
+ }
76
 
 
 
 
 
 
 
 
77
 
78
+ function kraken_settings_page() {
79
+
80
+ if ( !empty( $_POST ) ) {
81
+ $options = $_POST['_kraken_options'];
82
+ $result = $this->validate_options( $options );
83
+ update_option( '_kraken_options', $result['valid'] );
84
+ }
85
 
86
+ $settings = get_option( '_kraken_options' );
87
+ $lossy = isset( $settings['api_lossy'] ) ? $settings['api_lossy'] : 'lossy';
88
+ $auto_optimize = isset( $settings['auto_optimize'] ) ? $settings['auto_optimize'] : 1;
89
+
90
+ $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
91
+ $api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
92
+
93
+ $show_reset = isset( $settings['show_reset'] ) ? $settings['show_reset'] : 0;
94
+ $bulk_async_limit = isset( $settings['bulk_async_limit'] ) ? $settings['bulk_async_limit'] : 4;
95
 
96
+ $status = $this->get_api_status( $api_key, $api_secret );
 
 
 
 
 
 
97
 
98
+ $icon_url = admin_url() . 'images/';
99
+ if ( $status !== false && isset( $status['active'] ) && $status['active'] === true ) {
100
+ $icon_url .= 'yes.png';
101
+ $status_html = '<p class="apiStatus">Your credentials are valid <span class="apiValid" style="background:url(' . "'$icon_url') no-repeat 0 0" . '"></span></p>';
102
+ } else {
103
+ $icon_url .= 'no.png';
104
+ $status_html = '<p class="apiStatus">There is a problem with your credentials <span class="apiInvalid" style="background:url(' . "'$icon_url') no-repeat 0 0" . '"></span></p>';
105
+ }
 
 
 
 
 
 
 
106
 
107
+ ?> <h1 class="kraken-admin-section-title">Kraken.io Settings</h1>
108
+ <?php if ( isset( $result['error'] ) ) { ?>
109
+ <div class="kraken error settings-error">
110
+ <?php foreach( $result['error'] as $error ) { ?>
111
+ <p><?php echo $error; ?></p>
112
+ <?php } ?>
113
+ </div>
114
+ <?php } else if ( isset( $result['success'] ) ) { ?>
115
+ <div class="kraken updated settings-error">
116
+ <p>Settings saved.</p>
117
+ </div>
118
+ <?php } ?>
119
+
120
+ <?php if ( !function_exists( 'curl_init' ) ) { ?>
121
+ <p class="curl-warning"><strong>Warning: </strong>CURL is not available. Please install CURL before using this plugin</p>
122
+ <?php } ?>
123
+
124
+ <form id="krakenSettings" method="post">
125
+ <a href="http://kraken.io/account" target="_blank" title="Log in to your Kraken.io account">Kraken.io</a> API settings
126
+ <table class="form-table">
127
+ <tbody>
128
+ <tr>
129
+ <th scope="row">API Key:</th>
130
+ <td>
131
+ <input id="kraken_api_key" name="_kraken_options[api_key]" type="text" value="<?php echo esc_attr( $api_key ); ?>" size="50">
132
+ </td>
133
+ </tr>
134
+ <tr>
135
+ <th scope="row">API Secret:</th>
136
+ <td>
137
+ <input id="kraken_api_secret" name="_kraken_options[api_secret]" type="text" value="<?php echo esc_attr( $api_secret ); ?>" size="50">
138
+ </td>
139
+ </tr>
140
+ <tr>
141
+ <th scope="row">Optimization Type:</th>
142
+ <td>
143
+ <input type="radio" id="kraken_lossy" name="_kraken_options[api_lossy]" value="lossy" <?php checked( 'lossy', $lossy, true ); ?>/>
144
+ <label for="kraken_lossy">Lossy</label>
145
+ <input style="margin-left:10px;" type="radio" id="kraken_lossless" name="_kraken_options[api_lossy]" value="lossless" <?php checked( 'lossless', $lossy, true ) ?>/>
146
+ <label for="kraken_lossless">Lossless</label>
147
+ </td>
148
+ </tr>
149
+ <tr>
150
+ <th scope="row">Automatically optimize uploads:</th>
151
+ <td>
152
+ <input type="checkbox" id="auto_optimize" name="_kraken_options[auto_optimize]" value="1" <?php checked( 1, $auto_optimize, true ); ?>/>
153
+ </td>
154
+ </tr>
155
+ <tr>
156
+ <th scope="row">API status:</th>
157
+ <td>
158
+ <?php echo $status_html ?>
159
+ </td>
160
+ </tr>
161
+ <tr>
162
+ <td class="krakenAdvancedSettings"><h3><span class="kraken-advanced-settings-label" title="Click to toggle advanced settings">Advanced Settings</span><span class="kraken-plus-minus dashicons dashicons-arrow-right"></span></h3></td>
163
+ </tr>
164
+ <tr class="kraken-advanced-settings">
165
+ <td colspan="2" class="krakenAdvancedSettingsDescription"><small>We recommend that you leave these settings at their default values</td>
166
+ </tr>
167
+ <tr class="kraken-advanced-settings">
168
+ <th scope="row">
169
+ Show metadata reset per image:&nbsp;
170
+ <small class="krakenWhatsThis" title="Checking this option will add a Reset button in the Kraked Size column for each optimized image. Resetting an image will remove the Kraken.io metadata associated with it, effectively making your blog forget that it had been optimized in the first place, allowing further optimization in some cases. If an image has been optimized using the lossless setting, lossless optimization will not yield any greater savings. If in doubt, please contact support@kraken.io">What's this?</small>
171
+ </th>
172
+ <td>
173
+ <input type="checkbox" id="kraken_show_reset" name="_kraken_options[show_reset]" value="1" <?php checked( 1, $show_reset, true ); ?>/>
174
+ &nbsp;&nbsp;&nbsp;&nbsp;<span class="kraken-reset-all enabled">Reset All Images</span>
175
+ </td>
176
+ </tr>
177
+ <tr class="kraken-advanced-settings">
178
+ <th scope="row">
179
+ Bulk Concurrency:
180
+ <small class="krakenWhatsThis" title="This settings defines how many images can be processed at the same time using the bulk optimizer. The recommended value is 4. For blogs on very small hosting plans, or with reduced connectivity, a lower number might be necessary to avoid hitting request limits.">what's this?</small>
181
+ </th>
182
+ <td>
183
+ <select name="_kraken_options[bulk_async_limit]">
184
+ <?php foreach ( range(1, 10) as $number ) { ?>
185
+ <option value="<?php echo $number ?>" <?php selected( $bulk_async_limit, $number, true); ?>>
186
+ <?php echo $number ?>
187
+ </option>
188
+ <?php } ?>
189
+ </select>
190
+ </td>
191
+ </tr>
192
+ </tbody>
193
+ </table>
194
+ <input type="submit" name="kraken_save" id="kraken_save" class="button button-primary" value="Save All"/>
195
+ </form>
196
+ <?php
197
+ }
198
+
199
+ function validate_options( $input ) {
200
+ $valid = array();
201
+ $error = array();
202
+ $valid['api_lossy'] = $input['api_lossy'];
203
+ $valid['auto_optimize'] = isset( $input['auto_optimize'] )? 1 : 0;
204
+ $valid['show_reset'] = isset( $input['show_reset'] ) ? 1 : 0;
205
+ $valid['bulk_async_limit'] = isset( $input['bulk_async_limit'] ) ? $input['bulk_async_limit'] : 4;
206
+
207
+ if ( $valid['show_reset'] ) {
208
+ $valid['show_reset'] = $input['show_reset'];
209
+ }
210
+
211
+ if ( empty( $input['api_key']) || empty( $input['api_secret'] ) ) {
212
+ $error[] = 'API Credentials must not be left blank.';
213
+ } else {
214
+
215
+ $status = $this->get_api_status( $input['api_key'], $input['api_secret'] );
216
+
217
+ if ( $status !== false ) {
218
+
219
+ if ( isset($status['active']) && $status['active'] === true ) {
220
+ if ( $status['plan_name'] === 'Developers' ) {
221
+ $error[] = 'Developer API credentials cannot be used with this plugin.';
222
+ } else {
223
+ $valid['api_key'] = $input['api_key'];
224
+ $valid['api_secret'] = $input['api_secret'];
225
+ }
226
+ } else {
227
+ $error[] = 'There is a problem with your credentials. Please check them from your Kraken.io account.';
228
+ }
229
+
230
+ } else {
231
+ $error[] = 'Please enter a valid Kraken.io API key and secret.';
232
+ }
233
+ }
234
+
235
+ if ( !empty( $error ) ) {
236
+ return array( 'success' => false, 'error' => $error, 'valid' => $valid );
237
+ } else {
238
+ return array( 'success' => true, 'valid' => $valid );
239
+ }
240
  }
241
 
242
  function my_enqueue( $hook ) {
243
+ if ( $hook == 'options-media.php' || $hook == 'upload.php' || $hook == 'settings_page_wp-krakenio' ) {
244
  wp_enqueue_script( 'jquery' );
245
  if ( KRAKEN_DEV_MODE === true ) {
246
  wp_enqueue_script( 'async-js', plugins_url( '/js/async.js', __FILE__ ) );
249
  wp_enqueue_script( 'ajax-script', plugins_url( '/js/ajax.js', __FILE__ ), array( 'jquery' ) );
250
  wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
251
  wp_localize_script( 'ajax-script', 'kraken_settings', $this->kraken_settings );
252
+ wp_enqueue_style( 'kraken_admin_style', plugins_url( 'css/admin.css', __FILE__ ) );
253
+ wp_enqueue_style( 'tipsy-style', plugins_url( 'css/tipsy.css', __FILE__ ) );
254
+ wp_enqueue_style( 'modal-style', plugins_url( 'css/jquery.modal.css', __FILE__ ) );
255
  } else {
256
  wp_enqueue_script( 'kraken-js', plugins_url( '/js/dist/kraken.min.js', __FILE__ ), array( 'jquery' ) );
257
  wp_localize_script( 'kraken-js', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
258
+ wp_localize_script( 'kraken-js', 'kraken_settings', $this->kraken_settings );
259
+ wp_enqueue_style( 'kraken-css', plugins_url( 'css/dist/kraken.min.css', __FILE__ ) );
260
  }
 
 
 
261
  }
262
  }
263
 
491
  echo '<a href="http://kraken.io" title="Visit Kraken.io Homepage">Kraken.io</a> API settings';
492
  }
493
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  function show_api_key() {
495
  $settings = $this->kraken_settings;
496
  $value = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
535
  $show_reset = isset( $options['show_reset'] ) ? $options['show_reset'] : 0;
536
  ?>
537
  <input type="checkbox" id="show_reset" name="_kraken_options[show_reset]" value="1" <?php checked( 1, $show_reset, true ); ?>/>
538
+ <span class="kraken-reset-all enabled">Reset All Images</span>
539
  <?php
540
  }
541
 
lib/Kraken.php CHANGED
@@ -4,7 +4,7 @@ class Kraken
4
  {
5
 
6
  protected $auth = array();
7
- public static $kraken_plugin_version = '1.0.9.1';
8
 
9
  public function __construct($key = '', $secret = '')
10
  {
4
  {
5
 
6
  protected $auth = array();
7
+ public static $kraken_plugin_version = '2.0.0';
8
 
9
  public function __construct($key = '', $secret = '')
10
  {
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Kraken Image Optimizer ===
2
  Contributors: karim79
3
- Tags: Image Optimizer, Image Optimiser, Optimize, Optimise, Images, Media, Performance, SEO, faster loading times, smushit, smush.it, compress, kraken-image-optimizer, tinypng, tinyjpeg, pngquant, jpegmini, ewww, pagespeed, pagespeed insights, sitespeed, optimize gif, optimize jpeg, optimize png, optimize animated gif, svg, improve pagerank
4
  Requires at least: 3.0.1
5
- Tested up to: 4.1
6
  Donate link: https://kraken.io
7
- Stable tag: 1.0.9.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
 
@@ -13,33 +13,44 @@ This plugin allows you to optimize your WordPress images through the Kraken API,
13
 
14
  == Description ==
15
 
16
- This plugin allows you to optimize new and existing Wordpress image uploads through [Kraken Image Optimizer's](https://kraken.io "Kraken Image Optimizer") API. Both lossless and intelligent lossy optimization modes are supported. Supported filetypes are JPEG, PNG and GIF. Maximum filesize limit is 16 MB. For more details, including detailed documentation and plans and pricing, please visit [Kraken.io](https://kraken.io "Kraken Image Optimizer").
17
 
18
- = Get your FREE account with us =
19
- Sign up for your [FREE Kraken.io Account](https://kraken.io/plans "Kraken.io - Plan and Pricing") and try out our plugin and the rest of our features now, including:
20
 
21
- * API Access, with dozens of ready-to-use libraries and modules
22
- * Web Interface PRO with Image Resizing and sync-to-Dropbox
23
- * URL Paster
24
- * Page Cruncher
25
- * Optimization Stats and History
26
- * ...and more.
 
 
27
 
28
 
29
  = About the plugin =
 
30
  * All images uploaded throught the media uploader are optimized on-the-fly. All generated thumbnails are optimized too.
31
  * All images already present in the media library can be optimized individually, or using the Bulk Action menu "Krak 'em all" feature.
32
  * This plugin does not require any root or command-line access. No compilation and installation of any binaries is necessary.
33
  * All optimization is carried out by sending images to Kraken.io's infrastructure, and pulling the optimized files to your Wordpress installation.
34
  * To use this plugin, you must obtain a full API key and secret from [https://kraken.io/plans](https://kraken.io/plans "Kraken.io - Plans and Pricing"). Our free account comes with a limited quota for testing our premium features, including this plugin.
35
- * You can use your Kraken API key and secret on as many sites/blogs as you like. We have no per-site license.
36
  * Works great with WPEngine hosted blogs, including the staging area.
37
  * Since version 1.0.4, the plugin will work with local WordPress installations; the client site does not need to be published on the web.
38
 
39
 
40
- Once you have obtained your credentials, from your Wordpress admin, go to the Settings->Media page. The Kraken Wordpress plugin adds a Kraken.io Settings section to the bottom of the page, from where you can enter your API credentials, and select your optimization preferences. Once you have done this, click **Save**. If everything is in order, it will simply say "settings saved" and give you a reassuring green tick in the **Kraken.io settings** section. You can now start optimizing images from within Media Library. Any image you upload from now on, through any of the media upload screens will be optimized on-the-fly by Kraken.
 
 
 
 
 
 
 
 
41
 
42
- For advanced users, there is a third party WordPress Command Line Interface (CLI) tool to allow image optimization from the command line, or by using cron. For details, visit: https://github.com/tillkruss/wp-cli-kraken
 
 
43
 
44
  = Features on the way =
45
  * Optimize images directly to Amazon S3.
@@ -67,7 +78,7 @@ To install the Kraken Wordpress Plugin:
67
 
68
  == Screenshots ==
69
 
70
- 1. This screenshot shows the new section which this plugin to Settings->Media. You must enter your credentials, and select your optimization mode from there, then hit **save**.
71
  2. This screenshot shows the two columns added by Kraken Image Optimizer: **original image** and **Kraked size**, as well as the new **Optimize This Image** button which is present for images which already exist in your media library. Stats and optimization type are shown for optimized images.
72
  3. This screenshot shows the bulk optimizer aka the "Krak 'em all" feature which appears as an overlay.
73
 
@@ -94,6 +105,13 @@ You will need to switch the Media Library from the Thumbnail view to the List vi
94
 
95
  == Changelog ==
96
 
 
 
 
 
 
 
 
97
  = 1.0.9.1 =
98
  * Fixed another reported bootstrap CSS conflict.
99
 
@@ -172,7 +190,7 @@ You will need to switch the Media Library from the Thumbnail view to the List vi
172
  * Optimization mode (lossy/lossless) is now stored with kraken thumbnail metadata (for future Stats page).
173
 
174
  = 1.0.3 =
175
- * Bulk Actions menu in Media Library is now extended with "Krak 'em all", our Bulk Optimization feature.
176
  * Fixed a bug which caused old images' thumbnails to not be optimized.
177
  * Fixed a failure condition which occured only on WPEngine-hosted systems.
178
 
@@ -207,3 +225,4 @@ We love to hear from you! Just shoot an email to support (at) kraken dot io and
207
 
208
 
209
 
 
1
  === Kraken Image Optimizer ===
2
  Contributors: karim79
3
+ Tags: Image Optimizer, Image Optimiser, Optimize, Optimise, Images, Media, Performance, SEO, faster loading times, smushit, smush.it, compress, kraken-image-optimizer, tinypng, tinyjpeg, pngquant, jpegmini, ewww, pagespeed, pagespeed insights, sitespeed, optimize gif, optimize jpeg, optimize png, optimize animated gif, svg, improve pagerank, gtmetrix speed test
4
  Requires at least: 3.0.1
5
+ Tested up to: 4.2
6
  Donate link: https://kraken.io
7
+ Stable tag: 2.0.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
 
13
 
14
  == Description ==
15
 
16
+ This plugin allows you to optimize new and existing Wordpress image uploads through [Kraken Image Optimizer's](https://kraken.io "Kraken Image Optimizer") API. Both lossless and intelligent lossy optimization modes are supported. Supported filetypes are JPEG, PNG and GIF. Maximum filesize limit is 16 MB. For more details, including detailed documentation and plans and pricing, please visit [Kraken.io](https://kraken.io "Kraken Image Optimizer").
17
 
18
+ > **Get your FREE account with us**
 
19
 
20
+ > Sign up for your [FREE Kraken.io Account](https://kraken.io/plans "Kraken.io - Plan and Pricing") and try out our plugin and the rest of our features now, including:
21
+
22
+ > * API Access, with dozens of ready-to-use libraries and modules
23
+ > * Web Interface PRO with Image Resizing and sync-to-Dropbox
24
+ > * URL Paster
25
+ > * Page Cruncher
26
+ > * Optimization Stats and History
27
+ > * ...and more.
28
 
29
 
30
  = About the plugin =
31
+ * You can use your Kraken API key and secret on as many sites/blogs as you like. We have no per-site license.
32
  * All images uploaded throught the media uploader are optimized on-the-fly. All generated thumbnails are optimized too.
33
  * All images already present in the media library can be optimized individually, or using the Bulk Action menu "Krak 'em all" feature.
34
  * This plugin does not require any root or command-line access. No compilation and installation of any binaries is necessary.
35
  * All optimization is carried out by sending images to Kraken.io's infrastructure, and pulling the optimized files to your Wordpress installation.
36
  * To use this plugin, you must obtain a full API key and secret from [https://kraken.io/plans](https://kraken.io/plans "Kraken.io - Plans and Pricing"). Our free account comes with a limited quota for testing our premium features, including this plugin.
 
37
  * Works great with WPEngine hosted blogs, including the staging area.
38
  * Since version 1.0.4, the plugin will work with local WordPress installations; the client site does not need to be published on the web.
39
 
40
 
41
+ > ★★★★★ **Quality results, quality service**
42
+ > "The plugin works really well and effortlessly, and the support is prompt, thoughtful, and thorough. I'm hooked." — [illustrata](https://profiles.wordpress.org/illustrata)
43
+ >
44
+ > ★★★★★ **Optimize according to Google Pagespeed**
45
+ > "Kraken was instrumental in optimizing images to comply with Google's Pagespeed analyzing tool. Our travel blog travelmemo.com now sports Google's 'mobile friendly' tag for mobile searches" — [Walter Schaerer](https://profiles.wordpress.org/qualterio)
46
+ >
47
+ > ★★★★★ **Perfect solution to speed up site!**
48
+ > "I love this plugin! All the questions I had are quickly responded to and I see a huge saving with image size without losing the quality. I highly recommend this plugin!" — [ezone69](https://profiles.wordpress.org/ezone69)
49
+
50
 
51
+ Once you have obtained your credentials, from your Wordpress admin, go to the Kraken.io settings page. The from there you can enter your API credentials, and select your optimization preferences. Once you have done this, click on **Save**. If everything is in order, it will simply say "settings saved" and give you a reassuring green tick that your credentials are valid. You can now start optimizing images from within Media Library. Any image you upload from now on, through any of the media upload screens will be optimized on-the-fly by Kraken.
52
+
53
+ For advanced users, there is a third party WordPress Command Line Interface (CLI) tool to allow image optimization from the command line, or by using cron. For details, visit: https://github.com/tillkruss/wp-cli-kraken
54
 
55
  = Features on the way =
56
  * Optimize images directly to Amazon S3.
78
 
79
  == Screenshots ==
80
 
81
+ 1. This screenshot shows the Kraken.io Settings page. You must enter your credentials, and select your optimization mode from there, then hit **save**. Advanced options are also available.
82
  2. This screenshot shows the two columns added by Kraken Image Optimizer: **original image** and **Kraked size**, as well as the new **Optimize This Image** button which is present for images which already exist in your media library. Stats and optimization type are shown for optimized images.
83
  3. This screenshot shows the bulk optimizer aka the "Krak 'em all" feature which appears as an overlay.
84
 
105
 
106
  == Changelog ==
107
 
108
+ = 2.0.0 =
109
+ * Please read! Kraken.io settings have now moved to an own section (Settings->Kraken.io), in order to reduce clutter in Media Settings, and to accomodate new features on the way.
110
+ * Advanced settings grouped in "Advanced Settings" section of settings page.
111
+ * Direct link to Kraken.io settings from Kraken.io in the plugins section.
112
+ * Updated screenshots.
113
+ * WordPress version compatibility bumped to 4.2.
114
+
115
  = 1.0.9.1 =
116
  * Fixed another reported bootstrap CSS conflict.
117
 
190
  * Optimization mode (lossy/lossless) is now stored with kraken thumbnail metadata (for future Stats page).
191
 
192
  = 1.0.3 =
193
+ * Bulk Actions menu in Media Library is now extended with "Krak 'em all", our Bulk Optimization feature.
194
  * Fixed a bug which caused old images' thumbnails to not be optimized.
195
  * Fixed a failure condition which occured only on WPEngine-hosted systems.
196
 
225
 
226
 
227
 
228
+