diff --git a/app/importer/jobs/.htaccess b/app/importer/jobs/.htaccess new file mode 100644 index 0000000..184b59a --- /dev/null +++ b/app/importer/jobs/.htaccess @@ -0,0 +1,11 @@ + + # Apache 2.2 + + Order Allow,Deny + Deny from all + + # Apache 2.4 + + Require all denied + + \ No newline at end of file diff --git a/app/install/update/updater.php b/app/install/update/updater.php index 8f0d4f4..d495f23 100644 --- a/app/install/update/updater.php +++ b/app/install/update/updater.php @@ -117,22 +117,17 @@ try { case 'extract': $zip_file = $update_temp_dir . $_REQUEST['file']; - if (false === preg_match('/^Chevereto-Chevereto-Free-([\d.]+)-\d+-g(.*)_.*$/i', $_REQUEST['file'], $matches)) { + if (false === preg_match('/^(chevereto-chevereto-free)-([\d.]+)-\d+-g(.*)_.*$/i', $_REQUEST['file'], $matches)) { throw new Exception("Can't detect target zip file version"); } - $version = $matches[1]; - $etag_short = $matches[2]; - - // Test .zip + $version = $matches[2]; + $etag_short = $matches[3]; if (!is_readable($zip_file)) { throw new Exception('Missing '.$zip_file.' file', 400); } - // Unzip .zip $zip = new \ZipArchive; if ($zip->open($zip_file) === true) { - - // At this point we will enter the website in maintenance mode (if needed) try { $toggle_maintenance = !getSetting('maintenance'); if ($toggle_maintenance) { @@ -147,14 +142,12 @@ try { } else { throw new Exception(_s("Can't extract %s", G\absolute_to_relative($zip_file)), 401); } - // Recursive copy UPDATE -> CURRENT - $source = $update_temp_dir . G_APP_GITHUB_OWNER . '-' . G_APP_GITHUB_REPO . '-' . $etag_short . '/'; + $source = $update_temp_dir . $matches[1] . '-' . $etag_short . '/'; $dest = G_ROOT_PATH; foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item) { $target = $dest . $iterator->getSubPathName(); $target_visible = G\absolute_to_relative($target); - if ($item->isDir()) { if (!file_exists($target) and !@mkdir($target)) { $error = error_get_last(); @@ -164,7 +157,6 @@ try { ]), 402); } } else { - // Touch anything but .htaccess files if (!preg_match('/\.htaccess$/', $item)) { if (!@copy($item, $target)) { $error = error_get_last(); @@ -174,7 +166,7 @@ try { ]), 403); } } - unlink($item); // Save some valuable seconds... + unlink($item); } } @@ -184,8 +176,6 @@ try { $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink'); $todo($fileinfo->getRealPath()); } - - // Turn off maintenance mode (if needed) try { if ($toggle_maintenance) { DB::update('settings', ['value' => 0], ['name' => 'maintenance']); @@ -203,7 +193,7 @@ try { $json_array['request'] = $_REQUEST; G\Render\json_output($json_array); } - die(); // Terminate any remaining execution (if any) + die(); } catch (Exception $e) { if (!isset($_REQUEST['action'])) { Render\chevereto_die($e->getMessage(), "This installation can't use the automatic update functionality because this server is missing some crucial elements to allow Chevereto to perform the automatic update:", "Can't perform automatic update"); diff --git a/app/lib/chevereto.js b/app/lib/chevereto.js index b55eb50..853c84e 100644 --- a/app/lib/chevereto.js +++ b/app/lib/chevereto.js @@ -2919,7 +2919,7 @@ CHV.fn.system = { checkUpdates: function (callback) { $.ajax({ url: CHEVERETO.api.get.info + "/", - data: null, + data: { id: CHEVERETO.id }, cache: false, }).always(function (data, status, XHR) { if (typeof callback == "function") { @@ -5865,3 +5865,248 @@ CHV.fn.queuePixel = function () { '" width="1" height="1" alt="" style="display: none;">'; $("body").append(img); }; + +CHV.fn.import = { + errorHandler: function (response) { + PF.fn.growl.call(response.error.message); + }, + reset: function (id) { + var id = parseInt(id); + CHV.obj.import.working[id].stats = $.ajax({ + type: "POST", + data: { + action: "importReset", + id: id, + }, + }); + CHV.obj.import.working[id].stats.complete(function (XHR) { + var response = XHR.responseJSON; + if (response) { + var $html = CHV.fn.import.parseTemplate(response.import); + $( + "[data-id=" + response.import.id + "]", + CHV.obj.import.sel.root + ).replaceWith($html); + if (response.import.status != "working") { + clearInterval(CHV.obj.import.working[id].interval); + } + } + }); + }, + updateStats: function (id) { + var id = parseInt(id); + if ( + "readyState" in CHV.obj.import.working[id].stats && + CHV.obj.import.working[id].stats.readyState != 4 + ) { + console.log( + "Aborting stats timeout call (previous call is still not ready)" + ); + return; + } + CHV.obj.import.working[id].stats = $.ajax({ + type: "POST", + data: { + action: "importStats", + id: id, + }, + }); + CHV.obj.import.working[id].stats.complete(function (XHR) { + var response = XHR.responseJSON; + if (response) { + var $html = CHV.fn.import.parseTemplate(response.import); + $( + "[data-id=" + response.import.id + "]", + CHV.obj.import.sel.root + ).replaceWith($html); + if (response.import.status != "working") { + clearInterval(CHV.obj.import.working[id].interval); + } + } + }); + }, + add: { + submit: function () { + var modal = PF.obj.modal.selectors.root; + PF.obj.modal.form_data = { + action: "importAdd", + path: $("[name=form-path]", modal).val(), + options: { + root: $("[name=form-structure]", PF.obj.modal.selectors.root).val(), + }, + }; + return true; + }, + deferred: { + success: function (XHR) { + var response = XHR.responseJSON; + PF.fn.growl.expirable( + PF.fn._s( + "Import job ID %s added successfully, you can process the import now", + response.import.id + ) + ); + var $html = CHV.fn.import.parseTemplate(response.import); + $html.insertAfter(CHV.obj.import.sel.header, CHV.obj.import.sel.root); + $(CHV.obj.import.sel.root).removeClass("hidden"); + }, + error: function (XHR) { + CHV.fn.import.errorHandler(XHR.responseJSON); + }, + }, + }, + process: { + abortAll: function (id) { + var id = parseInt(id); + if (id in CHV.obj.import.working) { + CHV.obj.import.aborted.push(id); + for (var key in CHV.obj.import.working[id].threads) { + CHV.obj.import.working[id].threads[key].abort(); + } + PF.fn.growl.expirable( + "Aborted all threads for import job ID " + + id + + ", changing status now" + ); + if ("interval" in CHV.obj.import.working[id]) { + clearInterval(CHV.obj.import.working[id].interval); + if ("abort" in CHV.obj.import.working[id].stats) { + CHV.obj.import.working[id].stats.abort(); + } + } + } + }, + xhr: function (id, thread) { + var id = parseInt(id); + console.log("New XHR for thread #" + thread + " for import job ID"); + if (id in CHV.obj.import.working == false) { + CHV.obj.import.working[id] = { + threads: {}, + interval: {}, + stats: {}, + }; + } + CHV.obj.import.working[id].threads[thread] = $.ajax({ + type: "POST", + data: { + action: "importProcess", + id: id, + thread: thread, + }, + }); + CHV.obj.import.working[id].threads[thread].complete(function (XHR) { + if (XHR.status == 400) { + CHV.fn.import.errorHandler(XHR.responseJSON); + return; + } + var status = $("[data-id=" + id + "]", CHV.obj.import.sel.root).data( + "status" + ); + if ($.inArray(id, CHV.obj.import.aborted) == -1) { + CHV.fn.import.process.xhr(id, thread); + } + }); + }, + load: function () { + $("html").data("modal-form-values", ""); + return true; + }, + submit: function (id) { + var modal = PF.obj.modal.selectors.root; + var threads = $("[name=form-threads]", modal).val(); + if (threads == 0) { + PF.fn.growl.expirable(PF.fn._s("Select number of threads")); + return false; + } + PF.obj.modal.form_data = { + action: "importEdit", + id: id, + threads: threads, + values: { + status: "working", + }, + }; + return true; + }, + deferred: { + success: function (XHR) { + var response = XHR.responseJSON; + PF.fn.growl.expirable( + PF.fn._s( + "Import job ID %s is being processed now", + response.import.id + ) + ); + var $html = CHV.fn.import.parseTemplate(response.import); + $( + "[data-id=" + response.import.id + "]", + CHV.obj.import.sel.root + ).replaceWith($html); + // Once the row has been edited, start the actual jobs + var threads = parseInt(response.request.threads); + for (var i = 1; i <= threads; i++) { + CHV.fn.import.process.xhr(response.import.id, i); + } + CHV.obj.import.working[response.import.id].interval = setInterval( + function () { + CHV.fn.import.updateStats(response.import.id); + }, + 5000 + ); + }, + error: function (XHR) { + var response = XHR.responseJSON; + if (response.error.code == 900) { + console.log("Aborting current working process (status changed)"); + CHV.fn.import.process.abortAll(response.id); + } else { + CHV.fn.import.errorHandler(); + } + }, + }, + }, + delete: { + submit: function (id) { + PF.obj.modal.form_data = { + action: "importDelete", + id: id, + }; + return true; + }, + deferred: { + success: function (XHR) { + var response = XHR.responseJSON; + PF.fn.growl.call(PF.fn._s("Import ID %s removed", response.import.id)); + $( + "[data-id=" + response.import.id + "]", + CHV.obj.import.sel.root + ).remove(); + if ($("li", CHV.obj.import.sel.root).size() == 1) { + $(CHV.obj.import.sel.root).addClass("hidden"); + } + }, + error: function (XHR) { + CHV.fn.import.errorHandler(XHR.responseJSON); + }, + }, + }, + parseTemplate: function (dataset, $el) { + var tpl = CHV.obj.import.rowTpl; + for (var key in CHV.obj.import.importTr) { + if (typeof dataset[key] != typeof undefined) { + tpl = tpl.replaceAll("%" + key + "%", dataset[key]); + } + } + tpl = tpl.replaceAll("%parse%", dataset.options.root); + tpl = tpl.replaceAll("%shortParse%", dataset.options.root.charAt(0)); + tpl = tpl.replaceAll( + "%displayStatus%", + CHV.obj.import.statusesDisplay[dataset.status] + ); + var $html = $($.parseHTML(tpl)).attr( + "data-object", + JSON.stringify(dataset) + ); + return $html; + }, +}; diff --git a/app/lib/chevereto.min.js b/app/lib/chevereto.min.js index 191b3ec..ed7b1b9 100644 --- a/app/lib/chevereto.min.js +++ b/app/lib/chevereto.min.js @@ -1,3 +1,4 @@ -$(function(){function e(e){e=e.originalEvent;var t=!1;if(e.dataTransfer.types)for(var a=0;ae&&(a.height(e),a.closest(".antiscroll-wrap").antiscroll())}}function a(e){e.addClass("list-item-play-gif--loading");var t=e.closest(".list-item"),a=$(".image-container",t),o=$("img",a),i=o.attr("src"),n=".md",s=i.lastIndexOf(n);if(-1==s)n=".th",s=i.lastIndexOf(n);var r=i.substr(0,s)+i.substr(s+n.length,i.length);a.append(a.html()),$load=t.find(".image-container img").eq(1).attr("src",r).addClass("hidden"),$load.imagesLoaded(function(){e.remove(),o.remove(),$(this.elements).removeClass("hidden")})}if($(window).on("resize",function(){CHV.fn.uploader.boxSizer(),"function"==typeof user_background_full_fix&&user_background_full_fix(),CHV.fn.bindSelectableItems(),CHV.fn.listingViewer.placeholderSizing()}),window.opener&&($(window).on("load",function(e){window.opener.postMessage({id:window.name,requestAction:"postSettings"},"*")}),$(window).on("message",function(e){var t=e.originalEvent.data;void 0!==t.id&&void 0!==t.settings&&window.name===t.id&&(CHV.obj.opener.uploadPlugin[t.id]=t.settings)})),$("#home-cover, #maintenance-wrapper, #login").exists()){var o=$("#maintenance-wrapper").exists()?$("#maintenance-wrapper").css("background-image").slice(4,-1).replace(/^\"|\"$/g,""):$(".home-cover-img","#home-cover-slideshow").first().attr("data-src");function i(){$("body").addClass("load"),$("#maintenance-wrapper").exists()||$(".home-cover-img","#home-cover-slideshow").first().css("background-image","url("+o+")").addClass("animate-in--alt").removeAttr("data-src"),setTimeout(function(){setTimeout(function(){$("body").addClass("loaded")},1200),setTimeout(function(){s()},7e3)},600)}var n=function(){setTimeout(function(){s()},8e3)};function s(){var e=$(".home-cover-img[data-src]","#home-cover-slideshow").first(),t=$(".home-cover-img","#home-cover-slideshow");if(0==e.length){if(1==t.length)return;t.first().removeClass("animate-in"),$("#home-cover-slideshow").append(t.first()),setTimeout(function(){$(".home-cover-img:last","#home-cover-slideshow").addClass("animate-in")},20),setTimeout(function(){$(".home-cover-img:not(:last)","#home-cover-slideshow").removeClass("animate-in")},4e3),n()}else{var a=e.attr("data-src");$("").attr("src",a).on("load error",function(){$(this).remove(),e.css("background-image","url("+a+")").addClass("animate-in").removeAttr("data-src"),setTimeout(function(){$(".home-cover-img:not(:last)","#home-cover-slideshow").removeClass("animate-end animate-in--alt")},2e3),n()})}}o?$("").attr("src",o).on("load error",function(){$(this).remove(),i()}):i()}var r=CHV.fn.uploader.selectors.root,l=CHV.fn.uploader.selectors.queue,d=$(r),c=$(l);$(document).on("click","[data-action=top-bar-upload]",function(e){$("body").is("#upload")||1==$(this).data("link")||CHV.fn.uploader.toggle()});var u={tones:{light:{html:"tone-light top-bar-white",top:"white"},dark:{html:"tone-dark top-bar-black",top:"black"}},isDark:function(){return $("html").hasClass("tone-dark")},toggle:function(){var e=this.isDark()?"light":"dark";$("html").removeClass(this.tones.light.html+" "+this.tones.dark.html).addClass(this.tones[e].html),$("body#index").exists()||$("#top-bar").removeClass(this.tones.light.top+" "+this.tones.dark.top).addClass(this.tones[e].top)},save:function(){$.ajax({type:"POST",data:{action:"toggleTone"},cache:!1}),u.aux=u.isDark()},timeout:{},aux:{}};if(u.aux=u.isDark(),$(document).on("click","[data-action=top-bar-tone]",function(e){e.isPropagationStopped()||($("[data-action=top-bar-menu-full]").is(":visible")&&PF.fn.topMenu.hide(),clearTimeout(u.timeout),u.toggle(),u.timeout=setTimeout(function(){u.aux!==u.isDark()&&u.save()},750))}),$("[data-action=close-upload]",d).click(function(){d.is(":animated")||$("[data-action=top-bar-upload]","#top-bar").click()}),$("[data-action=reset-upload]",d).click(function(){CHV.fn.uploader.isUploading&&$("[data-action=cancel-upload-remaining], [data-action=cancel-upload]",d).trigger("click"),CHV.fn.uploader.reset()}),$("[data-action=cancel-upload-remaining], [data-action=cancel-upload]",d).click(function(){CHV.fn.uploader.isUploading=!1,$("[data-action=cancel]",c).click(),Object.size(CHV.fn.uploader.results.success)>0?CHV.fn.uploader.displayResults():CHV.fn.uploader.reset()}),$(document).on("click","[data-action=upload-privacy]:not(disabled)",function(e){e.isDefaultPrevented()||(current_privacy=$(this).data("privacy"),target_privacy="public"==current_privacy?"private":"public",this_lock=$(".icon",this).data("lock"),this_unlock=$(".icon",this).data("unlock"),$(".icon",this).removeClass(this_lock+" "+this_unlock).addClass("public"==current_privacy?this_lock:this_unlock),$(this).data("privacy",target_privacy),$("[data-action=upload-privacy-copy]").html($("[data-action=upload-privacy]").html()),$upload_button=$("[data-action=upload]",d),$upload_button.text($upload_button.data(target_privacy)),$(this).tipTip("hide"))}),$(CHV.fn.uploader.selectors.file+", "+CHV.fn.uploader.selectors.camera).on("change",function(e){$(CHV.fn.uploader.selectors.root).data("shown")?CHV.fn.uploader.add(e):CHV.fn.uploader.toggle({callback:function(e){CHV.fn.uploader.add(e)}},e)}).on("click",function(e){!$(this).data("login-needed")||PF.fn.is_user_logged()}),$(CHV.fn.uploader.selectors.root).exists()&&($("body").on({dragenter:function(t){if(t.preventDefault(),!e(t))return!1;$(CHV.fn.uploader.selectors.dropzone).exists()||$("body").append($('
').css({width:"100%",height:"100%",position:"fixed",zIndex:1e3,left:0,top:0}))}}),$(document).on({dragover:function(t){if(t.preventDefault(),!e(t))return!1;$(CHV.fn.uploader.selectors.root).data("shown")||CHV.fn.uploader.toggle({reset:!1})},dragleave:function(e){$(CHV.fn.uploader.selectors.dropzone).remove(),$.isEmptyObject(CHV.fn.uploader.files)&&CHV.fn.uploader.toggle()},drop:function(e){e.preventDefault(),CHV.fn.uploader.add(e),$(CHV.fn.uploader.selectors.dropzone).remove()}},CHV.fn.uploader.selectors.dropzone)),$(document).on("keyup change","[data-action=resize-combo-input]",function(e){var t=$(this).closest("[data-action=resize-combo-input]"),a=$("[name=form-width]",t),o=$("[name=form-height]",t),i=a.data("initial")/o.data("initial"),n={width:Math.round(a.prop("value")/i),height:Math.round(o.prop("value")*i)};$(e.target).is(a)?o.prop("value",Math.round(n.width)):a.prop("value",Math.round(n.height))}),$(document).on("click",l+" [data-action=edit]",function(){for(var e=$(this).closest("li"),t=(e.closest("ul"),e.data("id")),a=CHV.fn.uploader.files[t],o=PF.obj.modal.selectors.root,i=$.extend({},a.formValues||a.parsedMeta),n=["album_id","category_id","nsfw"],s=0;se.height&&(n.height=e.height,n.width=Math.round(n.height*s)),n.width>e.width&&(n.width=e.width,n.height=Math.round(n.width/s)),$.each(i,function(e,t){var i="[name=form-"+e.replace(/_/g,"-")+"]",s=$(i,o);if(!s.exists())return!0;if(s.is(":checkbox"))s.prop("checked",s.attr("value")==t);else if(s.is("select")){var r=s.find("[value="+t+"]");r.exists()||(r=s.find("option:first")),r.prop("selected",!0)}else s.prop("value",t);if("width"==e||"height"==e){var l=n[e],d=a.parsedMeta[e]>l?l:a.parsedMeta[e];s.prop("max",d).data("initial",a.parsedMeta[e]).prop("value",d)}}),"image/gif"!==a.parsedMeta.mimetype&&$("[ data-content=animated-gif-warning]",o).remove(),$(".image-preview",o).append($("",{class:"canvas"}));var r=$(".queue-item[data-id="+t+"] .preview .canvas")[0],l=$(".image-preview .canvas",o)[0];l.width=r.width,l.height=r.height;var d=l.getContext("2d");d.drawImage(r,0,0)},confirm:function(){if(PF.fn.form_modal_has_changed()){var e=!1;return $.each(["width","height"],function(t,a){var i=$("[name=form-"+a+"]",o),n=parseInt(i.val()),s=parseInt(i.attr("min")),r=parseInt(i.attr("max"));if(n>r||n-1&&CHV.fn.uploader.clipboardImages.splice(s,1)}delete CHV.fn.uploader.files[a],CHV.fn.uploader.queueSize(),0==Object.size(CHV.fn.uploader.files)?"success"in CHV.fn.uploader&&"results"in CHV.fn.uploader&&(0!=Object.size(CHV.fn.uploader.results.success)||0!=Object.size(CHV.fn.uploader.results.error))||CHV.fn.uploader.reset():i&&0!==$("li.waiting",t).first().length&&CHV.fn.uploader.upload($("li.waiting",t).first())}}),$(document).on("click","[data-action=upload]",function(){$("[data-group=upload], [data-group=upload-queue-ready]",d).hide(),d.removeClass("queueReady").addClass("queueUploading").find("[data-group=uploading]").show(),CHV.fn.uploader.queueSize(),CHV.fn.uploader.canAdd=!1,$queue_items=$("li",c),$queue_items.addClass("uploading waiting"),CHV.fn.uploader.timestamp=(new Date).getTime(),CHV.fn.uploader.upload($queue_items.first("li"))}),$("body#user").exists()&&PF.obj.listing.query_string.page>1){var m=History.getState();if(m.data&&void 0!==m.data.scrollTop)$(window).scrollTop()!==m.data.scrollTop&&$(window).scrollTop(m.data.scrollTop);else{var f=$("#background-cover").height()-160;$("html, body").animate({scrollTop:f},0)}}$("#top-bar-shade").exists()&&$("#top-bar-shade").css("opacity")&&$("#top-bar-shade").data("initial-opacity",Number($("#top-bar-shade").css("opacity"))),PF.fn.isDevice("phone"),$(window).on("scroll resize",function(){var e=$(window).scrollTop();if(!(e<0)){var t=$("#top-bar"),a=Number(e/($("#background-cover, [data-content=follow-scroll-opacity]").height()-t.height()));a>1&&(a=1),$("#top-bar-shade").data("initial-opacity")&&(a+=$("#top-bar-shade").data("initial-opacity")),$("#top-bar-shade").css({opacity:a}),$("#background-cover-src").css({transform:"translate(0, "+.8*e+"px)"})}}),CHV.fn.bindSelectableItems(),$("body#image").exists()&&($(CHV.obj.image_viewer.selector+" [data-load=full]").length>0?($(document).on("click",CHV.obj.image_viewer.loader,function(e){CHV.fn.viewerLoadImage()}),$(CHV.obj.image_viewer.loader).data("size")>CHV.obj.config.image.load_max_filesize.getBytes()?$(CHV.obj.image_viewer.loader).css("display","block"):CHV.fn.viewerLoadImage(),$(document).bind("DOMSubtreeModified",function(){$("html").height()>$(window).innerHeight()&&!$("html").hasClass("scrollbar-y")&&($("html").addClass("scrollbar-y"),$(document).data({width:$(this).width(),height:$(this).height()}),CHV.fn.image_viewer_full_fix())}),$(window).on("resize",function(){CHV.fn.image_viewer_full_fix()}),$(document).on("keyup",function(e){var t=$(e.target),a=e.charCode||e.keyCode;if(!t.is(":input")&&CHV.obj.image_viewer.$navigation.exists()&&(37==a||39==a)){var o=$("[data-action="+(37==a?"prev":"next")+"]",CHV.obj.image_viewer.$navigation).attr("href");void 0!==o&&""!==o&&(window.location=$("[data-action="+(37==a?"prev":"next")+"]",CHV.obj.image_viewer.$navigation).attr("href"))}})):CHV.fn.viewerImageZoomClass()),$(document).on("click",CHV.obj.image_viewer.container,function(e){if($(this).hasClass("cursor-zoom-in")||$(this).hasClass("cursor-zoom-out")){var t=$(this).hasClass("cursor-zoom-in");if($(this).removeClass("cursor-zoom-in cursor-zoom-out"),t){var a,o=$(this)[0].getBoundingClientRect().width,i=$(this)[0].getBoundingClientRect().height,n=$("img",this).attr("width")/$("img",this).attr("height");void 0===$(this).data("dimentions")&&$(this).data({dimentions:{width:o,height:i},ratio:n}),$("img",this).attr("width")>$(window).width()?($(this).css({width:"100%"}),a=$(this).width(),$(this).css({width:o})):a=$("img",this).attr("width"),$(this).addClass("cursor-zoom-out").css({width:a,height:a/n+"px"})}else $(this).addClass("cursor-zoom-in").css($(this).data("dimentions"));e.preventDefault()}}).on("contextmenu",CHV.obj.image_viewer.container,function(e){if(!CHV.obj.config.image.right_click)return e.preventDefault(),!1}),$(document).on("contextmenu","html.device-mobile a.image-container",function(e){return e.preventDefault(),!1}),$(document).on("keyup","input[data-dashboard-tool]",function(e){if(13==e.keyCode){var t=$("[data-action="+$(this).data("dashboard-tool")+"]");t.click()}}),$(document).on("click","[data-action=dashboardTool]",function(e){e.preventDefault();var t=$(this).data("tool"),a=$(this).data("data"),o=$.extend({},a),i={};for(var n in o){var s=$(o[n]).val();if($(o[n]).prop("disabled")||!s)return;i[n]=$(o[n]),o[n]=s}o.action=t;var r={type:"GET",cache:!1};r.data=o;var l,d=$(this).closest(".input-label"),c=!0;if(0!=c){for(var n in i);PF.fn.loading.inline($(".loading",d),{size:"small",valign:"middle"}),d.find(".btn .text").hide(),$.ajax(r).complete(function(e){var t=e.responseJSON;$(".loading",d).empty(),d.find(".btn .text").show(),200!=t.status_code||void 0===t.success.redirURL?PF.fn.growl.call(t[200==t.status_code?"success":"error"].message):window.location.href=t.success.redirURL})}else PF.fn.growl.expirable(l)}),$(document).on("click","[data-action=openerPostMessage]",function(e){if(window.opener){e.preventDefault();var t="data-action-target",a=$($(this).is("["+t+"]")?$(this).attr(t):this),o=a[a.is(":input")?"val":"html"]();window.opener.postMessage({id:window.name,message:o},"*")}}),$(document).on("click","[data-action=list-tools] [data-action]",function(e){var t=$(e.target),a=t.closest("[data-id]");a&&a.find("[data-action=select]").exists()&&(e.ctrlKey||e.metaKey)&&e.altKey&&(CHV.fn.list_editor.toggleSelectItem(a,!a.hasClass("selected")),e.preventDefault(),e.stopPropagation())}),PF.fn.listing.ajax.callback=function(e){200===e.status&&CHV.fn.list_editor.listMassActionSet("select")},$(document).on("click","[data-action=list-select-all]",function(){CHV.fn.list_editor.selectItem($(".list-item:visible:not(.selected)")),CHV.fn.list_editor.listMassActionSet("clear")}),$(document).on("click","[data-action=list-clear-all]",function(){PF.fn.close_pops(),CHV.fn.list_editor.clearSelection()}),$(document).on("click","[data-action=list-tools] [data-action]",function(e){if(e.isPropagationStopped())return!1;var t=$(this).closest(PF.obj.listing.selectors.list_item+", .viewer"),a=t.data("id");if(void 0!==t.data("type")){o=t.data("type");var o,i=$("[data-type="+o+"][data-id="+a+"]");switch($(this).data("action")){case"select":CHV.fn.list_editor.toggleSelectItem(t,!t.hasClass("selected"));break;case"edit":var n="[data-modal=form-edit-single]";switch(o){case"image":$("[name=form-image-title]",n).attr("value",t.attr("data-title")),$("[name=form-image-description]",n).html(PF.fn.htmlEncode(t.data("description"))),$("[name=form-album-id]",n).find("option").removeAttr("selected"),$("[name=form-album-id]",n).find("[value="+t.data("image"==o?"album-id":"id")+"]").attr("selected",!0),$("[name=form-category-id]",n).find("option").removeAttr("selected"),$("[name=form-category-id]",n).find("[value="+t.data("category-id")+"]").attr("selected",!0),$("[name=form-nsfw]",n).attr("checked","unsafe"==t.data("flag")),$("[name=form-album-name]",n).attr("value",""),$("[name=form-album-description]",n).html(""),$("[name=form-privacy]",n).find("option").removeAttr("selected");break;case"album":$("[data-action=album-switch]",n).remove(),$("[name=form-album-name]",n).attr("value",t.data("name")),$("[name=form-album-description]",n).html(PF.fn.htmlEncode(t.data("description"))),$("[name=form-privacy]",n).find("option").removeAttr("selected"),$("[name=form-privacy]",n).find("[value="+t.data("privacy")+"]").attr("selected",!0),"password"==t.data("privacy")?($("[data-combo-value=password]").show(),$("[name=form-album-password]",n).attr("value",t.data("password"))):($("[data-combo-value=password]").hide(),$("[name=form-album-password]",n).attr("value",""))}PF.fn.modal.call({type:"html",template:$(n).html(),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){CHV.fn.list_editor.updateItem("[data-type="+o+"][data-id="+a+"]",e.responseJSON[o],"edit")}}},confirm:function(){var e=$(PF.obj.modal.selectors.root);if(("image"==o||"album"==o)&&$("[data-content=form-new-album]",e).is(":visible")&&""==$("[name=form-album-name]",e).val())return PF.fn.growl.call(PF.fn._s("You must enter the album name.")),$("[name=form-album-name]",e).highlight(),!1;if(PF.fn.form_modal_has_changed()){switch(PF.obj.modal.form_data={action:"edit",edit:t.data("type"),single:!0,owner:CHV.obj.resource.user.id,editing:{id:a,description:$("[name=form-"+o+"-description]",e).val()}},o){case"image":PF.obj.modal.form_data.editing.title=$("[name=form-image-title]",e).val(),PF.obj.modal.form_data.editing.category_id=$("[name=form-category-id]",e).val()||null,PF.obj.modal.form_data.editing.nsfw=$("[name=form-nsfw]",e).prop("checked")?1:0;break;case"album":PF.obj.modal.form_data.editing.name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.editing.privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.editing.privacy&&(PF.obj.modal.form_data.editing.password=$("[name=form-album-password]",e).val())}return PF.obj.modal.form_data.editing.new_album=$("[data-content=form-new-album]",e).is(":visible"),PF.obj.modal.form_data.editing.new_album?(PF.obj.modal.form_data.editing.album_name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.editing.album_privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.editing.album_privacy&&(PF.obj.modal.form_data.editing.album_password=$("[name=form-album-password]",e).val()),PF.obj.modal.form_data.editing.album_description=$("[name=form-album-description]",e).val()):PF.obj.modal.form_data.editing.album_id=$("[name=form-album-id]",e).val(),!0}PF.fn.modal.close()}});break;case"move":n="[data-modal=form-move-single]";$("[name=form-album-id]",n).find("option").removeAttr("selected"),$("[name=form-album-id]",n).find("[value="+t.data("image"==o?"album-id":"id")+"]").attr("selected",!0),$("[name=form-album-name]",n).attr("value",""),$("[name=form-album-description]",n).html(""),$("[name=form-privacy]",n).find("option").removeAttr("selected"),PF.fn.modal.call({type:"html",template:$(n).html(),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){CHV.fn.list_editor.updateMoveItemLists(e.responseJSON,o,i)}}},load:function(){},confirm:function(){var e=$(PF.obj.modal.selectors.root);return $("[data-content=form-new-album]",e).is(":visible")&&""==$("[name=form-album-name]",e).val()?(PF.fn.growl.call(PF.fn._s("You must enter the album name.")),$("[name=form-album-name]",e).highlight(),!1):PF.fn.form_modal_has_changed()?(PF.obj.modal.form_data={action:"edit",edit:t.data("type"),single:!0,owner:CHV.obj.resource.user.id,editing:{id:a}},PF.obj.modal.form_data.editing.new_album=$("[data-content=form-new-album]",e).is(":visible"),PF.obj.modal.form_data.editing.new_album?(PF.obj.modal.form_data.editing.album_name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.editing.album_privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.editing.album_privacy&&(PF.obj.modal.form_data.editing.album_password=$("[name=form-album-password]",e).val()),PF.obj.modal.form_data.editing.album_description=$("[name=form-album-description]",e).val()):PF.obj.modal.form_data.editing.album_id=$("[name=form-album-id]",e).val(),!0):void PF.fn.modal.close()}});break;case"delete":PF.fn.modal.call({type:"html",template:$("[data-modal=form-delete-single]").html(),button_submit:PF.fn._s("Confirm"),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){"album"==o&&($("[name=form-album-id]","[data-modal]").find("[value="+a+"]").remove(),CHV.fn.list_editor.updateUserCounters("image",e.responseJSON.success.affected,"-")),CHV.fn.list_editor.deleteFromList(t),CHV.fn.queuePixel()}}},confirm:function(){return PF.obj.modal.form_data={action:"delete",single:!0,delete:t.data("type"),deleting:{id:a}},!0}});break;case"flag":$.ajax({type:"POST",data:{action:"edit",edit:"image",single:!0,editing:{id:a,nsfw:"unsafe"==t.data("flag")?0:1}}}).complete(function(e){var t=e.responseJSON,a=1==t.image.nsfw?"unsafe":"safe";i.attr("data-flag",a).data("flag",a),CHV.fn.list_editor.selectionCount()})}}else console.log("Error: data-type not defined")}),$(".pop-box-menu a","[data-content=list-selection]").click(function(e){var t=$(PF.obj.listing.selectors.content_listing_visible);if(void 0!==t.data("list")){dealing_with=t.data("list");var a=$(PF.obj.listing.selectors.list_item+".selected",t),o=$.map(a,function(e,t){return $(e).data("id")});switch($(this).closest(".pop-btn").click(),$(this).data("action")){case"get-embed-codes":var i="[data-modal=form-embed-codes]",n=[];$("textarea",i).html(""),a.each(function(){var e={image:$.parseJSON(decodeURIComponent($(this).data("object")))};"url"in e.image&&n.push(e)}),CHV.fn.fillEmbedCodes(n,i,"html"),PF.fn.modal.call({type:"html",template:$(i).html(),buttons:!1});break;case"clear":CHV.fn.list_editor.clearSelection(),e.stopPropagation();break;case"move":case"create-album":i="move"==$(this).data("action")?"form-move-multiple":"form-create-album";var s="[data-modal="+i+"]",r=/image/.test(dealing_with)?"album-id":"id";$("[name=form-album-id]",s).find("[value=null]").remove(),$("[name=form-album-id]",s).find("option").removeAttr("selected"),$("[name=form-album-name]",s).attr("value",""),$("[name=form-album-description]",s).html(""),$("[name=form-privacy]",s).find("option").removeAttr("selected");var l=a.first().data(r),d=!0;a.each(function(){if($(this).data(r)!==l)return d=!1,!1}),d||$("[name=form-album-id]",s).prepend('"),$("[name=form-album-id]",s).find("[value="+(d?a.first().data(r):"null")+"]").attr("selected",!0),PF.fn.modal.call({type:"html",template:$(s).html(),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){CHV.fn.list_editor.updateMoveItemLists(e.responseJSON,dealing_with,a)}}},load:function(){},confirm:function(){var e=$(PF.obj.modal.selectors.root),t=!1;if($("[data-content=form-new-album]",e).is(":visible")&&""==$("[name=form-album-name]",e).val())return PF.fn.growl.call(PF.fn._s("You must enter the album name.")),$("[name=form-album-name]",e).highlight(),!1;if($("[data-content=form-new-album]",e).is(":visible")&&(t=!0),PF.fn.form_modal_has_changed()){return PF.obj.modal.form_data={action:t?"create-album":"move",type:dealing_with,owner:CHV.obj.resource.user.id,multiple:!0,album:{ids:o,new:t}},t?(PF.obj.modal.form_data.album.name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.album.privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.album.privacy&&(PF.obj.modal.form_data.album.password=$("[name=form-album-password]",e).val()),PF.obj.modal.form_data.album.description=$("[name=form-album-description]",e).val()):PF.obj.modal.form_data.album.id=$("[name=form-album-id]",e).val(),!0}PF.fn.modal.close()}});break;case"delete":PF.fn.modal.call({template:$("[data-modal=form-delete-multiple]").html(),button_submit:PF.fn._s("Confirm"),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){"albums"==dealing_with&&(a.each(function(){$("[name=form-album-id]","[data-modal]").find("[value="+$(this).data("id")+"]").remove()}),CHV.fn.list_editor.updateUserCounters("image",e.responseJSON.success.affected,"-")),CHV.fn.list_editor.deleteFromList(a),CHV.fn.queuePixel()}}},confirm:function(){return PF.obj.modal.form_data={action:"delete",from:"list",delete:dealing_with,multiple:!0,deleting:{ids:o}},!0}});break;case"assign-category":var c=a.first().data("category-id"),u=!0;a.each(function(){if($(this).data("category-id")!==c)return u=!1,!1}),PF.fn.modal.call({type:"html",template:$("[data-modal=form-assign-category]").html(),forced:!0,ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){a.each(function(){var t=e.responseJSON;$(this).data("category-id",t.category_id)}),CHV.fn.list_editor.clearSelection()}}},confirm:function(){var e=$(PF.obj.modal.selectors.root),t=$("[name=form-category-id]",e).val()||null;return u&&c==t?(PF.fn.modal.close(function(){CHV.fn.list_editor.clearSelection()}),!1):(PF.obj.modal.form_data={action:"edit-category",from:"list",multiple:!0,editing:{ids:o,category_id:t}},!0)}});break;case"flag-safe":case"flag-unsafe":var m=$(this).data("action"),f="flag-safe"==m?"safe":"unsafe";PF.fn.modal.call({template:$("[data-modal=form-"+m+"]").html(),button_submit:PF.fn._s("Confirm"),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){a.each(function(){$(this).removeClass("safe unsafe").addClass(f).removeAttr("data-flag").attr("data-flag",f).data("flag",f)}),CHV.fn.list_editor.clearSelection()}}},confirm:function(){return PF.obj.modal.form_data={action:m,from:"list",multiple:!0,editing:{ids:o,nsfw:"flag-safe"==m?0:1}},!0}})}return!PF.fn.isDevice(["phone","phablet"])&&void 0}console.log("Error: data-list not defined")}),$("body#image").exists()&&$(window).scroll(function(){CHV.obj.topBar.transparencyScrollToggle()}),$(document).on("click","[data-action=disconnect]",function(){var e=$(this),t=e.data("connection");PF.fn.modal.confirm({message:e.data("confirm-message"),ajax:{data:{action:"disconnect",disconnect:t,user_id:CHV.obj.resource.user.id},deferred:{success:function(e){var a=e.responseJSON;$("[data-connection="+t+"]").fadeOut(function(){$($("[data-connect="+t+"]")).fadeIn(),$(this).remove(),0==$("[data-connection]").length&&$("[data-content=empty-message]").show(),PF.fn.growl.expirable(a.success.message)})},error:function(e){var t=e.responseJSON;PF.fn.growl.call(t.error.message)}}}})}),$(document).on("click","[data-action=delete-avatar]",function(){var e=$(".user-settings-avatar"),t=$(".loading-placeholder",e),a=$("#top-bar");t.removeClass("hidden"),PF.fn.loading.inline(t,{center:!0}),$.ajax({type:"POST",data:{action:"delete",delete:"avatar",owner:CHV.obj.resource.user.id}}).complete(function(o){t.addClass("hidden").empty(),200==o.status?(CHV.obj.logged_user.id==CHV.obj.resource.user.id&&($("img.user-image",a).hide(),$(".default-user-image",a).removeClass("hidden")),$(".default-user-image",e).removeClass("hidden").css({opacity:0}),$(".btn-alt",e).closest("div").hide(),$("img.user-image",e).fadeOut(function(){$(".default-user-image",e).animate({opacity:1})})):PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."))})}),$(document).on("change","[data-content=user-avatar-upload-input]",function(e){e.preventDefault(),e.stopPropagation();var t=$(this),a=$(".user-settings-avatar"),o=$(".loading-placeholder",".user-settings-avatar"),i=$("#top-bar"),n=$(this)[0].files[0];if(!t.data("uploading"))if(0!=/^image\/.*$/.test(n.type))if(n.size>CHV.obj.config.user.avatar_max_filesize.getBytes())PF.fn.growl.call(PF.fn._s("Please select a picture of at most %s size.",CHV.obj.config.user.avatar_max_filesize));else{o.removeClass("hidden"),PF.fn.loading.inline(o,{center:!0}),t.data("uploading",!0);var s=new FormData;s.append("source",n),s.append("action","upload"),s.append("type","file"),s.append("what","avatar"),s.append("owner",CHV.obj.resource.user.id),s.append("auth_token",PF.obj.config.auth_token),avatarXHR=new XMLHttpRequest,avatarXHR.open("POST",PF.obj.config.json_api,!0),avatarXHR.send(s),avatarXHR.onreadystatechange=function(){if(4==this.readyState){var e="json"!==this.responseType?JSON.parse(this.response):this.response,n=e.success.image;o.addClass("hidden").empty(),200==this.status?(change_avatar=function(e){$("img.user-image",e).attr("src",n.url).removeClass("hidden").show()},hide_default=function(e){$(".default-user-image",e).addClass("hidden")},hide_default(a),$(".btn-alt",a).closest("div").show(),change_avatar(a),CHV.obj.logged_user.id==CHV.obj.resource.user.id&&(change_avatar(i),hide_default(i)),PF.fn.growl.expirable(PF.fn._s("Profile image updated."))):PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")),t.data("uploading",!1)}}}else PF.fn.growl.call(PF.fn._s("Please select a valid image file type."))}),$(document).on("change","[data-content=user-background-upload-input]",function(e){e.preventDefault(),e.stopPropagation();var t=$(this),a=$("[data-content=user-background-cover]"),o=$("[data-content=user-background-cover-src]"),i=$(".loading-placeholder",a),n=($("#top-bar"),$(this)[0].files[0]);if(!t.data("uploading"))if(0!=/^image\/.*$/.test(n.type))if(n.size>CHV.obj.config.user.background_max_filesize.getBytes())PF.fn.growl.call(PF.fn._s("Please select a picture of at most %s size.",CHV.obj.config.user.background_max_filesize));else{i.removeClass("hidden"),PF.fn.loading.inline(i,{center:!0,size:"big",color:"#FFF"}),t.data("uploading",!0);var s=new FormData;s.append("source",n),s.append("action","upload"),s.append("type","file"),s.append("what","background"),s.append("owner",CHV.obj.resource.user.id),s.append("auth_token",PF.obj.config.auth_token),avatarXHR=new XMLHttpRequest,avatarXHR.open("POST",PF.obj.config.json_api,!0),avatarXHR.send(s),avatarXHR.onreadystatechange=function(){if(4==this.readyState){var e="json"!==this.responseType?JSON.parse(this.response):this.response,n=e.success.image;if(200==this.status){var s=$("");s.attr("src",n.url).imagesLoaded(function(){i.addClass("hidden").empty(),o.css("background-image","url("+n.url+")").hide().fadeIn(),$("[data-content=user-change-background]",a).removeClass("hidden"),a.removeClass("no-background"),$("[data-content=user-upload-background]").hide(),$("[data-content=user-change-background]").show(),PF.fn.growl.expirable(PF.fn._s("Profile background image updated.")),s.remove(),"function"==typeof user_background_full_fix&&user_background_full_fix()})}else i.addClass("hidden").empty(),PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."));t.data("uploading",!1)}}}else PF.fn.growl.call(PF.fn._s("Please select a valid image file type."))}),CHV.fn.user_background={delete:{submit:function(){return PF.obj.modal.form_data={action:"delete",delete:"background",owner:CHV.obj.resource.user.id},!0},deferred:{success:{before:function(e){$("[data-content=user-background-cover-src]").css("background-image","none"),$("[data-content=user-background-cover]").addClass("no-background").height(""),$("[data-content=user-upload-background]").removeClass("hidden").show(),$("[data-content=user-change-background]").hide(),$("#top-bar-shade").remove()}, -done:function(e){PF.fn.modal.close(function(){PF.fn.growl.expirable(PF.fn._s("Profile background image deleted."))})}},error:function(e){PF.fn.growl.expirable(PF.fn._s("Error deleting profile background image."))}}}},CHV.str.mainform="[data-content=main-form]",CHV.obj.timezone={selector:"[data-content=timezone]",input:"#timezone-region"},$(document).on("keyup change",CHV.str.mainform+" :input",function(){$(this).is("[name=username]")&&$("[data-text=username]").text($(this).val())}),$(document).on("change",CHV.obj.timezone.input,function(){var e=$(this).val(),t=$("#timezone-combo-"+e);t.find("option:first").prop("selected",!0),$(CHV.obj.timezone.selector).val(t.val()).change()}),$(document).on("change","[id^=timezone-combo-]",function(){var e=$(this).val();$(CHV.obj.timezone.selector).val(e).change()}),$(document).on("keyup change blur","[name^=new-password]",function(){var e=$("[name=new-password]"),t=$("[name=new-password-confirm]"),a=e.val()==t.val(),o=t.closest(".input-password").find(".input-warning");0==o.exists()&&(o=$("[data-message=new-password-confirm]")),$(this).is(t)&&t.data("touched",!0),t.data("touched")&&o.text(a?"":o.data("text"))[a?"addClass":"removeClass"]("hidden-visibility")}),$(document).on("submit",CHV.obj.mainform,function(){switch($(this).data("type")){case"password":var e=$("[name=new-password]",this),t=$("[name=new-password-confirm]",this);if((""!==e.val()||""!==t.val())&&e.val()!==t.val())return e.highlight(),t.highlight(),PF.fn.growl.expirable(PF.fn._s("Passwords don't match")),!1}}),$(document).on("click","[data-action=check-for-updates]",function(){PF.fn.loading.fullscreen(),CHV.fn.system.checkUpdates(function(e){if(PF.fn.loading.destroy("fullscreen"),200===e.status){var t=e.responseJSON.software;-1==PF.fn.versionCompare(CHV.obj.system_info.version,t.current_version)?PF.fn.modal.simple({title:PF.fn._s("Update available v%s",t.current_version),message:"

"+PF.fn._s("There is an update available for your system. You can automatic download and install this update or go to %s to proceed to download the file.",''+CHEVERETO.source.label+"")+"

"+PF.fn._s("The release notes for this update are:")+'

",html:!0}):PF.fn.growl.call(PF.fn._s("This website is running latest %s version",CHEVERETO.edition))}else PF.fn.growl.call(PF.fn._s("An error occurred. Please try again later."))})}),void 0!==PF.fn.get_url_var("checkUpdates")&&$("[data-action=check-for-updates]").click(),$("body#image").exists()&&window.scrollY>0&&$("#top-bar").removeClass("transparent"),$(document).on("click","[data-action=toggle-storage-https]",function(){CHV.fn.storage.toggleHttps($(this).closest("[data-content=storage]").data("storage-id"))}),$(document).on("click","[data-action=toggle-storage-active]",function(){CHV.fn.storage.toggleActive($(this).closest("[data-content=storage]").data("storage-id"))}),$(CHV.fn.uploader.selectors.root).exists()&&(CHV.fn.uploader.$pasteCatcher=$("
",{contenteditable:"true",id:CHV.fn.uploader.selectors.paste.replace(/#/,"")}),$("body").append(CHV.fn.uploader.$pasteCatcher),$(document).keydown(function(e){var t=e.keyCode,a=e.ctrlKey||e.metaKey;a&&86==t&&!$(e.target).is(":input")&&CHV.fn.uploader.$pasteCatcher.focus(e)}),window.addEventListener("paste",CHV.fn.uploader.pasteImageHandler)),$(document).on("click","[data-action=like]",function(){if(PF.fn.is_user_logged()){var e=$(this);if(!e.data("XHR")){e.data("XHR",!0);var t=$(this).is("[data-liked]")?$(this):$(this).closest("[data-liked]"),a=!t.closest("[data-list], .viewer").exists()&&void 0!==CHV.obj.resource,o=t.is("[data-liked=1]"),i=o?"dislike":"like",n={id:a?CHV.obj.resource.id:$(this).closest("[data-id]").attr("data-id"),type:a?CHV.obj.resource.type:$(this).closest("[data-type]").attr("data-type")},s=a?e:$("[data-type="+n.type+"][data-id="+n.id+"]"),r={type:"POST",data:{action:i},cache:!1};r.data[i]={object:n.type,id:n.id},$.ajax(r).complete(function(t){var i=t.responseJSON;e.data("XHR",!1),200===i.status_code?(a&&void 0!==i.content&&$("[data-text=likes-count]").html(i.content.likes),s.attr("data-liked",o?0:1)):PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."))})}}else window.location.href=CHV.obj.vars.urls.login}),$(document).on("click","[data-action=follow]",function(){if(PF.fn.is_user_logged()){var e=$(this);if(!e.data("XHR")){e.data("XHR",!0);var t=$(this).is("[data-followed]")?$(this):$(this).closest("[data-followed]"),a=void 0!==CHV.obj.resource,o=t.is("[data-followed=1]"),i=o?"unfollow":"follow",n={id:a?CHV.obj.resource.id:$(this).closest("[data-id]").data("id"),type:a?CHV.obj.resource.type:$(this).closest("[data-type]").data("type")},s={type:"POST",data:{action:i},cache:!1};s.data[i]={object:n.type,id:n.id},$.ajax(s).complete(function(i){var n=i.responseJSON;if(e.data("XHR",!1),200===n.status_code){if(a&&void 0!==n.user_followed){var s=$("[data-text=followers-label]"),r={single:s.data("label-single"),plural:s.data("label-plural")};$("[data-text=followers-count]").html(n.user_followed.followers),s.html(PF.fn._n(r.single,r.plural,n.user_followed.followers))}t.attr("data-followed",o?0:1)}else PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."))})}}else PF.fn.modal.call({type:"login"})}),$(document).on("click","[data-action=top-bar-notifications]",function(e){var a=this,o=$(this),i=$(".top-bar-notifications-container",o),n=$(".top-bar-notifications-list",o),s=$("ul",n),r=$(".loading",i);o.data("XHR")||(r.removeClass("hidden"),PF.fn.loading.inline(r,{size:"small",message:PF.fn._s("loading")}),$.ajax({type:"POST",data:{action:"notifications"},cache:!1}).complete(function(e){var l=e.responseJSON;if(200!==l.status_code)return PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")),o.data("XHR",!1),void r.addClass("hidden").html("");if(o.data("XHR",!0),r.remove(),l.html){n.removeClass("hidden"),s.html(l.html),t();var d=$("li.new",s);d.addClass("transition"),setTimeout(function(){d.removeClass("new"),$("[data-content=notifications-counter]",a).removeClass("on").html("0"),setTimeout(function(){d.removeClass("transition")},150)},1500)}else $(".empty",i).removeClass("hidden")}))}),$("#g-recaptcha").is(":empty")&&CHV.obj.config.recaptcha.enabled&&CHV.obj.config.recaptcha.sitekey&&(reCaptchaCallback=function(){0!=$("#g-recaptcha").is(":empty")&&grecaptcha.render("g-recaptcha",{sitekey:CHV.obj.config.recaptcha.sitekey})},$.getScript("https://www.google.com/recaptcha/api.js?onload=reCaptchaCallback&render=explicit")),$(document).on("click",".list-item a.image-container",function(e){var t=$(this).closest(".list-item"),o=t.find("[data-action=load-image]");o.length>0&&(a(o),e.preventDefault())}),$(document).on("click",".list-item [data-action=load-image]",function(e){a($(this)),e.preventDefault(),e.stopPropagation()}),$(document).on("click","#album [data-tab=tab-codes]",function(){var e=$(".content-listing-loading","#tab-codes");if(e.exists()){var t=$("#embed-codes");$.ajax({type:"POST",data:{action:"get-album-contents",albumid:CHV.obj.resource.id},cache:!1}).always(function(a){PF.fn.loading.destroy(e),200==a.status_code&&(CHV.fn.fillEmbedCodes(a.contents,"#tab-codes"),t.removeClass("soft-hidden"))})}}),$("body").is("#upload")&&CHV.fn.uploader.toggle({show:!0}),$(document).on("keyup",function(e){if(!$(PF.obj.modal.selectors.root).exists()&&$(".viewer").exists()&&e.which in CHV.fn.listingViewer.keys){var t=[88,37,39],a=CHV.fn.listingViewer.keys[e.which];-1==t.indexOf(e.which)?$("[data-action="+a+"]",CHV.fn.listingViewer.selectors.root).click():a in CHV.fn.listingViewer&&CHV.fn.listingViewer[a]()}}),$(document).on("click",CHV.fn.listingViewer.selectors.root+" [data-action^=viewer-]",function(){var e=$(this).data("action").substring("viewer-".length);e in CHV.fn.listingViewer&&CHV.fn.listingViewer[e]()}),$(document).on("click","a[data-href]:not([rel=popup-link]):not(.popup-link)",function(){var e=$(this).attr("data-href"),t=$(this).attr("href");(e||t)&&(location.href=t||e)}),void 0!==CHV.obj.config&&CHV.obj.config.listing.viewer&&$(document).on("click",PF.obj.listing.selectors.list_item+"[data-type=image] a.image-container",function(e){e.preventDefault(),e.stopPropagation();var t=$(this).closest(PF.obj.listing.selectors.list_item);t.exists()&&CHV.fn.listingViewer.open(t)}),$(document).on("contextmenu",CHV.fn.listingViewer.selectors.src,function(e){return e.preventDefault(),!1});var p=PF.fn.deparam(window.location.search);if(p&&"viewer"in p){var g=$(PF.obj.listing.selectors.content_listing_visible);if("images"==g.data("list")){var h=$(PF.obj.listing.selectors.list_item,g)["next"==p.viewer?"first":"last"]();CHV.fn.listingViewer.open(h)}}}),"undefined"==typeof CHV&&(CHV={obj:{},fn:{},str:{}}),window.opener&&(CHV.obj.opener={uploadPlugin:{}}),CHV.fn.listingViewer={selectors:{bodyShown:".--viewer-shown",template:"#viewer-template",root:".viewer",rootShow:".viewer--show",rootHide:".viewer--hide",rootZero:".viewer--zero",rootNavPrev:".viewer--nav-prev",rootNavNext:".viewer--nav-next",src:".viewer-src",tools:".viewer-tools",loader:".viewer-loader",owner:".viewer-owner",ownerGuest:".viewer-owner--guest",ownerUser:".viewer-owner--user",inputMap:".viewer-kb-input"},keys:{83:"select",76:"like",70:"flag",69:"edit",65:"move",46:"delete",88:"close",37:"prev",39:"next"},keymap:{select:["S",PF.fn._s("Toggle select")],like:["L",PF.fn._s("Like")],flag:["F",PF.fn._s("Toggle flag")],edit:["E",PF.fn._s("Edit")],move:["A",PF.fn._s("Album")],delete:["Del",PF.fn._s("Delete")],close:["X",PF.fn._s("Close")],prev:["◀",PF.fn._s("Previous")],next:["▶",PF.fn._s("Next")]},loading:null,idleTimer:0,$item:null,show:function(){this.getEl("root").removeClass(this.selectors.rootHide.substring(1)).addClass(this.selectors.rootShow.substring(1)),$("body").addClass(this.selectors.bodyShown.substring(1));var e=new Hammer($(CHV.fn.listingViewer.selectors.root).get(0),{direction:Hammer.DIRECTION_VERTICAL});e.on("swipeleft swiperight",function(e){var t="left"==e.type.substring("swipe".length)?"next":"prev";CHV.fn.listingViewer[t]()})},getItem:function(){return this.$item},getEl:function(e){var t=!e.startsWith("template")&&!e.startsWith("root")&&this.selectors.root;return t?$(this.selectors[e],t):$(this.selectors[e])},getObject:function(e){if(e||void 0===this.object){var t=decodeURIComponent(this.getItem().attr("data-object"));this.object=JSON&&JSON.parse(t)||$.parseJSON(t)}return this.object},placeholderSizing:function(){if(this.getEl("root").exists()){var e=Math.max(document.documentElement.clientWidth,window.innerWidth||0),t=Math.max(document.documentElement.clientHeight,window.innerHeight||0),a=e/t,o=this.getEl("src")[0],i=o.getAttribute("width"),n=o.getAttribute("height"),s=i/n,r=a0?"add":t.getItem()[o]().exists()?"add":"remove";a[n+"Class"](i.substring(1))}),$.each(this.getItem().get(0).attributes,function(e,t){if(!t.name.startsWith("data-"))return!0;a.attr(t.name,t.value)});var n=void 0===this.object.user?"user":"guest";n="owner"+(n.charAt(0).toUpperCase()+n.slice(1).toLowerCase()),this.getEl(n).remove(),void 0!==this.object.user&&$(this.object.user.avatar?".default-user-image":"img.user-image",this.getEl("ownerUser")).remove();var s=this.getItem().find(".list-item-image-tools");this.getEl("tools").append(s.html()),$.each(s.find("[data-action]"),function(e,a){var o=$(this).attr("data-action"),i=t.keymap[o];$('
'+i[0]+""+i[1]+"
").appendTo(t.getEl("inputMap"))}),this.placeholderSizing(),this.trickyLoad()},toggleFullscreen:function(e){var t=e?this.getEl("root")[0]:document,a=e?t.requestFullscreen||t.mozRequestFullScreen||t.webkitRequestFullScreen||t.msRequestFullscreen:t.exitFullscreen||t.webkitExitFullscreen||t.mozCancelFullScreen||t.msExitFullscreen;a.call(t)},fullscreen:function(){this.toggleFullscreen(!0)},normalscreen:function(){this.toggleFullscreen(!1)},remove:function(){this.getEl("root").remove()},getParsedTemplate:function(){var e=this.getObject(!0),t=this.getEl("template").html(),a=t.match(/%(\S+)%/g);return a&&$.each(a,function(a,o){var i,n=o.slice(1,-1).split(".");n.map(function(t){var a=i||e;t in a&&(i=a[t])});var s=new RegExp(o,"g");t=t.replace(s,i)}),t},insertEl:function(){var e=this.getParsedTemplate();this.getEl("rootZero").remove(),$(e).appendTo("body")},toggleIdle:function(e,t){var a=this;t=void 0===t||t;$("html")[(e?"add":"remove")+"Class"]("--idle"),e||(clearTimeout(a.idleTimer),t&&(a.idleTimer=setTimeout(function(){var e=$(".fullscreen"),t=a.getEl("root");a.toggleIdle(t.length>0&&0==e.length)},5e3)))},open:function(e){this.setItem(e),this.insertEl(),this.filler(),this.show(),this.toggleIdle(!1);var t=this;this.getEl("root").on("mousemove mouseout",function(){t.toggleIdle(!1)})},setItem:function(e){this.$item=e},trickyLoad:function(){var e=this.getEl("loader");if(this.object.image.url!=this.object.display_url){var t=this.getEl("src").parent().html(),a=$(t).attr("src",this.object.image.url);a.insertBefore(this.getEl("src")),PF.fn.loading.inline(e,{color:"white",size:"small",center:!0,valign:!0}),e.hide().fadeIn("slow"),a.imagesLoaded(function(){a.next().remove(),PF.fn.loading.destroy(e)})}else e.remove()},close:function(){var e=this;$(this.selectors.root).removeClass(this.selectors.rootShow.substring(1)).addClass(this.selectors.rootHide.substring(1)),$("body").removeClass(this.selectors.bodyShown.substring(1)),this.toggleIdle(!1,!1),setTimeout(function(){e.remove()},200)},browse:function(e){var t=this.getItem()[e]();if(t.exists()){this.setItem(t),this.filler(!0);var a=$(PF.obj.listing.selectors.content_listing_visible).find("[data-action=load-more]"),o=t[e+"All"]().length;a.length>0&&o<=5&&!PF.obj.listing.calling&&"next"==e&&$("[data-action=load-more]").click()}else{var i=$("[data-pagination="+e+"]",PF.obj.listing.selectors.content_listing_pagination+":visible"),n=i.attr("href");if(!n)return;PF.fn.deparam(window.location.search);window.location.href=n+"&viewer="+e}},prev:function(){this.browse("prev")},next:function(){this.browse("next")}},CHV.obj.image_viewer={selector:"#image-viewer",container:"#image-viewer-container",navigation:".image-viewer-navigation",loading:"#image-viewer-loading",loader:"#image-viewer-loader"},CHV.obj.image_viewer.$container=$(CHV.obj.image_viewer.container),CHV.obj.image_viewer.$navigation=$(CHV.obj.image_viewer.navigation),CHV.obj.image_viewer.$loading=$(CHV.obj.image_viewer.loading),CHV.fn.system={checkUpdates:function(e){$.ajax({url:CHEVERETO.api.get.info+"/",data:null,cache:!1}).always(function(t,a,o){"function"==typeof e&&e(o)})}},CHV.fn.bindSelectableItems=function(){var e="content-listing-wrapper",t="#"+e;$(t).exists()?$(t).hasClass("ui-selectable")&&$(t).selectable("destroy"):$("[data-content=list-selection]").closest(".content-width").wrap("
"),$("[data-content=list-selection]").exists()&&$("html.device-nonmobile "+t).selectable({delay:150,filter:PF.obj.listing.selectors.list_item,cancel:".content-empty, .header, #tab-share, #tab-full-info, .viewer-title, .header-link, .top-bar, .content-listing-pagination *, #fullscreen-modal, #top-user, #background-cover, .list-item-desc, .list-item-image-tools, [data-action=load-image], #tab-codes",selecting:function(e,t){var a=$(t.selecting),o=a.hasClass("selected");CHV.fn.list_editor[(o?"unselect":"select")+"Item"](a)},unselecting:function(e,t){CHV.fn.list_editor.unselectItem($(t.unselecting))}})},CHV.fn.isCachedImage=function(e){var t=new Image;return t.src=e,t.complete||t.width+t.height>0},CHV.fn.viewerImageZoomClass=function(){CHV.obj.image_viewer.$container.hasClass("jscursor-zoom-in")&&CHV.obj.image_viewer.$container.addClass("cursor-zoom-in").removeClass("jscursor-zoom-in")},CHV.fn.viewerLoadImage=function(){CHV.obj.image_viewer.$loading.exists()&&(CHV.obj.image_viewer.$loading.removeClass("soft-hidden").css({zIndex:2}),PF.fn.loading.inline(CHV.obj.image_viewer.$loading,{color:"white",size:"small",center:!0,valign:!0}),CHV.obj.image_viewer.$loading.hide().fadeIn("slow")),$(CHV.obj.image_viewer.loader).remove(),CHV.obj.image_viewer.image.html=CHV.obj.image_viewer.$container.html(),CHV.obj.image_viewer.$container.prepend($(CHV.obj.image_viewer.image.html).css({top:0,zIndex:0})),CHV.obj.image_viewer.$container.find("img").eq(0).css("zIndex",1),CHV.obj.image_viewer.$container.find("img").eq(1).attr("src",CHV.obj.image_viewer.image.url).css({width:"100%",height:"auto"}),CHV.obj.image_viewer.$container.find("img").eq(1).imagesLoaded(function(){CHV.obj.image_viewer.$container.find("img").eq(1).css({width:"",height:""}),CHV.obj.image_viewer.$container.find("img").eq(0).remove(),PF.fn.loading.destroy(CHV.obj.image_viewer.$loading)})},CHV.obj.embed_tpl={},CHV.obj.topBar={transparencyScrollToggle:function(){var e=$(window).scrollTop();$("#top-bar")[(e>0?"remove":"add")+"Class"]("transparent")}},CHV.obj.uploaderReset={isUploading:!1,canAdd:!0,queueStatus:"ready",uploadThreads:0,uploadParsedIds:[],uploadProcessedIds:[],files:{},results:{success:{},error:{}},toggleWorking:0,filesAddId:0,clipboardImages:[]},CHV.fn.uploader={selectors:{root:"#anywhere-upload",show:".upload-box--show",queue:"#anywhere-upload-queue",queue_complete:".queue-complete",queue_item:".queue-item",close_cancel:"[data-button=close-cancel]",file:"#anywhere-upload-input",camera:"#anywhere-upload-input-camera",upload_item_template:"#anywhere-upload-item-template",item_progress_bar:"[data-content=progress-bar]",item_progress_percent:"[data-text=progress-percent]",failed_result:"[data-content=failed-upload-result]",fullscreen_mask:"#fullscreen-uploader-mask",dropzone:"#uploader-dropzone",paste:"#anywhere-upload-paste",input:"[data-action=anywhere-upload-input]"},toggle:function(e,t){this.queueSize();var a=$("[data-action=top-bar-upload]",".top-bar"),o=!$(CHV.fn.uploader.selectors.root).data("shown");e=$.extend({callback:null,reset:!0},e);if(void 0!==e.show&&e.show&&(o=!0),PF.fn.growl.close(!0),PF.fn.close_pops(),!(1==this.toggleWorking||$(CHV.fn.uploader.selectors.root).is(":animated")||CHV.fn.uploader.isUploading||a.data("login-needed")&&!PF.fn.is_user_logged())){this.toggleWorking=1;var i={time:500,easing:null},n=function(){!o&&e.reset&&CHV.fn.uploader.reset(),PF.obj.follow_scroll.$node.exists()&&(PF.obj.follow_scroll.$node.removeClass("fixed"),PF.obj.follow_scroll.set()),PF.fn.topMenu.hide(),"function"==typeof e.callback&&e.callback(t),CHV.fn.uploader.boxSizer(),CHV.fn.uploader.toggleWorking=0};if($(CHV.fn.uploader.selectors.root)[(o?"add":"remove")+"Class"](this.selectors.show.substring(1)),o){if(!$("body").is("#upload")&&PF.fn.isDevice(["phone","phablet"])&&$("html").addClass("overflow-hidden"),$("html").data({"followed-scroll":$("html").hasClass("followed-scroll"),"top-bar-box-shadow-prevent":!0}).removeClass("followed-scroll").addClass("top-bar-box-shadow-none"),$("#top-bar").data({stock_classes:$("#top-bar").attr("class")}),$(".current[data-nav]",".top-bar").each(function(){$(this).is("[data-action=top-bar-menu-full]")||$(this).removeClass("current").attr("data-current",1)}),PF.fn.isDevice("mobile")){var s=$(".upload-box-heading",$(CHV.fn.uploader.selectors.root));s.css({position:"relative",top:.5*($(window).height()-s.height())+"px"})}CHV.fn.uploader.focus(function(){setTimeout(function(){n()},i.time)})}else{$("[data-nav][data-current=1]",".top-bar").each(function(){$(this).addClass("current")}),$(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity:0}),setTimeout(function(){$(CHV.fn.uploader.selectors.fullscreen_mask).remove(),$("html").data("followed-scroll")&&$("html").addClass("followed-scroll")},250);var r=$(CHV.fn.uploader.selectors.root).outerHeight(),l=r-parseInt($(CHV.fn.uploader.selectors.root).data("initial-height"))+"px";$(CHV.fn.uploader.selectors.root).css({transform:"translate(0,-"+l+")"}),setTimeout(function(){$("#top-bar").attr("class",$("#top-bar").data("stock_classes")),$("html").removeClass($(".follow-scroll-wrapper.position-fixed").exists()?"":"top-bar-box-shadow-none")},1*i.time/3),setTimeout(function(){$(CHV.fn.uploader.selectors.root).css({top:""}),$("body#image").exists()&&CHV.obj.topBar.transparencyScrollToggle(),n(),$("html,body").removeClass("overflow-hidden").data({"top-bar-box-shadow-prevent":!1})},i.time)}$(CHV.fn.uploader.selectors.root).data("shown",o),a.toggleClass("current").removeClass("opened")}},reset:function(){$.extend(this,$.extend(!0,{},CHV.obj.uploaderReset)),$("li",this.selectors.queue).remove(),$(this.selectors.root).height("").css({"overflow-y":"","overflow-x":""}),$(this.selectors.queue).addClass("queueEmpty").removeClass(this.selectors.queue_complete.substring(1)),$(this.selectors.input,this.selectors.root).each(function(){$(this).prop("value",null)}),$("[data-group=upload-result] textarea",this.selectors.root).prop("value",""),$.each(["upload-queue-ready","uploading","upload-result","upload-queue-ready","upload-queue"],function(e,t){$("[data-group="+t+"]").hide()}),$("[data-group=upload]",this.selectors.root).show(),$("[name=upload-album-id]",this.selectors.root).prop("value",function(){var e=$("option[selected]",this);if(e.exists())return e.attr("value")}),$(this.selectors.root).removeClass("queueCompleted queueReady queueHasResults").addClass("queueEmpty").attr("data-queue-size",0),$("[name=upload-category-id]",this.selectors.root).prop("value",""),$("[name=upload-nsfw]",this.selectors.root).prop("checked",this.defaultChecked),this.boxSizer(!0)},focus:function(e){$(this.selectors.fullscreen_mask).exists()||($("body").is("#upload")||$("body").append($("
",{id:this.selectors.fullscreen_mask.replace("#",""),class:"fullscreen soft-black"}).css({top:PF.fn.isDevice("phone")?0:$(CHV.fn.uploader.selectors.root).data("top")})),setTimeout(function(){$("body").is("#upload")||$(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity:1}),setTimeout(function(){"function"==typeof e&&e()},PF.fn.isDevice(["phone","phablet"])?0:250)},1))},boxSizer:function(e){var t=$(this.selectors.root).is(this.selectors.show),a=t||e;t&&!$("body").is("#upload")&&$("html")[(PF.fn.isDevice(["phone","phablet"])?"add":"remove")+"Class"]("overflow-hidden"),a&&($(this.selectors.root).height(""),!$("body").is("#upload")&&$(this.selectors.root).height()>$(window).height()?($(this.selectors.root).height($(window).height()).css({"overflow-y":"scroll","overflow-x":"auto"}),$("body").addClass("overflow-hidden")):($(this.selectors.root).css("overflow-y",""),$("body").removeClass("overflow-hidden")))},pasteURL:function(){var e=$("[name=urls]","#fullscreen-modal").val();e&&(CHV.fn.uploader.toggle({show:!0}),CHV.fn.uploader.add({},e))},pasteImageHandler:function(e){if(!$(e.target).is(":input")){if(void 0!==e.clipboardData&&e.clipboardData.items)var t=e.clipboardData.items;else setTimeout(function(){return e.clipboardData={},e.clipboardData.items=[],$.each($("img",CHV.fn.uploader.$pasteCatcher),function(t,a){e.clipboardData.items.push(PF.fn.dataURItoBlob($(this).attr("src")))}),$(CHV.fn.uploader.selectors.paste).html(""),CHV.fn.uploader.pasteImageHandler(e)},1);if(t)for(var a=0;ah||f==h){var v=hh&&$img.height(v).width(v*b)}if(f0){var w="";for(d=0;d"+PF.fn.htmlEncode(s[d].name)+"",delete CHV.fn.uploader.files[s[d].uid],$("li[data-id="+s[d].uid+"]",CHV.fn.uploader.selectors.queue).find("[data-action=cancel]").click();PF.fn.modal.simple({title:PF.fn._s("Some files couldn't be added"),message:"
    "+w+"
"})}else CHV.fn.uploader.focus();CHV.fn.uploader.boxSizer()}},$.extend({},h,{orientation:o.exif?o.exif.get("Orientation"):1})),setTimeout(function(){a(e+1)},25)})}else PF.fn.loading.destroy("fullscreen")}var o;if(!this.canAdd){e=e.originalEvent;return e.preventDefault(),e.stopPropagation(),!1}$fileinput=$(this.selectors.file),$fileinput.replaceWith($fileinput=$fileinput.clone(!0));var i=$(this.selectors.upload_item_template).html(),n=[];if(void 0===t){e=e.originalEvent;if(e.preventDefault(),e.stopPropagation(),n=e.dataTransfer||e.target,n=$.makeArray(n.files),e.clipboard){if(o=PF.fn.md5(e.dataURL),-1!=$.inArray(o,this.clipboardImages))return null;this.clipboardImages.push(o)}for(var s=[],r=0;rCHV.obj.config.image.max_filesize.getBytes()?s.push({uid:r,name:d.name.truncate_middle()+" - "+PF.fn._s("File too big.")}):-1!=CHV.obj.config.upload.image_types.indexOf(l)||0!=/android/i.test(navigator.userAgent)?(o&&(d.md5=o),d.fromClipboard=1==e.clipboard,d.uid=r):s.push({uid:r,name:d.name.truncate_middle()+" - "+PF.fn._s("Invalid or unsupported file format.")})}for(r=0;r0&&0==n.length){var u="";for(r=0;r"+PF.fn.htmlEncode(s[r].name)+"";return void PF.fn.modal.simple({title:PF.fn._s("Some files couldn't be added"),message:"
  • "+u+"
"})}if(0==n.length)return}else{if(t=t.replace(/(<([^>]+)>)/g,"").replace(/(\[([^\]]+)\])/g,""),n=t.match_urls(),!n)return;n=n.array_unique(),n=$.map(n,function(e,t){return{uid:t,name:e,url:e}})}if($.isEmptyObject(this.files))for(r=0;r0){var i=[];for(var o in this.results.error)"object"==typeof this.results.error[o]&&(i[o]=this.results.error[o].error.message);i.length>0&&$(this.selectors.failed_result).html("
  • "+i.join("
  • ")+"
  • ")}else $(a.error,this.selectors.root).hide();if(!window.opener&&CHV.obj.config.upload.redirect_single_upload&&1==Object.size(this.results.success)&&0==Object.size(this.results.error))return window.location.href=this.results.success[0].image.url_viewer,!1;if($("[data-text=queue-progress]",this.selectors.root).text(100),$("[data-group=uploading]",this.selectors.root).hide(),$(this.selectors.root).removeClass("queueUploading queueHasResults").addClass("queueCompleted"),$(this.selectors.queue).addClass(this.selectors.queue_complete.substring(1)),Object.size(this.results.success)>0&&$("[data-group=upload-result] textarea",this.selectors.root).exists()&&CHV.fn.fillEmbedCodes(this.results.success,CHV.fn.uploader.selectors.root,"val"),Object.size(this.results.success)>0&&Object.size(this.results.error)>0?$(a.mixed+", "+a.success,this.selectors.root).show():Object.size(this.results.success)>0?$(a.success,this.selectors.root).show():Object.size(this.results.error)>0&&$(a.error,this.selectors.root).show(),$(a.success,this.selectors.root).is(":visible")){$(a.success,this.selectors.root).find("[data-group^=user], [data-group=guest]").hide(),$(a.success,this.selectors.root).find("[data-group="+(PF.fn.is_user_logged()?"user":"guest")+"]").show();var n=Object.keys(this.results.success)[0];if(void 0!==this.results.success[n].image.album){var s=[];for(var r in this.results.success){var l=this.results.success[r].image;l.album&&l.album.id_encoded&&-1==s.indexOf(l.album.id_encoded)&&s.push(l.album.id_encoded)}var d={link:null,text:null};if(s.length<=1?(d.link=this.results.success[n].image.album.url,d.text=this.results.success[n].image.album.name):(d.link=this.results.success[n].image.user.url_albums,d.text=PF.fn._s("%s's Albums",this.results.success[n].image.user.name_short_html)),$("[data-text=upload-target]",this.selectors.root).text(d.text),$("[data-link=upload-target]",this.selectors.root).attr("href",d.link),PF.fn.is_user_logged()){var c=s.length>0?"album":"stream";$("[data-group=user-"+c+"]",this.selectors.root).show()}}}if(this.boxSizer(),this.queueStatus="done",window.opener&&void 0!==CHV.obj.opener.uploadPlugin[window.name]){if($('[data-action="copy"]',this.selectors.root).remove(),CHV.obj.opener.uploadPlugin[window.name].hasOwnProperty("autoInsert")&&CHV.obj.opener.uploadPlugin[window.name].autoInsert){var u=$(':input[name="'+CHV.obj.opener.uploadPlugin[window.name].autoInsert+'"]',CHV.fn.uploader.selectors.root),m=u.val();if(m)return window.opener.postMessage({id:window.name,message:m},"*"),void window.close()}}else $('[data-action="openerPostMessage"]',this.selectors.root).remove()}},$.extend(CHV.fn.uploader,$.extend(!0,{},CHV.obj.uploaderReset)),CHV.fn.fillEmbedCodes=function(e,t,a){void 0===a&&(a="val"),$.each(e,function(e,o){if(void 0!==o){var i="id_encoded"in o?o:o.image;if(!i.medium){i.medium={};for(var n=["filename","name","width","height","extension","size","size_formatted","url"],s=0;s0&&$.each(CHV.obj.categories,function(o,i){return void 0!==e&&i.id==e||(i.url_key==$("[name=form-category-url_key]",t).val()?(a=!0,!1):void 0)}),!a||(PF.fn.growl.call(PF.fn._s("Category URL key already being used.")),$("[name=form-category-url_key]",t).highlight(),!1)))},edit:{before:function(e){var t=$(e.target),a=t.data("category-id"),o=CHV.obj.categories[a],i="[data-modal="+t.data("target")+"]";$.each(CHV.fn.category.formFields,function(e,t){e="form-category-"+t,t=o[t];var a=$("[name="+e+"]",i);a.is("textarea")?a.html(PF.fn.htmlEncode(t)):a.attr("value",t)})},submit:function(){var e=PF.obj.modal.selectors.root,t=$("[name=form-category-id]",e).val();return!!CHV.fn.category.validateForm(t)&&(PF.obj.modal.form_data={action:"edit",edit:"category",editing:{}},$.each(CHV.fn.category.formFields,function(t,a){PF.obj.modal.form_data.editing[a]=$("[name=form-category-"+a+"]",e).val()}),!0)},complete:{success:function(e){var t=e.responseJSON.category,a="[data-content=category][data-category-id="+t.id+"]";$.each(t,function(e,t){$("[data-content=category-"+e+"]",a).html(PF.fn.htmlEncode(t))}),$("[data-link=category-url]").attr("href",t.url),CHV.obj.categories[t.id]=t}}},delete:{before:function(e){var t=$(e.target),a=t.data("category-id"),o=CHV.obj.categories[a];t.attr("data-confirm",t.attr("data-confirm").replace("%s",'"'+o.name+'"'))},submit:function(e){return PF.obj.modal.form_data={action:"delete",delete:"category",deleting:{id:e}},!0},complete:{success:function(e){PF.fn.growl.expirable(PF.fn._s("Category successfully deleted."));var t=e.responseJSON.request.deleting.id;$("[data-content=category][data-category-id="+t+"]").remove(),delete CHV.obj.categories[t]}}},add:{submit:function(){var e=PF.obj.modal.selectors.root;return!!CHV.fn.category.validateForm()&&(PF.obj.modal.form_data={action:"add-category",category:{}},$.each(CHV.fn.category.formFields,function(t,a){"id"!=a&&(PF.obj.modal.form_data.category[a]=$("[name=form-category-"+a+"]",e).val())}),!0)},complete:{success:function(e){var t=e.responseJSON.category,a="[data-content=dashboard-categories-list]",o=$("[data-content=category-dashboard-template]").html();$.each(t,function(e,t){o=o.replace(new RegExp("%"+e.toUpperCase()+"%","g"),t||"")}),$(a).append(o),0==Object.size(CHV.obj.categories)&&(CHV.obj.categories={}),CHV.obj.categories[t.id]=t,PF.fn.growl.call(PF.fn._s("Category %s added.",'"'+t.name+'"'))}}}},CHV.fn.ip_ban={formFields:["id","ip","expires","message"],validateForm:function(e){var t=PF.obj.modal.selectors.root,a=!1,o=$("[name=form-ip_ban-ip]",t).val();return!!CHV.fn.common.validateForm(t)&&(""!==$("[name=form-ip_ban-expires]",t).val()&&0==/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test($("[name=form-ip_ban-expires]",t).val())?(PF.fn.growl.call(PF.fn._s("Invalid expiration date.")),$("[name=form-ip_ban-expires]",t).highlight(),!1):(Object.size(CHV.obj.ip_bans)>0&&$.each(CHV.obj.ip_bans,function(t,i){return void 0!==e&&i.id==e||(i.ip==o?(a=!0,!1):void 0)}),!a||(PF.fn.growl.call(PF.fn._s("IP %s already banned.",o)),$("[name=form-ip_ban-ip]",t).highlight(),!1)))},add:{submit:function(){var e=PF.obj.modal.selectors.root;return!!CHV.fn.ip_ban.validateForm()&&(PF.obj.modal.form_data={action:"add-ip_ban",ip_ban:{}},$.each(CHV.fn.ip_ban.formFields,function(t,a){"id"!=a&&(PF.obj.modal.form_data.ip_ban[a]=$("[name=form-ip_ban-"+a+"]",e).val())}),!0)},complete:{success:function(e){var t=e.responseJSON.ip_ban,a="[data-content=dashboard-ip_bans-list]",o=$("[data-content=ip_ban-dashboard-template]").html();void 0!==o&&($.each(t,function(e,t){o=o.replace(new RegExp("%"+e.toUpperCase()+"%","g"),t||"")}),$(a).append(o)),0==Object.size(CHV.obj.ip_bans)&&(CHV.obj.ip_bans={}),CHV.obj.ip_bans[t.id]=t,$("[data-content=ban_ip]").hide(),$("[data-content=banned_ip]").show(),PF.fn.growl.call(PF.fn._s("IP %s banned.",t.ip))},error:function(e){var t=e.responseJSON.error;PF.fn.growl.call(PF.fn._s(t.message))}}},edit:{before:function(e){var t=$(e.target),a=t.data("ip_ban-id"),o=CHV.obj.ip_bans[a],i="[data-modal="+t.data("target")+"]";$.each(CHV.fn.ip_ban.formFields,function(e,t){e="form-ip_ban-"+t,t=o[t];var a=$("[name="+e+"]",i);a.is("textarea")?a.html(PF.fn.htmlEncode(t)):a.attr("value",t)})},submit:function(){var e=PF.obj.modal.selectors.root,t=$("[name=form-ip_ban-id]",e).val();return!!CHV.fn.ip_ban.validateForm(t)&&(PF.obj.modal.form_data={action:"edit",edit:"ip_ban",editing:{}},$.each(CHV.fn.ip_ban.formFields,function(t,a){PF.obj.modal.form_data.editing[a]=$("[name=form-ip_ban-"+a+"]",e).val()}),!0)},complete:{success:function(e){var t=e.responseJSON.ip_ban,a="[data-content=ip_ban][data-ip_ban-id="+t.id+"]";$.each(t,function(e,t){$("[data-content=ip_ban-"+e+"]",a).html(PF.fn.htmlEncode(t))}),CHV.obj.ip_bans[t.id]=t},error:function(e){var t=e.responseJSON.error;PF.fn.growl.call(PF.fn._s(t.message))}}},delete:{before:function(e){var t=$(e.target),a=t.data("ip_ban-id"),o=CHV.obj.ip_bans[a];t.attr("data-confirm",t.attr("data-confirm").replace("%s",o.ip))},submit:function(e){return PF.obj.modal.form_data={action:"delete",delete:"ip_ban",deleting:{id:e}},!0},complete:{success:function(e){PF.fn.growl.expirable(PF.fn._s("IP ban successfully deleted."));var t=e.responseJSON.request.deleting.id;$("[data-content=ip_ban][data-ip_ban-id="+t+"]").remove(),delete CHV.obj.ip_bans[t]}}}},CHV.fn.storage={formFields:["id","name","api_id","bucket","server","service","capacity","region","key","secret","url","account_id","account_name"],calling:!1,validateForm:function(){var e=PF.obj.modal.selectors.root,t=$("[name=form-storage-id]",e).val(),a=!0;if($.each($(":input",e),function(e,t){$(this).is(":hidden")?$(this).attr("required")&&$(this).removeAttr("required").attr("data-required",1):1==$(this).attr("data-required")&&$(this).attr("required","required"),$(this).is(":visible")&&""==$(this).val()&&$(this).attr("required")&&($(this).highlight(),a=!1)}),!a)return PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")),!1;var o,i=$("[name=form-storage-capacity]",e),n=i.val();return""!==n&&(0==/^[\d\.]+\s*[A-Za-z]{2}$/.test(n)||void 0===n.getBytes()?o=PF.fn._s("Invalid storage capacity value. Make sure to use a valid format."):void 0!==CHV.obj.storages[t]&&n.getBytes()0&&(t=t.formatBytes(2)),r.attr("value",t))}),$("[data-combo-value]").addClass("soft-hidden"),$(n).removeClass("soft-hidden")},submit:function(){var e=PF.obj.modal.selectors.root;$("[name=form-storage-id]",e).val();return!!CHV.fn.storage.validateForm()&&(PF.obj.modal.form_data={action:"edit",edit:"storage",editing:{}},$.each(CHV.fn.storage.formFields,function(t,a){var o;o="[name=form-storage-"+a+"]","hidden"!==$(o,e).attr("type")&&(o+=":visible"),PF.obj.modal.form_data.editing[a]=$(o,e).val()}),!0)},complete:{success:function(e){var t=e.responseJSON.storage,a="[data-content=storage][data-storage-id="+t.id+"]",o=$("[data-action=toggle-storage-https]",a);$.each(t,function(e,t){$("[data-content=storage-"+e+"]",a).html(PF.fn.htmlEncode(t))}),CHV.obj.storages[t.id]=t,CHV.fn.storage.toggleBoolDisplay(o,1==t.is_https),CHV.fn.queuePixel()},error:function(e){var t=e.responseJSON,a=t.error.message;PF.fn.growl.call(a)}}},add:{submit:function(){if(!CHV.fn.storage.validateForm())return!1;var e=PF.obj.modal.selectors.root;return PF.obj.modal.form_data={action:"add-storage",storage:{}},$.each(CHV.fn.storage.formFields,function(t,a){var o;"id"!=a&&(o="[name=form-storage-"+a+"]","hidden"!==$(o,e).attr("type")&&(o+=":visible"),PF.obj.modal.form_data.storage[a]=$(o,e).val())}),!0},complete:{success:function(e){var t=e.responseJSON.storage,a="[data-content=dashboard-storages-list]",o=$("[data-content=storage-dashboard-template]").html();$.each(t,function(e,t){var a=e.toUpperCase();if("is_https"==e||"is_active"==e)t=CHV.obj.storageTemplate.icon.replace("%TITLE%",CHV.obj.storageTemplate.messages[e]).replace("%ICON%",CHV.obj.storageTemplate.checkboxes[t]).replace("%PROP%",e.replace("is_",""));o=o.replace(new RegExp("%"+a+"%","g"),t||"")}),$(a).append(o),PF.fn.bindtipTip($("[data-storage-id="+t.id+"]")),0==CHV.obj.storages.length&&(CHV.obj.storages={}),CHV.obj.storages[t.id]=t,CHV.fn.queuePixel()},error:function(e){var t=e.responseJSON,a=t.error.message;PF.fn.growl.call(a)}}},toggleBoolDisplay:function(e,t){var a={0:e.data("unchecked-icon"),1:e.data("checked-icon")};e.removeClass(a[0]+" "+a[1]).addClass(a[t?1:0])}},CHV.fn.common={validateForm:function(e){if(void 0===e)e=PF.obj.modal.selectors.root;var t=!0;return $.each($(":input:visible",e),function(e,a){""==$(this).val()&&$(this).attr("required")&&($(this).highlight(),t=!1)}),!!t||(PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")),!1)},updateDoctitle:function(e){void 0!==CHV.obj.page_info&&(CHV.obj.page_info.pre_doctitle=e,CHV.obj.page_info.doctitle=CHV.obj.page_info.pre_doctitle+CHV.obj.page_info.pos_doctitle,document.title=CHV.obj.page_info.doctitle)}},CHV.fn.user={add:{submit:function(){var e=$(PF.obj.modal.selectors.root),t=!0;return $.each($(":input",e),function(e,a){""==$(this).val()&&$(this).attr("required")&&($(this).highlight(),t=!1)}),t?(PF.obj.modal.form_data={action:"add-user",user:{username:$("[name=form-username]",e).val(),email:$("[name=form-email]",e).val(),password:$("[name=form-password]",e).val(),role:$("[name=form-role]",e).val()}},!0):(PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")),!1)},complete:{success:function(e){e.responseJSON;PF.fn.growl.expirable(PF.fn._s("User added successfully."))},error:function(e){var t=e.responseJSON;PF.fn.growl.call(PF.fn._s(t.error.message))}}},delete:{submit:function(){return PF.obj.modal.form_data={action:"delete",delete:"user",owner:CHV.obj.resource.user.id,deleting:CHV.obj.resource.user},!0}}},CHV.fn.submit_resource_delete=function(){return PF.obj.modal.form_data={action:"delete",delete:CHV.obj.resource.type,from:"resource",owner:void 0!==CHV.obj.resource.user?CHV.obj.resource.user.id:null,deleting:CHV.obj.resource},!0},CHV.fn.complete_resource_delete={success:function(e){e.responseJSON;$("body").fadeOut("normal",function(){var e;e="album"==CHV.obj.resource.type||"image"==CHV.obj.resource.type?CHV.obj.resource.parent_url:CHV.obj.resource.user?CHV.obj.resource.user.url:CHV.obj.resource.url,void 0!==e&&(window.location=e+"?deleted")})}},CHV.fn.list_editor={selectionCount:function(){var e=$(PF.obj.listing.selectors.content_listing);e.each(function(){var t=$("[data-content=pop-selection]","[data-content=list-selection][data-tab="+$(this).attr("id")+"]"),a=$(PF.obj.listing.selectors.list_item+".selected",this).length;if(all_count=$(PF.obj.listing.selectors.list_item,this).length,t[a>0?"removeClass":"addClass"]("disabled"),$("[data-text=selection-count]",t).text(a>0?a:""),"images"==e.data("list")&&a>0){var o=$(PF.obj.listing.selectors.list_item+".selected[data-flag=safe]",this).length>0,i=$(PF.obj.listing.selectors.list_item+".selected[data-flag=unsafe]",this).length>0;$("[data-action=flag-safe]",t)[(i?"remove":"add")+"Class"]("hidden"),$("[data-action=flag-unsafe]",t)[(o?"remove":"add")+"Class"]("hidden")}$(this).is(":visible")&&CHV.fn.list_editor.listMassActionSet(all_count==a?"clear":"select")})},removeFromList:function(e,t){if(void 0!==e){e=e instanceof jQuery==0?$(e):e;var a=$(PF.obj.listing.selectors.content_listing_visible),o=e.length;e.fadeOut("fast");var i=e.first().data("type"),n=parseInt($("[data-text="+i+"-count]").text())-o;CHV.fn.list_editor.updateUserCounters(e.first().data("type"),o,"-"),e.promise().done(function(){$(document).removeClass(CHV.fn.listingViewer.selectors.bodyShown.substr(1));var i={};if(e.each(function(){$("[data-id="+$(this).data("id")+"]").each(function(){var e=$(this).closest(PF.obj.listing.selectors.content_listing).attr("id");i[e]||(i[e]=0),i[e]+=1})}),1==o?$("[data-id="+$(this).data("id")+"]").remove():e.each(function(){$("[data-id="+$(this).data("id")+"]").remove()}),PF.fn.listing.columnizerQueue(),PF.fn.listing.refresh(),CHV.fn.list_editor.selectionCount(),void 0!==t&&"string"==typeof t&&PF.fn.growl.expirable(t),$(PF.obj.listing.selectors.content_listing_pagination,a).exists()||0!=$(".list-item",a).length||(n=0),0==n)a.html(PF.obj.listing.template.empty),$(PF.obj.listing.selectors.content_listing+":not("+PF.obj.listing.selectors.content_listing_visible+")").data({empty:null,load:"ajax"}),$("[data-content=list-selection][data-tab="+a.attr("id")+"]").addClass("disabled");else if(0==$(PF.obj.listing.selectors.list_item,a).length){if($(PF.obj.listing.selectors.pad_content).height(0),$("[data-action=load-more]",a).exists())return $(PF.obj.listing.selectors.content_listing_visible).data("page",0),$("[data-action=load-more]",a).click(),void(PF.obj.listing.recolumnize=!0);var s=$("[data-pagination=next]",a);if(s.exists()){var r=s.attr("href"),l=PF.fn.deparam(r);return"page"in l&&l.page>1&&(r=r.changeURLParameterValue("page",l.page-1)),void(window.location=r)}}})}},deleteFromList:function(e){if(void 0===t)var t=!0;e=e instanceof jQuery==0?$(e):e;this.removeFromList(e,t?PF.fn._s("The content has been deleted."):null)},moveFromList:function(e,t){if(void 0===t)t=!0;e=e instanceof jQuery==0?$(e):e;this.removeFromList(e,t?PF.fn._s("The content has been moved."):null)},toggleSelectItem:function(e,t){if("boolean"!=typeof t)t=!0;var a,o,i,n=$(".viewer").is(":visible")?$("[data-type=image][data-id="+e.attr("data-id")+"]"):e,s=$("[data-action=select] .btn-icon",n);t?(n.addClass("selected"),a=s.data("icon-selected"),o=s.data("icon-unselected"),i=PF.fn._s("Unselect")):(n.removeClass("selected"),a=s.data("icon-unselected"),o=s.data("icon-selected"),i=PF.fn._s("Select")),s.removeClass(o).addClass(a),$("[data-action=select] .label",n).text(i),CHV.fn.list_editor.selectionCount()},selectItem:function(e){this.toggleSelectItem(e,!0)},unselectItem:function(e){this.toggleSelectItem(e,!1)},clearSelection:function(e){var t=$(PF.obj.listing.selectors.list_item+".selected",PF.obj.listing.selectors[e?"content_listing":"content_listing_visible"]);this.unselectItem(t),this.listMassActionSet("select")},listMassActionSet:function(e){var t="select"==e?"clear":"select",a=$("[data-action=list-"+t+"-all]:visible"),o=a.data("text-"+e+"-all");a.text(o).attr("data-action","list-"+e+"-all")},updateItem:function(e,t,a,o){if(e instanceof jQuery==0)e=$(e);var i=e.data("type"),n="image"==i?t.album:t;if(console.log(e,n,i),this.addAlbumtoModals(n),$("option[value="+n.id_encoded+"]","[name=form-album-id]").html(PF.fn.htmlEncode(n.name_with_privacy_readable_html)),void 0===a)a="edit";if("edit"==a||"move"==a){if("move"==a&&"album"==CHV.obj.resource.type)return void CHV.fn.list_editor.moveFromList(e,o);e.attr("data-description",t.description),"image"==i?(void 0!==t.title&&(e.attr("data-title",t.title),e.find("[title]").attr("title",t.title),$("[data-text=image-title]",e).html(PF.fn.htmlEncode(t.title))),void 0!==t.title_truncated&&$("[data-text=image-title-truncated]",e).html(PF.fn.htmlEncode(t.title_truncated)),void 0!==t.category_id&&e.attr("data-category-id",t.category_id),e.attr({"data-album-id":n.id_encoded,"data-flag":1==t.nsfw?"unsafe":"safe"}),$("[data-content=album-link]",e).attr("href",n.url)):e.attr({"data-privacy":n.privacy,"data-password":n.password,"data-name":n.name}),e.attr("data-privacy",n.privacy),$("[data-text=album-name]",e).html(PF.fn.htmlEncode(n.name)),PF.fn.growl.expirable("edit"==a?PF.fn._s("The content has been edited."):PF.fn._s("The content has been moved."))}},addAlbumtoModals:function(e){var t=!1;$("[name=form-album-id]","[data-modal]").each(function(){e.id_encoded&&!$("option[value="+e.id_encoded+"]",this).exists()&&($(this).append('"),t=!0)}),t&&CHV.fn.list_editor.updateUserCounters("album",1,"+")},updateAlbum:function(e){$("[data-id="+e.id_encoded+"]").each(function(){""!==e.html&&($(this).after(e.html),$(this).remove())})},updateUserCounters:function(e,t,a){if(void 0===a)a="+";var o,i,n=$("[data-text="+e+"-count]"),s=$("[data-text="+e+"-label]"),r=(t=parseInt(t),parseInt(n.html()));switch(a){case"+":o=r+t;break;case"-":o=r-t;break;case"=":o=t}i=o-r;var l=$("[data-text=total-"+n.data("text")+"]"),d=$("[data-text="+l.data("text")+"-label]"),c=parseInt(l.html()),u=c+i;n.text(o),l.text(u),s.text(s.data(1==o?"label-single":"label-plural")),d.text(s.data(1==u?"label-single":"label-plural"))},updateMoveItemLists:function(e,t,a){if(CHV.fn.list_editor.clearSelection(),/image/.test(t))"image"==t?CHV.fn.list_editor.updateItem("[data-type=image][data-id="+a.data("id")+"]",e.image,"move"):(a.each(function(){CHV.fn.list_editor.updateItem("[data-type=image][data-id="+$(this).data("id")+"]",e,"move",!1)}),PF.fn.growl.expirable(PF.fn._s("The content has been moved.")));else{if("album"==CHV.obj.resource.type?CHV.fn.list_editor.moveFromList(a):PF.fn.growl.expirable(PF.fn._s("The content has been moved.")),void 0!==e.albums_old)for(var o=0;o';$("body").append(e)}; \ No newline at end of file +$(function(){function e(e){e=e.originalEvent;var t=!1;if(e.dataTransfer.types)for(var a=0;ae&&(a.height(e),a.closest(".antiscroll-wrap").antiscroll())}}function a(e){e.addClass("list-item-play-gif--loading");var t=e.closest(".list-item"),a=$(".image-container",t),o=$("img",a),i=o.attr("src"),r=".md",n=i.lastIndexOf(r);if(-1==n)r=".th",n=i.lastIndexOf(r);var s=i.substr(0,n)+i.substr(n+r.length,i.length);a.append(a.html()),$load=t.find(".image-container img").eq(1).attr("src",s).addClass("hidden"),$load.imagesLoaded(function(){e.remove(),o.remove(),$(this.elements).removeClass("hidden")})}if($(window).on("resize",function(){CHV.fn.uploader.boxSizer(),"function"==typeof user_background_full_fix&&user_background_full_fix(),CHV.fn.bindSelectableItems(),CHV.fn.listingViewer.placeholderSizing()}),window.opener&&($(window).on("load",function(e){window.opener.postMessage({id:window.name,requestAction:"postSettings"},"*")}),$(window).on("message",function(e){var t=e.originalEvent.data;void 0!==t.id&&void 0!==t.settings&&window.name===t.id&&(CHV.obj.opener.uploadPlugin[t.id]=t.settings)})),$("#home-cover, #maintenance-wrapper, #login").exists()){var o=$("#maintenance-wrapper").exists()?$("#maintenance-wrapper").css("background-image").slice(4,-1).replace(/^\"|\"$/g,""):$(".home-cover-img","#home-cover-slideshow").first().attr("data-src");function i(){$("body").addClass("load"),$("#maintenance-wrapper").exists()||$(".home-cover-img","#home-cover-slideshow").first().css("background-image","url("+o+")").addClass("animate-in--alt").removeAttr("data-src"),setTimeout(function(){setTimeout(function(){$("body").addClass("loaded")},1200),setTimeout(function(){n()},7e3)},600)}var r=function(){setTimeout(function(){n()},8e3)};function n(){var e=$(".home-cover-img[data-src]","#home-cover-slideshow").first(),t=$(".home-cover-img","#home-cover-slideshow");if(0==e.length){if(1==t.length)return;t.first().removeClass("animate-in"),$("#home-cover-slideshow").append(t.first()),setTimeout(function(){$(".home-cover-img:last","#home-cover-slideshow").addClass("animate-in")},20),setTimeout(function(){$(".home-cover-img:not(:last)","#home-cover-slideshow").removeClass("animate-in")},4e3),r()}else{var a=e.attr("data-src");$("").attr("src",a).on("load error",function(){$(this).remove(),e.css("background-image","url("+a+")").addClass("animate-in").removeAttr("data-src"),setTimeout(function(){$(".home-cover-img:not(:last)","#home-cover-slideshow").removeClass("animate-end animate-in--alt")},2e3),r()})}}o?$("").attr("src",o).on("load error",function(){$(this).remove(),i()}):i()}var s=CHV.fn.uploader.selectors.root,l=CHV.fn.uploader.selectors.queue,d=$(s),c=$(l);$(document).on("click","[data-action=top-bar-upload]",function(e){$("body").is("#upload")||1==$(this).data("link")||CHV.fn.uploader.toggle()});var u={tones:{light:{html:"tone-light top-bar-white",top:"white"},dark:{html:"tone-dark top-bar-black",top:"black"}},isDark:function(){return $("html").hasClass("tone-dark")},toggle:function(){var e=this.isDark()?"light":"dark";$("html").removeClass(this.tones.light.html+" "+this.tones.dark.html).addClass(this.tones[e].html),$("body#index").exists()||$("#top-bar").removeClass(this.tones.light.top+" "+this.tones.dark.top).addClass(this.tones[e].top)},save:function(){$.ajax({type:"POST",data:{action:"toggleTone"},cache:!1}),u.aux=u.isDark()},timeout:{},aux:{}};if(u.aux=u.isDark(),$(document).on("click","[data-action=top-bar-tone]",function(e){e.isPropagationStopped()||($("[data-action=top-bar-menu-full]").is(":visible")&&PF.fn.topMenu.hide(),clearTimeout(u.timeout),u.toggle(),u.timeout=setTimeout(function(){u.aux!==u.isDark()&&u.save()},750))}),$("[data-action=close-upload]",d).click(function(){d.is(":animated")||$("[data-action=top-bar-upload]","#top-bar").click()}),$("[data-action=reset-upload]",d).click(function(){CHV.fn.uploader.isUploading&&$("[data-action=cancel-upload-remaining], [data-action=cancel-upload]",d).trigger("click"),CHV.fn.uploader.reset()}),$("[data-action=cancel-upload-remaining], [data-action=cancel-upload]",d).click(function(){CHV.fn.uploader.isUploading=!1,$("[data-action=cancel]",c).click(),Object.size(CHV.fn.uploader.results.success)>0?CHV.fn.uploader.displayResults():CHV.fn.uploader.reset()}),$(document).on("click","[data-action=upload-privacy]:not(disabled)",function(e){e.isDefaultPrevented()||(current_privacy=$(this).data("privacy"),target_privacy="public"==current_privacy?"private":"public",this_lock=$(".icon",this).data("lock"),this_unlock=$(".icon",this).data("unlock"),$(".icon",this).removeClass(this_lock+" "+this_unlock).addClass("public"==current_privacy?this_lock:this_unlock),$(this).data("privacy",target_privacy),$("[data-action=upload-privacy-copy]").html($("[data-action=upload-privacy]").html()),$upload_button=$("[data-action=upload]",d),$upload_button.text($upload_button.data(target_privacy)),$(this).tipTip("hide"))}),$(CHV.fn.uploader.selectors.file+", "+CHV.fn.uploader.selectors.camera).on("change",function(e){$(CHV.fn.uploader.selectors.root).data("shown")?CHV.fn.uploader.add(e):CHV.fn.uploader.toggle({callback:function(e){CHV.fn.uploader.add(e)}},e)}).on("click",function(e){!$(this).data("login-needed")||PF.fn.is_user_logged()}),$(CHV.fn.uploader.selectors.root).exists()&&($("body").on({dragenter:function(t){if(t.preventDefault(),!e(t))return!1;$(CHV.fn.uploader.selectors.dropzone).exists()||$("body").append($('
    ').css({width:"100%",height:"100%",position:"fixed",zIndex:1e3,left:0,top:0}))}}),$(document).on({dragover:function(t){if(t.preventDefault(),!e(t))return!1;$(CHV.fn.uploader.selectors.root).data("shown")||CHV.fn.uploader.toggle({reset:!1})},dragleave:function(e){$(CHV.fn.uploader.selectors.dropzone).remove(),$.isEmptyObject(CHV.fn.uploader.files)&&CHV.fn.uploader.toggle()},drop:function(e){e.preventDefault(),CHV.fn.uploader.add(e),$(CHV.fn.uploader.selectors.dropzone).remove()}},CHV.fn.uploader.selectors.dropzone)),$(document).on("keyup change","[data-action=resize-combo-input]",function(e){var t=$(this).closest("[data-action=resize-combo-input]"),a=$("[name=form-width]",t),o=$("[name=form-height]",t),i=a.data("initial")/o.data("initial"),r={width:Math.round(a.prop("value")/i),height:Math.round(o.prop("value")*i)};$(e.target).is(a)?o.prop("value",Math.round(r.width)):a.prop("value",Math.round(r.height))}),$(document).on("click",l+" [data-action=edit]",function(){for(var e=$(this).closest("li"),t=(e.closest("ul"),e.data("id")),a=CHV.fn.uploader.files[t],o=PF.obj.modal.selectors.root,i=$.extend({},a.formValues||a.parsedMeta),r=["album_id","category_id","nsfw"],n=0;ne.height&&(r.height=e.height,r.width=Math.round(r.height*n)),r.width>e.width&&(r.width=e.width,r.height=Math.round(r.width/n)),$.each(i,function(e,t){var i="[name=form-"+e.replace(/_/g,"-")+"]",n=$(i,o);if(!n.exists())return!0;if(n.is(":checkbox"))n.prop("checked",n.attr("value")==t);else if(n.is("select")){var s=n.find("[value="+t+"]");s.exists()||(s=n.find("option:first")),s.prop("selected",!0)}else n.prop("value",t);if("width"==e||"height"==e){var l=r[e],d=a.parsedMeta[e]>l?l:a.parsedMeta[e];n.prop("max",d).data("initial",a.parsedMeta[e]).prop("value",d)}}),"image/gif"!==a.parsedMeta.mimetype&&$("[ data-content=animated-gif-warning]",o).remove(),$(".image-preview",o).append($("",{class:"canvas"}));var s=$(".queue-item[data-id="+t+"] .preview .canvas")[0],l=$(".image-preview .canvas",o)[0];l.width=s.width,l.height=s.height;var d=l.getContext("2d");d.drawImage(s,0,0)},confirm:function(){if(PF.fn.form_modal_has_changed()){var e=!1;return $.each(["width","height"],function(t,a){var i=$("[name=form-"+a+"]",o),r=parseInt(i.val()),n=parseInt(i.attr("min")),s=parseInt(i.attr("max"));if(r>s||r-1&&CHV.fn.uploader.clipboardImages.splice(n,1)}delete CHV.fn.uploader.files[a],CHV.fn.uploader.queueSize(),0==Object.size(CHV.fn.uploader.files)?"success"in CHV.fn.uploader&&"results"in CHV.fn.uploader&&(0!=Object.size(CHV.fn.uploader.results.success)||0!=Object.size(CHV.fn.uploader.results.error))||CHV.fn.uploader.reset():i&&0!==$("li.waiting",t).first().length&&CHV.fn.uploader.upload($("li.waiting",t).first())}}),$(document).on("click","[data-action=upload]",function(){$("[data-group=upload], [data-group=upload-queue-ready]",d).hide(),d.removeClass("queueReady").addClass("queueUploading").find("[data-group=uploading]").show(),CHV.fn.uploader.queueSize(),CHV.fn.uploader.canAdd=!1,$queue_items=$("li",c),$queue_items.addClass("uploading waiting"),CHV.fn.uploader.timestamp=(new Date).getTime(),CHV.fn.uploader.upload($queue_items.first("li"))}),$("body#user").exists()&&PF.obj.listing.query_string.page>1){var m=History.getState();if(m.data&&void 0!==m.data.scrollTop)$(window).scrollTop()!==m.data.scrollTop&&$(window).scrollTop(m.data.scrollTop);else{var f=$("#background-cover").height()-160;$("html, body").animate({scrollTop:f},0)}}$("#top-bar-shade").exists()&&$("#top-bar-shade").css("opacity")&&$("#top-bar-shade").data("initial-opacity",Number($("#top-bar-shade").css("opacity"))),PF.fn.isDevice("phone"),$(window).on("scroll resize",function(){var e=$(window).scrollTop();if(!(e<0)){var t=$("#top-bar"),a=Number(e/($("#background-cover, [data-content=follow-scroll-opacity]").height()-t.height()));a>1&&(a=1),$("#top-bar-shade").data("initial-opacity")&&(a+=$("#top-bar-shade").data("initial-opacity")),$("#top-bar-shade").css({opacity:a}),$("#background-cover-src").css({transform:"translate(0, "+.8*e+"px)"})}}),CHV.fn.bindSelectableItems(),$("body#image").exists()&&($(CHV.obj.image_viewer.selector+" [data-load=full]").length>0?($(document).on("click",CHV.obj.image_viewer.loader,function(e){CHV.fn.viewerLoadImage()}),$(CHV.obj.image_viewer.loader).data("size")>CHV.obj.config.image.load_max_filesize.getBytes()?$(CHV.obj.image_viewer.loader).css("display","block"):CHV.fn.viewerLoadImage(),$(document).bind("DOMSubtreeModified",function(){$("html").height()>$(window).innerHeight()&&!$("html").hasClass("scrollbar-y")&&($("html").addClass("scrollbar-y"),$(document).data({width:$(this).width(),height:$(this).height()}),CHV.fn.image_viewer_full_fix())}),$(window).on("resize",function(){CHV.fn.image_viewer_full_fix()}),$(document).on("keyup",function(e){var t=$(e.target),a=e.charCode||e.keyCode;if(!t.is(":input")&&CHV.obj.image_viewer.$navigation.exists()&&(37==a||39==a)){var o=$("[data-action="+(37==a?"prev":"next")+"]",CHV.obj.image_viewer.$navigation).attr("href");void 0!==o&&""!==o&&(window.location=$("[data-action="+(37==a?"prev":"next")+"]",CHV.obj.image_viewer.$navigation).attr("href"))}})):CHV.fn.viewerImageZoomClass()),$(document).on("click",CHV.obj.image_viewer.container,function(e){if($(this).hasClass("cursor-zoom-in")||$(this).hasClass("cursor-zoom-out")){var t=$(this).hasClass("cursor-zoom-in");if($(this).removeClass("cursor-zoom-in cursor-zoom-out"),t){var a,o=$(this)[0].getBoundingClientRect().width,i=$(this)[0].getBoundingClientRect().height,r=$("img",this).attr("width")/$("img",this).attr("height");void 0===$(this).data("dimentions")&&$(this).data({dimentions:{width:o,height:i},ratio:r}),$("img",this).attr("width")>$(window).width()?($(this).css({width:"100%"}),a=$(this).width(),$(this).css({width:o})):a=$("img",this).attr("width"),$(this).addClass("cursor-zoom-out").css({width:a,height:a/r+"px"})}else $(this).addClass("cursor-zoom-in").css($(this).data("dimentions"));e.preventDefault()}}).on("contextmenu",CHV.obj.image_viewer.container,function(e){if(!CHV.obj.config.image.right_click)return e.preventDefault(),!1}),$(document).on("contextmenu","html.device-mobile a.image-container",function(e){return e.preventDefault(),!1}),$(document).on("keyup","input[data-dashboard-tool]",function(e){if(13==e.keyCode){var t=$("[data-action="+$(this).data("dashboard-tool")+"]");t.click()}}),$(document).on("click","[data-action=dashboardTool]",function(e){e.preventDefault();var t=$(this).data("tool"),a=$(this).data("data"),o=$.extend({},a),i={};for(var r in o){var n=$(o[r]).val();if($(o[r]).prop("disabled")||!n)return;i[r]=$(o[r]),o[r]=n}o.action=t;var s={type:"GET",cache:!1};s.data=o;var l,d=$(this).closest(".input-label"),c=!0;if(0!=c){for(var r in i);PF.fn.loading.inline($(".loading",d),{size:"small",valign:"middle"}),d.find(".btn .text").hide(),$.ajax(s).complete(function(e){var t=e.responseJSON;$(".loading",d).empty(),d.find(".btn .text").show(),200!=t.status_code||void 0===t.success.redirURL?PF.fn.growl.call(t[200==t.status_code?"success":"error"].message):window.location.href=t.success.redirURL})}else PF.fn.growl.expirable(l)}),$(document).on("click","[data-action=openerPostMessage]",function(e){if(window.opener){e.preventDefault();var t="data-action-target",a=$($(this).is("["+t+"]")?$(this).attr(t):this),o=a[a.is(":input")?"val":"html"]();window.opener.postMessage({id:window.name,message:o},"*")}}),$(document).on("click","[data-action=list-tools] [data-action]",function(e){var t=$(e.target),a=t.closest("[data-id]");a&&a.find("[data-action=select]").exists()&&(e.ctrlKey||e.metaKey)&&e.altKey&&(CHV.fn.list_editor.toggleSelectItem(a,!a.hasClass("selected")),e.preventDefault(),e.stopPropagation())}),PF.fn.listing.ajax.callback=function(e){200===e.status&&CHV.fn.list_editor.listMassActionSet("select")},$(document).on("click","[data-action=list-select-all]",function(){CHV.fn.list_editor.selectItem($(".list-item:visible:not(.selected)")),CHV.fn.list_editor.listMassActionSet("clear")}),$(document).on("click","[data-action=list-clear-all]",function(){PF.fn.close_pops(),CHV.fn.list_editor.clearSelection()}),$(document).on("click","[data-action=list-tools] [data-action]",function(e){if(e.isPropagationStopped())return!1;var t=$(this).closest(PF.obj.listing.selectors.list_item+", .viewer"),a=t.data("id");if(void 0!==t.data("type")){o=t.data("type");var o,i=$("[data-type="+o+"][data-id="+a+"]");switch($(this).data("action")){case"select":CHV.fn.list_editor.toggleSelectItem(t,!t.hasClass("selected"));break;case"edit":var r="[data-modal=form-edit-single]";switch(o){case"image":$("[name=form-image-title]",r).attr("value",t.attr("data-title")),$("[name=form-image-description]",r).html(PF.fn.htmlEncode(t.data("description"))),$("[name=form-album-id]",r).find("option").removeAttr("selected"),$("[name=form-album-id]",r).find("[value="+t.data("image"==o?"album-id":"id")+"]").attr("selected",!0),$("[name=form-category-id]",r).find("option").removeAttr("selected"),$("[name=form-category-id]",r).find("[value="+t.data("category-id")+"]").attr("selected",!0),$("[name=form-nsfw]",r).attr("checked","unsafe"==t.data("flag")),$("[name=form-album-name]",r).attr("value",""),$("[name=form-album-description]",r).html(""),$("[name=form-privacy]",r).find("option").removeAttr("selected");break;case"album":$("[data-action=album-switch]",r).remove(),$("[name=form-album-name]",r).attr("value",t.data("name")),$("[name=form-album-description]",r).html(PF.fn.htmlEncode(t.data("description"))),$("[name=form-privacy]",r).find("option").removeAttr("selected"),$("[name=form-privacy]",r).find("[value="+t.data("privacy")+"]").attr("selected",!0),"password"==t.data("privacy")?($("[data-combo-value=password]").show(),$("[name=form-album-password]",r).attr("value",t.data("password"))):($("[data-combo-value=password]").hide(),$("[name=form-album-password]",r).attr("value",""))}PF.fn.modal.call({type:"html",template:$(r).html(),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){CHV.fn.list_editor.updateItem("[data-type="+o+"][data-id="+a+"]",e.responseJSON[o],"edit")}}},confirm:function(){var e=$(PF.obj.modal.selectors.root);if(("image"==o||"album"==o)&&$("[data-content=form-new-album]",e).is(":visible")&&""==$("[name=form-album-name]",e).val())return PF.fn.growl.call(PF.fn._s("You must enter the album name.")),$("[name=form-album-name]",e).highlight(),!1;if(PF.fn.form_modal_has_changed()){switch(PF.obj.modal.form_data={action:"edit",edit:t.data("type"),single:!0,owner:CHV.obj.resource.user.id,editing:{id:a,description:$("[name=form-"+o+"-description]",e).val()}},o){case"image":PF.obj.modal.form_data.editing.title=$("[name=form-image-title]",e).val(),PF.obj.modal.form_data.editing.category_id=$("[name=form-category-id]",e).val()||null,PF.obj.modal.form_data.editing.nsfw=$("[name=form-nsfw]",e).prop("checked")?1:0;break;case"album":PF.obj.modal.form_data.editing.name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.editing.privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.editing.privacy&&(PF.obj.modal.form_data.editing.password=$("[name=form-album-password]",e).val())}return PF.obj.modal.form_data.editing.new_album=$("[data-content=form-new-album]",e).is(":visible"),PF.obj.modal.form_data.editing.new_album?(PF.obj.modal.form_data.editing.album_name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.editing.album_privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.editing.album_privacy&&(PF.obj.modal.form_data.editing.album_password=$("[name=form-album-password]",e).val()),PF.obj.modal.form_data.editing.album_description=$("[name=form-album-description]",e).val()):PF.obj.modal.form_data.editing.album_id=$("[name=form-album-id]",e).val(),!0}PF.fn.modal.close()}});break;case"move":r="[data-modal=form-move-single]";$("[name=form-album-id]",r).find("option").removeAttr("selected"),$("[name=form-album-id]",r).find("[value="+t.data("image"==o?"album-id":"id")+"]").attr("selected",!0),$("[name=form-album-name]",r).attr("value",""),$("[name=form-album-description]",r).html(""),$("[name=form-privacy]",r).find("option").removeAttr("selected"),PF.fn.modal.call({type:"html",template:$(r).html(),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){CHV.fn.list_editor.updateMoveItemLists(e.responseJSON,o,i)}}},load:function(){},confirm:function(){var e=$(PF.obj.modal.selectors.root);return $("[data-content=form-new-album]",e).is(":visible")&&""==$("[name=form-album-name]",e).val()?(PF.fn.growl.call(PF.fn._s("You must enter the album name.")),$("[name=form-album-name]",e).highlight(),!1):PF.fn.form_modal_has_changed()?(PF.obj.modal.form_data={action:"edit",edit:t.data("type"),single:!0,owner:CHV.obj.resource.user.id,editing:{id:a}},PF.obj.modal.form_data.editing.new_album=$("[data-content=form-new-album]",e).is(":visible"),PF.obj.modal.form_data.editing.new_album?(PF.obj.modal.form_data.editing.album_name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.editing.album_privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.editing.album_privacy&&(PF.obj.modal.form_data.editing.album_password=$("[name=form-album-password]",e).val()),PF.obj.modal.form_data.editing.album_description=$("[name=form-album-description]",e).val()):PF.obj.modal.form_data.editing.album_id=$("[name=form-album-id]",e).val(),!0):void PF.fn.modal.close()}});break;case"delete":PF.fn.modal.call({type:"html",template:$("[data-modal=form-delete-single]").html(),button_submit:PF.fn._s("Confirm"),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){"album"==o&&($("[name=form-album-id]","[data-modal]").find("[value="+a+"]").remove(),CHV.fn.list_editor.updateUserCounters("image",e.responseJSON.success.affected,"-")),CHV.fn.list_editor.deleteFromList(t),CHV.fn.queuePixel()}}},confirm:function(){return PF.obj.modal.form_data={action:"delete",single:!0,delete:t.data("type"),deleting:{id:a}},!0}});break;case"flag":$.ajax({type:"POST",data:{action:"edit",edit:"image",single:!0,editing:{id:a,nsfw:"unsafe"==t.data("flag")?0:1}}}).complete(function(e){var t=e.responseJSON,a=1==t.image.nsfw?"unsafe":"safe";i.attr("data-flag",a).data("flag",a),CHV.fn.list_editor.selectionCount()})}}else console.log("Error: data-type not defined")}),$(".pop-box-menu a","[data-content=list-selection]").click(function(e){var t=$(PF.obj.listing.selectors.content_listing_visible);if(void 0!==t.data("list")){dealing_with=t.data("list");var a=$(PF.obj.listing.selectors.list_item+".selected",t),o=$.map(a,function(e,t){return $(e).data("id")});switch($(this).closest(".pop-btn").click(),$(this).data("action")){case"get-embed-codes":var i="[data-modal=form-embed-codes]",r=[];$("textarea",i).html(""),a.each(function(){var e={image:$.parseJSON(decodeURIComponent($(this).data("object")))};"url"in e.image&&r.push(e)}),CHV.fn.fillEmbedCodes(r,i,"html"),PF.fn.modal.call({type:"html",template:$(i).html(),buttons:!1});break;case"clear":CHV.fn.list_editor.clearSelection(),e.stopPropagation();break;case"move":case"create-album":i="move"==$(this).data("action")?"form-move-multiple":"form-create-album";var n="[data-modal="+i+"]",s=/image/.test(dealing_with)?"album-id":"id";$("[name=form-album-id]",n).find("[value=null]").remove(),$("[name=form-album-id]",n).find("option").removeAttr("selected"),$("[name=form-album-name]",n).attr("value",""),$("[name=form-album-description]",n).html(""),$("[name=form-privacy]",n).find("option").removeAttr("selected");var l=a.first().data(s),d=!0;a.each(function(){if($(this).data(s)!==l)return d=!1,!1}),d||$("[name=form-album-id]",n).prepend('"),$("[name=form-album-id]",n).find("[value="+(d?a.first().data(s):"null")+"]").attr("selected",!0),PF.fn.modal.call({type:"html",template:$(n).html(),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){CHV.fn.list_editor.updateMoveItemLists(e.responseJSON,dealing_with,a)}}},load:function(){},confirm:function(){var e=$(PF.obj.modal.selectors.root),t=!1;if($("[data-content=form-new-album]",e).is(":visible")&&""==$("[name=form-album-name]",e).val())return PF.fn.growl.call(PF.fn._s("You must enter the album name.")),$("[name=form-album-name]",e).highlight(),!1;if($("[data-content=form-new-album]",e).is(":visible")&&(t=!0),PF.fn.form_modal_has_changed()){return PF.obj.modal.form_data={action:t?"create-album":"move",type:dealing_with,owner:CHV.obj.resource.user.id,multiple:!0,album:{ids:o,new:t}},t?(PF.obj.modal.form_data.album.name=$("[name=form-album-name]",e).val(),PF.obj.modal.form_data.album.privacy=$("[name=form-privacy]",e).val(),"password"==PF.obj.modal.form_data.album.privacy&&(PF.obj.modal.form_data.album.password=$("[name=form-album-password]",e).val()),PF.obj.modal.form_data.album.description=$("[name=form-album-description]",e).val()):PF.obj.modal.form_data.album.id=$("[name=form-album-id]",e).val(),!0}PF.fn.modal.close()}});break;case"delete":PF.fn.modal.call({template:$("[data-modal=form-delete-multiple]").html(),button_submit:PF.fn._s("Confirm"),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){"albums"==dealing_with&&(a.each(function(){$("[name=form-album-id]","[data-modal]").find("[value="+$(this).data("id")+"]").remove()}),CHV.fn.list_editor.updateUserCounters("image",e.responseJSON.success.affected,"-")),CHV.fn.list_editor.deleteFromList(a),CHV.fn.queuePixel()}}},confirm:function(){return PF.obj.modal.form_data={action:"delete",from:"list",delete:dealing_with,multiple:!0,deleting:{ids:o}},!0}});break;case"assign-category":var c=a.first().data("category-id"),u=!0;a.each(function(){if($(this).data("category-id")!==c)return u=!1,!1}),PF.fn.modal.call({type:"html",template:$("[data-modal=form-assign-category]").html(),forced:!0,ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){a.each(function(){var t=e.responseJSON;$(this).data("category-id",t.category_id)}),CHV.fn.list_editor.clearSelection()}}},confirm:function(){var e=$(PF.obj.modal.selectors.root),t=$("[name=form-category-id]",e).val()||null;return u&&c==t?(PF.fn.modal.close(function(){CHV.fn.list_editor.clearSelection()}),!1):(PF.obj.modal.form_data={action:"edit-category",from:"list",multiple:!0,editing:{ids:o,category_id:t}},!0)}});break;case"flag-safe":case"flag-unsafe":var m=$(this).data("action"),f="flag-safe"==m?"safe":"unsafe";PF.fn.modal.call({template:$("[data-modal=form-"+m+"]").html(),button_submit:PF.fn._s("Confirm"),ajax:{url:PF.obj.config.json_api,deferred:{success:function(e){a.each(function(){$(this).removeClass("safe unsafe").addClass(f).removeAttr("data-flag").attr("data-flag",f).data("flag",f)}),CHV.fn.list_editor.clearSelection()}}},confirm:function(){return PF.obj.modal.form_data={action:m,from:"list",multiple:!0,editing:{ids:o,nsfw:"flag-safe"==m?0:1}},!0}})}return!PF.fn.isDevice(["phone","phablet"])&&void 0}console.log("Error: data-list not defined")}),$("body#image").exists()&&$(window).scroll(function(){CHV.obj.topBar.transparencyScrollToggle()}),$(document).on("click","[data-action=disconnect]",function(){var e=$(this),t=e.data("connection");PF.fn.modal.confirm({message:e.data("confirm-message"),ajax:{data:{action:"disconnect",disconnect:t,user_id:CHV.obj.resource.user.id},deferred:{success:function(e){var a=e.responseJSON;$("[data-connection="+t+"]").fadeOut(function(){$($("[data-connect="+t+"]")).fadeIn(),$(this).remove(),0==$("[data-connection]").length&&$("[data-content=empty-message]").show(),PF.fn.growl.expirable(a.success.message)})},error:function(e){var t=e.responseJSON;PF.fn.growl.call(t.error.message)}}}})}),$(document).on("click","[data-action=delete-avatar]",function(){var e=$(".user-settings-avatar"),t=$(".loading-placeholder",e),a=$("#top-bar");t.removeClass("hidden"),PF.fn.loading.inline(t,{center:!0}),$.ajax({type:"POST",data:{action:"delete",delete:"avatar",owner:CHV.obj.resource.user.id}}).complete(function(o){t.addClass("hidden").empty(),200==o.status?(CHV.obj.logged_user.id==CHV.obj.resource.user.id&&($("img.user-image",a).hide(),$(".default-user-image",a).removeClass("hidden")),$(".default-user-image",e).removeClass("hidden").css({opacity:0}),$(".btn-alt",e).closest("div").hide(),$("img.user-image",e).fadeOut(function(){$(".default-user-image",e).animate({opacity:1})})):PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."))})}),$(document).on("change","[data-content=user-avatar-upload-input]",function(e){e.preventDefault(),e.stopPropagation();var t=$(this),a=$(".user-settings-avatar"),o=$(".loading-placeholder",".user-settings-avatar"),i=$("#top-bar"),r=$(this)[0].files[0];if(!t.data("uploading"))if(0!=/^image\/.*$/.test(r.type))if(r.size>CHV.obj.config.user.avatar_max_filesize.getBytes())PF.fn.growl.call(PF.fn._s("Please select a picture of at most %s size.",CHV.obj.config.user.avatar_max_filesize));else{o.removeClass("hidden"),PF.fn.loading.inline(o,{center:!0}),t.data("uploading",!0);var n=new FormData;n.append("source",r),n.append("action","upload"),n.append("type","file"),n.append("what","avatar"),n.append("owner",CHV.obj.resource.user.id),n.append("auth_token",PF.obj.config.auth_token),avatarXHR=new XMLHttpRequest,avatarXHR.open("POST",PF.obj.config.json_api,!0),avatarXHR.send(n),avatarXHR.onreadystatechange=function(){if(4==this.readyState){var e="json"!==this.responseType?JSON.parse(this.response):this.response,r=e.success.image;o.addClass("hidden").empty(),200==this.status?(change_avatar=function(e){$("img.user-image",e).attr("src",r.url).removeClass("hidden").show()},hide_default=function(e){$(".default-user-image",e).addClass("hidden")},hide_default(a),$(".btn-alt",a).closest("div").show(),change_avatar(a),CHV.obj.logged_user.id==CHV.obj.resource.user.id&&(change_avatar(i),hide_default(i)),PF.fn.growl.expirable(PF.fn._s("Profile image updated."))):PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")),t.data("uploading",!1)}}}else PF.fn.growl.call(PF.fn._s("Please select a valid image file type."))}),$(document).on("change","[data-content=user-background-upload-input]",function(e){e.preventDefault(),e.stopPropagation();var t=$(this),a=$("[data-content=user-background-cover]"),o=$("[data-content=user-background-cover-src]"),i=$(".loading-placeholder",a),r=($("#top-bar"),$(this)[0].files[0]);if(!t.data("uploading"))if(0!=/^image\/.*$/.test(r.type))if(r.size>CHV.obj.config.user.background_max_filesize.getBytes())PF.fn.growl.call(PF.fn._s("Please select a picture of at most %s size.",CHV.obj.config.user.background_max_filesize));else{i.removeClass("hidden"),PF.fn.loading.inline(i,{center:!0,size:"big",color:"#FFF"}),t.data("uploading",!0);var n=new FormData;n.append("source",r),n.append("action","upload"),n.append("type","file"),n.append("what","background"),n.append("owner",CHV.obj.resource.user.id),n.append("auth_token",PF.obj.config.auth_token),avatarXHR=new XMLHttpRequest,avatarXHR.open("POST",PF.obj.config.json_api,!0),avatarXHR.send(n),avatarXHR.onreadystatechange=function(){if(4==this.readyState){var e="json"!==this.responseType?JSON.parse(this.response):this.response,r=e.success.image;if(200==this.status){var n=$("");n.attr("src",r.url).imagesLoaded(function(){i.addClass("hidden").empty(),o.css("background-image","url("+r.url+")").hide().fadeIn(),$("[data-content=user-change-background]",a).removeClass("hidden"),a.removeClass("no-background"),$("[data-content=user-upload-background]").hide(),$("[data-content=user-change-background]").show(),PF.fn.growl.expirable(PF.fn._s("Profile background image updated.")),n.remove(),"function"==typeof user_background_full_fix&&user_background_full_fix()})}else i.addClass("hidden").empty(),PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."));t.data("uploading",!1)}}}else PF.fn.growl.call(PF.fn._s("Please select a valid image file type."))}),CHV.fn.user_background={delete:{submit:function(){return PF.obj.modal.form_data={action:"delete",delete:"background",owner:CHV.obj.resource.user.id},!0},deferred:{success:{before:function(e){$("[data-content=user-background-cover-src]").css("background-image","none"),$("[data-content=user-background-cover]").addClass("no-background").height(""),$("[data-content=user-upload-background]").removeClass("hidden").show(),$("[data-content=user-change-background]").hide(),$("#top-bar-shade").remove()}, +done:function(e){PF.fn.modal.close(function(){PF.fn.growl.expirable(PF.fn._s("Profile background image deleted."))})}},error:function(e){PF.fn.growl.expirable(PF.fn._s("Error deleting profile background image."))}}}},CHV.str.mainform="[data-content=main-form]",CHV.obj.timezone={selector:"[data-content=timezone]",input:"#timezone-region"},$(document).on("keyup change",CHV.str.mainform+" :input",function(){$(this).is("[name=username]")&&$("[data-text=username]").text($(this).val())}),$(document).on("change",CHV.obj.timezone.input,function(){var e=$(this).val(),t=$("#timezone-combo-"+e);t.find("option:first").prop("selected",!0),$(CHV.obj.timezone.selector).val(t.val()).change()}),$(document).on("change","[id^=timezone-combo-]",function(){var e=$(this).val();$(CHV.obj.timezone.selector).val(e).change()}),$(document).on("keyup change blur","[name^=new-password]",function(){var e=$("[name=new-password]"),t=$("[name=new-password-confirm]"),a=e.val()==t.val(),o=t.closest(".input-password").find(".input-warning");0==o.exists()&&(o=$("[data-message=new-password-confirm]")),$(this).is(t)&&t.data("touched",!0),t.data("touched")&&o.text(a?"":o.data("text"))[a?"addClass":"removeClass"]("hidden-visibility")}),$(document).on("submit",CHV.obj.mainform,function(){switch($(this).data("type")){case"password":var e=$("[name=new-password]",this),t=$("[name=new-password-confirm]",this);if((""!==e.val()||""!==t.val())&&e.val()!==t.val())return e.highlight(),t.highlight(),PF.fn.growl.expirable(PF.fn._s("Passwords don't match")),!1}}),$(document).on("click","[data-action=check-for-updates]",function(){PF.fn.loading.fullscreen(),CHV.fn.system.checkUpdates(function(e){if(PF.fn.loading.destroy("fullscreen"),200===e.status){var t=e.responseJSON.software;-1==PF.fn.versionCompare(CHV.obj.system_info.version,t.current_version)?PF.fn.modal.simple({title:PF.fn._s("Update available v%s",t.current_version),message:"

    "+PF.fn._s("There is an update available for your system. You can automatic download and install this update or go to %s to proceed to download the file.",''+CHEVERETO.source.label+"")+"

    "+PF.fn._s("The release notes for this update are:")+'

    ",html:!0}):PF.fn.growl.call(PF.fn._s("This website is running latest %s version",CHEVERETO.edition))}else PF.fn.growl.call(PF.fn._s("An error occurred. Please try again later."))})}),void 0!==PF.fn.get_url_var("checkUpdates")&&$("[data-action=check-for-updates]").click(),$("body#image").exists()&&window.scrollY>0&&$("#top-bar").removeClass("transparent"),$(document).on("click","[data-action=toggle-storage-https]",function(){CHV.fn.storage.toggleHttps($(this).closest("[data-content=storage]").data("storage-id"))}),$(document).on("click","[data-action=toggle-storage-active]",function(){CHV.fn.storage.toggleActive($(this).closest("[data-content=storage]").data("storage-id"))}),$(CHV.fn.uploader.selectors.root).exists()&&(CHV.fn.uploader.$pasteCatcher=$("
    ",{contenteditable:"true",id:CHV.fn.uploader.selectors.paste.replace(/#/,"")}),$("body").append(CHV.fn.uploader.$pasteCatcher),$(document).keydown(function(e){var t=e.keyCode,a=e.ctrlKey||e.metaKey;a&&86==t&&!$(e.target).is(":input")&&CHV.fn.uploader.$pasteCatcher.focus(e)}),window.addEventListener("paste",CHV.fn.uploader.pasteImageHandler)),$(document).on("click","[data-action=like]",function(){if(PF.fn.is_user_logged()){var e=$(this);if(!e.data("XHR")){e.data("XHR",!0);var t=$(this).is("[data-liked]")?$(this):$(this).closest("[data-liked]"),a=!t.closest("[data-list], .viewer").exists()&&void 0!==CHV.obj.resource,o=t.is("[data-liked=1]"),i=o?"dislike":"like",r={id:a?CHV.obj.resource.id:$(this).closest("[data-id]").attr("data-id"),type:a?CHV.obj.resource.type:$(this).closest("[data-type]").attr("data-type")},n=a?e:$("[data-type="+r.type+"][data-id="+r.id+"]"),s={type:"POST",data:{action:i},cache:!1};s.data[i]={object:r.type,id:r.id},$.ajax(s).complete(function(t){var i=t.responseJSON;e.data("XHR",!1),200===i.status_code?(a&&void 0!==i.content&&$("[data-text=likes-count]").html(i.content.likes),n.attr("data-liked",o?0:1)):PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."))})}}else window.location.href=CHV.obj.vars.urls.login}),$(document).on("click","[data-action=follow]",function(){if(PF.fn.is_user_logged()){var e=$(this);if(!e.data("XHR")){e.data("XHR",!0);var t=$(this).is("[data-followed]")?$(this):$(this).closest("[data-followed]"),a=void 0!==CHV.obj.resource,o=t.is("[data-followed=1]"),i=o?"unfollow":"follow",r={id:a?CHV.obj.resource.id:$(this).closest("[data-id]").data("id"),type:a?CHV.obj.resource.type:$(this).closest("[data-type]").data("type")},n={type:"POST",data:{action:i},cache:!1};n.data[i]={object:r.type,id:r.id},$.ajax(n).complete(function(i){var r=i.responseJSON;if(e.data("XHR",!1),200===r.status_code){if(a&&void 0!==r.user_followed){var n=$("[data-text=followers-label]"),s={single:n.data("label-single"),plural:n.data("label-plural")};$("[data-text=followers-count]").html(r.user_followed.followers),n.html(PF.fn._n(s.single,s.plural,r.user_followed.followers))}t.attr("data-followed",o?0:1)}else PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later."))})}}else PF.fn.modal.call({type:"login"})}),$(document).on("click","[data-action=top-bar-notifications]",function(e){var a=this,o=$(this),i=$(".top-bar-notifications-container",o),r=$(".top-bar-notifications-list",o),n=$("ul",r),s=$(".loading",i);o.data("XHR")||(s.removeClass("hidden"),PF.fn.loading.inline(s,{size:"small",message:PF.fn._s("loading")}),$.ajax({type:"POST",data:{action:"notifications"},cache:!1}).complete(function(e){var l=e.responseJSON;if(200!==l.status_code)return PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")),o.data("XHR",!1),void s.addClass("hidden").html("");if(o.data("XHR",!0),s.remove(),l.html){r.removeClass("hidden"),n.html(l.html),t();var d=$("li.new",n);d.addClass("transition"),setTimeout(function(){d.removeClass("new"),$("[data-content=notifications-counter]",a).removeClass("on").html("0"),setTimeout(function(){d.removeClass("transition")},150)},1500)}else $(".empty",i).removeClass("hidden")}))}),$("#g-recaptcha").is(":empty")&&CHV.obj.config.recaptcha.enabled&&CHV.obj.config.recaptcha.sitekey&&(reCaptchaCallback=function(){0!=$("#g-recaptcha").is(":empty")&&grecaptcha.render("g-recaptcha",{sitekey:CHV.obj.config.recaptcha.sitekey})},$.getScript("https://www.google.com/recaptcha/api.js?onload=reCaptchaCallback&render=explicit")),$(document).on("click",".list-item a.image-container",function(e){var t=$(this).closest(".list-item"),o=t.find("[data-action=load-image]");o.length>0&&(a(o),e.preventDefault())}),$(document).on("click",".list-item [data-action=load-image]",function(e){a($(this)),e.preventDefault(),e.stopPropagation()}),$(document).on("click","#album [data-tab=tab-codes]",function(){var e=$(".content-listing-loading","#tab-codes");if(e.exists()){var t=$("#embed-codes");$.ajax({type:"POST",data:{action:"get-album-contents",albumid:CHV.obj.resource.id},cache:!1}).always(function(a){PF.fn.loading.destroy(e),200==a.status_code&&(CHV.fn.fillEmbedCodes(a.contents,"#tab-codes"),t.removeClass("soft-hidden"))})}}),$("body").is("#upload")&&CHV.fn.uploader.toggle({show:!0}),$(document).on("keyup",function(e){if(!$(PF.obj.modal.selectors.root).exists()&&$(".viewer").exists()&&e.which in CHV.fn.listingViewer.keys){var t=[88,37,39],a=CHV.fn.listingViewer.keys[e.which];-1==t.indexOf(e.which)?$("[data-action="+a+"]",CHV.fn.listingViewer.selectors.root).click():a in CHV.fn.listingViewer&&CHV.fn.listingViewer[a]()}}),$(document).on("click",CHV.fn.listingViewer.selectors.root+" [data-action^=viewer-]",function(){var e=$(this).data("action").substring("viewer-".length);e in CHV.fn.listingViewer&&CHV.fn.listingViewer[e]()}),$(document).on("click","a[data-href]:not([rel=popup-link]):not(.popup-link)",function(){var e=$(this).attr("data-href"),t=$(this).attr("href");(e||t)&&(location.href=t||e)}),void 0!==CHV.obj.config&&CHV.obj.config.listing.viewer&&$(document).on("click",PF.obj.listing.selectors.list_item+"[data-type=image] a.image-container",function(e){e.preventDefault(),e.stopPropagation();var t=$(this).closest(PF.obj.listing.selectors.list_item);t.exists()&&CHV.fn.listingViewer.open(t)}),$(document).on("contextmenu",CHV.fn.listingViewer.selectors.src,function(e){return e.preventDefault(),!1});var p=PF.fn.deparam(window.location.search);if(p&&"viewer"in p){var g=$(PF.obj.listing.selectors.content_listing_visible);if("images"==g.data("list")){var h=$(PF.obj.listing.selectors.list_item,g)["next"==p.viewer?"first":"last"]();CHV.fn.listingViewer.open(h)}}}),"undefined"==typeof CHV&&(CHV={obj:{},fn:{},str:{}}),window.opener&&(CHV.obj.opener={uploadPlugin:{}}),CHV.fn.listingViewer={selectors:{bodyShown:".--viewer-shown",template:"#viewer-template",root:".viewer",rootShow:".viewer--show",rootHide:".viewer--hide",rootZero:".viewer--zero",rootNavPrev:".viewer--nav-prev",rootNavNext:".viewer--nav-next",src:".viewer-src",tools:".viewer-tools",loader:".viewer-loader",owner:".viewer-owner",ownerGuest:".viewer-owner--guest",ownerUser:".viewer-owner--user",inputMap:".viewer-kb-input"},keys:{83:"select",76:"like",70:"flag",69:"edit",65:"move",46:"delete",88:"close",37:"prev",39:"next"},keymap:{select:["S",PF.fn._s("Toggle select")],like:["L",PF.fn._s("Like")],flag:["F",PF.fn._s("Toggle flag")],edit:["E",PF.fn._s("Edit")],move:["A",PF.fn._s("Album")],delete:["Del",PF.fn._s("Delete")],close:["X",PF.fn._s("Close")],prev:["◀",PF.fn._s("Previous")],next:["▶",PF.fn._s("Next")]},loading:null,idleTimer:0,$item:null,show:function(){this.getEl("root").removeClass(this.selectors.rootHide.substring(1)).addClass(this.selectors.rootShow.substring(1)),$("body").addClass(this.selectors.bodyShown.substring(1));var e=new Hammer($(CHV.fn.listingViewer.selectors.root).get(0),{direction:Hammer.DIRECTION_VERTICAL});e.on("swipeleft swiperight",function(e){var t="left"==e.type.substring("swipe".length)?"next":"prev";CHV.fn.listingViewer[t]()})},getItem:function(){return this.$item},getEl:function(e){var t=!e.startsWith("template")&&!e.startsWith("root")&&this.selectors.root;return t?$(this.selectors[e],t):$(this.selectors[e])},getObject:function(e){if(e||void 0===this.object){var t=decodeURIComponent(this.getItem().attr("data-object"));this.object=JSON&&JSON.parse(t)||$.parseJSON(t)}return this.object},placeholderSizing:function(){if(this.getEl("root").exists()){var e=Math.max(document.documentElement.clientWidth,window.innerWidth||0),t=Math.max(document.documentElement.clientHeight,window.innerHeight||0),a=e/t,o=this.getEl("src")[0],i=o.getAttribute("width"),r=o.getAttribute("height"),n=i/r,s=a0?"add":t.getItem()[o]().exists()?"add":"remove";a[r+"Class"](i.substring(1))}),$.each(this.getItem().get(0).attributes,function(e,t){if(!t.name.startsWith("data-"))return!0;a.attr(t.name,t.value)});var r=void 0===this.object.user?"user":"guest";r="owner"+(r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()),this.getEl(r).remove(),void 0!==this.object.user&&$(this.object.user.avatar?".default-user-image":"img.user-image",this.getEl("ownerUser")).remove();var n=this.getItem().find(".list-item-image-tools");this.getEl("tools").append(n.html()),$.each(n.find("[data-action]"),function(e,a){var o=$(this).attr("data-action"),i=t.keymap[o];$('
    '+i[0]+""+i[1]+"
    ").appendTo(t.getEl("inputMap"))}),this.placeholderSizing(),this.trickyLoad()},toggleFullscreen:function(e){var t=e?this.getEl("root")[0]:document,a=e?t.requestFullscreen||t.mozRequestFullScreen||t.webkitRequestFullScreen||t.msRequestFullscreen:t.exitFullscreen||t.webkitExitFullscreen||t.mozCancelFullScreen||t.msExitFullscreen;a.call(t)},fullscreen:function(){this.toggleFullscreen(!0)},normalscreen:function(){this.toggleFullscreen(!1)},remove:function(){this.getEl("root").remove()},getParsedTemplate:function(){var e=this.getObject(!0),t=this.getEl("template").html(),a=t.match(/%(\S+)%/g);return a&&$.each(a,function(a,o){var i,r=o.slice(1,-1).split(".");r.map(function(t){var a=i||e;t in a&&(i=a[t])});var n=new RegExp(o,"g");t=t.replace(n,i)}),t},insertEl:function(){var e=this.getParsedTemplate();this.getEl("rootZero").remove(),$(e).appendTo("body")},toggleIdle:function(e,t){var a=this;t=void 0===t||t;$("html")[(e?"add":"remove")+"Class"]("--idle"),e||(clearTimeout(a.idleTimer),t&&(a.idleTimer=setTimeout(function(){var e=$(".fullscreen"),t=a.getEl("root");a.toggleIdle(t.length>0&&0==e.length)},5e3)))},open:function(e){this.setItem(e),this.insertEl(),this.filler(),this.show(),this.toggleIdle(!1);var t=this;this.getEl("root").on("mousemove mouseout",function(){t.toggleIdle(!1)})},setItem:function(e){this.$item=e},trickyLoad:function(){var e=this.getEl("loader");if(this.object.image.url!=this.object.display_url){var t=this.getEl("src").parent().html(),a=$(t).attr("src",this.object.image.url);a.insertBefore(this.getEl("src")),PF.fn.loading.inline(e,{color:"white",size:"small",center:!0,valign:!0}),e.hide().fadeIn("slow"),a.imagesLoaded(function(){a.next().remove(),PF.fn.loading.destroy(e)})}else e.remove()},close:function(){var e=this;$(this.selectors.root).removeClass(this.selectors.rootShow.substring(1)).addClass(this.selectors.rootHide.substring(1)),$("body").removeClass(this.selectors.bodyShown.substring(1)),this.toggleIdle(!1,!1),setTimeout(function(){e.remove()},200)},browse:function(e){var t=this.getItem()[e]();if(t.exists()){this.setItem(t),this.filler(!0);var a=$(PF.obj.listing.selectors.content_listing_visible).find("[data-action=load-more]"),o=t[e+"All"]().length;a.length>0&&o<=5&&!PF.obj.listing.calling&&"next"==e&&$("[data-action=load-more]").click()}else{var i=$("[data-pagination="+e+"]",PF.obj.listing.selectors.content_listing_pagination+":visible"),r=i.attr("href");if(!r)return;PF.fn.deparam(window.location.search);window.location.href=r+"&viewer="+e}},prev:function(){this.browse("prev")},next:function(){this.browse("next")}},CHV.obj.image_viewer={selector:"#image-viewer",container:"#image-viewer-container",navigation:".image-viewer-navigation",loading:"#image-viewer-loading",loader:"#image-viewer-loader"},CHV.obj.image_viewer.$container=$(CHV.obj.image_viewer.container),CHV.obj.image_viewer.$navigation=$(CHV.obj.image_viewer.navigation),CHV.obj.image_viewer.$loading=$(CHV.obj.image_viewer.loading),CHV.fn.system={checkUpdates:function(e){$.ajax({url:CHEVERETO.api.get.info+"/",data:{id:CHEVERETO.id},cache:!1}).always(function(t,a,o){"function"==typeof e&&e(o)})}},CHV.fn.bindSelectableItems=function(){var e="content-listing-wrapper",t="#"+e;$(t).exists()?$(t).hasClass("ui-selectable")&&$(t).selectable("destroy"):$("[data-content=list-selection]").closest(".content-width").wrap("
    "),$("[data-content=list-selection]").exists()&&$("html.device-nonmobile "+t).selectable({delay:150,filter:PF.obj.listing.selectors.list_item,cancel:".content-empty, .header, #tab-share, #tab-full-info, .viewer-title, .header-link, .top-bar, .content-listing-pagination *, #fullscreen-modal, #top-user, #background-cover, .list-item-desc, .list-item-image-tools, [data-action=load-image], #tab-codes",selecting:function(e,t){var a=$(t.selecting),o=a.hasClass("selected");CHV.fn.list_editor[(o?"unselect":"select")+"Item"](a)},unselecting:function(e,t){CHV.fn.list_editor.unselectItem($(t.unselecting))}})},CHV.fn.isCachedImage=function(e){var t=new Image;return t.src=e,t.complete||t.width+t.height>0},CHV.fn.viewerImageZoomClass=function(){CHV.obj.image_viewer.$container.hasClass("jscursor-zoom-in")&&CHV.obj.image_viewer.$container.addClass("cursor-zoom-in").removeClass("jscursor-zoom-in")},CHV.fn.viewerLoadImage=function(){CHV.obj.image_viewer.$loading.exists()&&(CHV.obj.image_viewer.$loading.removeClass("soft-hidden").css({zIndex:2}),PF.fn.loading.inline(CHV.obj.image_viewer.$loading,{color:"white",size:"small",center:!0,valign:!0}),CHV.obj.image_viewer.$loading.hide().fadeIn("slow")),$(CHV.obj.image_viewer.loader).remove(),CHV.obj.image_viewer.image.html=CHV.obj.image_viewer.$container.html(),CHV.obj.image_viewer.$container.prepend($(CHV.obj.image_viewer.image.html).css({top:0,zIndex:0})),CHV.obj.image_viewer.$container.find("img").eq(0).css("zIndex",1),CHV.obj.image_viewer.$container.find("img").eq(1).attr("src",CHV.obj.image_viewer.image.url).css({width:"100%",height:"auto"}),CHV.obj.image_viewer.$container.find("img").eq(1).imagesLoaded(function(){CHV.obj.image_viewer.$container.find("img").eq(1).css({width:"",height:""}),CHV.obj.image_viewer.$container.find("img").eq(0).remove(),PF.fn.loading.destroy(CHV.obj.image_viewer.$loading)})},CHV.obj.embed_tpl={},CHV.obj.topBar={transparencyScrollToggle:function(){var e=$(window).scrollTop();$("#top-bar")[(e>0?"remove":"add")+"Class"]("transparent")}},CHV.obj.uploaderReset={isUploading:!1,canAdd:!0,queueStatus:"ready",uploadThreads:0,uploadParsedIds:[],uploadProcessedIds:[],files:{},results:{success:{},error:{}},toggleWorking:0,filesAddId:0,clipboardImages:[]},CHV.fn.uploader={selectors:{root:"#anywhere-upload",show:".upload-box--show",queue:"#anywhere-upload-queue",queue_complete:".queue-complete",queue_item:".queue-item",close_cancel:"[data-button=close-cancel]",file:"#anywhere-upload-input",camera:"#anywhere-upload-input-camera",upload_item_template:"#anywhere-upload-item-template",item_progress_bar:"[data-content=progress-bar]",item_progress_percent:"[data-text=progress-percent]",failed_result:"[data-content=failed-upload-result]",fullscreen_mask:"#fullscreen-uploader-mask",dropzone:"#uploader-dropzone",paste:"#anywhere-upload-paste",input:"[data-action=anywhere-upload-input]"},toggle:function(e,t){this.queueSize();var a=$("[data-action=top-bar-upload]",".top-bar"),o=!$(CHV.fn.uploader.selectors.root).data("shown");e=$.extend({callback:null,reset:!0},e);if(void 0!==e.show&&e.show&&(o=!0),PF.fn.growl.close(!0),PF.fn.close_pops(),!(1==this.toggleWorking||$(CHV.fn.uploader.selectors.root).is(":animated")||CHV.fn.uploader.isUploading||a.data("login-needed")&&!PF.fn.is_user_logged())){this.toggleWorking=1;var i={time:500,easing:null},r=function(){!o&&e.reset&&CHV.fn.uploader.reset(),PF.obj.follow_scroll.$node.exists()&&(PF.obj.follow_scroll.$node.removeClass("fixed"),PF.obj.follow_scroll.set()),PF.fn.topMenu.hide(),"function"==typeof e.callback&&e.callback(t),CHV.fn.uploader.boxSizer(),CHV.fn.uploader.toggleWorking=0};if($(CHV.fn.uploader.selectors.root)[(o?"add":"remove")+"Class"](this.selectors.show.substring(1)),o){if(!$("body").is("#upload")&&PF.fn.isDevice(["phone","phablet"])&&$("html").addClass("overflow-hidden"),$("html").data({"followed-scroll":$("html").hasClass("followed-scroll"),"top-bar-box-shadow-prevent":!0}).removeClass("followed-scroll").addClass("top-bar-box-shadow-none"),$("#top-bar").data({stock_classes:$("#top-bar").attr("class")}),$(".current[data-nav]",".top-bar").each(function(){$(this).is("[data-action=top-bar-menu-full]")||$(this).removeClass("current").attr("data-current",1)}),PF.fn.isDevice("mobile")){var n=$(".upload-box-heading",$(CHV.fn.uploader.selectors.root));n.css({position:"relative",top:.5*($(window).height()-n.height())+"px"})}CHV.fn.uploader.focus(function(){setTimeout(function(){r()},i.time)})}else{$("[data-nav][data-current=1]",".top-bar").each(function(){$(this).addClass("current")}),$(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity:0}),setTimeout(function(){$(CHV.fn.uploader.selectors.fullscreen_mask).remove(),$("html").data("followed-scroll")&&$("html").addClass("followed-scroll")},250);var s=$(CHV.fn.uploader.selectors.root).outerHeight(),l=s-parseInt($(CHV.fn.uploader.selectors.root).data("initial-height"))+"px";$(CHV.fn.uploader.selectors.root).css({transform:"translate(0,-"+l+")"}),setTimeout(function(){$("#top-bar").attr("class",$("#top-bar").data("stock_classes")),$("html").removeClass($(".follow-scroll-wrapper.position-fixed").exists()?"":"top-bar-box-shadow-none")},1*i.time/3),setTimeout(function(){$(CHV.fn.uploader.selectors.root).css({top:""}),$("body#image").exists()&&CHV.obj.topBar.transparencyScrollToggle(),r(),$("html,body").removeClass("overflow-hidden").data({"top-bar-box-shadow-prevent":!1})},i.time)}$(CHV.fn.uploader.selectors.root).data("shown",o),a.toggleClass("current").removeClass("opened")}},reset:function(){$.extend(this,$.extend(!0,{},CHV.obj.uploaderReset)),$("li",this.selectors.queue).remove(),$(this.selectors.root).height("").css({"overflow-y":"","overflow-x":""}),$(this.selectors.queue).addClass("queueEmpty").removeClass(this.selectors.queue_complete.substring(1)),$(this.selectors.input,this.selectors.root).each(function(){$(this).prop("value",null)}),$("[data-group=upload-result] textarea",this.selectors.root).prop("value",""),$.each(["upload-queue-ready","uploading","upload-result","upload-queue-ready","upload-queue"],function(e,t){$("[data-group="+t+"]").hide()}),$("[data-group=upload]",this.selectors.root).show(),$("[name=upload-album-id]",this.selectors.root).prop("value",function(){var e=$("option[selected]",this);if(e.exists())return e.attr("value")}),$(this.selectors.root).removeClass("queueCompleted queueReady queueHasResults").addClass("queueEmpty").attr("data-queue-size",0),$("[name=upload-category-id]",this.selectors.root).prop("value",""),$("[name=upload-nsfw]",this.selectors.root).prop("checked",this.defaultChecked),this.boxSizer(!0)},focus:function(e){$(this.selectors.fullscreen_mask).exists()||($("body").is("#upload")||$("body").append($("
    ",{id:this.selectors.fullscreen_mask.replace("#",""),class:"fullscreen soft-black"}).css({top:PF.fn.isDevice("phone")?0:$(CHV.fn.uploader.selectors.root).data("top")})),setTimeout(function(){$("body").is("#upload")||$(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity:1}),setTimeout(function(){"function"==typeof e&&e()},PF.fn.isDevice(["phone","phablet"])?0:250)},1))},boxSizer:function(e){var t=$(this.selectors.root).is(this.selectors.show),a=t||e;t&&!$("body").is("#upload")&&$("html")[(PF.fn.isDevice(["phone","phablet"])?"add":"remove")+"Class"]("overflow-hidden"),a&&($(this.selectors.root).height(""),!$("body").is("#upload")&&$(this.selectors.root).height()>$(window).height()?($(this.selectors.root).height($(window).height()).css({"overflow-y":"scroll","overflow-x":"auto"}),$("body").addClass("overflow-hidden")):($(this.selectors.root).css("overflow-y",""),$("body").removeClass("overflow-hidden")))},pasteURL:function(){var e=$("[name=urls]","#fullscreen-modal").val();e&&(CHV.fn.uploader.toggle({show:!0}),CHV.fn.uploader.add({},e))},pasteImageHandler:function(e){if(!$(e.target).is(":input")){if(void 0!==e.clipboardData&&e.clipboardData.items)var t=e.clipboardData.items;else setTimeout(function(){return e.clipboardData={},e.clipboardData.items=[],$.each($("img",CHV.fn.uploader.$pasteCatcher),function(t,a){e.clipboardData.items.push(PF.fn.dataURItoBlob($(this).attr("src")))}),$(CHV.fn.uploader.selectors.paste).html(""),CHV.fn.uploader.pasteImageHandler(e)},1);if(t)for(var a=0;ah||f==h){var v=hh&&$img.height(v).width(v*b)}if(f0){var C="";for(d=0;d"+PF.fn.htmlEncode(n[d].name)+"",delete CHV.fn.uploader.files[n[d].uid],$("li[data-id="+n[d].uid+"]",CHV.fn.uploader.selectors.queue).find("[data-action=cancel]").click();PF.fn.modal.simple({title:PF.fn._s("Some files couldn't be added"),message:"
      "+C+"
    "})}else CHV.fn.uploader.focus();CHV.fn.uploader.boxSizer()}},$.extend({},h,{orientation:o.exif?o.exif.get("Orientation"):1})),setTimeout(function(){a(e+1)},25)})}else PF.fn.loading.destroy("fullscreen")}var o;if(!this.canAdd){e=e.originalEvent;return e.preventDefault(),e.stopPropagation(),!1}$fileinput=$(this.selectors.file),$fileinput.replaceWith($fileinput=$fileinput.clone(!0));var i=$(this.selectors.upload_item_template).html(),r=[];if(void 0===t){e=e.originalEvent;if(e.preventDefault(),e.stopPropagation(),r=e.dataTransfer||e.target,r=$.makeArray(r.files),e.clipboard){if(o=PF.fn.md5(e.dataURL),-1!=$.inArray(o,this.clipboardImages))return null;this.clipboardImages.push(o)}for(var n=[],s=0;sCHV.obj.config.image.max_filesize.getBytes()?n.push({uid:s,name:d.name.truncate_middle()+" - "+PF.fn._s("File too big.")}):-1!=CHV.obj.config.upload.image_types.indexOf(l)||0!=/android/i.test(navigator.userAgent)?(o&&(d.md5=o),d.fromClipboard=1==e.clipboard,d.uid=s):n.push({uid:s,name:d.name.truncate_middle()+" - "+PF.fn._s("Invalid or unsupported file format.")})}for(s=0;s0&&0==r.length){var u="";for(s=0;s"+PF.fn.htmlEncode(n[s].name)+"";return void PF.fn.modal.simple({title:PF.fn._s("Some files couldn't be added"),message:"
    • "+u+"
    "})}if(0==r.length)return}else{if(t=t.replace(/(<([^>]+)>)/g,"").replace(/(\[([^\]]+)\])/g,""),r=t.match_urls(),!r)return;r=r.array_unique(),r=$.map(r,function(e,t){return{uid:t,name:e,url:e}})}if($.isEmptyObject(this.files))for(s=0;s0){var i=[];for(var o in this.results.error)"object"==typeof this.results.error[o]&&(i[o]=this.results.error[o].error.message);i.length>0&&$(this.selectors.failed_result).html("
  • "+i.join("
  • ")+"
  • ")}else $(a.error,this.selectors.root).hide();if(!window.opener&&CHV.obj.config.upload.redirect_single_upload&&1==Object.size(this.results.success)&&0==Object.size(this.results.error))return window.location.href=this.results.success[0].image.url_viewer,!1;if($("[data-text=queue-progress]",this.selectors.root).text(100),$("[data-group=uploading]",this.selectors.root).hide(),$(this.selectors.root).removeClass("queueUploading queueHasResults").addClass("queueCompleted"),$(this.selectors.queue).addClass(this.selectors.queue_complete.substring(1)),Object.size(this.results.success)>0&&$("[data-group=upload-result] textarea",this.selectors.root).exists()&&CHV.fn.fillEmbedCodes(this.results.success,CHV.fn.uploader.selectors.root,"val"),Object.size(this.results.success)>0&&Object.size(this.results.error)>0?$(a.mixed+", "+a.success,this.selectors.root).show():Object.size(this.results.success)>0?$(a.success,this.selectors.root).show():Object.size(this.results.error)>0&&$(a.error,this.selectors.root).show(),$(a.success,this.selectors.root).is(":visible")){$(a.success,this.selectors.root).find("[data-group^=user], [data-group=guest]").hide(),$(a.success,this.selectors.root).find("[data-group="+(PF.fn.is_user_logged()?"user":"guest")+"]").show();var r=Object.keys(this.results.success)[0];if(void 0!==this.results.success[r].image.album){var n=[];for(var s in this.results.success){var l=this.results.success[s].image;l.album&&l.album.id_encoded&&-1==n.indexOf(l.album.id_encoded)&&n.push(l.album.id_encoded)}var d={link:null,text:null};if(n.length<=1?(d.link=this.results.success[r].image.album.url,d.text=this.results.success[r].image.album.name):(d.link=this.results.success[r].image.user.url_albums,d.text=PF.fn._s("%s's Albums",this.results.success[r].image.user.name_short_html)),$("[data-text=upload-target]",this.selectors.root).text(d.text),$("[data-link=upload-target]",this.selectors.root).attr("href",d.link),PF.fn.is_user_logged()){var c=n.length>0?"album":"stream";$("[data-group=user-"+c+"]",this.selectors.root).show()}}}if(this.boxSizer(),this.queueStatus="done",window.opener&&void 0!==CHV.obj.opener.uploadPlugin[window.name]){if($('[data-action="copy"]',this.selectors.root).remove(),CHV.obj.opener.uploadPlugin[window.name].hasOwnProperty("autoInsert")&&CHV.obj.opener.uploadPlugin[window.name].autoInsert){var u=$(':input[name="'+CHV.obj.opener.uploadPlugin[window.name].autoInsert+'"]',CHV.fn.uploader.selectors.root),m=u.val();if(m)return window.opener.postMessage({id:window.name,message:m},"*"),void window.close()}}else $('[data-action="openerPostMessage"]',this.selectors.root).remove()}},$.extend(CHV.fn.uploader,$.extend(!0,{},CHV.obj.uploaderReset)),CHV.fn.fillEmbedCodes=function(e,t,a){void 0===a&&(a="val"),$.each(e,function(e,o){if(void 0!==o){var i="id_encoded"in o?o:o.image;if(!i.medium){i.medium={};for(var r=["filename","name","width","height","extension","size","size_formatted","url"],n=0;n0&&$.each(CHV.obj.categories,function(o,i){return void 0!==e&&i.id==e||(i.url_key==$("[name=form-category-url_key]",t).val()?(a=!0,!1):void 0)}),!a||(PF.fn.growl.call(PF.fn._s("Category URL key already being used.")),$("[name=form-category-url_key]",t).highlight(),!1)))},edit:{before:function(e){var t=$(e.target),a=t.data("category-id"),o=CHV.obj.categories[a],i="[data-modal="+t.data("target")+"]";$.each(CHV.fn.category.formFields,function(e,t){e="form-category-"+t,t=o[t];var a=$("[name="+e+"]",i);a.is("textarea")?a.html(PF.fn.htmlEncode(t)):a.attr("value",t)})},submit:function(){var e=PF.obj.modal.selectors.root,t=$("[name=form-category-id]",e).val();return!!CHV.fn.category.validateForm(t)&&(PF.obj.modal.form_data={action:"edit",edit:"category",editing:{}},$.each(CHV.fn.category.formFields,function(t,a){PF.obj.modal.form_data.editing[a]=$("[name=form-category-"+a+"]",e).val()}),!0)},complete:{success:function(e){var t=e.responseJSON.category,a="[data-content=category][data-category-id="+t.id+"]";$.each(t,function(e,t){$("[data-content=category-"+e+"]",a).html(PF.fn.htmlEncode(t))}),$("[data-link=category-url]").attr("href",t.url),CHV.obj.categories[t.id]=t}}},delete:{before:function(e){var t=$(e.target),a=t.data("category-id"),o=CHV.obj.categories[a];t.attr("data-confirm",t.attr("data-confirm").replace("%s",'"'+o.name+'"'))},submit:function(e){return PF.obj.modal.form_data={action:"delete",delete:"category",deleting:{id:e}},!0},complete:{success:function(e){PF.fn.growl.expirable(PF.fn._s("Category successfully deleted."));var t=e.responseJSON.request.deleting.id;$("[data-content=category][data-category-id="+t+"]").remove(),delete CHV.obj.categories[t]}}},add:{submit:function(){var e=PF.obj.modal.selectors.root;return!!CHV.fn.category.validateForm()&&(PF.obj.modal.form_data={action:"add-category",category:{}},$.each(CHV.fn.category.formFields,function(t,a){"id"!=a&&(PF.obj.modal.form_data.category[a]=$("[name=form-category-"+a+"]",e).val())}),!0)},complete:{success:function(e){var t=e.responseJSON.category,a="[data-content=dashboard-categories-list]",o=$("[data-content=category-dashboard-template]").html();$.each(t,function(e,t){o=o.replace(new RegExp("%"+e.toUpperCase()+"%","g"),t||"")}),$(a).append(o),0==Object.size(CHV.obj.categories)&&(CHV.obj.categories={}),CHV.obj.categories[t.id]=t,PF.fn.growl.call(PF.fn._s("Category %s added.",'"'+t.name+'"'))}}}},CHV.fn.ip_ban={formFields:["id","ip","expires","message"],validateForm:function(e){var t=PF.obj.modal.selectors.root,a=!1,o=$("[name=form-ip_ban-ip]",t).val();return!!CHV.fn.common.validateForm(t)&&(""!==$("[name=form-ip_ban-expires]",t).val()&&0==/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test($("[name=form-ip_ban-expires]",t).val())?(PF.fn.growl.call(PF.fn._s("Invalid expiration date.")),$("[name=form-ip_ban-expires]",t).highlight(),!1):(Object.size(CHV.obj.ip_bans)>0&&$.each(CHV.obj.ip_bans,function(t,i){return void 0!==e&&i.id==e||(i.ip==o?(a=!0,!1):void 0)}),!a||(PF.fn.growl.call(PF.fn._s("IP %s already banned.",o)),$("[name=form-ip_ban-ip]",t).highlight(),!1)))},add:{submit:function(){var e=PF.obj.modal.selectors.root;return!!CHV.fn.ip_ban.validateForm()&&(PF.obj.modal.form_data={action:"add-ip_ban",ip_ban:{}},$.each(CHV.fn.ip_ban.formFields,function(t,a){"id"!=a&&(PF.obj.modal.form_data.ip_ban[a]=$("[name=form-ip_ban-"+a+"]",e).val())}),!0)},complete:{success:function(e){var t=e.responseJSON.ip_ban,a="[data-content=dashboard-ip_bans-list]",o=$("[data-content=ip_ban-dashboard-template]").html();void 0!==o&&($.each(t,function(e,t){o=o.replace(new RegExp("%"+e.toUpperCase()+"%","g"),t||"")}),$(a).append(o)),0==Object.size(CHV.obj.ip_bans)&&(CHV.obj.ip_bans={}),CHV.obj.ip_bans[t.id]=t,$("[data-content=ban_ip]").hide(),$("[data-content=banned_ip]").show(),PF.fn.growl.call(PF.fn._s("IP %s banned.",t.ip))},error:function(e){var t=e.responseJSON.error;PF.fn.growl.call(PF.fn._s(t.message))}}},edit:{before:function(e){var t=$(e.target),a=t.data("ip_ban-id"),o=CHV.obj.ip_bans[a],i="[data-modal="+t.data("target")+"]";$.each(CHV.fn.ip_ban.formFields,function(e,t){e="form-ip_ban-"+t,t=o[t];var a=$("[name="+e+"]",i);a.is("textarea")?a.html(PF.fn.htmlEncode(t)):a.attr("value",t)})},submit:function(){var e=PF.obj.modal.selectors.root,t=$("[name=form-ip_ban-id]",e).val();return!!CHV.fn.ip_ban.validateForm(t)&&(PF.obj.modal.form_data={action:"edit",edit:"ip_ban",editing:{}},$.each(CHV.fn.ip_ban.formFields,function(t,a){PF.obj.modal.form_data.editing[a]=$("[name=form-ip_ban-"+a+"]",e).val()}),!0)},complete:{success:function(e){var t=e.responseJSON.ip_ban,a="[data-content=ip_ban][data-ip_ban-id="+t.id+"]";$.each(t,function(e,t){$("[data-content=ip_ban-"+e+"]",a).html(PF.fn.htmlEncode(t))}),CHV.obj.ip_bans[t.id]=t},error:function(e){var t=e.responseJSON.error;PF.fn.growl.call(PF.fn._s(t.message))}}},delete:{before:function(e){var t=$(e.target),a=t.data("ip_ban-id"),o=CHV.obj.ip_bans[a];t.attr("data-confirm",t.attr("data-confirm").replace("%s",o.ip))},submit:function(e){return PF.obj.modal.form_data={action:"delete",delete:"ip_ban",deleting:{id:e}},!0},complete:{success:function(e){PF.fn.growl.expirable(PF.fn._s("IP ban successfully deleted."));var t=e.responseJSON.request.deleting.id;$("[data-content=ip_ban][data-ip_ban-id="+t+"]").remove(),delete CHV.obj.ip_bans[t]}}}},CHV.fn.storage={formFields:["id","name","api_id","bucket","server","service","capacity","region","key","secret","url","account_id","account_name"],calling:!1,validateForm:function(){var e=PF.obj.modal.selectors.root,t=$("[name=form-storage-id]",e).val(),a=!0;if($.each($(":input",e),function(e,t){$(this).is(":hidden")?$(this).attr("required")&&$(this).removeAttr("required").attr("data-required",1):1==$(this).attr("data-required")&&$(this).attr("required","required"),$(this).is(":visible")&&""==$(this).val()&&$(this).attr("required")&&($(this).highlight(),a=!1)}),!a)return PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")),!1;var o,i=$("[name=form-storage-capacity]",e),r=i.val();return""!==r&&(0==/^[\d\.]+\s*[A-Za-z]{2}$/.test(r)||void 0===r.getBytes()?o=PF.fn._s("Invalid storage capacity value. Make sure to use a valid format."):void 0!==CHV.obj.storages[t]&&r.getBytes()0&&(t=t.formatBytes(2)),s.attr("value",t))}),$("[data-combo-value]").addClass("soft-hidden"),$(r).removeClass("soft-hidden")},submit:function(){var e=PF.obj.modal.selectors.root;$("[name=form-storage-id]",e).val();return!!CHV.fn.storage.validateForm()&&(PF.obj.modal.form_data={action:"edit",edit:"storage",editing:{}},$.each(CHV.fn.storage.formFields,function(t,a){var o;o="[name=form-storage-"+a+"]","hidden"!==$(o,e).attr("type")&&(o+=":visible"),PF.obj.modal.form_data.editing[a]=$(o,e).val()}),!0)},complete:{success:function(e){var t=e.responseJSON.storage,a="[data-content=storage][data-storage-id="+t.id+"]",o=$("[data-action=toggle-storage-https]",a);$.each(t,function(e,t){$("[data-content=storage-"+e+"]",a).html(PF.fn.htmlEncode(t))}),CHV.obj.storages[t.id]=t,CHV.fn.storage.toggleBoolDisplay(o,1==t.is_https),CHV.fn.queuePixel()},error:function(e){var t=e.responseJSON,a=t.error.message;PF.fn.growl.call(a)}}},add:{submit:function(){if(!CHV.fn.storage.validateForm())return!1;var e=PF.obj.modal.selectors.root;return PF.obj.modal.form_data={action:"add-storage",storage:{}},$.each(CHV.fn.storage.formFields,function(t,a){var o;"id"!=a&&(o="[name=form-storage-"+a+"]","hidden"!==$(o,e).attr("type")&&(o+=":visible"),PF.obj.modal.form_data.storage[a]=$(o,e).val())}),!0},complete:{success:function(e){var t=e.responseJSON.storage,a="[data-content=dashboard-storages-list]",o=$("[data-content=storage-dashboard-template]").html();$.each(t,function(e,t){var a=e.toUpperCase();if("is_https"==e||"is_active"==e)t=CHV.obj.storageTemplate.icon.replace("%TITLE%",CHV.obj.storageTemplate.messages[e]).replace("%ICON%",CHV.obj.storageTemplate.checkboxes[t]).replace("%PROP%",e.replace("is_",""));o=o.replace(new RegExp("%"+a+"%","g"),t||"")}),$(a).append(o),PF.fn.bindtipTip($("[data-storage-id="+t.id+"]")),0==CHV.obj.storages.length&&(CHV.obj.storages={}),CHV.obj.storages[t.id]=t,CHV.fn.queuePixel()},error:function(e){var t=e.responseJSON,a=t.error.message;PF.fn.growl.call(a)}}},toggleBoolDisplay:function(e,t){var a={0:e.data("unchecked-icon"),1:e.data("checked-icon")};e.removeClass(a[0]+" "+a[1]).addClass(a[t?1:0])}},CHV.fn.common={validateForm:function(e){if(void 0===e)e=PF.obj.modal.selectors.root;var t=!0;return $.each($(":input:visible",e),function(e,a){""==$(this).val()&&$(this).attr("required")&&($(this).highlight(),t=!1)}),!!t||(PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")),!1)},updateDoctitle:function(e){void 0!==CHV.obj.page_info&&(CHV.obj.page_info.pre_doctitle=e,CHV.obj.page_info.doctitle=CHV.obj.page_info.pre_doctitle+CHV.obj.page_info.pos_doctitle,document.title=CHV.obj.page_info.doctitle)}},CHV.fn.user={add:{submit:function(){var e=$(PF.obj.modal.selectors.root),t=!0;return $.each($(":input",e),function(e,a){""==$(this).val()&&$(this).attr("required")&&($(this).highlight(),t=!1)}),t?(PF.obj.modal.form_data={action:"add-user",user:{username:$("[name=form-username]",e).val(),email:$("[name=form-email]",e).val(),password:$("[name=form-password]",e).val(),role:$("[name=form-role]",e).val()}},!0):(PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")),!1)},complete:{success:function(e){e.responseJSON;PF.fn.growl.expirable(PF.fn._s("User added successfully."))},error:function(e){var t=e.responseJSON;PF.fn.growl.call(PF.fn._s(t.error.message))}}},delete:{submit:function(){return PF.obj.modal.form_data={action:"delete",delete:"user",owner:CHV.obj.resource.user.id,deleting:CHV.obj.resource.user},!0}}},CHV.fn.submit_resource_delete=function(){return PF.obj.modal.form_data={action:"delete",delete:CHV.obj.resource.type,from:"resource",owner:void 0!==CHV.obj.resource.user?CHV.obj.resource.user.id:null,deleting:CHV.obj.resource},!0},CHV.fn.complete_resource_delete={success:function(e){e.responseJSON;$("body").fadeOut("normal",function(){var e;e="album"==CHV.obj.resource.type||"image"==CHV.obj.resource.type?CHV.obj.resource.parent_url:CHV.obj.resource.user?CHV.obj.resource.user.url:CHV.obj.resource.url,void 0!==e&&(window.location=e+"?deleted")})}},CHV.fn.list_editor={selectionCount:function(){var e=$(PF.obj.listing.selectors.content_listing);e.each(function(){var t=$("[data-content=pop-selection]","[data-content=list-selection][data-tab="+$(this).attr("id")+"]"),a=$(PF.obj.listing.selectors.list_item+".selected",this).length;if(all_count=$(PF.obj.listing.selectors.list_item,this).length,t[a>0?"removeClass":"addClass"]("disabled"),$("[data-text=selection-count]",t).text(a>0?a:""),"images"==e.data("list")&&a>0){var o=$(PF.obj.listing.selectors.list_item+".selected[data-flag=safe]",this).length>0,i=$(PF.obj.listing.selectors.list_item+".selected[data-flag=unsafe]",this).length>0;$("[data-action=flag-safe]",t)[(i?"remove":"add")+"Class"]("hidden"),$("[data-action=flag-unsafe]",t)[(o?"remove":"add")+"Class"]("hidden")}$(this).is(":visible")&&CHV.fn.list_editor.listMassActionSet(all_count==a?"clear":"select")})},removeFromList:function(e,t){if(void 0!==e){e=e instanceof jQuery==0?$(e):e;var a=$(PF.obj.listing.selectors.content_listing_visible),o=e.length;e.fadeOut("fast");var i=e.first().data("type"),r=parseInt($("[data-text="+i+"-count]").text())-o;CHV.fn.list_editor.updateUserCounters(e.first().data("type"),o,"-"),e.promise().done(function(){$(document).removeClass(CHV.fn.listingViewer.selectors.bodyShown.substr(1));var i={};if(e.each(function(){$("[data-id="+$(this).data("id")+"]").each(function(){var e=$(this).closest(PF.obj.listing.selectors.content_listing).attr("id");i[e]||(i[e]=0),i[e]+=1})}),1==o?$("[data-id="+$(this).data("id")+"]").remove():e.each(function(){$("[data-id="+$(this).data("id")+"]").remove()}),PF.fn.listing.columnizerQueue(),PF.fn.listing.refresh(),CHV.fn.list_editor.selectionCount(),void 0!==t&&"string"==typeof t&&PF.fn.growl.expirable(t),$(PF.obj.listing.selectors.content_listing_pagination,a).exists()||0!=$(".list-item",a).length||(r=0),0==r)a.html(PF.obj.listing.template.empty),$(PF.obj.listing.selectors.content_listing+":not("+PF.obj.listing.selectors.content_listing_visible+")").data({empty:null,load:"ajax"}),$("[data-content=list-selection][data-tab="+a.attr("id")+"]").addClass("disabled");else if(0==$(PF.obj.listing.selectors.list_item,a).length){if($(PF.obj.listing.selectors.pad_content).height(0),$("[data-action=load-more]",a).exists())return $(PF.obj.listing.selectors.content_listing_visible).data("page",0),$("[data-action=load-more]",a).click(),void(PF.obj.listing.recolumnize=!0);var n=$("[data-pagination=next]",a);if(n.exists()){var s=n.attr("href"),l=PF.fn.deparam(s);return"page"in l&&l.page>1&&(s=s.changeURLParameterValue("page",l.page-1)),void(window.location=s)}}})}},deleteFromList:function(e){if(void 0===t)var t=!0;e=e instanceof jQuery==0?$(e):e;this.removeFromList(e,t?PF.fn._s("The content has been deleted."):null)},moveFromList:function(e,t){if(void 0===t)t=!0;e=e instanceof jQuery==0?$(e):e;this.removeFromList(e,t?PF.fn._s("The content has been moved."):null)},toggleSelectItem:function(e,t){if("boolean"!=typeof t)t=!0;var a,o,i,r=$(".viewer").is(":visible")?$("[data-type=image][data-id="+e.attr("data-id")+"]"):e,n=$("[data-action=select] .btn-icon",r);t?(r.addClass("selected"),a=n.data("icon-selected"),o=n.data("icon-unselected"),i=PF.fn._s("Unselect")):(r.removeClass("selected"),a=n.data("icon-unselected"),o=n.data("icon-selected"),i=PF.fn._s("Select")),n.removeClass(o).addClass(a),$("[data-action=select] .label",r).text(i),CHV.fn.list_editor.selectionCount()},selectItem:function(e){this.toggleSelectItem(e,!0)},unselectItem:function(e){this.toggleSelectItem(e,!1)},clearSelection:function(e){var t=$(PF.obj.listing.selectors.list_item+".selected",PF.obj.listing.selectors[e?"content_listing":"content_listing_visible"]);this.unselectItem(t),this.listMassActionSet("select")},listMassActionSet:function(e){var t="select"==e?"clear":"select",a=$("[data-action=list-"+t+"-all]:visible"),o=a.data("text-"+e+"-all");a.text(o).attr("data-action","list-"+e+"-all")},updateItem:function(e,t,a,o){if(e instanceof jQuery==0)e=$(e);var i=e.data("type"),r="image"==i?t.album:t;if(console.log(e,r,i),this.addAlbumtoModals(r),$("option[value="+r.id_encoded+"]","[name=form-album-id]").html(PF.fn.htmlEncode(r.name_with_privacy_readable_html)),void 0===a)a="edit";if("edit"==a||"move"==a){if("move"==a&&"album"==CHV.obj.resource.type)return void CHV.fn.list_editor.moveFromList(e,o);e.attr("data-description",t.description),"image"==i?(void 0!==t.title&&(e.attr("data-title",t.title),e.find("[title]").attr("title",t.title),$("[data-text=image-title]",e).html(PF.fn.htmlEncode(t.title))),void 0!==t.title_truncated&&$("[data-text=image-title-truncated]",e).html(PF.fn.htmlEncode(t.title_truncated)),void 0!==t.category_id&&e.attr("data-category-id",t.category_id),e.attr({"data-album-id":r.id_encoded,"data-flag":1==t.nsfw?"unsafe":"safe"}),$("[data-content=album-link]",e).attr("href",r.url)):e.attr({"data-privacy":r.privacy,"data-password":r.password,"data-name":r.name}),e.attr("data-privacy",r.privacy),$("[data-text=album-name]",e).html(PF.fn.htmlEncode(r.name)),PF.fn.growl.expirable("edit"==a?PF.fn._s("The content has been edited."):PF.fn._s("The content has been moved."))}},addAlbumtoModals:function(e){var t=!1;$("[name=form-album-id]","[data-modal]").each(function(){e.id_encoded&&!$("option[value="+e.id_encoded+"]",this).exists()&&($(this).append('"),t=!0)}),t&&CHV.fn.list_editor.updateUserCounters("album",1,"+")},updateAlbum:function(e){$("[data-id="+e.id_encoded+"]").each(function(){""!==e.html&&($(this).after(e.html),$(this).remove())})},updateUserCounters:function(e,t,a){if(void 0===a)a="+";var o,i,r=$("[data-text="+e+"-count]"),n=$("[data-text="+e+"-label]"),s=(t=parseInt(t),parseInt(r.html()));switch(a){case"+":o=s+t;break;case"-":o=s-t;break;case"=":o=t}i=o-s;var l=$("[data-text=total-"+r.data("text")+"]"),d=$("[data-text="+l.data("text")+"-label]"),c=parseInt(l.html()),u=c+i;r.text(o),l.text(u),n.text(n.data(1==o?"label-single":"label-plural")),d.text(n.data(1==u?"label-single":"label-plural"))},updateMoveItemLists:function(e,t,a){if(CHV.fn.list_editor.clearSelection(),/image/.test(t))"image"==t?CHV.fn.list_editor.updateItem("[data-type=image][data-id="+a.data("id")+"]",e.image,"move"):(a.each(function(){CHV.fn.list_editor.updateItem("[data-type=image][data-id="+$(this).data("id")+"]",e,"move",!1)}),PF.fn.growl.expirable(PF.fn._s("The content has been moved.")));else{if("album"==CHV.obj.resource.type?CHV.fn.list_editor.moveFromList(a):PF.fn.growl.expirable(PF.fn._s("The content has been moved.")),void 0!==e.albums_old)for(var o=0;o';$("body").append(e)},CHV.fn.import={errorHandler:function(e){PF.fn.growl.call(e.error.message)},reset:function(e){e=parseInt(e);CHV.obj.import.working[e].stats=$.ajax({type:"POST",data:{action:"importReset",id:e}}),CHV.obj.import.working[e].stats.complete(function(t){var a=t.responseJSON;if(a){var o=CHV.fn.import.parseTemplate(a.import);$("[data-id="+a.import.id+"]",CHV.obj.import.sel.root).replaceWith(o), +"working"!=a.import.status&&clearInterval(CHV.obj.import.working[e].interval)}})},updateStats:function(e){e=parseInt(e);"readyState"in CHV.obj.import.working[e].stats&&4!=CHV.obj.import.working[e].stats.readyState?console.log("Aborting stats timeout call (previous call is still not ready)"):(CHV.obj.import.working[e].stats=$.ajax({type:"POST",data:{action:"importStats",id:e}}),CHV.obj.import.working[e].stats.complete(function(t){var a=t.responseJSON;if(a){var o=CHV.fn.import.parseTemplate(a.import);$("[data-id="+a.import.id+"]",CHV.obj.import.sel.root).replaceWith(o),"working"!=a.import.status&&clearInterval(CHV.obj.import.working[e].interval)}}))},add:{submit:function(){var e=PF.obj.modal.selectors.root;return PF.obj.modal.form_data={action:"importAdd",path:$("[name=form-path]",e).val(),options:{root:$("[name=form-structure]",PF.obj.modal.selectors.root).val()}},!0},deferred:{success:function(e){var t=e.responseJSON;PF.fn.growl.expirable(PF.fn._s("Import job ID %s added successfully, you can process the import now",t.import.id));var a=CHV.fn.import.parseTemplate(t.import);a.insertAfter(CHV.obj.import.sel.header,CHV.obj.import.sel.root),$(CHV.obj.import.sel.root).removeClass("hidden")},error:function(e){CHV.fn.import.errorHandler(e.responseJSON)}}},process:{abortAll:function(e){e=parseInt(e);if(e in CHV.obj.import.working){for(var t in CHV.obj.import.aborted.push(e),CHV.obj.import.working[e].threads)CHV.obj.import.working[e].threads[t].abort();PF.fn.growl.expirable("Aborted all threads for import job ID "+e+", changing status now"),"interval"in CHV.obj.import.working[e]&&(clearInterval(CHV.obj.import.working[e].interval),"abort"in CHV.obj.import.working[e].stats&&CHV.obj.import.working[e].stats.abort())}},xhr:function(e,t){e=parseInt(e);console.log("New XHR for thread #"+t+" for import job ID"),e in CHV.obj.import.working==0&&(CHV.obj.import.working[e]={threads:{},interval:{},stats:{}}),CHV.obj.import.working[e].threads[t]=$.ajax({type:"POST",data:{action:"importProcess",id:e,thread:t}}),CHV.obj.import.working[e].threads[t].complete(function(a){if(400!=a.status){$("[data-id="+e+"]",CHV.obj.import.sel.root).data("status");-1==$.inArray(e,CHV.obj.import.aborted)&&CHV.fn.import.process.xhr(e,t)}else CHV.fn.import.errorHandler(a.responseJSON)})},load:function(){return $("html").data("modal-form-values",""),!0},submit:function(e){var t=PF.obj.modal.selectors.root,a=$("[name=form-threads]",t).val();return 0==a?(PF.fn.growl.expirable(PF.fn._s("Select number of threads")),!1):(PF.obj.modal.form_data={action:"importEdit",id:e,threads:a,values:{status:"working"}},!0)},deferred:{success:function(e){var t=e.responseJSON;PF.fn.growl.expirable(PF.fn._s("Import job ID %s is being processed now",t.import.id));var a=CHV.fn.import.parseTemplate(t.import);$("[data-id="+t.import.id+"]",CHV.obj.import.sel.root).replaceWith(a);for(var o=parseInt(t.request.threads),i=1;i<=o;i++)CHV.fn.import.process.xhr(t.import.id,i);CHV.obj.import.working[t.import.id].interval=setInterval(function(){CHV.fn.import.updateStats(t.import.id)},5e3)},error:function(e){var t=e.responseJSON;900==t.error.code?(console.log("Aborting current working process (status changed)"),CHV.fn.import.process.abortAll(t.id)):CHV.fn.import.errorHandler()}}},delete:{submit:function(e){return PF.obj.modal.form_data={action:"importDelete",id:e},!0},deferred:{success:function(e){var t=e.responseJSON;PF.fn.growl.call(PF.fn._s("Import ID %s removed",t.import.id)),$("[data-id="+t.import.id+"]",CHV.obj.import.sel.root).remove(),1==$("li",CHV.obj.import.sel.root).size()&&$(CHV.obj.import.sel.root).addClass("hidden")},error:function(e){CHV.fn.import.errorHandler(e.responseJSON)}}},parseTemplate:function(e,t){var a=CHV.obj.import.rowTpl;for(var o in CHV.obj.import.importTr)void 0!==e[o]&&(a=a.replaceAll("%"+o+"%",e[o]));a=a.replaceAll("%parse%",e.options.root),a=a.replaceAll("%shortParse%",e.options.root.charAt(0)),a=a.replaceAll("%displayStatus%",CHV.obj.import.statusesDisplay[e.status]);var i=$($.parseHTML(a)).attr("data-object",JSON.stringify(e));return i}}; \ No newline at end of file diff --git a/app/lib/classes/class.import.php b/app/lib/classes/class.import.php new file mode 100644 index 0000000..f8b3bb7 --- /dev/null +++ b/app/lib/classes/class.import.php @@ -0,0 +1,1005 @@ + + + + Copyright (C) Rodolfo Berrios A. All rights reserved. + + BY USING THIS SOFTWARE YOU DECLARE TO ACCEPT THE CHEVERETO EULA + http://chevereto.com/license + + --------------------------------------------------------------------- */ + +namespace CHV; + +use G; +use Exception; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; +use FilterIterator; +use FilesystemIterator; +use LogicException; + +class Import +{ + const DEBUG = 1; + const PATH = G_APP_PATH . 'importer/'; + const PATH_JOBS = self::PATH . 'jobs/'; + const CHUNK_SIZE = 500; // How many items to iterate (directoryIterator) + const METADATA_KEY_TYPES = ['album' => 'albumData', 'user' => 'userData', 'image' => 'imageData']; + + protected static $imageExtensions; + + protected static $imageExtensionsRegex; + + protected static $max_execution_time; + + public $path; + + /** + * [root => users] Parse root folders as /user/album?/file.jpg + * [root => albums] Parse root folders as /album/file.jpg + * [root => plain] Don't parse folders /file.jpg + * @var string[] + */ + public $options = ['root' => 'users']; + protected $logFile; + protected $import; + protected $increment; + protected $components; + + public function __construct() // $path, $thread=1 + { + if (!isset(static::$max_execution_time)) { + @set_time_limit(60); + @ini_set('max_execution_time', 60); + static::$max_execution_time = ini_get('max_execution_time'); + static::$imageExtensions = Image::getEnabledImageFormats(); + static::$imageExtensionsRegex = '/\.(' . implode('|', static::$imageExtensions) . ')$/i'; + } + } + + public static function refresh() + { + $db = DB::getInstance(); + $db->query('UPDATE ' . DB::getTable('imports') . ' SET import_status = "working" WHERE import_continuous = 1 AND DATE_ADD(import_time_updated, INTERVAL 1 MINUTE) <= UTC_TIMESTAMP();'); + $db->exec(); + } + + public static function autoJobs() + { + return DB::get('imports', ['continuous' => 1, 'status' => 'working'], 'AND', ['field' => 'time_updated', 'order' => 'asc']); + } + + public static function imageExtensionsRegex() + { + return static::$imageExtensionsRegex; + } + /** + * @return Array parsedImport + */ + public function get() + { + if ($this->import = static::getSingle($this->id)) { + $this->path = $this->import['path']; + $this->options = $this->import['options'] ? unserialize($this->import['options']) : null; + $this->parsedImport = array_merge($this->import, ['options' => $this->options]); + return $this->parsedImport; + } else { + throw new Exception('Import ID ' . $this->id . 'not found', 100); + } + } + /** + * @return void + */ + public function checkPath() + { + $this->path = G\sanitize_path_slashes(rtrim($this->path, '/')); + $rootPath = G\sanitize_path_slashes(rtrim(G_ROOT_PATH, '/')); + if (stream_resolve_include_path($this->path) == false) { + throw new Exception("Target path $this->path doesn't exists", 100); + } + $message = "Target path $this->path can't be used for importing"; + if ($this->path == rtrim(CHV_PATH_IMAGES, '/')) { + throw new Exception("$message (image upload path)", 101); + } + if ($this->path == $rootPath) { + throw new Exception("$message (application root path)", 101); + } + if (G\starts_with($this->path, $rootPath)) { + throw new Exception("$message (application folder ancestor)", 103); + } + if (G\starts_with($rootPath . '/importing', $this->path)) { + throw new Exception("$message (automatic importing path)", 104); + } + } + public function delete() + { + $import = static::getSingle($this->id); + if ($import['continuous'] == 1) { + throw new LogicException("Import of type continuous can't be deleted"); + } + DB::delete('importing', ['import_id' => $this->id]); + return DB::delete('imports', ['id' => $this->id]); + } + /** + * @return import id + */ + public function add() + { + $this->checkPath(); + if (!(new FilesystemIterator($this->path))->valid()) { + throw new Exception("$this->path is empty", 101); + } + if ($get = static::getSingle($this->path, 'path')) { + throw new Exception('Import ID ' . $get['id'] . ' is blocking the addition of a new importer job under the ' . $this->path . ' path', 102); + } + $this->id = DB::insert('imports', [ + 'time_created' => G\datetimegmt(), + 'path' => $this->path, + 'options' => $this->options ? serialize($this->options) : null, + 'status' => 'queued', + ]); + return $this->id; + } + /** + * Static aux helper for get stuff + */ + public static function getSingle($var, $by = 'id') + { + $db = DB::getInstance(); + switch ($by) { + case 'id': + $where = 'import_id=:var'; + break; + case 'path': + $where = "import_path=:var AND import_status NOT IN ('completed', 'canceled')"; + break; + } + $db->query("SELECT * FROM " . DB::getTable('imports') . " WHERE $where LIMIT 1;"); + $db->bind(':var', $var); + if ($import = $db->fetchSingle()) { + return DB::formatRows($import); + } + } + + public static function getContinuous() + { + if ($all = DB::get('imports', ['continuous' => 1])) { + $format = DB::formatRows($all); + foreach ($format as &$v) { + $v['options'] = $v['options'] ? unserialize($v['options']) : null; + } + return $format; + } + } + + public static function getOneTime() + { + if ($all = DB::get('imports', ['continuous' => 0])) { + $format = DB::formatRows($all); + foreach ($format as &$v) { + $v['options'] = $v['options'] ? unserialize($v['options']) : null; + } + return $format; + } + } + + public function edit($values = null) + { + if (isset($values['options'])) { + $values['options'] = serialize($values['options']); + } + $values['time_updated'] = G\datetimegmt(); + DB::update('imports', $values, ['id' => $this->id]); + } + + protected function getImportingLock($pathName) + { + $this->logProcess("About to get DB importing lock for $pathName"); + if ($importing = DB::get('importing', ['path' => $pathName])[0]) { + return DB::formatRows($importing); + }; + } + + private function getLogPath() + { + return static::PATH_JOBS . $this->id . '/'; + } + + public function reset() + { + $this->edit([ + 'status' => 'working', + 'users' => '0', + 'images' => '0', + 'albums' => '0', + 'errors' => '0', + 'started' => '0', + ]); + foreach (['errors', 'process'] as $type) { + $filename = $this->getLogPath() . $type . '.txt'; + if (!file_exists($filename)) { + continue; + } + if (!@unlink($filename)) { + throw new Exception('File ' . $filename . " can't be removed", 100); + } + } + $this->get(); + } + + public function resume() + { + if (!$this->import['continuous']) { + throw new Exception('Only continuous importing can be resumed', 100); + } + $this->edit(['status' => 'working']); + $this->get(); + } + + /** + * Logger helper + * Writes logs in importer/jobs/ with filenames like error.2.txt for + * errors being catched by the thread id "2" + */ + protected function log($message, $type) + { + $logPath = $this->getLogPath(); + if (stream_resolve_include_path($logPath) == false) { + @mkdir($logPath, 0755, true); + } + // $logFile = $logPath . $type . '.' . $this->thread . '.txt'; + $logFile = $logPath . $type . '.txt'; + $message = time() . ' - ' . '[Thread #' . $this->thread . '] ' . $message; + $fpc = file_put_contents($logFile, $message . "\n", FILE_APPEND); + return $fpc !== false; + } + + /** + * Log process action, useful for debugging + */ + public function logProcess($message, $logError = false) + { + if ($logError) { + $this->log($message, 'errors'); + } + $this->log($message, 'process'); + } + + /** + * Log error + */ + public function logError($message) + { + if ($this->import['errors'] == 0) { + $this->logProcess('Adding "errors" flag to import row'); + $this->edit(['errors' => 1]); + } + return $this->log($message, 'errors'); + } + /** + * Issue or resume a target import job + */ + public function process() + { + // only paused and queued reach here... + if (in_array($this->import['status'], ['paused', 'canceled', 'completed'])) { + throw new Exception('Import job ID ' . $this->id . ' is ' . $this->import['status'], 900); + return; + } + $values = []; + $this->metadata = []; + $this->parsed = []; + $this->logProcess('Import process started (job ID ' . $this->id . ')'); + $this->logProcess(str_repeat('=', 80)); + if ($this->import['started'] == 0) { + $values['started'] = 1; + $this->logProcess('Import row has been updated adding the "started" flag'); + } + if ($this->import['status'] != 'working') { + $values['status'] = 'working'; + } + if ($values) { + $this->edit($values); + $this->get(); + } + $killed = false; + $i = 0; + $parsedItems = 0; + $cwd = null; // Current Working Directory + $pwd = null; // Previous Working Directory + foreach ($this->getItems() as $fileinfo) { + if (in_array($this->import['status'], ['queued', 'working']) == false) { + throw new Exception('Import job ID ' . $this->id . ' is ' . $this->import['status'], 900); + return; + } + if ($i > 0) { + $this->logProcess(str_repeat('-', 80)); + // Refresh $import on each loop, needed for hot editing + $this->get(); + } + if ($parsedItems > static::CHUNK_SIZE - 1 || isSafeToExecute(static::$max_execution_time) == false) { + $abortMessage = ($parsedItems > static::CHUNK_SIZE - 1) ? 'Chunk limit reached (' . static::CHUNK_SIZE . ')' : 'About to run out of time'; + $this->logProcess("$abortMessage, breaking iteration now"); + $killed = true; + break; + } + $pathHandle = null; + $insertId = null; + $parsed = false; + $i++; + $this->setParse(null); + $pathName = $fileinfo->getPathName(); + $this->logProcess("Current iteration: $pathName"); + if (!file_exists($pathName)) { + $this->logProcess("PathName is gone, continue iteration"); + continue; + } + if ($fileinfo->isFile()) { + // File already locked + if ($lock = static::getImportingLock($pathName)) { + $this->logProcess("Concurrency: $pathName is locked by another process, continue iteration"); + continue; + } else { + if ($fileinfo->isWritable()) { + // Insert DB lock + try { + DB::insert('importing', [ + 'import_id' => $this->id, + 'path' => $pathName, + 'content_type' => 'image', + 'content_id' => 0, + ]); + } catch (Exception $e) { + $this->logProcess("Unable to insert DB lock for $pathName: " . $e->getMessage() . ', breaking iteration'); + $killed = true; + break; + } + } + } + } + if (!file_exists($pathName)) { + $this->logProcess("PathName is gone!, continue iteration"); + continue; + } + if (!$fileinfo->isWritable()) { + $this->logProcess("Path $pathName is not writable, the job #" . $this->id ." must be canceled", true); + $this->edit(['status' => 'canceled', 'errors' => '1']); + $this->logProcess('Updating importing status to canceled (the error must be addressed)'); + $killed = true; + break; + } + $component = $this->getComponent($fileinfo); + $this->parseComponent($component); + if ($this->parse == null) { + $this->logProcess('No parse applicable, continue iteration'); + continue; + } + // For images, we remove the file.ext part + if ($fileinfo->isFile() && is_array($this->components)) { + array_pop($this->components); + } + // Analyze $cwd (at this point, containing previous scanned dir) + if ($cwd !== null) { + $pwd = $cwd; + $this->logProcess("Previous working directory is: $pwd"); + } + if ($fileinfo->isDir()) { + $cwd = $pathName; + } else { + $cwd = $fileinfo->getPath(); // no filename + } + $this->logProcess("Current working directory is: $cwd"); + /** + * On directory change, check and delete the already parsed directories + */ + if ($pwd && $pwd != $cwd) { + $this->logProcess('Directory changed, about to detect if the previous directory should be removed or not'); + $delete_dir = null; + // Detect kind of jump + $pwd_explode = explode('/', ltrim($pwd, '/')); + $cwd_explode = explode('/', ltrim($cwd, '/')); + $cnt_pwd = count($pwd_explode); + $cnt_cwd = count($cwd_explode); + switch (true) { + case $cnt_pwd > $cnt_cwd: + $delete_dir = $pwd; + $this->logProcess("$delete_dir should be removed"); + break; + case $cnt_pwd < $cnt_cwd: + $this->logProcess('Entering sub-directory, nothing to remove yet'); + break; + case $cnt_pwd == $cnt_cwd && $pwd != $cwd: + $this->logProcess("Entering sibling directory, $pwd should be removed"); + $delete_dir = $pwd; + break; + } + if ($delete_dir) { + $this->removeDir($delete_dir); + } + } + /** + * Flatenize deeps, used to ignore sub-directories beyond the base + * structure. + */ + if ($this->options['root'] == 'plain') { + $pathHandle = null; + } else { + $pathHandle = rtrim($this->path, '/') . '/'; // The actual path used for lock, relative to importing path + if (strpos($component, '/') !== false) { // /some/dir/ + // /0/1/2/3/n... + switch ($this->options['root']) { + case 'users': // /0:user/1:album/ + if ($this->components[2] == null) { + $pathHandle .= implode('/', $this->components); + } else { + $pathHandle .= $this->components[0] . '/' . $this->components[1]; + $this->logProcess("Extra sub-directory structure detected, path handle has been capped to 2 levels"); + } + break; + case 'albums': + $pathHandle .= $this->components[0]; + $this->logProcess("Extra sub-directory structure detected, path handle has been capped to 1 level"); + break; + } + } else { // No sub-dirs here, just files in / + $this->logProcess("Plain directory structure detected in component"); + if ($fileinfo->isFile()) { + $pathHandle = null; // file.ext -> null + } + // Why this?? + if ($fileinfo->isDir()) { + $pathHandle .= $component; // /dir + } + } + $this->logProcess('Path handle is: ' . ($pathHandle ?: 'null')); + } + /** + * If we are handling a folder, check for any locks preventing dir + * parsing + */ + if ($pathHandle) { + if ($lock = static::getImportingLock($pathHandle)) { + $this->logProcess("Path handle $pathHandle is already locked in DB"); + /** + * No content id: The lock is being created. Terminate. + */ + if ($lock['content_id'] == 0) { + $this->logProcess("Content id has not been set, another process is working in this same path, delaying operation"); + die(); + break; + } + /** + * Content id: This folder has been parsed. Get the content + * id + type associated to this dir + */ + $content_id = $lock['content_id']; + $content_type = $lock['content_type']; + $this->logProcess("Content ID ($content_type): $content_id (taken from DB lock)"); + } else { + /** + * Note: No image should be here anyway... + */ + if ($this->parse == 'image') { + $this->logProcess("This shouldn't be loged!!!!! PANIC!"); + break; + } + /** + * Try to create the lock AND parse path contents + */ + try { + $this->logProcess("Path handle $pathHandle is not locked, about to create DB lock for it"); + // Insert DB lock + $lockId = DB::insert('importing', [ + 'import_id' => $this->id, + 'path' => $pathHandle, + 'content_type' => $this->parse, + 'content_id' => 0, // dummy + ]); + $this->logProcess('DB lock inserted (' . $lockId . '), about to parse directory as ' . $this->parse); + $this->parseMetadata($cwd . '/metadata.json'); + // TODO: Always parse metadata updates (if needed) + // Switch depending on dir kind + switch ($this->parse) { + case 'user': + // By default we look for matching users... + $userLookup = true; + $username = basename($pathHandle); + $username_max_length = Settings::get('username_max_length'); + $username_min_length = Settings::get('username_min_length'); + // Replace spaces + $usernameClean = preg_replace('/\s+/', '_', $username); + // Get only \w + $usernameClean = preg_replace('/\W/', null, $usernameClean); + // Make sure to fullfill the limit + $usernameClean = substr($usernameClean, 0, $username_max_length); + // Add some padding + if (strlen($usernameClean) < $username_min_length) { + $usernameClean .= '_' . G\random_string($username_min_length - $usernameClean); + } + // Folder name doesn't satisfy a valid username string + if ($username != $usernameClean) { + $this->logProcess("Username $username is invalid username string, switching to $usernameClean"); + // Don't look, just create a new user + $userLookup = false; + } + $parsed = array_merge([ + 'username' => $username, + 'registration_ip' => '127.0.0.1', + ], $this->parsed); + // If username exists, assing its $content_id + if ($userLookup && $user = User::getSingle($username, 'username')) { + $this->logProcess("Username $username already exists"); + $insertId = $user['id']; + if ($this->parsed !== []) { + $this->logProcess("About to update $username ($insertId) with parsed data " . var_export($this->parsed, true)); + User::update($insertId, $this->parsed); + $this->logProcess("Updated parsed user metadata"); + } + } else { + // Make sure to insert a new user + $u = 0; + while (User::getSingle($usernameClean, 'username')) { + $this->logProcess("Must try a different username as $usernameClean already exists"); + // It strips the number previously appended, so we get user1, user2, and so on. + if ($u > 0) { + $usernameClean = G\str_replace_last($u, null, $usernameClean); + } + // Soon as this gets too big, we trim the last $usernameClean char + if (strlen($usernameClean . $u) > $username_max_length) { + $usernameClean = substr($usernameClean, 0, -1); + } + $u++; + $usernameClean .= $u; + $parsed['username'] = $usernameClean; + } + $this->logProcess("About to insert user $usernameClean"); + $insertId = User::insert($parsed); + $this->logProcess("Username $usernameClean (id $insertId) inserted"); + $user = User::getSingle($insertId, 'id'); + } + if ($user && $this->metadata['profileImages']) { + try { + // Insert user assets (profile images) + foreach ($this->metadata['profileImages'] as $k => $v) { + $userAsset = [ + 'name' => 'asset.jpg', + 'type' => 'image/jpeg', // dummy + 'tmp_name' => $pathName . '/.assets/' . $v, + 'error' => 0, + 'size' => 1, + ]; + $this->logProcess("Uploading user $k image"); + User::uploadPicture($user, $k, $userAsset); + } + } catch (Exception $e) { + $this->logProcess("Failed to upload user $k: " . $e->getMessage()); + } + } + break; + case 'album': + $albumName = ltrim(basename($pathHandle), '/'); + // Username = Album parent dir + $user_lock = static::getImportingLock(dirname($pathHandle)); + $user_id = $user_lock ? $user_lock['content_id'] : null; + $db = DB::getInstance(); + $query = 'SELECT album_id FROM ' . DB::getTable('albums') . ' WHERE album_name = :name AND '; + if ($user_id) { + $query .= 'album_user_id = :user_id'; + } else { + $query .= 'album_user_id IS NULL'; + } + $query .= ' ORDER BY album_id DESC;'; + $db->query($query); + $db->bind(':name', $albumName); + if ($user_id) { + $db->bind(':user_id', $user_id); + } + $album = $db->fetchSingle(); + if ($album) { + $insertId = $album['album_id']; + $this->logProcess("Album $albumName already exists (id $insertId)"); + // Album::update($insertId, $this->parsed); + $this->logProcess("Updated parsed album metadata"); + } else { + $parsed = array_merge([ + 'name' => $albumName, + 'user_id' => $user_id, + 'privacy' => 'public', + 'description' => '', + 'password' => null, + 'creation_ip' => '127.0.0.1' + ], $this->parsed); + $this->logProcess('About to insert album "' . $parsed['name'] . '" under user_id ' . ($user_id ?: 'guest')); + $insertId = Album::insert($parsed); + $this->logProcess("Album $username inserted (id $insertId)"); + } + break; + } + // Update lock content_id + $this->logProcess("About to update importing table (current job)"); + DB::update('importing', ['content_id' => $insertId], ['id' => $lockId]); + $this->logProcess("Importing table updated"); + // continue; + } catch (Exception $e) { + $this->logProcess("Process interrupted when parsing $pathHandle, check the error log"); + $this->logError('Exception ' . $e->getMessage() . ' thrown when parsing directory ' . $pathHandle); + // If $lockId == insertion failed (user or album) + if ($lockId) { + $this->logProcess("Unable to parse directory, about to release DB lock ($lockId)"); + DB::delete('importing', ['id' => $lockId]); + $this->logProcess("DB lock ($lockId) released"); + } else { + $this->logProcess("Unable to insert DB lock for $pathHandle: " . $e->getMessage() . ', continue iteration'); + } + continue; + } + } + } + /** + * Image parsing goes now... + */ + if ($this->parse == 'image') { + $this->logProcess('About to parse image: ' . $pathName); + // Forged $_FILES for Image::uploadToWebsite() + $parsed = [ + 'name' => $fileinfo->getFilename(), + 'type' => 'image/jpeg', // dummy + 'tmp_name' => $pathName, + 'error' => 0, + 'size' => 1, // $fileinfo->getSize() sometimes fails... + ]; + $user_id = null; + $params = []; + // Has a parent context (user, user/album OR album) + // Note: $content_id has being set from DB lock data. + if ($pathHandle && $content_type && $content_id) { + $this->logProcess("Using DB lock for content context data (id and type)"); + if ($content_type == 'user') { + $user_id = $content_id; + } else { + $params['album_id'] = $content_id; + $album = Album::getSingle($content_id, false, false); + if ($album['user_id']) { + $user_id = $album['user_id']; + } + } + } + try { + $insertId = Image::uploadToWebsite($parsed, $user_id, $params, false, '127.0.0.1'); + $this->logProcess("Image ID $insertId inserted"); + // Parse image date only after image insert + $this->parseMetadata(G\change_pathname_extension($pathName, 'json')); + // $this->metadata contains categoryId // category {} + if ($this->parsed['category_id'] == false) { + $this->logProcess("No implicit categoryId property found, about to check category metadata object"); + if ($urlKey = $this->metadata['category']['urlKey']) { + $this->logProcess("Explicit urlKey property declared, determine its category ID (create if doesn't exists)"); + if ($categoryId = DB::get('categories', ['url_key' => $this->metadata['category']['urlKey']])[0]['category_id']) { + $this->logProcess("Category ID set: $categoryId"); + } else { + $category = [ + 'url_key' => $urlKey, + 'name' => $this->metadata['category']['name'] ?: $urlKey, + 'description' => $this->metadata['category']['description'] ?: null + ]; + try { + $categoryId = DB::insert('categories', $category); + $this->logProcess("Category ID: $categoryId created"); + } catch (Exception $e) { + $this->logProcess("Unable to create category $urlKey: " . $e->getMessage(), true); + } // sshhh + } + if ($categoryId) { + $this->parsed['category_id'] = $categoryId; + } + } + } + if ($this->parsed) { + Image::update($insertId, $this->parsed); + $this->logProcess("Image updated with parsed metadata"); + } + // $this->parse updates image info + } catch (Exception $e) { + if ($e->getCode() == 666) { + $this->logProcess($e->getMessage()); + } else { + $this->logProcess('Failed to insert image, exception thrown: ' . $e->getMessage()); + $this->logError("Image insertion failed for $pathName: " . $e->getMessage()); + if (stream_resolve_include_path($pathName) && @unlink($pathName) == false) { + $this->logProcess("Failed to remove $pathName from importing path", true); + } + $this->logProcess("Image $pathName removed from importing path", true); + } + } + } + if ($insertId) { + $this->logProcess('Inserted content, items++'); + DB::increment('imports', [$this->parseGroup => '+1'], ['id' => $this->id]); + $this->edit(); // updates timestamp + $parsedItems++; + } + } // foreach ($this->getItems() as $fileinfo) { + // Nothing left to parse, complete the process and wipe the path + if ($killed == false && ($i == 0 || $parsedItems == 0)) { + $this->logProcess('Nothing parsed in ' . $this->path); + try { + $this->edit(['status' => 'completed']); + DB::delete('importing', ['import_id' => $this->id]); + $this->logProcess('DB status changed to completed'); + if ($this->import['continuous']) { + $this->logProcess('DB status should be changed to "working" to keep this job alive'); + } + } catch (Exception $e) { + $this->logProcess('Error updating DB: ' . $e->getMessage(), true); + } + if ($this->import['continuous']) { + if ($this->removeDir($this->path, false) == false) { + $this->logProcess('Unable to remove ' . $this->path . ' contents', true); + } + } else { + if ($this->removeDir($this->path) == false) { + $this->logProcess('Unable to remove ' . $this->path, true); + } + } + } + $this->logProcess('Chunked process ended' . ($killed ? ' (killed)' : null)); + $this->logProcess(str_repeat('=', 80)); + } + + public function getItems($path = null) + { + if ($path == null) { + $path = $this->path; + } + $iterator = new RecursiveDirectoryIterator($path); + $iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS); + return new ImporterFilterIterator(new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST)); + } + + protected function setParse($parse) + { + $this->parse = $parse; + $this->parseGroup = $parse == null ? null : ($this->parse . 's'); + if ($parse !== null) { + $this->logProcess("Parse has been set to: $parse"); + } + } + + /** + * Determine the item compontent + * + * @param $filepath string Filepath + */ + public function getComponent($filepath) + { + $component = G\str_replace_first($this->path, null, (string) $filepath); + $return = ltrim(rtrim($component, '/'), '/'); + $this->logProcess("Component is: $return"); + return $return; + } + + /** + * Parse path component + * + * @param string $component Path section (without the $importer path) + */ + public function parseComponent($component) + { + $this->logProcess("About to parse component for $component (root: " . $this->options['root'] . ')'); + $this->components = explode('/', $component); // /0/1/2/3/n... + $this->setParse(null); + if (preg_match(static::$imageExtensionsRegex, $component) == true) { + $this->setParse('image'); + return; + } + $component_cnt = count($this->components); + switch ($this->options['root']) { + case 'users': + switch ($component_cnt) { + case 1: + $this->setParse('user'); + break; + case 2: + $this->setParse('album'); + break; + } + break; + case 'albums': + switch ($component_cnt) { + case 1: + $this->setParse('album'); + break; + } + break; + } + if ($this->parse == null) { + $this->logProcess("Parse is null"); + } + } + /** + * Recursive directory remove (files and folders) + * + * @param string $dir Directory to wipe + * @return mixed TRUE if the directory was wiped *or empty. Array of items + * failed to delete + */ + protected function removeDir($dir, $removeSelf = true) + { + $contents = !$removeSelf ? ' contents' : ''; + $failed = []; + $this->logProcess("About to remove $dir directory$contents (recursively)..."); + if (stream_resolve_include_path($dir) == false) { + $this->logProcess("The directory doesn't exists, no need to remove it"); + return true; + } + $isDirEmpty = !(new FilesystemIterator($dir))->valid(); + if ($isDirEmpty) { + $this->logProcess("The directory is already empty, no need to iterate its contents"); + if ($removeSelf) { + $res = @rmdir($dir); + } else { + $res = true; + } + } else { + $this->logProcess("The directory is not empty, prepate to iterate and remove its contents"); + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), + RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ($files as $fileinfo) { + $filepath = $fileinfo->getRealPath(); + $todo = $fileinfo->isDir() ? 'rmdir' : 'unlink'; + $type = $fileinfo->isDir() ? ('directory' . $contents) : 'file'; + $this->logProcess("Loop: Removing $type $filepath ($todo)"); + $res = @$todo($filepath); + if ($res == false) { + $this->logProcess("Unable to remove $filepath", true); + $failed[] = ['filepath' => $filepath, 'isDir' => $fileinfo->isDir()]; + } + } + if ($removeSelf) { + $res = @rmdir($dir); + } else { + $res = true; + } + } + if ($res == true) { + $this->logProcess("Directory $dir$contents removed"); + return true; + } + return $failed; + } + + /** + * Metadata parsing, used to inject user, album and image data + */ + public function parseMetadata($filename, $type = null) + { + $this->metadata = []; + $this->parsed = []; + if (stream_resolve_include_path($filename) == false) { + // Nothing to do here! + return; + } + if ($type == null) { + $type = $this->parse; + } + if (array_key_exists($type, static::METADATA_KEY_TYPES) == false) { + $this->logProcess("Error: Invalid type $type metadata key", true); + return; + } else { + $metadataKey = static::METADATA_KEY_TYPES[$type]; + } + if (is_readable($filename) == false) { + $this->logProcess("File reading error: $filename is not readable", true); + return; + } + if ($contents = @file_get_contents($filename)) { + $this->logProcess("$filename readed"); + $metadata = json_decode($contents, true); + if (json_last_error() !== JSON_ERROR_NONE) { + $this->logProcess("File format error: $filename contains invalid JSON", true); + $metadata = null; + } + } else { + $this->logProcess("Unable to read $filename", true); + return; + } + if ($metadata = $metadata[$metadataKey]) { + // [0 => 'TYPE', keys] Wow, such typing. Very modern. + switch ($type) { + case 'album': + $tr = [ + 'name' => [0 => 'string', 'title'], + 'description' => [0 => 'string', 'description'], + 'privacy' => [0 => 'string', ['privacy', 'type']], + 'password' => [0 => 'string', ['privacy', 'password']], + ]; + break; + case 'user': + $tr = [ + 'name' => [0 => 'string', 'name'], + 'email' => [0 => 'string', 'email'], + 'website' => [0 => 'string', 'website'], + 'bio' => [0 => 'string', 'bio'], + 'facebook_username' => [0 => 'string', ['networks', 'facebook']], + 'twitter_username' => [0 => 'string', ['networks', 'twitter']], + 'timezone' => [0 => 'string', 'timezone'], + 'language' => [0 => 'string', 'language'], + 'is_private' => [0 => 'boolean', 'is_private'], + 'is_manager' => [0 => 'boolean', 'is_manager'], + 'is_admin' => [0 => 'boolean', 'is_admin'], + ]; + break; + case 'image': + $tr = [ + 'title' => [0 => 'string', 'title'], + 'description' => [0 => 'string', 'description'], + 'category_id' => [0 => 'integer', 'categoryId'], + 'nsfw' => [0 => 'boolean', 'nsfw'], + ]; + break; + } + $parsed = []; + // date->timestamp must be handled as date + date_gmt + // Assing the parse props based on the $tr array + foreach ($tr as $metaProp => $metaValue) { + $propValue = null; + $propType = $metaValue[0]; + $val = $metaValue[1]; + if ($propValue = $metadata[is_array($val) ? $val[0] : $val]) { + if (is_array($val) && is_array($propValue)) { + unset($val[0]); // Get rid of the parent (already taken just above) + foreach ($val as $k => $v) { + if ($propValue[$v] == false) { + break; + } + $propValue = $propValue[$v]; + } + } + } + if ($propValue) { + $gettype = gettype($propValue); + if ($gettype != $propType) { + $this->logProcess("Metadata error: Type $gettype provided, expected $propType for $metaProp"); + continue; + } + $parsed[$metaProp] = $propValue; + } + } + $this->metadata = $metadata; + $this->parsed = $parsed; + } else { + $this->logProcess("Metadata error: Missing metakey $metadataKey"); + } + return; + } +} + +// Accept images + folders +class ImporterFilterIterator extends FilterIterator +{ + protected $fileinfo; + public function accept() + { + $this->fileinfo = $this->getInnerIterator()->current(); + if ($this->fileinfo->isFile() && (preg_match(Import::imageExtensionsRegex(), $this->fileinfo) == false || $this->filterAssets())) { + return false; + } + if ($this->fileinfo->isDir() && $this->filterAssets()) { + return false; + } + return true; + } + protected function filterAssets() + { + return $this->fileinfo->getBasename() == '.assets' || basename($this->fileinfo->getPath()) == '.assets'; + } +} diff --git a/app/lib/integrity-check.php b/app/lib/integrity-check.php index 2114795..3f031ec 100644 --- a/app/lib/integrity-check.php +++ b/app/lib/integrity-check.php @@ -129,7 +129,7 @@ function check_system_integrity() } } else { // Can write? if (!is_writable($v)) { - $install_errors[] = 'No write permission in '.G\absolute_to_relative($v).' directory. Chevereto needs to be able to write in this directory.'; + $install_errors[] = 'No write permission for user '.get_current_user().' in '.G\absolute_to_relative($v).' directory. Chevereto needs to be able to write in this directory.'; } } } @@ -178,6 +178,10 @@ function check_system_integrity() } if (is_array($install_errors) && count($install_errors) > 0) { + if (access === 'cli') { + G\debug($install_errors); + die(255); + } Render\chevereto_die($install_errors); } } diff --git a/app/loader.php b/app/loader.php index 6653155..8c9021c 100644 --- a/app/loader.php +++ b/app/loader.php @@ -23,8 +23,6 @@ namespace CHV; use G; use Exception; -error_reporting(E_ALL); - if (!defined('access') or !access) { die('This file cannot be directly accessed.'); } diff --git a/app/routes/route.dashboard.php b/app/routes/route.dashboard.php index e4538ea..520e02c 100644 --- a/app/routes/route.dashboard.php +++ b/app/routes/route.dashboard.php @@ -44,11 +44,12 @@ $route = function ($handler) { $route_prefix = 'dashboard'; $sub_routes = [ - 'stats' => _s('Stats'), - 'images' => _s('Images'), - 'albums' => _s('Albums'), - 'users' => _s('Users'), - 'settings' => _s('Settings') + 'stats' => _s('Stats'), + 'images' => _s('Images'), + 'albums' => _s('Albums'), + 'users' => _s('Users'), + 'settings' => _s('Settings'), + 'bulk' => _s('Bulk importer'), ]; $default_route = 'stats'; @@ -75,7 +76,7 @@ $route = function ($handler) { ); } $route_menu['upgrade'] = [ - 'label' => '💎 Upgrade to premium', + 'label' => '⭐ Upgrade', 'id' => 'upgrade' ]; @@ -188,6 +189,7 @@ $route = function ($handler) { $chevereto_urls = [ 'Chevereto' => 'https://chevereto.com', _s('Community') => 'https://chevereto.com/community/', + _s('Collaboration') => 'https://chevereto.com/community/collaboration/', _s('Support') => 'https://chevereto.com/support', _s('Documentation') => 'https://v3-docs.chevereto.com/', _s('Changelog') => 'https://chevereto.com/changelog', diff --git a/app/routes/route.importer-jobs.php b/app/routes/route.importer-jobs.php new file mode 100644 index 0000000..9b05a81 --- /dev/null +++ b/app/routes/route.importer-jobs.php @@ -0,0 +1,43 @@ + + + + Copyright (C) Rodolfo Berrios A. All rights reserved. + + BY USING THIS SOFTWARE YOU DECLARE TO ACCEPT THE CHEVERETO EULA + http://chevereto.com/license + + --------------------------------------------------------------------- */ + +$route = function ($handler) { + try { + if (!CHV\Login::isAdmin()) { + $this->template = 'request-denied'; + return; + } + // Allow 3 levels only -> /importer-jobs/X/process + if ($handler->isRequestLevel(4)) { + return $handler->issue404(); + } + if (is_null($handler->request[0]) || is_null($handler->request[1])) { + return $handler->issue404(); + } + $filepath = G_ROOT_PATH . sprintf('app/importer/jobs/%1$s/%2$s.txt', $handler->request[0], $handler->request[1]); + if (!file_exists($filepath)) { + return $handler->issue404(); + } + if (!headers_sent()) { + header('Content-Type: text/plain'); + } + readfile($filepath); + exit; + } catch (Exception $e) { + G\exception_to_error($e); + } +}; diff --git a/app/routes/route.json.php b/app/routes/route.json.php index e97a25f..e08329d 100644 --- a/app/routes/route.json.php +++ b/app/routes/route.json.php @@ -34,6 +34,12 @@ $route = function ($handler) { $doing = 'deny'; } + if (in_array($doing, ['importAdd', 'importStats', 'importProcess', 'importEdit', 'importDelete']) && $logged_user['is_admin'] == false) { + throw new Exception(_s('Request denied'), 400); + } else { + $import = new CHV\Import(); + } + switch ($doing) { case 'deny': throw new Exception(_s('Request denied'), 403); @@ -1314,11 +1320,91 @@ $route = function ($handler) { } catch (Exception $e) { throw new Exception('Error: ' . $e->getMessage()); } - break; + break; + // Adds the importer job (path+options) + case 'importAdd': + if ($_REQUEST['path'] == false) { + throw new Exception('Missing path parameter', 100); + } + $import->path = $_REQUEST['path']; + if ($_REQUEST['options'] != false) { + $import->options = $_REQUEST['options']; + } + $import->add(); + $import->get(); + $json_array['status_code'] = 200; + $json_array['import'] = $import->parsedImport; + break; + // Common operations + case 'importStats': + case 'importProcess': + case 'importEdit': + case 'importDelete': + case 'importReset': + case 'importResume': + if ($_REQUEST['id'] == false) { + throw new Exception('Missing id parameter', 100); + } + $import->id = (int) $_REQUEST['id']; + $import->get(); + break; + case 'toggleTone': + if (!$logged_user) { + throw new Exception('Invalid request', 403); + } + CHV\User::update($logged_user['id'], ['is_dark_mode' => $logged_user['is_dark_mode'] ? 0 : 1]); + $json_array['status_code'] = 200; + $logged_user = CHV\User::getSingle($logged_user['id']); + $json_array['is_dark_mode'] = (bool) $logged_user['is_dark_mode']; + break; default: // EX X - throw new Exception(!G\check_value($_REQUEST['action']) ? 'empty action' : 'invalid action', !G\check_value($_REQUEST['action']) ? 0 : 1); - break; + throw new Exception(!G\check_value($doing) ? 'empty action' : 'invalid action', !G\check_value($doing) ? 0 : 1); + break; + } + if (isset($import->id)) { + switch ($doing) { + // Check the importer stats (id) + case 'importStats': + $json_array['status_code'] = 200; + $json_array['import'] = $import->parsedImport; + break; + // Issue/Resume import operation (id+thread) + case 'importProcess': + session_write_close(); + $import->thread = (int) $_REQUEST['thread'] ?: 1; + $import->process(); + $json_array['status_code'] = 200; + break; + // Edit import job (id,values) + case 'importEdit': + if ($_REQUEST['values'] == false) { + throw new Exception('Missing values parameter', 101); + } + if (is_array($_REQUEST['values']) == false) { + throw new Exception('Expecting array values', 102); + } + $import->edit($_REQUEST['values']); + $import->get(); + $json_array['import'] = $import->parsedImport; + $json_array['status_code'] = 200; + break; + case 'importReset': + $import->reset(); + $json_array['import'] = $import->parsedImport; + $json_array['status_code'] = 200; + break; + case 'importResume': + $import->resume(); + $json_array['import'] = $import->parsedImport; + $json_array['status_code'] = 200; + break; + case 'importDelete': + $import->delete(); + $json_array['status_code'] = 200; + $json_array['import'] = $import->parsedImport; + break; + } } // Inject any missing status_code if (isset($json_array['success']) and !isset($json_array['status_code'])) { diff --git a/app/themes/Peafowl/footer.php b/app/themes/Peafowl/footer.php index 85bce37..703c039 100644 --- a/app/themes/Peafowl/footer.php +++ b/app/themes/Peafowl/footer.php @@ -52,11 +52,11 @@ if (CHV\Login::isAdmin()) {
    -
  • 💎 Upgrade
  • +
  • ⭐ Upgrade
  • diff --git a/app/themes/Peafowl/snippets/listing.php b/app/themes/Peafowl/snippets/listing.php index 10e8127..940a35a 100644 --- a/app/themes/Peafowl/snippets/listing.php +++ b/app/themes/Peafowl/snippets/listing.php @@ -34,7 +34,7 @@ foreach ($tabs as $tab) { parse_str($QS, $current_page_qs); unset($current_page_qs['lang']); // Get rid of any ?lang= $current_url = $currentUrlPath . '?' . http_build_query($current_page_qs); - $page = intval($_GET['page'] ? $_GET['page'] : $current_page_qs['page'] ?: 1); + $page = intval(($_GET['page'] ? $_GET['page'] : $current_page_qs['page']) ?: 1); $pages = []; foreach (['prev', 'next'] as $v) { $params = $current_page_qs; diff --git a/app/themes/Peafowl/snippets/modal_login.php b/app/themes/Peafowl/snippets/modal_login.php deleted file mode 100644 index bedd97c..0000000 --- a/app/themes/Peafowl/snippets/modal_login.php +++ /dev/null @@ -1,54 +0,0 @@ - - - \ No newline at end of file diff --git a/app/themes/Peafowl/style.css b/app/themes/Peafowl/style.css index 7b08ae7..4084a8d 100644 --- a/app/themes/Peafowl/style.css +++ b/app/themes/Peafowl/style.css @@ -2331,6 +2331,7 @@ body.full--wh { [data-content="dashboard-imports"] [data-status="paused"] [data-action="pause"], [data-content="dashboard-imports"] [data-status="canceled"] [data-action="pause"], +[data-content="dashboard-imports"] [data-status="completed"] [data-action="pause"], [data-content="dashboard-imports"] [data-status="queued"] [data-action="pause"], [data-content="dashboard-imports"] [data-status="canceled"] [data-action="cancel"], [data-content="dashboard-imports"] [data-status="canceled"] [data-target="modal-process-import"], diff --git a/app/themes/Peafowl/style.min.css b/app/themes/Peafowl/style.min.css index e9f76c0..793638b 100644 --- a/app/themes/Peafowl/style.min.css +++ b/app/themes/Peafowl/style.min.css @@ -1 +1 @@ -body{padding-top:65px;padding-bottom:20px;min-height:100%;background:#fefefe;position:relative;font-family:Helvetica,Arial,sans-serif;font-size:14px}body.landing{min-height:500px;height:100%;padding:0;margin:0}.phone body.landing{min-height:auto}.js body.landing{overflow:hidden;opacity:0}.js body.landing.load{-webkit-transition:-webkit-transform .6s ease,opacity 350ms linear;-webkit-transition:opacity 350ms linear,-webkit-transform .6s ease;transition:opacity 350ms linear,-webkit-transform .6s ease;transition:transform .6s ease,opacity 350ms linear;transition:transform .6s ease,opacity 350ms linear,-webkit-transform .6s ease;opacity:1}#home-cover-content,#index .flex-center{opacity:0}.js body#index.load .flex-center,.js body.load #home-cover-content{transition:all .6s ease;transition-delay:150ms;opacity:1}.js body.loaded{overflow:auto}body.split{margin-top:0;padding-top:0}.content-width.fluid,.fluid .content-width{width:100%}@media (min-width:992px){.content-width.wide{max-width:none}}html.device-mobile .device-mobile--hide{display:none!important}html.device-nonmobile .device-nonmobile--hide{display:none!important}body#upload{padding-top:50px;padding-bottom:0;background-color:transparent}.image-viewer{text-align:center;background:#f7f7f7;position:relative;min-height:72px;overflow:hidden}.image-viewer-main{display:inline-block;vertical-align:middle}.image-viewer-container{display:block;margin:0 auto;position:relative}.image-viewer-container img{display:block;margin:0 auto;max-height:100%;width:auto}.js .image-viewer-container img{position:absolute;width:100%;height:auto}.image-viewer .btn-download{position:absolute;top:20px;right:20px;z-index:1}.image-viewer-navigation a{z-index:3}.image-viewer-navigation a:hover{background-color:#aaa;background-color:rgba(0,0,0,.3)}#image-viewer-loading,.viewer-loader{width:30px;height:30px;position:absolute;left:50%;top:50%;margin-left:-15px;margin-top:-15px;border-radius:100%;background:rgba(17,17,17,.9)}#image-viewer-loader{position:absolute;background:rgba(0,0,0,.5);border:2px solid rgba(255,255,255,.7);color:rgba(255,255,255,.9);font-size:13px;left:50%;top:50%;padding:8px 14px;border-radius:100px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);cursor:pointer;display:none}#image-viewer-loader:hover{background:rgba(0,0,0,.6);border-color:rgba(255,255,255,.8);color:#fff}#image-viewer-loader .btn-icon{position:relative;top:1px;font-size:12px}#image .top-bar-placeholder,.image-viewer.full-viewer{background:#111}.top-bar-white #image .top-bar-placeholder,.top-bar-white .image-viewer.full-viewer{background:#fff}.btn-like .btn.btn-liked,.btn-like .btn.btn-unliked{display:none}.btn-like[data-liked="0"] .btn-unliked{display:inline-block}.btn-like[data-liked="1"] .btn-liked{display:inline-block}.btn-follow .btn.btn-followed,.btn-follow .btn.btn-unfollowed{display:none}.btn-follow[data-followed="0"] .btn-unfollowed{display:inline-block}.btn-follow[data-followed="1"] .btn-followed{display:inline-block}#fullscreen-uploader-mask{z-index:99}.phone #fullscreen-uploader-mask{z-index:400}#anywhere-upload{z-index:400;scroll:auto;-webkit-overflow-scrolling:touch;-webkit-transition:transform .3s ease;-webkit-transition:-webkit-transform .3s ease;transition:-webkit-transform .3s ease;transition:transform .3s ease;transition:transform .3s ease,-webkit-transform .3s ease}#anywhere-upload.hidden-visibility iframe{visibility:hidden}.phone #anywhere-upload{z-index:500;height:100vh!important}#upload #anywhere-upload{overflow:hidden!important;height:auto!important}#upload .upload-box .upload-box-allowed-files,.phone .upload-box .upload-box-allowed-files{display:none}#upload .upload-box[data-queue-size="0"] .upload-box-allowed-files,.phone .upload-box[data-queue-size="0"] .upload-box-allowed-files{display:block}#upload .upload-box-allowed-files,.phone .upload-box-allowed-files{position:fixed;top:auto;left:0;right:0;text-align:center;bottom:10px}#anywhere-upload-paste{height:0;opacity:0;font-size:0}#anywhere-upload-paste *{display:none}.upload-box{border-bottom:0}.upload-box-queue{text-align:center;font-size:0;margin-top:35px;margin-bottom:35px}.upload-box-queue li{position:relative;text-align:center;display:inline-block;background:red;margin:5px;background:#efefef;-webkit-box-shadow:inset 0 2px 10px 0 rgba(0,0,0,.07);box-shadow:inset 0 2px 10px 0 rgba(0,0,0,.07)}.tone-dark .upload-box-queue li{background:#222}.upload-box-queue .block,.upload-box-queue li{border-radius:0}.ios .upload-box-queue .block,.ios .upload-box-queue li,.upload-box-queue .block.failed{border-radius:0}.upload-box-queue li,.upload-box-queue li.normal{width:110px;height:110px;font-size:14px;font-size:1rem}.upload-box-queue li.small{width:77px;height:77px;font-size:9px;font-size:.643rem}.upload-box-queue li.tiny{width:54px;height:54px;font-size:7px;font-size:.5rem}.upload-box-queue .block{width:100%;height:100%;top:0;left:0;overflow:hidden;position:absolute}.upload-box-queue a.image-link{display:none}.upload-box-queue .completed a.image-link{display:block;position:absolute;overflow:hidden;z-index:1;-webkit-transform:rotate(.000001deg)}.upload-box-queue .queue-item .block.edit,.upload-box-queue .queue-item .queue-item-button{display:block;position:absolute;cursor:pointer;z-index:100}.upload-box-queue .queue-item .queue-item-button .icon{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.upload-box-queue .queue-item.completed:hover .queue-item-button{display:none}.upload-box-queue .queue-item .queue-item-button{font-size:7px;width:21px;height:21px;line-height:23px;background:#fff;color:#333;border-radius:200px;left:-7px;-webkit-box-shadow:1px 1px 4px 0 rgba(0,0,0,.5);box-shadow:1px 1px 4px 0 rgba(0,0,0,.5)}.tone-dark .upload-box-queue .queue-item .queue-item-button{background:#333;color:#fff}.upload-box-queue .queue-item .queue-item-button.cancel{top:-7px}.upload-box-queue .queue-item .queue-item-button.edit{top:16px;font-size:9px}.upload-box-queue .big-icon{position:absolute;color:#dadada;font-size:5.36em;width:1em;height:1em;left:50%;top:50%;margin-left:-.5em;margin-top:-.5em;text-shadow:1px 1px 0 rgba(255,255,255,.9)}.tone-dark .upload-box-queue .big-icon{color:#444;text-shadow:1px 1px 0 rgba(0,0,0,.9)}.upload-box-queue .done,.upload-box-queue .preview{position:relative;overflow:hidden}.upload-box-queue .preview .canvas{position:absolute;top:50%;left:50%}.upload-box-queue .progress{position:absolute}.upload-box-queue .progress-bar,.upload-box-queue .progress-percent{height:100%}.upload-box-queue .uploading .progress-percent{display:block}.queue-item.uploading .block.edit,.queue-item.uploading .queue-item-button.edit,.queue-item.uploading.waiting .progress-percent{display:none}.upload-box-queue .progress-percent{font-family:arial,helvetica,sans-serif;font-size:2.86em;font-weight:400;color:#fff;text-shadow:2px 2px 10px rgba(0,0,0,.8);text-align:center;width:100%;height:1em;position:absolute;top:.86em;z-index:1;display:none}.upload-box-queue .progress-percent b{font-weight:700}.upload-box-queue .progress-percent span{font-size:.5em;font-weight:400;position:relative}.upload-box-queue .progress-bar{float:right;width:100%;display:none}.upload-box-queue .failed .result,.upload-box-queue .progress-bar{background:rgba(255,255,255,.65)}.upload-box-queue .uploading .progress-bar{display:block}.upload-box-queue .completed .result.done,.upload-box-queue .failed .result.failed{display:block}.upload-box-queue .result{position:absolute;z-index:1;display:none}.tone-dark .upload-box-queue .failed .result,.tone-dark .upload-box-queue .progress-bar{background:rgba(0,0,0,.65)}.upload-box-queue .result .icon{position:absolute;width:1em;font-size:3.429em;color:#fff;top:50%;left:50%;margin-top:-.5em;margin-left:-.5em;margin-left:-.5em;opacity:.92;text-shadow:none}.upload-box-queue .done .result .icon{text-shadow:2px 2px 6px rgba(0,0,0,.2)}.upload-box-queue .failed .result .icon{color:#e84c3d;font-size:3.429em}.upload-box-queue.queue-complete .cancel,.upload-box-queue.queue-complete .edit{display:none}#form-embed-toggle-combo,#uploaded-embed-toggle-combo{position:relative}#upload .top-bar{-webkit-box-shadow:none;box-shadow:none;border-bottom-color:transparent}#upload #anywhere-upload{background:0 0}#upload .upload-box{transform:none;position:static}body#upload [data-action=close-upload]{display:none!important}.upload-box.queueHasResults [data-action=cancel-upload],.upload-box.queueReady [data-action=close-upload],.upload-box.queueUploading [data-action=close-upload],.upload-box:not(.queueHasResults) [data-action=cancel-upload-remaining],.upload-box:not(.queueReady):not(.queueCompleted) [data-action=reset-upload],.upload-box:not(.queueUploading) [data-action^=cancel-upload],.upload-box:not([data-queue-size="0"]) [data-action=close-upload]{display:none}#background-cover{height:290px;background-color:#000;position:relative}.phone #background-cover{height:230px}#background-cover.no-background{background-color:#f9f9f9;background-image:none!important;padding:9px 0;height:auto;margin-top:50px}.tone-dark #background-cover.no-background{background:#101010}#background-cover-wrap{height:100%;overflow:hidden;position:relative}#background-cover .content-width{text-align:center}#change-background-cover{position:absolute;right:10px;bottom:10px}#user-background-upload{top:0;left:0;width:1px;height:1px}#background-cover-src{overflow:hidden;background-position:center center;background-size:cover}#background-cover .loading-placeholder,#background-cover-src{position:absolute;top:0;left:0;width:100%;height:100%}#background-cover .loading-placeholder{background:rgba(0,0,0,.8)}[data-privacy=public] .list-item-privacy{display:none}.list-item-thumbs li,.list-item-thumbs li a{display:block;height:auto;overflow:hidden}.list-item-thumbs li a{height:100%;background-size:cover;background-position:center center}.list-item-thumbs li img{width:100%;display:block}.input-copy{position:relative}.input-copy .btn-copy{font-size:10px;position:absolute;right:2px;top:8px;background:#fff;padding:0 4px;height:18px;line-height:18px;text-transform:uppercase;cursor:pointer;border-width:0 4px;border-style:solid;border-color:#fff;display:none}.input-copy .btn-copy:hover{background:#e5e5e5}.list-item-image-tools{position:absolute;right:0;top:0}.list-item.selected .list-item-image-tools li.tool-select .icon{color:#fff;background:#27ae60}.list-item-image-tools li{margin:2px;cursor:pointer;position:relative;height:2.4em;line-height:2.4em;font-size:1em;right:calc(-2.4em - 2px);transition:all .2s ease-in-out}.list-item .hover-display.list-item-image-tools{opacity:1}.list-item.selected li.tool-select,.list-item[data-flag=unsafe] li.tool-flag,html:not(.--idle) .list-item:hover .list-item-image-tools li{right:0}.list-item-image-tools li,.list-item-image-tools li *{display:block;color:inherit}.list-item-image-tools li span{float:right}.list-item-image-tools li .label{font-size:.86em}.list-item-image-tools li .btn-icon{font-size:1em}.list-item-image-tools li .label{text-transform:uppercase;padding-left:1em;padding-right:0;display:none;height:100%}.list-item-image-tools li:hover .label{display:block}.small-cols .list-item-image-tools li:hover .label{display:none}[data-flag=safe] li:hover .label-flag-safe,[data-flag=unsafe] li:hover .label-flag-unsafe{display:none}.unsafe-blur-on .list-item .list-item-thumbs li[data-flag=unsafe] a,.unsafe-blur-on [data-flag=unsafe] .image-container{filter:blur(5px);-webkit-filter:blur(5px);-webkit-transform:scale(1.04);transform:scale(1.04)}.unsafe-blur-on .list-item:hover .list-item-thumbs li[data-flag=unsafe] a,.unsafe-blur-on [data-flag=unsafe]:hover .image-container{filter:none;-webkit-filter:none}.list-item-image-tools li .btn-icon{width:2.4em;height:2.4em;line-height:2.4em;color:#fff;background:#000;background:rgba(0,0,0,.2);text-align:center}.list-item-image-tools li .label,.list-item-image-tools li:hover .btn-icon{color:#fff;background:rgba(0,0,0,.4)}.list-item.selected li.tool-select .btn-icon,[data-flag=unsafe] li.tool-flag .btn-icon{background:rgba(0,0,0,.4)}.list-item-album .tool-flag{display:none}.list-item-image-tools li .label{text-shadow:1px 1px 0 rgba(0,0,0,.1)}.list-item .list-item-avatar-cover,.list-item .list-item-avatar-cover>*{border-radius:100%}.list-item .list-item-avatar-cover{width:160px;height:160px;border:0;background-color:#e5e5e5;position:absolute;left:50%;top:50%;margin-top:-80px!important;margin-left:-80px!important;-webkit-transition:all .3s;transition:all .3s}.tone-dark .list-item .list-item-avatar-cover{background:#555}.list-item .list-item-avatar-cover>*{width:100px;height:100px}.list-item .list-item-avatar-cover img{height:auto;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,.3);box-shadow:2px 2px 2px rgba(0,0,0,.3)}.list-item .list-item-avatar-cover .icon.empty{display:block;top:50%;position:relative;margin-top:-45px}.list-item .list-item-avatar-cover .icon.empty,.tone-dark .list-item-image .list-item-avatar-cover .icon.empty{color:#fff}.list-item-privacy{position:absolute;left:0;top:0;width:2.4em;height:2.4em;line-height:2.4em;color:#fff;text-shadow:1px 1px 5px rgba(0,0,0,.5);text-align:center}.tone-dark .list-item-privacy{background:rgba(0,0,0,.5);color:#fff}.list-item-like{color:#fff;position:absolute;right:0;bottom:0}.list-item-like .btn-like{font-size:20px;padding:10px;cursor:pointer;display:none;opacity:.8}.list-item-like .btn-like.btn-liked,.list-item-like .btn-like:hover{opacity:1}[data-liked="0"] .list-item-like .btn-like.btn-unliked{display:block}[data-liked="1"] .list-item-like .btn-like.btn-liked{display:block}.list-item-play-gif,.list-item-play-gif *{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAACdCAMAAAAgwM7pAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAcVQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///9///+///+///+///+///+///9///8///1///5///9///9///u///f///+///+///+///9///q///z///9///+///9///8///9///+///+///+///+///8///w///9///+///3///8///9///2///9///7///t///+///8///b///9///9///M///+///y//+A///9///r///7///+///7///3///+///8//+////8//+q///8///+///z///+///+///9///6///m///7///j///7///9///+///+///9///9///6///+///+///+///7///V///+///9///5///9///+///+///8///9///6///8///+///9///4///+///+///+///+///4///9///5///+///v///7///9///8///o///9///9///8///6///y///9///0///+///x///+///6////////////vBUIqgAAAJd0Uk5TABQmNkZSWF5iCipmAiRKZAQuXCwYVDoMUBpgIiil+enVw7GJUBoujZkOCPf/45sMFnDPbEqhtcfZ714Qi9EgWI8adDgO21oGbmoEyxICcgw87Toe+1QEVgJg/RTru344CkIIRnrx55VmMNf1wT4GyaMoh+HlTJcyYt+pJrfTzd0ipyqtEECTXAp8aGQ2FIMWxRKzLrhG/4D2XIEAAAQlSURBVHiczZjnWxNBEMYPCCThgNC7IIKCyaCIdJCmgIooYkFCEwsqTRRQQREb9l7u7/UuuZhccm1vX5+H99Ne2d/d7uzOzowgmCgpOcWVmub2eNxpqa6U5CSzdw3lTXe5xTi5XeleNkpGZpYvnhKWLyszwzYmOydXnxJWbk62PU5ewpAShphnA5NfYIVRVJBvgckoNJibhLkqNJ2qomJ7GEXFRcacklL7HFEsLTHilHlYOKLoKdPnlNucnqh85br/w8yRSTr/VMI4rrA8CfNUxDTPUZXG2S6Dwe5aFWvXU6FTjigWxnLyHUx0RL7Y3WJrfxmpIMrJ4+GI4j9fkG3pN8zljvinHD6OKOaopjf1h3aUG14CmbwcUcwMgbL4QVkKx8uxhiLyefltH5ayAlwIkEsGcS6isNzy+Y7giGKSkIwBJQspGFAKZq6V2U7FgFKFNAwoDWN9xf6OTqFEeXAg2NBgkw0zP2xBwrYIbNPC3AjMseFcLcT5pyOPI9gBiTuyYUEELKzBBVqw0A8XjOLCY1jAjkshYEkNLs3CJX64VBSXHOPSdVwBAVfSEGBFFkWgso+AK0QJsNJYSN48RLFOFaR8CNe+isr9VQeqaw46636otu5wqOEPkKr6I0dZKQ3HGuWOx8MXTc0trW3tIVQHG6azK/QTJ7pjb3b39La29rFg/P3K19vrTrJ9PUGnBmTMwOCQySunB/ptgE4SVZ45a/rKMFHLOUvQSP/5CxavjF6ULThm46csdamV6PIVBOlql0waN3x8jQE1ETQkTZ6Y6tZ/YkQK6q6QkWmiJgaQ0BGMLH2tZoiqWMYmCLPnr+vcnQvSFNMGMNCNegreBHCEW0TVCM7kbZpn9jV6ukN011nPe1pLX6YFNotFdHSRJmKvlwLLzn5oZZHua26YuR9TrRI9cNpXozmihxCQsEbrGFA1amwbzIeUgSaJHqnNx0tPeEib1Ki2tmiNB7RKU2priTZ5QE+fRQa0Tc95QFGt0zQGFKCtPQaCDW2bhjGgJdrh6f5ia1BtvaQ2HlAzVaqtV683eEDRLcKnmE3LJ5gbkR3bUwgI5WrntGe9/41TkPY4WlkI7DrjDGkPSL/jI/twgDR++q3jIGLsneZSCWveOyPFCRVoCdfriSChn7ArB6MOc804fZDD4xGmHrMf/Xq3lYB9lIUjB+yfdB80VC10MnCUFOIzy4eNOSbpkW1ZpFm2ZSvx889YpqLLchpeb2mYGqIpi+R421Zy/GUnlK7rLhFVX+ftpOvCkFpAmLXzsrk6ayuUksbwt9ib3eO935/9YEVNhoosql16mn9GiixOLP6r9m14nvroX9mnjstnjUxXzPMUovaIfv8BgSQJhJIkEEqSQChJAqEkCYSSJBBKkkCo/wICDQ002SDzgxYkaIuANi0X5i8hpIpr8W0lCwAAAABJRU5ErkJggg==);position:absolute;top:50%;left:50%}.list-item-play-gif{width:72px;height:72px;margin-left:-36px;margin-top:-36px;background-position:0 0;cursor:pointer}.list-item-play-gif>span{width:66px;height:66px;margin-left:-33px;margin-top:-33px;background-position:0 -73px}.list-item-play-gif--loading>span,.list-item-play-gif:hover>span{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.list-item-play-gif>i{width:32px;height:17px;margin-left:-16px;margin-top:-9px;background-position:0 -140px}@-webkit-keyframes spin{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@keyframes spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.settings-group{display:none}.settings-group-isolated{display:block}.stats-block,a.stats-block{text-decoration:none;color:inherit;padding:10px}a.stats-block:hover{background:#f9f9f9}.tone-dark a.stats-block:hover{background:#222}.text-align-center .stats-big-number{text-align:center}.stats-big-number .number{font-size:44px;font-weight:200}.stats-big-number .number span{font-size:24px}.stats-big-number .label{display:block}.text-content code{background:#f9f9f9;padding:2px;border:1px solid #ddd}.tone-dark .text-content code{border-color:#222;background:#111}#home-top-bar-placeholder{margin-top:-65px}#home-cover{width:100%;background-position:center center;background-color:#333;background-size:cover;color:#fff;position:relative}body.landing #home-cover{margin:0;padding:0;height:100%;min-height:500px}body.split #home-cover{margin:0;height:500px}#home-cover-content{position:relative;text-align:center}body.landing #home-cover-content,body.split #home-cover-content{top:50%;position:relative;-webkit-transform:translateY(-50%);transform:translateY(-50%);overflow:auto}#home-cover-content h1,#home-cover-content p{text-shadow:1px 1px 2px rgba(0,0,0,.25)}#home-cover-content h1{font-size:2.4em;line-height:120%;font-weight:600}@media (min-width:768px){#home-cover-content h1{font-size:2.7em}}@media (min-width:992px){#home-cover-content h1{font-size:3em}}#home-cover-content p{font-size:22px;margin:20px 0;font-weight:100}#home-cover-content .home-buttons{margin:30px 0 20px}.home-buttons{margin:20px 0;text-align:center}.home-buttons a{font-size:16px;text-transform:uppercase;min-height:50px;line-height:1.5;height:auto;text-align:center;letter-spacing:2px;padding:12px 30px}#home-pics-feature{height:700px;overflow:hidden;position:relative;margin:10px 0}#home-pics-feature.empty{height:auto}#home-pics-feature-overlay{background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0)),to(rgba(255,255,255,1)));background:linear-gradient(to bottom,rgba(255,255,255,0) 0,rgba(255,255,255,1) 100%);width:100%;height:200px;position:absolute;bottom:0;z-index:1}.tone-dark #home-pics-feature-overlay{background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(#0b0b0b));background:linear-gradient(to bottom,rgba(0,0,0,0) 0,#0b0b0b 100%)}#home-pics-feature.empty #home-pics-overlay{display:none}#home-join{margin:40px 0}#home-join h1{font-size:38px;font-weight:100}#home-join p{margin:20px 0;font-size:18px}.ad-banner{margin:10px;text-align:center}.ad-banner img{display:block;margin:0 auto}.ad-banner-size-300x250{width:300px;height:250px}.ad-banner-size-336x280{width:336px;height:280px}.ad-banner-size-728x90{width:728px;height:90px}.ad-banner-size-300x600{width:300px;height:600px}.ad-banner-size-320x100{width:320px;height:100px}.ad-banner-size-320x50{width:320px;height:50px}.ad-banner-size-468x60{width:468px;height:60px}.ad-banner-size-234x60{width:234px;height:60px}.ad-banner-size-120x600{width:120px;height:600px}.ad-banner-size-120x240{width:120px;height:240px}.ad-banner-size-160x600{width:160px;height:600px}.ad-banner-size-300x1050{width:300px;height:1050px}.ad-banner-size-970x90{width:970px;height:90px}.ad-banner-size-970x250{width:970px;height:250px}.ad-banner-size-250x250{width:250px;height:250px}.ad-banner-size-200x200{width:200px;height:200px}.ad-banner-size-180x150{width:180px;height:150px}.ad-banner-size-125x125{width:125px;height:125px}#banner_before_home_cover{margin:0;padding:10px;background:#000}#banner_image_image-viewer_foot,#banner_image_image-viewer_top{height:90px;margin-left:auto;margin-right:auto}body#consent-screen,body#maintenance{padding:0;margin:0;width:100%;height:100%}#consent-screen-cover,#maintenance-cover{height:100%;background-position:center center;background-color:#333;background-size:cover}#consent-screen-cover-inner,#maintenance-cover-inner{background:rgba(0,0,0,.25);width:100%;height:100%}#consent-screen-cover-content,#maintenance-cover-content{color:#fff;padding:40px;text-align:center;position:relative;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}#maintenance-cover-content #logo{display:inline-block;margin-bottom:20px}#maintenance-cover-content #logo img{height:30px}#maintenance-cover-content h1{font-size:2.5em;margin-bottom:20px}#maintenance-cover-content p{font-size:1.2em}#consent-screen-cover-inner{background:0 0}#consent-screen-cover-src{width:100%;height:100%;position:absolute;top:0;left:0;background-position:center;background-size:cover}#consent-screen-content{background:#fff;margin:0 auto;padding:30px;-webkit-box-shadow:0 0 50px 6px rgba(0,0,0,.25);box-shadow:0 0 50px 6px rgba(0,0,0,.25);top:50%;position:relative;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.tone-dark #consent-screen-content{background:#161616}#consent-screen-content h1{line-height:2em}#consent-screen-content .logo{width:2em;height:auto;display:inline;margin-right:10px;vertical-align:top}#fullscreen-modal-box .image-preview .canvas{border:0;display:block;margin:0 auto;max-width:100%;max-height:500px}.content-password-gate{background:#f9f9f9;border-radius:10px;padding:30px;font-size:16px;text-align:center}.tone-dark .content-password-gate{background:0 0}.content-password-gate h1{font-size:30px;margin-bottom:10px}.content-password-gate h1 .icon{display:block;font-size:60px;margin-bottom:10px}.content-password-gate .g-recaptcha>div{margin-right:auto;margin-left:auto}.tone-dark .growl{background:#212121;color:#fff}#home-cover-slideshow{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden}.home-cover-img{position:absolute;left:0;top:0;width:100%;height:100%;background-size:cover;background-repeat:no-repeat;background-position:center center;display:block;opacity:0;-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.home-cover-img.animate-in,.home-cover-img.animate-in--alt{-webkit-animation-name:slideshow;animation-name:slideshow;-webkit-animation-duration:10s;animation-duration:10s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.home-cover-img.animate-in--alt{opacity:1;-webkit-animation-name:slideshow--alt;animation-name:slideshow--alt}.home-cover-img.animate-end{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1);-webkit-animation:none;animation:none}@-webkit-keyframes slideshow{0%{opacity:0}20%{opacity:1}100%{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1)}}@keyframes slideshow{0%{opacity:0}20%{opacity:1}100%{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1)}}@-webkit-keyframes slideshow--alt{100%{-webkit-transform:scale(1.1);transform:scale(1.1)}}@keyframes slideshow--alt{100%{-webkit-transform:scale(1.1);transform:scale(1.1)}}@supports (-ms-accelerator:true){.home-cover-img.animate-end{-webkit-transform:scale(1);transform:scale(1)}@-webkit-keyframes slideshow{0%{opacity:0}20%{opacity:1}}@keyframes slideshow{0%{opacity:0}20%{opacity:1}}@-webkit-keyframes slideshow--alt{100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes slideshow--alt{100%{-webkit-transform:scale(1);transform:scale(1)}}}#home-cover-slideshow::after{content:"";z-index:1;height:50px;position:absolute;top:0;left:0;right:0;background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.1)),to(rgba(0,0,0,0)));background:-webkit-linear-gradient(top,rgba(0,0,0,.1) 0,rgba(0,0,0,0) 100%);background:-o-linear-gradient(top,rgba(0,0,0,.1) 0,rgba(0,0,0,0) 100%);background:linear-gradient(to bottom,rgba(0,0,0,.1) 0,rgba(0,0,0,0) 100%)}#dashboard-settings{min-height:400px}.footer{color:#ccc;font-size:10px;line-height:20px;text-align:center;width:100%;position:absolute;bottom:0}.tone-dark .footer{color:#444}.js #powered-by.footer{display:none}body.landing .footer{color:#fff;text-shadow:2px 2px 6px rgba(0,0,0,.4)}body.landing .footer a{color:rgba(255,255,255,.7)}body.landing .footer,body.landing .footer a:hover{color:#fff}body.--viewer-shown{overflow:hidden}.viewer{background:#000;position:fixed;top:0;right:0;bottom:0;left:0;z-index:500}.js .viewer{display:block;touch-action:pinch-zoom!important}.viewer--hide{opacity:0}.viewer--show{opacity:1}.viewer.viewer--no-cursor,.viewer.viewer--no-cursor *{cursor:none}.viewer .btn-icon{font-size:20px}.viewer-content{position:relative;top:0;left:0;width:100%;height:100%}.viewer-content img{position:absolute;max-height:100vh;max-width:100vw;transform:translate(-50%,-50%);top:50%;left:50%}.viewer-close,.viewer-wheel>div{color:#fff;top:0;font-size:1em;text-shadow:1px 1px 0 rgba(0,0,0,.5);text-align:center}.viewer-close{position:absolute;width:2.4em;height:2.4em;line-height:2.4em;cursor:pointer;right:-2.4em;z-index:500}.viewer:hover .hover-display.viewer-close{right:2px}.viewer-wheel>div{position:fixed;bottom:0;width:calc(1em + 20px);cursor:pointer;padding:10px;opacity:.7;display:none}.viewer-wheel>div:hover{opacity:1}.viewer--nav-prev .viewer-wheel-prev{left:0;display:block}.viewer--nav-next .viewer-wheel-next{right:0;display:block}.viewer-wheel>div>.icon{position:absolute;top:50%;transform:translateY(-50%);display:block}.viewer-foot{padding:20px;position:absolute;left:0;right:0;bottom:0;height:80px;background:-webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.6)));background:-webkit-linear-gradient(top,transparent 0,rgba(0,0,0,.6) 100%);background:-moz-linear-gradient(top,transparent 0,rgba(0,0,0,.6) 100%);background:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.6) 100%)}.viewer-foot{display:flex;flex-wrap:wrap;flex-flow:row}.viewer-owner{width:190px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.viewer-owner .user-image{width:40px;height:40px;vertical-align:bottom;margin-right:10px}.viewer-owner .user-name{font-size:initial;text-decoration:none;vertical-align:middle;line-height:40px;color:inherit}.viewer-owner a.user-name:hover{color:rgba(255,255,255,.8)}.viewer-owner{order:1}.viewer-kb{font-size:.86em;flex-grow:1;order:2;padding-right:190px;text-align:center}.device-mobile .viewer-kb{display:none}.viewer-kb-input{display:inline-block}.viewer-kb-key{color:#fff;display:inline-block;margin:10px}.viewer-kb-key kbd{border:1px solid rgba(0,0,0,.5);background:rgba(120,120,120,.5);color:#fff;padding:4px 6px;border-radius:2px;display:inline-block;margin-right:5px;line-height:1}.viewer-like{transform:none;top:auto;bottom:20px;right:20px;position:absolute}.viewer:hover .hover-display--flex{display:flex}.--width-auto{width:auto}.--height-auto{height:auto}html.--idle .viewer,html.--idle .viewer *{cursor:none!important}html .fullscreen-show{display:none}:-webkit-full-screen .fullscreen-hide{display:none}:-moz-full-screen .fullscreen-hide{display:none}:-ms-fullscreen .fullscreen-hide{display:none}:fullscreen .fullscreen-hide{display:none}:-webkit-full-screen .fullscreen-show{display:block}:-moz-full-screen .fullscreen-show{display:block}:-ms-fullscreen .fullscreen-show{display:block}:fullscreen .fullscreen-show{display:block}a.image-container{-webkit-tap-highlight-color:transparent}a{color:#3498db;outline:0}a{text-decoration:none}input,textarea{border-color:#c6c8ca}.content-section,.input-label{margin-top:20px;margin-bottom:20px;position:relative}.content-section:first-child{margin-top:0}.input-label .input{width:100%;margin-bottom:0}.input-label .input+.input{margin-top:5px}.input-label .input-label{margin-bottom:10px}.input-label .input-label .label{font-weight:400}.input-label label .caption,.input-label label .optional{font-weight:400;font-size:.92em}.input-label label .caption:before,.input-label label .optional:before{content:"("}.input-label label .caption:after,.input-label label .optional:after{content:")"}.input-label-below{margin-top:5px;clear:both}.background-cover{position:fixed;top:0;right:0;bottom:0;left:0;background-position:center center;background-size:cover}.input-with-button{position:relative}.input-with-button button{background:0 0;position:absolute;right:0;top:50%;transform:translateY(-50%);border:none;font-size:22px;width:1em;height:1em;outline:0;color:#d9d9d9}.tone-dark .input-with-button button{color:#666}.input-with-button button:focus,.input-with-button button:hover{color:#3498db}#top-left{position:fixed;padding:5px;left:0;top:0}.top-button{padding:5px}.top-button .menu-box{margin-top:5px}.top-button-icon{font-size:16px;color:#fff;cursor:pointer;text-shadow:1px 1px 0 rgba(0,0,0,.15)}.background-default{background:#2ecc71;background:-moz-linear-gradient(top,#2ecc71 0,#3498db 100%);background:-webkit-linear-gradient(top,#2ecc71 0,#3498db 100%);background:linear-gradient(to bottom,#2ecc71 0,#3498db 100%)}.content-box{position:relative;margin:20px}.content-box-text :first-child{margin-top:0}.content-box-text :last-child{margin-bottom:0}.logo{max-height:50px;max-width:220px;margin-bottom:20px}.card-box{min-width:270px;width:calc(100vw - 40px)}.access-box-content{background:#fff}.fancy-box-heading{font-size:22px;margin:20px 0 30px 0}.fancy-fieldset{border:0;padding:0;margin:0}.fancy-fieldset input:not([type=checkbox]),.fancy-fieldset input[type=text],.fancy-fieldset select,.fancy-fieldset textarea{outline:0;padding:10px 0;width:100%;border-radius:0;border-color:#ebebeb;background:0 0;box-shadow:none}.fancy-fieldset .checkbox-label input[type=checkbox]{width:auto;vertical-align:middle;margin:0 0 0 -20px}.tone-dark .fancy-fieldset input,.tone-dark .fancy-fieldset input[type=text],.tone-dark .fancy-fieldset select,.tone-dark .fancy-fieldset textarea{box-shadow:none;border-color:#212121}.fancy-fieldset select{-webkit-appearance:none;-moz-appearance:none;appearance:none}.fancy-fieldset input,.fancy-fieldset select{padding:10px 0;border-top:transparent;border-left:transparent;border-right:transparent}.fancy-fieldset input:focus,.fancy-fieldset input:focus[type=text],.fancy-fieldset select:focus,.fancy-fieldset textarea:focus{border-color:#3498db}.fancy-fieldset .input-with-button input[type=password]{padding-right:30px}.fancy-fieldset>div:last-child{margin-bottom:inherit}.fancy-fieldset .label{line-height:1.5}.fancy-fieldset .input-label:last-child{margin-bottom:0}.fancy-fieldset .checkbox-label{margin:0}a.social-button{position:relative;text-decoration:none;display:inline-block;font-size:1em;margin:10px 0;background:#d9d9d9;padding:8px;text-decoration:none;display:block;color:#fff;border-radius:3px}a.social-button--facebook{background-color:#4267b2}a.social-button--facebook .icon:before{content:"\e8c9"}a.social-button--twitter{background-color:#1da1f2}a.social-button--google{background-color:#ea4335}a.social-button--vk{background-color:#45668e}.social-button-outline{position:relative;text-decoration:none;width:32px;height:32px;display:inline-block;border-radius:50%;border-width:1px;border-style:solid;font-size:16px;margin:5px}.social-button-outline .icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.social-button-outline.border-color-facebook:focus,.social-button-outline.border-color-facebook:hover{background-color:#3b5998}.social-button-outline.border-color-twitter:focus,.social-button-outline.border-color-twitter:hover{background-color:#1da1f2}.social-button-outline.border-color-google:focus,.social-button-outline.border-color-google:hover{background-color:#ea4335}.social-button-outline.border-color-vk:focus,.social-button-outline.border-color-vk:hover{background-color:#45668e}.social-button-outline:focus .icon,.social-button-outline:hover .icon{color:#fff}#login{padding:0;margin:0}.content-section--recaptchaFix #g-recaptcha{min-height:78px;-webkit-transform:scale(.89);-ms-transform:scale(.89);transform:scale(.89);-webkit-transform-origin:left;-ms-transform-origin:left;transform-origin:left}#login .input{margin:0}.btn-container--fixed{position:fixed;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);padding:10px;margin:0;border:0}.tone-dark .btn-container--fixed{background:rgba(0,0,0,.75)}body#dashboard{min-height:100%;padding-bottom:4em}body.full--wh{height:100%;width:100%}.display-flex #home-cover-slideshow{position:fixed}[data-content=dashboard-imports] [data-action=resume],[data-content=dashboard-imports] [data-errors="0"] [data-content=log-errors],[data-content=dashboard-imports] [data-result],[data-content=dashboard-imports] [data-started="0"] [data-content^=log]{display:none}[data-content=dashboard-imports] [data-errors="1"] [data-content=log-process],[data-content=dashboard-imports] [data-status=completed] [data-action=pause],[data-content=dashboard-imports] [data-status=completed][data-errors="0"] [data-result=success],[data-content=dashboard-imports] [data-status=paused] [data-action=resume],[data-content=dashboard-imports] [data-status][data-errors="1"] [data-result=error]{display:initial}[data-content=dashboard-imports] [data-status=canceled] [data-action=cancel],[data-content=dashboard-imports] [data-status=canceled] [data-action=pause],[data-content=dashboard-imports] [data-status=canceled] [data-target=modal-process-import],[data-content=dashboard-imports] [data-status=completed] [data-action=cancel],[data-content=dashboard-imports] [data-status=completed] [data-target=modal-process-import],[data-content=dashboard-imports] [data-status=paused] [data-action=pause],[data-content=dashboard-imports] [data-status=queued] [data-action=pause],[data-content=dashboard-imports] [data-status=working] [data-target=modal-process-import]{display:none!important}.panel-thumb-list li{overflow:hidden}.connecting-ip{font-family:monospace;font-size:27px}.code{padding:2px;background:#ecf0f1}.tone-dark .code{background:#0b0b0b}.importing{background:#ecf0f1;padding:10px;position:relative}.tone-dark .importing{background:#111}.importing:nth-child(even){margin:0 10px}.phablet .importing:nth-child(even),.phone .importing:nth-child(even){margin:10px 0}.importing-stats{margin:10px 0}.importing-stats .figure{display:inline-block;padding:5px;background:rgba(0,0,0,.1)}.tone-dark .importing-stats .figure{background:rgba(255,255,255,.1)}body#index.landing [data-action=top-bar-tone]{display:none} \ No newline at end of file +body{padding-top:65px;padding-bottom:20px;min-height:100%;background:#fefefe;position:relative;font-family:Helvetica,Arial,sans-serif;font-size:14px}body.landing{min-height:500px;height:100%;padding:0;margin:0}.phone body.landing{min-height:auto}.js body.landing{overflow:hidden;opacity:0}.js body.landing.load{-webkit-transition:-webkit-transform .6s ease,opacity 350ms linear;-webkit-transition:opacity 350ms linear,-webkit-transform .6s ease;transition:opacity 350ms linear,-webkit-transform .6s ease;transition:transform .6s ease,opacity 350ms linear;transition:transform .6s ease,opacity 350ms linear,-webkit-transform .6s ease;opacity:1}#home-cover-content,#index .flex-center{opacity:0}.js body#index.load .flex-center,.js body.load #home-cover-content{transition:all .6s ease;transition-delay:150ms;opacity:1}.js body.loaded{overflow:auto}body.split{margin-top:0;padding-top:0}.content-width.fluid,.fluid .content-width{width:100%}@media (min-width:992px){.content-width.wide{max-width:none}}html.device-mobile .device-mobile--hide{display:none!important}html.device-nonmobile .device-nonmobile--hide{display:none!important}body#upload{padding-top:50px;padding-bottom:0;background-color:transparent}.image-viewer{text-align:center;background:#f7f7f7;position:relative;min-height:72px;overflow:hidden}.image-viewer-main{display:inline-block;vertical-align:middle}.image-viewer-container{display:block;margin:0 auto;position:relative}.image-viewer-container img{display:block;margin:0 auto;max-height:100%;width:auto}.js .image-viewer-container img{position:absolute;width:100%;height:auto}.image-viewer .btn-download{position:absolute;top:20px;right:20px;z-index:1}.image-viewer-navigation a{z-index:3}.image-viewer-navigation a:hover{background-color:#aaa;background-color:rgba(0,0,0,.3)}#image-viewer-loading,.viewer-loader{width:30px;height:30px;position:absolute;left:50%;top:50%;margin-left:-15px;margin-top:-15px;border-radius:100%;background:rgba(17,17,17,.9)}#image-viewer-loader{position:absolute;background:rgba(0,0,0,.5);border:2px solid rgba(255,255,255,.7);color:rgba(255,255,255,.9);font-size:13px;left:50%;top:50%;padding:8px 14px;border-radius:100px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);cursor:pointer;display:none}#image-viewer-loader:hover{background:rgba(0,0,0,.6);border-color:rgba(255,255,255,.8);color:#fff}#image-viewer-loader .btn-icon{position:relative;top:1px;font-size:12px}#image .top-bar-placeholder,.image-viewer.full-viewer{background:#111}.top-bar-white #image .top-bar-placeholder,.top-bar-white .image-viewer.full-viewer{background:#fff}.btn-like .btn.btn-liked,.btn-like .btn.btn-unliked{display:none}.btn-like[data-liked="0"] .btn-unliked{display:inline-block}.btn-like[data-liked="1"] .btn-liked{display:inline-block}.btn-follow .btn.btn-followed,.btn-follow .btn.btn-unfollowed{display:none}.btn-follow[data-followed="0"] .btn-unfollowed{display:inline-block}.btn-follow[data-followed="1"] .btn-followed{display:inline-block}#fullscreen-uploader-mask{z-index:99}.phone #fullscreen-uploader-mask{z-index:400}#anywhere-upload{z-index:400;scroll:auto;-webkit-overflow-scrolling:touch;-webkit-transition:transform .3s ease;-webkit-transition:-webkit-transform .3s ease;transition:-webkit-transform .3s ease;transition:transform .3s ease;transition:transform .3s ease,-webkit-transform .3s ease}#anywhere-upload.hidden-visibility iframe{visibility:hidden}.phone #anywhere-upload{z-index:500;height:100vh!important}#upload #anywhere-upload{overflow:hidden!important;height:auto!important}#upload .upload-box .upload-box-allowed-files,.phone .upload-box .upload-box-allowed-files{display:none}#upload .upload-box[data-queue-size="0"] .upload-box-allowed-files,.phone .upload-box[data-queue-size="0"] .upload-box-allowed-files{display:block}#upload .upload-box-allowed-files,.phone .upload-box-allowed-files{position:fixed;top:auto;left:0;right:0;text-align:center;bottom:10px}#anywhere-upload-paste{height:0;opacity:0;font-size:0}#anywhere-upload-paste *{display:none}.upload-box{border-bottom:0}.upload-box-queue{text-align:center;font-size:0;margin-top:35px;margin-bottom:35px}.upload-box-queue li{position:relative;text-align:center;display:inline-block;background:red;margin:5px;background:#efefef;-webkit-box-shadow:inset 0 2px 10px 0 rgba(0,0,0,.07);box-shadow:inset 0 2px 10px 0 rgba(0,0,0,.07)}.tone-dark .upload-box-queue li{background:#222}.upload-box-queue .block,.upload-box-queue li{border-radius:0}.ios .upload-box-queue .block,.ios .upload-box-queue li,.upload-box-queue .block.failed{border-radius:0}.upload-box-queue li,.upload-box-queue li.normal{width:110px;height:110px;font-size:14px;font-size:1rem}.upload-box-queue li.small{width:77px;height:77px;font-size:9px;font-size:.643rem}.upload-box-queue li.tiny{width:54px;height:54px;font-size:7px;font-size:.5rem}.upload-box-queue .block{width:100%;height:100%;top:0;left:0;overflow:hidden;position:absolute}.upload-box-queue a.image-link{display:none}.upload-box-queue .completed a.image-link{display:block;position:absolute;overflow:hidden;z-index:1;-webkit-transform:rotate(.000001deg)}.upload-box-queue .queue-item .block.edit,.upload-box-queue .queue-item .queue-item-button{display:block;position:absolute;cursor:pointer;z-index:100}.upload-box-queue .queue-item .queue-item-button .icon{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.upload-box-queue .queue-item.completed:hover .queue-item-button{display:none}.upload-box-queue .queue-item .queue-item-button{font-size:7px;width:21px;height:21px;line-height:23px;background:#fff;color:#333;border-radius:200px;left:-7px;-webkit-box-shadow:1px 1px 4px 0 rgba(0,0,0,.5);box-shadow:1px 1px 4px 0 rgba(0,0,0,.5)}.tone-dark .upload-box-queue .queue-item .queue-item-button{background:#333;color:#fff}.upload-box-queue .queue-item .queue-item-button.cancel{top:-7px}.upload-box-queue .queue-item .queue-item-button.edit{top:16px;font-size:9px}.upload-box-queue .big-icon{position:absolute;color:#dadada;font-size:5.36em;width:1em;height:1em;left:50%;top:50%;margin-left:-.5em;margin-top:-.5em;text-shadow:1px 1px 0 rgba(255,255,255,.9)}.tone-dark .upload-box-queue .big-icon{color:#444;text-shadow:1px 1px 0 rgba(0,0,0,.9)}.upload-box-queue .done,.upload-box-queue .preview{position:relative;overflow:hidden}.upload-box-queue .preview .canvas{position:absolute;top:50%;left:50%}.upload-box-queue .progress{position:absolute}.upload-box-queue .progress-bar,.upload-box-queue .progress-percent{height:100%}.upload-box-queue .uploading .progress-percent{display:block}.queue-item.uploading .block.edit,.queue-item.uploading .queue-item-button.edit,.queue-item.uploading.waiting .progress-percent{display:none}.upload-box-queue .progress-percent{font-family:arial,helvetica,sans-serif;font-size:2.86em;font-weight:400;color:#fff;text-shadow:2px 2px 10px rgba(0,0,0,.8);text-align:center;width:100%;height:1em;position:absolute;top:.86em;z-index:1;display:none}.upload-box-queue .progress-percent b{font-weight:700}.upload-box-queue .progress-percent span{font-size:.5em;font-weight:400;position:relative}.upload-box-queue .progress-bar{float:right;width:100%;display:none}.upload-box-queue .failed .result,.upload-box-queue .progress-bar{background:rgba(255,255,255,.65)}.upload-box-queue .uploading .progress-bar{display:block}.upload-box-queue .completed .result.done,.upload-box-queue .failed .result.failed{display:block}.upload-box-queue .result{position:absolute;z-index:1;display:none}.tone-dark .upload-box-queue .failed .result,.tone-dark .upload-box-queue .progress-bar{background:rgba(0,0,0,.65)}.upload-box-queue .result .icon{position:absolute;width:1em;font-size:3.429em;color:#fff;top:50%;left:50%;margin-top:-.5em;margin-left:-.5em;margin-left:-.5em;opacity:.92;text-shadow:none}.upload-box-queue .done .result .icon{text-shadow:2px 2px 6px rgba(0,0,0,.2)}.upload-box-queue .failed .result .icon{color:#e84c3d;font-size:3.429em}.upload-box-queue.queue-complete .cancel,.upload-box-queue.queue-complete .edit{display:none}#form-embed-toggle-combo,#uploaded-embed-toggle-combo{position:relative}#upload .top-bar{-webkit-box-shadow:none;box-shadow:none;border-bottom-color:transparent}#upload #anywhere-upload{background:0 0}#upload .upload-box{transform:none;position:static}body#upload [data-action=close-upload]{display:none!important}.upload-box.queueHasResults [data-action=cancel-upload],.upload-box.queueReady [data-action=close-upload],.upload-box.queueUploading [data-action=close-upload],.upload-box:not(.queueHasResults) [data-action=cancel-upload-remaining],.upload-box:not(.queueReady):not(.queueCompleted) [data-action=reset-upload],.upload-box:not(.queueUploading) [data-action^=cancel-upload],.upload-box:not([data-queue-size="0"]) [data-action=close-upload]{display:none}#background-cover{height:290px;background-color:#000;position:relative}.phone #background-cover{height:230px}#background-cover.no-background{background-color:#f9f9f9;background-image:none!important;padding:9px 0;height:auto;margin-top:50px}.tone-dark #background-cover.no-background{background:#101010}#background-cover-wrap{height:100%;overflow:hidden;position:relative}#background-cover .content-width{text-align:center}#change-background-cover{position:absolute;right:10px;bottom:10px}#user-background-upload{top:0;left:0;width:1px;height:1px}#background-cover-src{overflow:hidden;background-position:center center;background-size:cover}#background-cover .loading-placeholder,#background-cover-src{position:absolute;top:0;left:0;width:100%;height:100%}#background-cover .loading-placeholder{background:rgba(0,0,0,.8)}[data-privacy=public] .list-item-privacy{display:none}.list-item-thumbs li,.list-item-thumbs li a{display:block;height:auto;overflow:hidden}.list-item-thumbs li a{height:100%;background-size:cover;background-position:center center}.list-item-thumbs li img{width:100%;display:block}.input-copy{position:relative}.input-copy .btn-copy{font-size:10px;position:absolute;right:2px;top:8px;background:#fff;padding:0 4px;height:18px;line-height:18px;text-transform:uppercase;cursor:pointer;border-width:0 4px;border-style:solid;border-color:#fff;display:none}.input-copy .btn-copy:hover{background:#e5e5e5}.list-item-image-tools{position:absolute;right:0;top:0}.list-item.selected .list-item-image-tools li.tool-select .icon{color:#fff;background:#27ae60}.list-item-image-tools li{margin:2px;cursor:pointer;position:relative;height:2.4em;line-height:2.4em;font-size:1em;right:calc(-2.4em - 2px);transition:all .2s ease-in-out}.list-item .hover-display.list-item-image-tools{opacity:1}.list-item.selected li.tool-select,.list-item[data-flag=unsafe] li.tool-flag,html:not(.--idle) .list-item:hover .list-item-image-tools li{right:0}.list-item-image-tools li,.list-item-image-tools li *{display:block;color:inherit}.list-item-image-tools li span{float:right}.list-item-image-tools li .label{font-size:.86em}.list-item-image-tools li .btn-icon{font-size:1em}.list-item-image-tools li .label{text-transform:uppercase;padding-left:1em;padding-right:0;display:none;height:100%}.list-item-image-tools li:hover .label{display:block}.small-cols .list-item-image-tools li:hover .label{display:none}[data-flag=safe] li:hover .label-flag-safe,[data-flag=unsafe] li:hover .label-flag-unsafe{display:none}.unsafe-blur-on .list-item .list-item-thumbs li[data-flag=unsafe] a,.unsafe-blur-on [data-flag=unsafe] .image-container{filter:blur(5px);-webkit-filter:blur(5px);-webkit-transform:scale(1.04);transform:scale(1.04)}.unsafe-blur-on .list-item:hover .list-item-thumbs li[data-flag=unsafe] a,.unsafe-blur-on [data-flag=unsafe]:hover .image-container{filter:none;-webkit-filter:none}.list-item-image-tools li .btn-icon{width:2.4em;height:2.4em;line-height:2.4em;color:#fff;background:#000;background:rgba(0,0,0,.2);text-align:center}.list-item-image-tools li .label,.list-item-image-tools li:hover .btn-icon{color:#fff;background:rgba(0,0,0,.4)}.list-item.selected li.tool-select .btn-icon,[data-flag=unsafe] li.tool-flag .btn-icon{background:rgba(0,0,0,.4)}.list-item-album .tool-flag{display:none}.list-item-image-tools li .label{text-shadow:1px 1px 0 rgba(0,0,0,.1)}.list-item .list-item-avatar-cover,.list-item .list-item-avatar-cover>*{border-radius:100%}.list-item .list-item-avatar-cover{width:160px;height:160px;border:0;background-color:#e5e5e5;position:absolute;left:50%;top:50%;margin-top:-80px!important;margin-left:-80px!important;-webkit-transition:all .3s;transition:all .3s}.tone-dark .list-item .list-item-avatar-cover{background:#555}.list-item .list-item-avatar-cover>*{width:100px;height:100px}.list-item .list-item-avatar-cover img{height:auto;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,.3);box-shadow:2px 2px 2px rgba(0,0,0,.3)}.list-item .list-item-avatar-cover .icon.empty{display:block;top:50%;position:relative;margin-top:-45px}.list-item .list-item-avatar-cover .icon.empty,.tone-dark .list-item-image .list-item-avatar-cover .icon.empty{color:#fff}.list-item-privacy{position:absolute;left:0;top:0;width:2.4em;height:2.4em;line-height:2.4em;color:#fff;text-shadow:1px 1px 5px rgba(0,0,0,.5);text-align:center}.tone-dark .list-item-privacy{background:rgba(0,0,0,.5);color:#fff}.list-item-like{color:#fff;position:absolute;right:0;bottom:0}.list-item-like .btn-like{font-size:20px;padding:10px;cursor:pointer;display:none;opacity:.8}.list-item-like .btn-like.btn-liked,.list-item-like .btn-like:hover{opacity:1}[data-liked="0"] .list-item-like .btn-like.btn-unliked{display:block}[data-liked="1"] .list-item-like .btn-like.btn-liked{display:block}.list-item-play-gif,.list-item-play-gif *{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAACdCAMAAAAgwM7pAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAcVQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///9///+///+///+///+///+///9///8///1///5///9///9///u///f///+///+///+///9///q///z///9///+///9///8///9///+///+///+///+///8///w///9///+///3///8///9///2///9///7///t///+///8///b///9///9///M///+///y//+A///9///r///7///+///7///3///+///8//+////8//+q///8///+///z///+///+///9///6///m///7///j///7///9///+///+///9///9///6///+///+///+///7///V///+///9///5///9///+///+///8///9///6///8///+///9///4///+///+///+///+///4///9///5///+///v///7///9///8///o///9///9///8///6///y///9///0///+///x///+///6////////////vBUIqgAAAJd0Uk5TABQmNkZSWF5iCipmAiRKZAQuXCwYVDoMUBpgIiil+enVw7GJUBoujZkOCPf/45sMFnDPbEqhtcfZ714Qi9EgWI8adDgO21oGbmoEyxICcgw87Toe+1QEVgJg/RTru344CkIIRnrx55VmMNf1wT4GyaMoh+HlTJcyYt+pJrfTzd0ipyqtEECTXAp8aGQ2FIMWxRKzLrhG/4D2XIEAAAQlSURBVHiczZjnWxNBEMYPCCThgNC7IIKCyaCIdJCmgIooYkFCEwsqTRRQQREb9l7u7/UuuZhccm1vX5+H99Ne2d/d7uzOzowgmCgpOcWVmub2eNxpqa6U5CSzdw3lTXe5xTi5XeleNkpGZpYvnhKWLyszwzYmOydXnxJWbk62PU5ewpAShphnA5NfYIVRVJBvgckoNJibhLkqNJ2qomJ7GEXFRcacklL7HFEsLTHilHlYOKLoKdPnlNucnqh85br/w8yRSTr/VMI4rrA8CfNUxDTPUZXG2S6Dwe5aFWvXU6FTjigWxnLyHUx0RL7Y3WJrfxmpIMrJ4+GI4j9fkG3pN8zljvinHD6OKOaopjf1h3aUG14CmbwcUcwMgbL4QVkKx8uxhiLyefltH5ayAlwIkEsGcS6isNzy+Y7giGKSkIwBJQspGFAKZq6V2U7FgFKFNAwoDWN9xf6OTqFEeXAg2NBgkw0zP2xBwrYIbNPC3AjMseFcLcT5pyOPI9gBiTuyYUEELKzBBVqw0A8XjOLCY1jAjkshYEkNLs3CJX64VBSXHOPSdVwBAVfSEGBFFkWgso+AK0QJsNJYSN48RLFOFaR8CNe+isr9VQeqaw46636otu5wqOEPkKr6I0dZKQ3HGuWOx8MXTc0trW3tIVQHG6azK/QTJ7pjb3b39La29rFg/P3K19vrTrJ9PUGnBmTMwOCQySunB/ptgE4SVZ45a/rKMFHLOUvQSP/5CxavjF6ULThm46csdamV6PIVBOlql0waN3x8jQE1ETQkTZ6Y6tZ/YkQK6q6QkWmiJgaQ0BGMLH2tZoiqWMYmCLPnr+vcnQvSFNMGMNCNegreBHCEW0TVCM7kbZpn9jV6ukN011nPe1pLX6YFNotFdHSRJmKvlwLLzn5oZZHua26YuR9TrRI9cNpXozmihxCQsEbrGFA1amwbzIeUgSaJHqnNx0tPeEib1Ki2tmiNB7RKU2priTZ5QE+fRQa0Tc95QFGt0zQGFKCtPQaCDW2bhjGgJdrh6f5ia1BtvaQ2HlAzVaqtV683eEDRLcKnmE3LJ5gbkR3bUwgI5WrntGe9/41TkPY4WlkI7DrjDGkPSL/jI/twgDR++q3jIGLsneZSCWveOyPFCRVoCdfriSChn7ArB6MOc804fZDD4xGmHrMf/Xq3lYB9lIUjB+yfdB80VC10MnCUFOIzy4eNOSbpkW1ZpFm2ZSvx889YpqLLchpeb2mYGqIpi+R421Zy/GUnlK7rLhFVX+ftpOvCkFpAmLXzsrk6ayuUksbwt9ib3eO935/9YEVNhoosql16mn9GiixOLP6r9m14nvroX9mnjstnjUxXzPMUovaIfv8BgSQJhJIkEEqSQChJAqEkCYSSJBBKkkCo/wICDQ002SDzgxYkaIuANi0X5i8hpIpr8W0lCwAAAABJRU5ErkJggg==);position:absolute;top:50%;left:50%}.list-item-play-gif{width:72px;height:72px;margin-left:-36px;margin-top:-36px;background-position:0 0;cursor:pointer}.list-item-play-gif>span{width:66px;height:66px;margin-left:-33px;margin-top:-33px;background-position:0 -73px}.list-item-play-gif--loading>span,.list-item-play-gif:hover>span{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.list-item-play-gif>i{width:32px;height:17px;margin-left:-16px;margin-top:-9px;background-position:0 -140px}@-webkit-keyframes spin{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@keyframes spin{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.settings-group{display:none}.settings-group-isolated{display:block}.stats-block,a.stats-block{text-decoration:none;color:inherit;padding:10px}a.stats-block:hover{background:#f9f9f9}.tone-dark a.stats-block:hover{background:#222}.text-align-center .stats-big-number{text-align:center}.stats-big-number .number{font-size:44px;font-weight:200}.stats-big-number .number span{font-size:24px}.stats-big-number .label{display:block}.text-content code{background:#f9f9f9;padding:2px;border:1px solid #ddd}.tone-dark .text-content code{border-color:#222;background:#111}#home-top-bar-placeholder{margin-top:-65px}#home-cover{width:100%;background-position:center center;background-color:#333;background-size:cover;color:#fff;position:relative}body.landing #home-cover{margin:0;padding:0;height:100%;min-height:500px}body.split #home-cover{margin:0;height:500px}#home-cover-content{position:relative;text-align:center}body.landing #home-cover-content,body.split #home-cover-content{top:50%;position:relative;-webkit-transform:translateY(-50%);transform:translateY(-50%);overflow:auto}#home-cover-content h1,#home-cover-content p{text-shadow:1px 1px 2px rgba(0,0,0,.25)}#home-cover-content h1{font-size:2.4em;line-height:120%;font-weight:600}@media (min-width:768px){#home-cover-content h1{font-size:2.7em}}@media (min-width:992px){#home-cover-content h1{font-size:3em}}#home-cover-content p{font-size:22px;margin:20px 0;font-weight:100}#home-cover-content .home-buttons{margin:30px 0 20px}.home-buttons{margin:20px 0;text-align:center}.home-buttons a{font-size:16px;text-transform:uppercase;min-height:50px;line-height:1.5;height:auto;text-align:center;letter-spacing:2px;padding:12px 30px}#home-pics-feature{height:700px;overflow:hidden;position:relative;margin:10px 0}#home-pics-feature.empty{height:auto}#home-pics-feature-overlay{background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0)),to(rgba(255,255,255,1)));background:linear-gradient(to bottom,rgba(255,255,255,0) 0,rgba(255,255,255,1) 100%);width:100%;height:200px;position:absolute;bottom:0;z-index:1}.tone-dark #home-pics-feature-overlay{background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(#0b0b0b));background:linear-gradient(to bottom,rgba(0,0,0,0) 0,#0b0b0b 100%)}#home-pics-feature.empty #home-pics-overlay{display:none}#home-join{margin:40px 0}#home-join h1{font-size:38px;font-weight:100}#home-join p{margin:20px 0;font-size:18px}.ad-banner{margin:10px;text-align:center}.ad-banner img{display:block;margin:0 auto}.ad-banner-size-300x250{width:300px;height:250px}.ad-banner-size-336x280{width:336px;height:280px}.ad-banner-size-728x90{width:728px;height:90px}.ad-banner-size-300x600{width:300px;height:600px}.ad-banner-size-320x100{width:320px;height:100px}.ad-banner-size-320x50{width:320px;height:50px}.ad-banner-size-468x60{width:468px;height:60px}.ad-banner-size-234x60{width:234px;height:60px}.ad-banner-size-120x600{width:120px;height:600px}.ad-banner-size-120x240{width:120px;height:240px}.ad-banner-size-160x600{width:160px;height:600px}.ad-banner-size-300x1050{width:300px;height:1050px}.ad-banner-size-970x90{width:970px;height:90px}.ad-banner-size-970x250{width:970px;height:250px}.ad-banner-size-250x250{width:250px;height:250px}.ad-banner-size-200x200{width:200px;height:200px}.ad-banner-size-180x150{width:180px;height:150px}.ad-banner-size-125x125{width:125px;height:125px}#banner_before_home_cover{margin:0;padding:10px;background:#000}#banner_image_image-viewer_foot,#banner_image_image-viewer_top{height:90px;margin-left:auto;margin-right:auto}body#consent-screen,body#maintenance{padding:0;margin:0;width:100%;height:100%}#consent-screen-cover,#maintenance-cover{height:100%;background-position:center center;background-color:#333;background-size:cover}#consent-screen-cover-inner,#maintenance-cover-inner{background:rgba(0,0,0,.25);width:100%;height:100%}#consent-screen-cover-content,#maintenance-cover-content{color:#fff;padding:40px;text-align:center;position:relative;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}#maintenance-cover-content #logo{display:inline-block;margin-bottom:20px}#maintenance-cover-content #logo img{height:30px}#maintenance-cover-content h1{font-size:2.5em;margin-bottom:20px}#maintenance-cover-content p{font-size:1.2em}#consent-screen-cover-inner{background:0 0}#consent-screen-cover-src{width:100%;height:100%;position:absolute;top:0;left:0;background-position:center;background-size:cover}#consent-screen-content{background:#fff;margin:0 auto;padding:30px;-webkit-box-shadow:0 0 50px 6px rgba(0,0,0,.25);box-shadow:0 0 50px 6px rgba(0,0,0,.25);top:50%;position:relative;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.tone-dark #consent-screen-content{background:#161616}#consent-screen-content h1{line-height:2em}#consent-screen-content .logo{width:2em;height:auto;display:inline;margin-right:10px;vertical-align:top}#fullscreen-modal-box .image-preview .canvas{border:0;display:block;margin:0 auto;max-width:100%;max-height:500px}.content-password-gate{background:#f9f9f9;border-radius:10px;padding:30px;font-size:16px;text-align:center}.tone-dark .content-password-gate{background:0 0}.content-password-gate h1{font-size:30px;margin-bottom:10px}.content-password-gate h1 .icon{display:block;font-size:60px;margin-bottom:10px}.content-password-gate .g-recaptcha>div{margin-right:auto;margin-left:auto}.tone-dark .growl{background:#212121;color:#fff}#home-cover-slideshow{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden}.home-cover-img{position:absolute;left:0;top:0;width:100%;height:100%;background-size:cover;background-repeat:no-repeat;background-position:center center;display:block;opacity:0;-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.home-cover-img.animate-in,.home-cover-img.animate-in--alt{-webkit-animation-name:slideshow;animation-name:slideshow;-webkit-animation-duration:10s;animation-duration:10s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.home-cover-img.animate-in--alt{opacity:1;-webkit-animation-name:slideshow--alt;animation-name:slideshow--alt}.home-cover-img.animate-end{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1);-webkit-animation:none;animation:none}@-webkit-keyframes slideshow{0%{opacity:0}20%{opacity:1}100%{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1)}}@keyframes slideshow{0%{opacity:0}20%{opacity:1}100%{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1)}}@-webkit-keyframes slideshow--alt{100%{-webkit-transform:scale(1.1);transform:scale(1.1)}}@keyframes slideshow--alt{100%{-webkit-transform:scale(1.1);transform:scale(1.1)}}@supports (-ms-accelerator:true){.home-cover-img.animate-end{-webkit-transform:scale(1);transform:scale(1)}@-webkit-keyframes slideshow{0%{opacity:0}20%{opacity:1}}@keyframes slideshow{0%{opacity:0}20%{opacity:1}}@-webkit-keyframes slideshow--alt{100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes slideshow--alt{100%{-webkit-transform:scale(1);transform:scale(1)}}}#home-cover-slideshow::after{content:"";z-index:1;height:50px;position:absolute;top:0;left:0;right:0;background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.1)),to(rgba(0,0,0,0)));background:-webkit-linear-gradient(top,rgba(0,0,0,.1) 0,rgba(0,0,0,0) 100%);background:-o-linear-gradient(top,rgba(0,0,0,.1) 0,rgba(0,0,0,0) 100%);background:linear-gradient(to bottom,rgba(0,0,0,.1) 0,rgba(0,0,0,0) 100%)}#dashboard-settings{min-height:400px}.footer{color:#ccc;font-size:10px;line-height:20px;text-align:center;width:100%;position:absolute;bottom:0}.tone-dark .footer{color:#444}.js #powered-by.footer{display:none}body.landing .footer{color:#fff;text-shadow:2px 2px 6px rgba(0,0,0,.4)}body.landing .footer a{color:rgba(255,255,255,.7)}body.landing .footer,body.landing .footer a:hover{color:#fff}body.--viewer-shown{overflow:hidden}.viewer{background:#000;position:fixed;top:0;right:0;bottom:0;left:0;z-index:500}.js .viewer{display:block;touch-action:pinch-zoom!important}.viewer--hide{opacity:0}.viewer--show{opacity:1}.viewer.viewer--no-cursor,.viewer.viewer--no-cursor *{cursor:none}.viewer .btn-icon{font-size:20px}.viewer-content{position:relative;top:0;left:0;width:100%;height:100%}.viewer-content img{position:absolute;max-height:100vh;max-width:100vw;transform:translate(-50%,-50%);top:50%;left:50%}.viewer-close,.viewer-wheel>div{color:#fff;top:0;font-size:1em;text-shadow:1px 1px 0 rgba(0,0,0,.5);text-align:center}.viewer-close{position:absolute;width:2.4em;height:2.4em;line-height:2.4em;cursor:pointer;right:-2.4em;z-index:500}.viewer:hover .hover-display.viewer-close{right:2px}.viewer-wheel>div{position:fixed;bottom:0;width:calc(1em + 20px);cursor:pointer;padding:10px;opacity:.7;display:none}.viewer-wheel>div:hover{opacity:1}.viewer--nav-prev .viewer-wheel-prev{left:0;display:block}.viewer--nav-next .viewer-wheel-next{right:0;display:block}.viewer-wheel>div>.icon{position:absolute;top:50%;transform:translateY(-50%);display:block}.viewer-foot{padding:20px;position:absolute;left:0;right:0;bottom:0;height:80px;background:-webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.6)));background:-webkit-linear-gradient(top,transparent 0,rgba(0,0,0,.6) 100%);background:-moz-linear-gradient(top,transparent 0,rgba(0,0,0,.6) 100%);background:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.6) 100%)}.viewer-foot{display:flex;flex-wrap:wrap;flex-flow:row}.viewer-owner{width:190px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.viewer-owner .user-image{width:40px;height:40px;vertical-align:bottom;margin-right:10px}.viewer-owner .user-name{font-size:initial;text-decoration:none;vertical-align:middle;line-height:40px;color:inherit}.viewer-owner a.user-name:hover{color:rgba(255,255,255,.8)}.viewer-owner{order:1}.viewer-kb{font-size:.86em;flex-grow:1;order:2;padding-right:190px;text-align:center}.device-mobile .viewer-kb{display:none}.viewer-kb-input{display:inline-block}.viewer-kb-key{color:#fff;display:inline-block;margin:10px}.viewer-kb-key kbd{border:1px solid rgba(0,0,0,.5);background:rgba(120,120,120,.5);color:#fff;padding:4px 6px;border-radius:2px;display:inline-block;margin-right:5px;line-height:1}.viewer-like{transform:none;top:auto;bottom:20px;right:20px;position:absolute}.viewer:hover .hover-display--flex{display:flex}.--width-auto{width:auto}.--height-auto{height:auto}html.--idle .viewer,html.--idle .viewer *{cursor:none!important}html .fullscreen-show{display:none}:-webkit-full-screen .fullscreen-hide{display:none}:-moz-full-screen .fullscreen-hide{display:none}:-ms-fullscreen .fullscreen-hide{display:none}:fullscreen .fullscreen-hide{display:none}:-webkit-full-screen .fullscreen-show{display:block}:-moz-full-screen .fullscreen-show{display:block}:-ms-fullscreen .fullscreen-show{display:block}:fullscreen .fullscreen-show{display:block}a.image-container{-webkit-tap-highlight-color:transparent}a{color:#3498db;outline:0}a{text-decoration:none}input,textarea{border-color:#c6c8ca}.content-section,.input-label{margin-top:20px;margin-bottom:20px;position:relative}.content-section:first-child{margin-top:0}.input-label .input{width:100%;margin-bottom:0}.input-label .input+.input{margin-top:5px}.input-label .input-label{margin-bottom:10px}.input-label .input-label .label{font-weight:400}.input-label label .caption,.input-label label .optional{font-weight:400;font-size:.92em}.input-label label .caption:before,.input-label label .optional:before{content:"("}.input-label label .caption:after,.input-label label .optional:after{content:")"}.input-label-below{margin-top:5px;clear:both}.background-cover{position:fixed;top:0;right:0;bottom:0;left:0;background-position:center center;background-size:cover}.input-with-button{position:relative}.input-with-button button{background:0 0;position:absolute;right:0;top:50%;transform:translateY(-50%);border:none;font-size:22px;width:1em;height:1em;outline:0;color:#d9d9d9}.tone-dark .input-with-button button{color:#666}.input-with-button button:focus,.input-with-button button:hover{color:#3498db}#top-left{position:fixed;padding:5px;left:0;top:0}.top-button{padding:5px}.top-button .menu-box{margin-top:5px}.top-button-icon{font-size:16px;color:#fff;cursor:pointer;text-shadow:1px 1px 0 rgba(0,0,0,.15)}.background-default{background:#2ecc71;background:-moz-linear-gradient(top,#2ecc71 0,#3498db 100%);background:-webkit-linear-gradient(top,#2ecc71 0,#3498db 100%);background:linear-gradient(to bottom,#2ecc71 0,#3498db 100%)}.content-box{position:relative;margin:20px}.content-box-text :first-child{margin-top:0}.content-box-text :last-child{margin-bottom:0}.logo{max-height:50px;max-width:220px;margin-bottom:20px}.card-box{min-width:270px;width:calc(100vw - 40px)}.access-box-content{background:#fff}.fancy-box-heading{font-size:22px;margin:20px 0 30px 0}.fancy-fieldset{border:0;padding:0;margin:0}.fancy-fieldset input:not([type=checkbox]),.fancy-fieldset input[type=text],.fancy-fieldset select,.fancy-fieldset textarea{outline:0;padding:10px 0;width:100%;border-radius:0;border-color:#ebebeb;background:0 0;box-shadow:none}.fancy-fieldset .checkbox-label input[type=checkbox]{width:auto;vertical-align:middle;margin:0 0 0 -20px}.tone-dark .fancy-fieldset input,.tone-dark .fancy-fieldset input[type=text],.tone-dark .fancy-fieldset select,.tone-dark .fancy-fieldset textarea{box-shadow:none;border-color:#212121}.fancy-fieldset select{-webkit-appearance:none;-moz-appearance:none;appearance:none}.fancy-fieldset input,.fancy-fieldset select{padding:10px 0;border-top:transparent;border-left:transparent;border-right:transparent}.fancy-fieldset input:focus,.fancy-fieldset input:focus[type=text],.fancy-fieldset select:focus,.fancy-fieldset textarea:focus{border-color:#3498db}.fancy-fieldset .input-with-button input[type=password]{padding-right:30px}.fancy-fieldset>div:last-child{margin-bottom:inherit}.fancy-fieldset .label{line-height:1.5}.fancy-fieldset .input-label:last-child{margin-bottom:0}.fancy-fieldset .checkbox-label{margin:0}a.social-button{position:relative;text-decoration:none;display:inline-block;font-size:1em;margin:10px 0;background:#d9d9d9;padding:8px;text-decoration:none;display:block;color:#fff;border-radius:3px}a.social-button--facebook{background-color:#4267b2}a.social-button--facebook .icon:before{content:"\e8c9"}a.social-button--twitter{background-color:#1da1f2}a.social-button--google{background-color:#ea4335}a.social-button--vk{background-color:#45668e}.social-button-outline{position:relative;text-decoration:none;width:32px;height:32px;display:inline-block;border-radius:50%;border-width:1px;border-style:solid;font-size:16px;margin:5px}.social-button-outline .icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.social-button-outline.border-color-facebook:focus,.social-button-outline.border-color-facebook:hover{background-color:#3b5998}.social-button-outline.border-color-twitter:focus,.social-button-outline.border-color-twitter:hover{background-color:#1da1f2}.social-button-outline.border-color-google:focus,.social-button-outline.border-color-google:hover{background-color:#ea4335}.social-button-outline.border-color-vk:focus,.social-button-outline.border-color-vk:hover{background-color:#45668e}.social-button-outline:focus .icon,.social-button-outline:hover .icon{color:#fff}#login{padding:0;margin:0}.content-section--recaptchaFix #g-recaptcha{min-height:78px;-webkit-transform:scale(.89);-ms-transform:scale(.89);transform:scale(.89);-webkit-transform-origin:left;-ms-transform-origin:left;transform-origin:left}#login .input{margin:0}.btn-container--fixed{position:fixed;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);padding:10px;margin:0;border:0}.tone-dark .btn-container--fixed{background:rgba(0,0,0,.75)}body#dashboard{min-height:100%;padding-bottom:4em}body.full--wh{height:100%;width:100%}.display-flex #home-cover-slideshow{position:fixed}[data-content=dashboard-imports] [data-action=resume],[data-content=dashboard-imports] [data-errors="0"] [data-content=log-errors],[data-content=dashboard-imports] [data-result],[data-content=dashboard-imports] [data-started="0"] [data-content^=log]{display:none}[data-content=dashboard-imports] [data-errors="1"] [data-content=log-process],[data-content=dashboard-imports] [data-status=completed] [data-action=pause],[data-content=dashboard-imports] [data-status=completed][data-errors="0"] [data-result=success],[data-content=dashboard-imports] [data-status=paused] [data-action=resume],[data-content=dashboard-imports] [data-status][data-errors="1"] [data-result=error]{display:initial}[data-content=dashboard-imports] [data-status=canceled] [data-action=cancel],[data-content=dashboard-imports] [data-status=canceled] [data-action=pause],[data-content=dashboard-imports] [data-status=canceled] [data-target=modal-process-import],[data-content=dashboard-imports] [data-status=completed] [data-action=cancel],[data-content=dashboard-imports] [data-status=completed] [data-action=pause],[data-content=dashboard-imports] [data-status=completed] [data-target=modal-process-import],[data-content=dashboard-imports] [data-status=paused] [data-action=pause],[data-content=dashboard-imports] [data-status=queued] [data-action=pause],[data-content=dashboard-imports] [data-status=working] [data-target=modal-process-import]{display:none!important}.panel-thumb-list li{overflow:hidden}.connecting-ip{font-family:monospace;font-size:27px}.code{padding:2px;background:#ecf0f1}.tone-dark .code{background:#0b0b0b}.importing{background:#ecf0f1;padding:10px;position:relative}.tone-dark .importing{background:#111}.importing:nth-child(even){margin:0 10px}.phablet .importing:nth-child(even),.phone .importing:nth-child(even){margin:10px 0}.importing-stats{margin:10px 0}.importing-stats .figure{display:inline-block;padding:5px;background:rgba(0,0,0,.1)}.tone-dark .importing-stats .figure{background:rgba(255,255,255,.1)}body#index.landing [data-action=top-bar-tone]{display:none} \ No newline at end of file diff --git a/app/themes/Peafowl/views/dashboard.php b/app/themes/Peafowl/views/dashboard.php index 4e5157b..3ef1be2 100644 --- a/app/themes/Peafowl/views/dashboard.php +++ b/app/themes/Peafowl/views/dashboard.php @@ -108,7 +108,359 @@ function free_version_waring($wrap=true) -
    +
    + + +
    +

    +
    +
    + +
    +
    +
    +
    +

    +
    +
    +

    🤖

    +

    '' . G_ROOT_PATH . 'importing']); ?> '1', + '%m' => _n('minute', 'minutes', '1') + ]); ?>

    +
    +
    + _s('Queued'), + 'working' => _s('Working'), + 'paused' => _s('Paused'), + 'canceled' => _s('Canceled'), + 'completed' => _s('Completed'), + ]; + if ($continuous = CHV\Import::getContinuous()) { + foreach ($continuous as $v) { + $boxTpl = '
    +

    Path %pathRelative%

    + + +
    + %images% images + %albums% albums + %users% users +
    +
    ' . _s('Status') . ': %displayStatus%
    +
    @%dateTime% UTC
    +
    +
    '; + echo strtr($boxTpl, [ + '%id%' => $v['id'], + '%dateTime%' => $v['time_updated'], + '%object%' => htmlspecialchars(json_encode($v), ENT_QUOTES, 'UTF-8'), + '%status%' => $v['status'], + '%parse%' => $v['options']['root'], + '%shortParse%' => $v['options']['root'][0], + '%displayStatus%' => $statusesDisplay[$v['status']], + '%path%' => $v['path'], + '%pathRelative%' => '.' . G\absolute_to_relative($v['path']), + '%users%' => $v['users'] ?: 0, + '%images%' => $v['images'] ?: 0, + '%albums%' => $v['albums'] ?: 0, + '%errors%' => $v['errors'] ?: 0, + '%started%' => $v['started'] ?: 0, + ]); + } + } ?> +
    +
    +
    +
    + * * * * * IS_CRON=1 THREAD_ID=1 /usr/bin/php >/dev/null 2>&1 +
    +
    'THREAD_ID']); ?>
    +
    + G_ROOT_PATH . 'importing']); ?> +
    +
    +
    + + + + &$v) { + if ($v['status'] != 'working') { + continue; + } + $then = strtotime($v['time_updated']); + $now = strtotime(G\datetimegmt()); + if ($now > ($then + 300)) { // 5 min + $v['status'] = 'paused'; + CHV\DB::update('imports', ['status' => 'paused'], ['id' => $v['id']]); + } + } + $imports = array_reverse($imports); + } + $rowTpl = '
  • + %id% + %shortParse% + + + + %displayStatus% + + %path% + %users% ' . _s('Users') . ' + %albums% ' . _s('Albums') . ' + %images% ' . _s('Images') . ' + +
  • '; + $manualImportingClass = is_array($imports) == false ? ' hidden' : ''; + ?> +
    +

    +

    +
    + +
      +
    • + ID + + + + + + +   +
    • + $v) { + echo strtr($rowTpl, [ + '%id%' => $v['id'], + '%object%' => htmlspecialchars(json_encode($v), ENT_QUOTES, 'UTF-8'), + '%status%' => $v['status'], + '%parse%' => $v['options']['root'], + '%shortParse%' => $v['options']['root'][0], + '%displayStatus%' => $statusesDisplay[$v['status']], + '%path%' => $v['path'], + '%users%' => $v['users'] ?: 0, + '%images%' => $v['images'] ?: 0, + '%albums%' => $v['albums'] ?: 0, + '%errors%' => $v['errors'] ?: 0, + '%started%' => $v['started'] ?: 0, + ]); + } + } + ?> +
    + * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { diff --git a/app/vendor/composer/InstalledVersions.php b/app/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..c67d75f --- /dev/null +++ b/app/vendor/composer/InstalledVersions.php @@ -0,0 +1,245 @@ + + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '892dc79d4abe4d0139868de4b440739906564564', + 'name' => 'chevereto/chevereto-free', + ), + 'versions' => + array ( + 'chevereto/chevereto-free' => + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '892dc79d4abe4d0139868de4b440739906564564', + ), + 'jbroadway/urlify' => + array ( + 'pretty_version' => '1.1.3-stable', + 'version' => '1.1.3.0', + 'aliases' => + array ( + ), + 'reference' => '37fe4e7680a1c8cd68ac43a27dac7ef4be476300', + ), + 'mobiledetect/mobiledetectlib' => + array ( + 'pretty_version' => '2.8.34', + 'version' => '2.8.34.0', + 'aliases' => + array ( + ), + 'reference' => '6f8113f57a508494ca36acbcfa2dc2d923c7ed5b', + ), + 'phpmailer/phpmailer' => + array ( + 'pretty_version' => 'v6.1.7', + 'version' => '6.1.7.0', + 'aliases' => + array ( + ), + 'reference' => '2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0', + ), + 'tijsverkoyen/akismet' => + array ( + 'pretty_version' => '1.1.1', + 'version' => '1.1.1.0', + 'aliases' => + array ( + ), + 'reference' => '6f7987fe181fd0fddbc9832f2ddeaf088425c83f', + ), + ), +); + + + + + + + +public static function getInstalledPackages() +{ +return array_keys(self::$installed['versions']); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +return isset(self::$installed['versions'][$packageName]); +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +$ranges = array(); +if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + + + + + +public static function getVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['version']; +} + + + + + +public static function getPrettyVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['pretty_version']; +} + + + + + +public static function getReference($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['reference'])) { +return null; +} + +return self::$installed['versions'][$packageName]['reference']; +} + + + + + +public static function getRootPackage() +{ +return self::$installed['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +} +} diff --git a/app/vendor/composer/autoload_classmap.php b/app/vendor/composer/autoload_classmap.php index 5b216c3..c5ad0ae 100644 --- a/app/vendor/composer/autoload_classmap.php +++ b/app/vendor/composer/autoload_classmap.php @@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname(dirname($vendorDir)); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Detection\\MobileDetect' => $vendorDir . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php', 'Mobile_Detect' => $vendorDir . '/mobiledetect/mobiledetectlib/Mobile_Detect.php', 'PHPMailer\\PHPMailer\\Exception' => $vendorDir . '/phpmailer/phpmailer/src/Exception.php', @@ -16,5 +17,4 @@ return array( 'TijsVerkoyen\\Akismet\\Akismet' => $vendorDir . '/tijsverkoyen/akismet/Akismet.php', 'TijsVerkoyen\\Akismet\\Exception' => $vendorDir . '/tijsverkoyen/akismet/Exception.php', 'URLify' => $vendorDir . '/jbroadway/urlify/URLify.php', - 'URLifyTest' => $vendorDir . '/jbroadway/urlify/tests/URLifyTest.php', ); diff --git a/app/vendor/composer/autoload_real.php b/app/vendor/composer/autoload_real.php index 0b8ba41..ce157b0 100644 --- a/app/vendor/composer/autoload_real.php +++ b/app/vendor/composer/autoload_real.php @@ -22,13 +22,15 @@ class ComposerAutoloaderInit5ebab6dc32ca006b1a67a63e20c04846 return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInit5ebab6dc32ca006b1a67a63e20c04846', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit5ebab6dc32ca006b1a67a63e20c04846', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInit5ebab6dc32ca006b1a67a63e20c04846::getInitializer($loader)); } else { diff --git a/app/vendor/composer/autoload_static.php b/app/vendor/composer/autoload_static.php index 7f6ce08..8321846 100644 --- a/app/vendor/composer/autoload_static.php +++ b/app/vendor/composer/autoload_static.php @@ -38,6 +38,7 @@ class ComposerStaticInit5ebab6dc32ca006b1a67a63e20c04846 ); public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Detection\\MobileDetect' => __DIR__ . '/..' . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php', 'Mobile_Detect' => __DIR__ . '/..' . '/mobiledetect/mobiledetectlib/Mobile_Detect.php', 'PHPMailer\\PHPMailer\\Exception' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/Exception.php', @@ -48,7 +49,6 @@ class ComposerStaticInit5ebab6dc32ca006b1a67a63e20c04846 'TijsVerkoyen\\Akismet\\Akismet' => __DIR__ . '/..' . '/tijsverkoyen/akismet/Akismet.php', 'TijsVerkoyen\\Akismet\\Exception' => __DIR__ . '/..' . '/tijsverkoyen/akismet/Exception.php', 'URLify' => __DIR__ . '/..' . '/jbroadway/urlify/URLify.php', - 'URLifyTest' => __DIR__ . '/..' . '/jbroadway/urlify/tests/URLifyTest.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/app/vendor/composer/installed.json b/app/vendor/composer/installed.json index 50850ee..144cafa 100644 --- a/app/vendor/composer/installed.json +++ b/app/vendor/composer/installed.json @@ -1,226 +1,237 @@ -[ - { - "name": "jbroadway/urlify", - "version": "1.1.3-stable", - "version_normalized": "1.1.3.0", - "source": { - "type": "git", - "url": "https://github.com/jbroadway/urlify.git", - "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jbroadway/urlify/zipball/37fe4e7680a1c8cd68ac43a27dac7ef4be476300", - "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5" - }, - "time": "2019-06-13T18:30:56+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "URLify": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause-Clear" - ], - "authors": [ - { - "name": "Johnny Broadway", - "email": "johnny@johnnybroadway.com", - "homepage": "http://www.johnnybroadway.com/" - } - ], - "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.", - "homepage": "https://github.com/jbroadway/urlify", - "keywords": [ - "encode", - "iconv", - "link", - "slug", - "translit", - "transliterate", - "transliteration", - "url", - "urlify" - ] - }, - { - "name": "mobiledetect/mobiledetectlib", - "version": "2.8.34", - "version_normalized": "2.8.34.0", - "source": { - "type": "git", - "url": "https://github.com/serbanghita/Mobile-Detect.git", - "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", - "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", - "shasum": "" - }, - "require": { - "php": ">=5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.35||~5.7" - }, - "time": "2019-09-18T18:44:20+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "Mobile_Detect.php" +{ + "packages": [ + { + "name": "jbroadway/urlify", + "version": "1.1.3-stable", + "version_normalized": "1.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/jbroadway/urlify.git", + "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jbroadway/urlify/zipball/37fe4e7680a1c8cd68ac43a27dac7ef4be476300", + "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5" + }, + "time": "2019-06-13T18:30:56+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "URLify": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause-Clear" ], - "psr-0": { - "Detection": "namespaced/" - } + "authors": [ + { + "name": "Johnny Broadway", + "email": "johnny@johnnybroadway.com", + "homepage": "http://www.johnnybroadway.com/" + } + ], + "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.", + "homepage": "https://github.com/jbroadway/urlify", + "keywords": [ + "encode", + "iconv", + "link", + "slug", + "translit", + "transliterate", + "transliteration", + "url", + "urlify" + ], + "install-path": "../jbroadway/urlify" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Serban Ghita", - "email": "serbanghita@gmail.com", - "homepage": "http://mobiledetect.net", - "role": "Developer" - } - ], - "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", - "homepage": "https://github.com/serbanghita/Mobile-Detect", - "keywords": [ - "detect mobile devices", - "mobile", - "mobile detect", - "mobile detector", - "php mobile detect" - ] - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.1.6", - "version_normalized": "6.1.6.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", - "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "doctrine/annotations": "^1.2", - "friendsofphp/php-cs-fixer": "^2.2", - "phpunit/phpunit": "^4.8 || ^5.7" - }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" - }, - "time": "2020-05-27T12:24:03+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" + { + "name": "mobiledetect/mobiledetectlib", + "version": "2.8.34", + "version_normalized": "2.8.34.0", + "source": { + "type": "git", + "url": "https://github.com/serbanghita/Mobile-Detect.git", + "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b" }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", + "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", + "shasum": "" }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" + "require": { + "php": ">=5.0.0" }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "funding": [ - { - "url": "https://github.com/synchro", - "type": "github" - } - ] - }, - { - "name": "tijsverkoyen/akismet", - "version": "1.1.1", - "version_normalized": "1.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/tijsverkoyen/Akismet.git", - "reference": "6f7987fe181fd0fddbc9832f2ddeaf088425c83f" + "require-dev": { + "phpunit/phpunit": "~4.8.35||~5.7" + }, + "time": "2019-09-18T18:44:20+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "Mobile_Detect.php" + ], + "psr-0": { + "Detection": "namespaced/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Serban Ghita", + "email": "serbanghita@gmail.com", + "homepage": "http://mobiledetect.net", + "role": "Developer" + } + ], + "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", + "homepage": "https://github.com/serbanghita/Mobile-Detect", + "keywords": [ + "detect mobile devices", + "mobile", + "mobile detect", + "mobile detector", + "php mobile detect" + ], + "install-path": "../mobiledetect/mobiledetectlib" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/Akismet/zipball/6f7987fe181fd0fddbc9832f2ddeaf088425c83f", - "reference": "6f7987fe181fd0fddbc9832f2ddeaf088425c83f", - "shasum": "" + { + "name": "phpmailer/phpmailer", + "version": "v6.1.7", + "version_normalized": "6.1.7.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", + "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "doctrine/annotations": "^1.2", + "friendsofphp/php-cs-fixer": "^2.2", + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "time": "2020-07-14T18:50:27+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://github.com/synchro", + "type": "github" + } + ], + "install-path": "../phpmailer/phpmailer" }, - "require": { - "ext-curl": "*", - "php": ">=5.2.0" - }, - "time": "2016-07-19T13:50:18+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD" - ], - "authors": [ - { - "name": "Tijs Verkoyen", - "email": "akismet@verkoyen.eu", - "role": "Developer" - } - ], - "description": "Akismet is a wrapper-class to communicate with the Akismet API.", - "homepage": "https://github.com/tijsverkoyen/Akismet" - } -] + { + "name": "tijsverkoyen/akismet", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/Akismet.git", + "reference": "6f7987fe181fd0fddbc9832f2ddeaf088425c83f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/Akismet/zipball/6f7987fe181fd0fddbc9832f2ddeaf088425c83f", + "reference": "6f7987fe181fd0fddbc9832f2ddeaf088425c83f", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.2.0" + }, + "time": "2016-07-19T13:50:18+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "akismet@verkoyen.eu", + "role": "Developer" + } + ], + "description": "Akismet is a wrapper-class to communicate with the Akismet API.", + "homepage": "https://github.com/tijsverkoyen/Akismet", + "install-path": "../tijsverkoyen/akismet" + } + ], + "dev": true +} diff --git a/app/vendor/composer/installed.php b/app/vendor/composer/installed.php new file mode 100644 index 0000000..1ac16ff --- /dev/null +++ b/app/vendor/composer/installed.php @@ -0,0 +1,60 @@ + + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '892dc79d4abe4d0139868de4b440739906564564', + 'name' => 'chevereto/chevereto-free', + ), + 'versions' => + array ( + 'chevereto/chevereto-free' => + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '892dc79d4abe4d0139868de4b440739906564564', + ), + 'jbroadway/urlify' => + array ( + 'pretty_version' => '1.1.3-stable', + 'version' => '1.1.3.0', + 'aliases' => + array ( + ), + 'reference' => '37fe4e7680a1c8cd68ac43a27dac7ef4be476300', + ), + 'mobiledetect/mobiledetectlib' => + array ( + 'pretty_version' => '2.8.34', + 'version' => '2.8.34.0', + 'aliases' => + array ( + ), + 'reference' => '6f8113f57a508494ca36acbcfa2dc2d923c7ed5b', + ), + 'phpmailer/phpmailer' => + array ( + 'pretty_version' => 'v6.1.7', + 'version' => '6.1.7.0', + 'aliases' => + array ( + ), + 'reference' => '2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0', + ), + 'tijsverkoyen/akismet' => + array ( + 'pretty_version' => '1.1.1', + 'version' => '1.1.1.0', + 'aliases' => + array ( + ), + 'reference' => '6f7987fe181fd0fddbc9832f2ddeaf088425c83f', + ), + ), +); diff --git a/app/vendor/composer/platform_check.php b/app/vendor/composer/platform_check.php new file mode 100644 index 0000000..b9728b4 --- /dev/null +++ b/app/vendor/composer/platform_check.php @@ -0,0 +1,23 @@ += 50500)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 5.5.0". You are running ' . PHP_VERSION . '.'; +} + +$missingExtensions = array(); +extension_loaded('ctype') || $missingExtensions[] = 'ctype'; +extension_loaded('curl') || $missingExtensions[] = 'curl'; +extension_loaded('filter') || $missingExtensions[] = 'filter'; + +if ($missingExtensions) { + $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions); +} + +if ($issues) { + echo 'Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues); + exit(104); +} diff --git a/app/vendor/phpmailer/phpmailer/VERSION b/app/vendor/phpmailer/phpmailer/VERSION index 3af67b5..cb6b1ff 100644 --- a/app/vendor/phpmailer/phpmailer/VERSION +++ b/app/vendor/phpmailer/phpmailer/VERSION @@ -1 +1 @@ -6.1.6 \ No newline at end of file +6.1.7 \ No newline at end of file diff --git a/app/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php b/app/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php index 4408e63..c78237e 100644 --- a/app/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php +++ b/app/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php @@ -19,8 +19,8 @@ $PHPMAILER_LANG['invalid_address'] = 'Felaktig adress: '; $PHPMAILER_LANG['provide_address'] = 'Du måste ange minst en mottagares e-postadress.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP fel: Följande mottagare är felaktig: '; -$PHPMAILER_LANG['signing'] = 'Signerings fel: '; +$PHPMAILER_LANG['signing'] = 'Signeringsfel: '; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() misslyckades.'; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server fel: '; +$PHPMAILER_LANG['smtp_error'] = 'SMTP serverfel: '; $PHPMAILER_LANG['variable_set'] = 'Kunde inte definiera eller återställa variabel: '; $PHPMAILER_LANG['extension_missing'] = 'Tillägg ej tillgängligt: '; diff --git a/app/vendor/phpmailer/phpmailer/src/PHPMailer.php b/app/vendor/phpmailer/phpmailer/src/PHPMailer.php index ed14d7c..2d4156f 100644 --- a/app/vendor/phpmailer/phpmailer/src/PHPMailer.php +++ b/app/vendor/phpmailer/phpmailer/src/PHPMailer.php @@ -441,6 +441,8 @@ class PHPMailer * Only supported in `mail` and `sendmail` transports, not in SMTP. * * @var bool + * + * @deprecated 6.0.0 PHPMailer isn't a mailing list manager! */ public $SingleTo = false; @@ -745,7 +747,7 @@ class PHPMailer * * @var string */ - const VERSION = '6.1.6'; + const VERSION = '6.1.7'; /** * Error severity: message only, continue processing. @@ -1307,7 +1309,7 @@ class PHPMailer $patternselect = static::$validator; } if (is_callable($patternselect)) { - return $patternselect($address); + return call_user_func($patternselect, $address); } //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 if (strpos($address, "\n") !== false || strpos($address, "\r") !== false) { @@ -2975,7 +2977,6 @@ class PHPMailer if ('' === $name) { $name = $filename; } - if (!$this->validateEncoding($encoding)) { throw new Exception($this->lang('encoding') . $encoding); } @@ -3990,7 +3991,8 @@ class PHPMailer * @param string $message HTML message string * @param string $basedir Absolute path to a base directory to prepend to relative paths to images * @param bool|callable $advanced Whether to use the internal HTML to text converter - * or your own custom converter @return string $message The transformed message Body + * or your own custom converter + * @return string The transformed message body * * @throws Exception * @@ -4114,7 +4116,7 @@ class PHPMailer public function html2text($html, $advanced = false) { if (is_callable($advanced)) { - return $advanced($html); + return call_user_func($advanced, $html); } return html_entity_decode( diff --git a/app/vendor/phpmailer/phpmailer/src/POP3.php b/app/vendor/phpmailer/phpmailer/src/POP3.php index 7d4c88f..9a3b07c 100644 --- a/app/vendor/phpmailer/phpmailer/src/POP3.php +++ b/app/vendor/phpmailer/phpmailer/src/POP3.php @@ -45,7 +45,7 @@ class POP3 * * @var string */ - const VERSION = '6.1.6'; + const VERSION = '6.1.7'; /** * Default POP3 port number. diff --git a/app/vendor/phpmailer/phpmailer/src/SMTP.php b/app/vendor/phpmailer/phpmailer/src/SMTP.php index aa55551..6b0b73d 100644 --- a/app/vendor/phpmailer/phpmailer/src/SMTP.php +++ b/app/vendor/phpmailer/phpmailer/src/SMTP.php @@ -34,7 +34,7 @@ class SMTP * * @var string */ - const VERSION = '6.1.6'; + const VERSION = '6.1.7'; /** * SMTP line break constant. @@ -311,12 +311,6 @@ class SMTP */ public function connect($host, $port = null, $timeout = 30, $options = []) { - static $streamok; - //This is enabled by default since 5.0.0 but some providers disable it - //Check this once and cache the result - if (null === $streamok) { - $streamok = function_exists('stream_socket_client'); - } // Clear errors to avoid confusion $this->setError(''); // Make sure we are __not__ connected @@ -335,12 +329,48 @@ class SMTP (count($options) > 0 ? var_export($options, true) : 'array()'), self::DEBUG_CONNECTION ); + + $this->smtp_conn = $this->getSMTPConnection($host, $port, $timeout, $options); + + if ($this->smtp_conn === false) { + //Error info already set inside `getSMTPConnection()` + return false; + } + + $this->edebug('Connection: opened', self::DEBUG_CONNECTION); + + // Get any announcement + $this->last_reply = $this->get_lines(); + $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); + + return true; + } + + /** + * Create connection to the SMTP server. + * + * @param string $host SMTP server IP or host name + * @param int $port The port number to connect to + * @param int $timeout How long to wait for the connection to open + * @param array $options An array of options for stream_context_create() + * + * @return false|resource + */ + protected function getSMTPConnection($host, $port = null, $timeout = 30, $options = []) + { + static $streamok; + //This is enabled by default since 5.0.0 but some providers disable it + //Check this once and cache the result + if (null === $streamok) { + $streamok = function_exists('stream_socket_client'); + } + $errno = 0; $errstr = ''; if ($streamok) { $socket_context = stream_context_create($options); set_error_handler([$this, 'errorHandler']); - $this->smtp_conn = stream_socket_client( + $connection = stream_socket_client( $host . ':' . $port, $errno, $errstr, @@ -356,7 +386,7 @@ class SMTP self::DEBUG_CONNECTION ); set_error_handler([$this, 'errorHandler']); - $this->smtp_conn = fsockopen( + $connection = fsockopen( $host, $port, $errno, @@ -365,8 +395,9 @@ class SMTP ); restore_error_handler(); } + // Verify we connected properly - if (!is_resource($this->smtp_conn)) { + if (!is_resource($connection)) { $this->setError( 'Failed to connect to server', '', @@ -381,22 +412,19 @@ class SMTP return false; } - $this->edebug('Connection: opened', self::DEBUG_CONNECTION); + // SMTP server can take longer to respond, give longer timeout for first read // Windows does not have support for this timeout function if (strpos(PHP_OS, 'WIN') !== 0) { - $max = (int) ini_get('max_execution_time'); + $max = (int)ini_get('max_execution_time'); // Don't bother if unlimited if (0 !== $max && $timeout > $max) { @set_time_limit($timeout); } - stream_set_timeout($this->smtp_conn, $timeout, 0); + stream_set_timeout($connection, $timeout, 0); } - // Get any announcement - $announce = $this->get_lines(); - $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER); - return true; + return $connection; } /** @@ -1166,13 +1194,40 @@ class SMTP $selW = null; while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { //Must pass vars in here as params are by reference - if (!stream_select($selR, $selW, $selW, $this->Timelimit)) { + //solution for signals inspired by https://github.com/symfony/symfony/pull/6540 + set_error_handler([$this, 'errorHandler']); + $n = stream_select($selR, $selW, $selW, $this->Timelimit); + restore_error_handler(); + + if ($n === false) { + $message = $this->getError()['detail']; + + $this->edebug( + 'SMTP -> get_lines(): select failed (' . $message . ')', + self::DEBUG_LOWLEVEL + ); + + //stream_select returns false when the `select` system call is interrupted by an incoming signal, try the select again + if (stripos($message, 'interrupted system call') !== false) { + $this->edebug( + 'SMTP -> get_lines(): retrying stream_select', + self::DEBUG_LOWLEVEL + ); + $this->setError(''); + continue; + } + + break; + } + + if (!$n) { $this->edebug( 'SMTP -> get_lines(): select timed-out in (' . $this->Timelimit . ' sec)', self::DEBUG_LOWLEVEL ); break; } + //Deliberate noise suppression - errors are handled afterwards $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH); $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL); diff --git a/composer.lock b/composer.lock index 18d630f..a06d489 100644 --- a/composer.lock +++ b/composer.lock @@ -61,6 +61,10 @@ "url", "urlify" ], + "support": { + "issues": "https://github.com/jbroadway/urlify/issues", + "source": "https://github.com/jbroadway/urlify/tree/1.1.3-stable" + }, "time": "2019-06-13T18:30:56+00:00" }, { @@ -113,20 +117,24 @@ "mobile detector", "php mobile detect" ], + "support": { + "issues": "https://github.com/serbanghita/Mobile-Detect/issues", + "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.34" + }, "time": "2019-09-18T18:44:20+00:00" }, { "name": "phpmailer/phpmailer", - "version": "v6.1.6", + "version": "v6.1.7", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3" + "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", - "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", + "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", "shasum": "" }, "require": { @@ -175,13 +183,17 @@ } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.1.7" + }, "funding": [ { "url": "https://github.com/synchro", "type": "github" } ], - "time": "2020-05-27T12:24:03+00:00" + "time": "2020-07-14T18:50:27+00:00" }, { "name": "tijsverkoyen/akismet", @@ -220,6 +232,10 @@ ], "description": "Akismet is a wrapper-class to communicate with the Akismet API.", "homepage": "https://github.com/tijsverkoyen/Akismet", + "support": { + "issues": "https://github.com/tijsverkoyen/Akismet/issues", + "source": "https://github.com/tijsverkoyen/Akismet/tree/master" + }, "time": "2016-07-19T13:50:18+00:00" } ], @@ -231,5 +247,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.0.0" } diff --git a/importing.php b/importing.php new file mode 100644 index 0000000..e0359f1 --- /dev/null +++ b/importing.php @@ -0,0 +1,52 @@ + + + + Copyright (C) Rodolfo Berrios A. All rights reserved. + + BY USING THIS SOFTWARE YOU DECLARE TO ACCEPT THE CHEVERETO EULA + http://chevereto.com/license + + --------------------------------------------------------------------- */ + +define('access', 'cli'); + +$isCron = getenv('IS_CRON'); +if (!$isCron) { + header('HTTP/1.0 403 Forbidden'); + die("403 Forbidden\n"); +} +$threadID = getenv('THREAD_ID'); +if (!$threadID) { + die("Missing thread id (int)\n"); +} +if (!include_once('app/loader.php')) { + die("Can't find app/loader.php\n"); +} +do { + try { + CHV\Import::refresh(); + $jobs = CHV\Import::autoJobs(); + if (!$jobs) { + echo "No jobs left.\n"; + die(0); + } + $id = $jobs[0]['import_id']; + $import = new CHV\Import(); + $import->id = $id; + $import->thread = (int) $threadID; + $import->process(); + echo "Processed job id #$id\n"; + $loop++; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + die(255); + } +} while (CHV\isSafeToExecute()); +echo "--\nLooped $loop times ~ /dashboard/bulk for stats \n"; +die(0); diff --git a/importing/.htaccess b/importing/.htaccess new file mode 100644 index 0000000..2fdb79b --- /dev/null +++ b/importing/.htaccess @@ -0,0 +1 @@ +SetHandler default-handler \ No newline at end of file