Massive graphical overhaul

This commit is contained in:
2018-01-07 21:42:19 +01:00
parent 9a4eddcbd1
commit 636643c9e0
44 changed files with 600 additions and 548 deletions

View File

@@ -24,6 +24,7 @@ func Init(r *httprouter.Router, prefix string) {
r.GET(prefix+"/", webcontroller.ServeHome) r.GET(prefix+"/", webcontroller.ServeHome)
r.GET(prefix+"/favicon.ico", webcontroller.ServeFavicon) r.GET(prefix+"/favicon.ico", webcontroller.ServeFavicon)
r.GET(prefix+"/global.css", webcontroller.GlobalCSSHandler)
r.GET(prefix+"/api", webcontroller.ServeAPIDoc) r.GET(prefix+"/api", webcontroller.ServeAPIDoc)
r.GET(prefix+"/history", webcontroller.ServeHistory) r.GET(prefix+"/history", webcontroller.ServeHistory)
r.GET(prefix+"/u/:id", webcontroller.ServeFileViewer) r.GET(prefix+"/u/:id", webcontroller.ServeFileViewer)

View File

@@ -2,11 +2,18 @@ package pixelapi
import ( import (
"encoding/json" "encoding/json"
"io"
"fornaxian.com/pixeldrain-web/conf" "fornaxian.com/pixeldrain-web/conf"
"fornaxian.com/pixeldrain-web/log" "fornaxian.com/pixeldrain-web/log"
) )
// GetFile makes a file download request and returns a readcloser. Don't forget
// to close it!
func GetFile(id string) (io.ReadCloser, error) {
return getRaw(conf.ApiUrlInternal() + "/file/" + id)
}
// FileInfo File information object from the pixeldrain API // FileInfo File information object from the pixeldrain API
type FileInfo struct { type FileInfo struct {
ID string `json:"id"` ID string `json:"id"`
@@ -24,7 +31,7 @@ type FileInfo struct {
// GetFileInfo gets the FileInfo from the pixeldrain API // GetFileInfo gets the FileInfo from the pixeldrain API
func GetFileInfo(id string) *FileInfo { func GetFileInfo(id string) *FileInfo {
body, err := get(conf.ApiUrlInternal() + "/file/" + id + "/info") body, err := getString(conf.ApiUrlInternal() + "/file/" + id + "/info")
if err != nil { if err != nil {
log.Error("req failed: %v", err) log.Error("req failed: %v", err)

View File

@@ -28,7 +28,7 @@ type ListFile struct {
// GetList get a List from the pixeldrain API // GetList get a List from the pixeldrain API
func GetList(id string) *List { func GetList(id string) *List {
body, err := get(conf.ApiUrlInternal() + "/list/" + id) body, err := getString(conf.ApiUrlInternal() + "/list/" + id)
if err != nil { if err != nil {
log.Error("req failed: %v", err) log.Error("req failed: %v", err)

View File

@@ -2,8 +2,9 @@ package pixelapi
import "net/http" import "net/http"
import "io/ioutil" import "io/ioutil"
import "io"
func get(url string) (string, error) { func getString(url string) (string, error) {
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return "", err return "", err
@@ -22,3 +23,19 @@ func get(url string) (string, error) {
return string(bodyBytes), err return string(bodyBytes), err
} }
func getRaw(url string) (io.ReadCloser, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp.Body, err
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

View File

@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<title>PixelDrain ~ Free file sharing service</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/home.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/history.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" href="/res/img/tray32.png"/>
<meta name="theme-color" content="#9FCF6C"/>
<link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/>
<link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/>
<style>
body, .checkers{
background-image: url("/res/img/checker9.png");
background-attachment: fixed;
}
</style>
<script src="/res/script/jquery-2.1.4.min.js"></script>
<meta name="description" content="PixelDrain is a free file sharing service, you
can upload any file and you will be given a shareable link right away.
PixelDrain also supports previews for images, videos, audio, PDFs and much more.
Uncensored, unmonitored and unmoderated."/>
<meta property="og:type" content="website" />
<meta property="og:title" content="Home ~ PixelDrain" />
<meta property="og:site_name" content="PixelDrain" />
<meta property="og:description" content="Instant file and screenshot sharing." />
<meta property="og:url" content="http://pixeldra.in/" />
<meta property="og:image" content="/res/img/pixeldrain_big.png" />
<meta property="og:image:type" content="image/png" />
</head>
<body>
<img id="header-image" src="/res/img/header_blackchancery.png" alt="Header image"/>
<div id="body" class="body">
<div class="highlight_light border-top border-bottom menu">
<a href="/">Home</a> ~
<a href="/history">My&nbsp;Files</a> ~
<a href="/api">API&nbsp;Documentation</a>
</div>
<div class="highlight_middle border-bottom">
<input id="fileInputField" type="file" name="file" multiple='multiple'/>
<button id="selectFileButton" class="big_button button_highlight">Upload Files</button>
<button id="textButton" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/>
<div id="progress-bar" class="progress-bar">
<span class="progress-text"></span>
<div id="upload-progress" class="progressbar-inner">
<span class="progress-text"></span>
</div>
</div>
<div id="uploads-completed"></div>
</div>
<div class="highlight_dark border-bottom">
<button id="btnCreateList">Create list with uploaded files</button>
</div>
<h1>Widgets testing page</h1>
Buttons <button>Regular ol' button!</button>
Width indicator
<button class="button_highlight">Important button!</button>
Width indicator
<button class="button_red">Dangerous button!</button>
<hr/>
Textarea <textarea>Hello!</textarea>
<hr/>
Checkbox <input type="checkbox"/>
<hr/>
Radio
<input name="radioform" type="radio"/>
<input name="radioform" type="radio"/>
<hr/>
Text field <input type="text"/>
<hr/>
Password <input type="password"/>
<hr/>
Number <input type="number"/>
<hr/>
Select
<select name="select">
<option>cherry</option>
<option>orange</option>
<option>apple</option>
</select>
<hr/>
Select2 <select name="select2" size="3">
<option>cherry</option>
<option>orange</option>
<option>apple</option>
</select>
<hr/>
File <input type="file" name="file">
<hr/>
Color <input type="color" name="favcolor" value="#ff0000">
<br/>
<div class="highlight_dark border-top border-bottom">
Pixeldrain is a product by <a href="//fornaxian.com" target="_blank">Fornaxian Technologies</a>.
</div>
</div>
</body>
</html>

View File

@@ -3,9 +3,11 @@ var DetailsWindow = {
toggle: function () { toggle: function () {
if (this.visible) { if (this.visible) {
$("#info-popup").fadeOut(500); $("#info-popup").fadeOut(500);
$("#btnDetails").removeClass("button_highlight");
this.visible = false; this.visible = false;
} else { } else {
$("#info-popup").fadeIn(500); $("#info-popup").fadeIn(500);
$("#btnDetails").addClass("button_highlight");
this.visible = true; this.visible = true;
} }
}, },
@@ -13,7 +15,7 @@ var DetailsWindow = {
var fileInfo = "<table>" var fileInfo = "<table>"
+ "<tr><td>Name<td><td>" + escapeHTML(file.file_name) + "</td></tr>" + "<tr><td>Name<td><td>" + escapeHTML(file.file_name) + "</td></tr>"
+ "<tr><td>Url<td><td><a href=\"/u/" + file.id + "\">Open</a></td></tr>" + "<tr><td>Url<td><td><a href=\"/u/" + file.id + "\">Open</a></td></tr>"
+ "<tr><td>Mime Type<td><td>" + escapeHTML(file.mime) + "</td></tr>" + "<tr><td>Mime Type<td><td>" + escapeHTML(file.mime_type) + "</td></tr>"
+ "<tr><td>Id<td><td>" + file.id + "</td></tr>" + "<tr><td>Id<td><td>" + file.id + "</td></tr>"
+ "<tr><td>Size<td><td class=\"bytecounter\">" + file.file_size + "</td></tr>" + "<tr><td>Size<td><td class=\"bytecounter\">" + file.file_size + "</td></tr>"
+ "<tr><td>Upload Date<td><td>" + file.date_upload + "</td></tr>" + "<tr><td>Upload Date<td><td>" + file.date_upload + "</td></tr>"

View File

@@ -102,8 +102,10 @@ var ListNavigator = {
if(this.shuffle){ if(this.shuffle){
$("#btnShuffle > span").html("&nbsp;Shuffle&nbsp;&#x2611;"); // Check icon $("#btnShuffle > span").html("&nbsp;Shuffle&nbsp;&#x2611;"); // Check icon
$("#btnShuffle").addClass("button_highlight");
}else{ }else{
$("#btnShuffle > span").html("&nbsp;Shuffle&nbsp;&#x2610;"); // Empty checkbox $("#btnShuffle > span").html("&nbsp;Shuffle&nbsp;&#x2610;"); // Empty checkbox
$("#btnShuffle").removeClass("button_highlight");
} }
}, },
@@ -187,7 +189,7 @@ var ListNavigator = {
// Add the shuffle button to the toolbar // Add the shuffle button to the toolbar
var btnShuffle = document.createElement("button"); var btnShuffle = document.createElement("button");
btnShuffle.setAttribute("id", "btnShuffle"); btnShuffle.setAttribute("id", "btnShuffle");
btnShuffle.setAttribute("class", "toolbar-button"); btnShuffle.setAttribute("class", "toolbar_button button_full_width");
btnShuffle.setAttribute("onClick", "ListNavigator.toggleShuffle();"); btnShuffle.setAttribute("onClick", "ListNavigator.toggleShuffle();");
var btnShuffleImg = document.createElement("img"); var btnShuffleImg = document.createElement("img");
@@ -205,22 +207,11 @@ var ListNavigator = {
// We need to adjust the height of some elements to make the navigation bar fit // We need to adjust the height of some elements to make the navigation bar fit
var navHeight = $("#listNavigator").height() + 2; var navHeight = $("#listNavigator").height() + 2;
window.setTimeout(function(){ window.setTimeout(function(){
$("#listNavigator").animate( $("#listNavigator").animate( {top: 0}, {"duration": 1500, "queue": false});
{"top": "0"}, $("#filepreview").animate( {top: navHeight},{"duration": 1500, "queue": false});
{"duration": 800, "queue": false} $("#toolbar").animate( {top: navHeight},{"duration": 1500, "queue": false});
); $("#button-expand-toolbar").animate({top: navHeight},{"duration": 1500, "queue": false});
$("#filepreview").animate( $("#sharebar").animate( {top: navHeight},{"duration": 1500, "queue": false});
{top: navHeight},
{"duration": 1200, "queue": false}
);
$("#toolbar").animate(
{top: navHeight},
{"duration": 1200, "queue": false}
);
$("#sharebar").animate(
{top: navHeight},
{"duration": 1200, "queue": false}
);
$("#info-popup").css("top", "120px"); $("#info-popup").css("top", "120px");
}, 100); }, 100);
} }

View File

@@ -1,12 +1,3 @@
/*
* Time for a more Java-like approach.
* - Fornax
*
* Feel free to use this of course
*/
/* global Toolbar */
var Sharebar = { var Sharebar = {
visible: false, visible: false,
@@ -16,11 +7,13 @@ var Sharebar = {
} }
if(this.visible){ if(this.visible){
$("#sharebar").animate({left: "-102"}, 600); $("#sharebar").animate({left: "-112"}, 600);
$("#btnShare").removeClass("button_highlight");
this.visible = false; this.visible = false;
}else{ }else{
$("#sharebar").animate({left: "120"}, 400); $("#sharebar").animate({left: "120"}, 400);
$("#btnShare").addClass("button_highlight");
this.visible = true; this.visible = true;
} }

View File

@@ -16,7 +16,7 @@ var Toolbar = {
Sharebar.toggle(); Sharebar.toggle();
} }
$("#toolbar").animate({left: "-122"}, 400); $("#toolbar").animate({left: "-132"}, 400);
$("#filepreview").animate({left: "0"}, 400); $("#filepreview").animate({left: "0"}, 400);
$("#button-expand-toolbar").css("visibility", "visible"); $("#button-expand-toolbar").css("visibility", "visible");
@@ -26,7 +26,11 @@ var Toolbar = {
$("#toolbar").animate({left: "0"}, 400); $("#toolbar").animate({left: "0"}, 400);
$("#filepreview").animate({left: "122"}, 400); $("#filepreview").animate({left: "122"}, 400);
$("#button-expand-toolbar").css("visibility", "hidden"); setTimeout(function(){
if(this.visible){
$("#button-expand-toolbar").css("visibility", "hidden");
}
}, 1000)
this.visible = true; this.visible = true;
} }
@@ -49,6 +53,7 @@ var Toolbar = {
var success = document.execCommand('copy'); var success = document.execCommand('copy');
console.log('Text copied'); console.log('Text copied');
$("#btnCopy>span").text("Copied!"); $("#btnCopy>span").text("Copied!");
$("#btnCopy").addClass("button_highlight");
} catch (err) { } catch (err) {
console.log('Copying not supported'); console.log('Copying not supported');
$("#btnCopy>span").text("Error!"); $("#btnCopy>span").text("Error!");
@@ -56,7 +61,10 @@ var Toolbar = {
} }
// Return to normal // Return to normal
setTimeout(function(){$("#btnCopy>span").text("Copy")}, 5000); setTimeout(function(){
$("#btnCopy>span").text("Copy");
$("#btnCopy").removeClass("button_highlight");
}, 10000);
}, },
setViews: function(amount){ setViews: function(amount){
$("#views").html(amount); $("#views").html(amount);

File diff suppressed because one or more lines are too long

1
res/static/res/script/jquery.js vendored Symbolic link
View File

@@ -0,0 +1 @@
jquery-3.2.1.min.js

View File

@@ -1,242 +0,0 @@
/*
* Lazy Load - jQuery plugin for lazy loading images
*
* Copyright (c) 2007-2013 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* http://www.appelsiini.net/projects/lazyload
*
* Version: 1.9.3
*
*/
(function($, window, document, undefined) {
var $window = $(window);
$.fn.lazyload = function(options) {
var elements = this;
var $container;
var settings = {
threshold : 0,
failure_limit : 0,
event : "scroll",
effect : "show",
container : window,
data_attribute : "original",
skip_invisible : true,
appear : null,
load : null,
placeholder : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
};
function update() {
var counter = 0;
elements.each(function() {
var $this = $(this);
if (settings.skip_invisible && !$this.is(":visible")) {
return;
}
if ($.abovethetop(this, settings) ||
$.leftofbegin(this, settings)) {
/* Nothing. */
} else if (!$.belowthefold(this, settings) &&
!$.rightoffold(this, settings)) {
$this.trigger("appear");
/* if we found an image we'll load, reset the counter */
counter = 0;
} else {
if (++counter > settings.failure_limit) {
return false;
}
}
});
}
if(options) {
/* Maintain BC for a couple of versions. */
if (undefined !== options.failurelimit) {
options.failure_limit = options.failurelimit;
delete options.failurelimit;
}
if (undefined !== options.effectspeed) {
options.effect_speed = options.effectspeed;
delete options.effectspeed;
}
$.extend(settings, options);
}
/* Cache container as jQuery as object. */
$container = (settings.container === undefined ||
settings.container === window) ? $window : $(settings.container);
/* Fire one scroll event per scroll. Not one scroll event per image. */
if (0 === settings.event.indexOf("scroll")) {
$container.bind(settings.event, function() {
return update();
});
}
this.each(function() {
var self = this;
var $self = $(self);
self.loaded = false;
/* If no src attribute given use data:uri. */
if ($self.attr("src") === undefined || $self.attr("src") === false) {
if ($self.is("img")) {
$self.attr("src", settings.placeholder);
}
}
/* When appear is triggered load original image. */
$self.one("appear", function() {
if (!this.loaded) {
if (settings.appear) {
var elements_left = elements.length;
settings.appear.call(self, elements_left, settings);
}
$("<img />")
.bind("load", function() {
var original = $self.attr("data-" + settings.data_attribute);
$self.hide();
if ($self.is("img")) {
$self.attr("src", original);
} else {
$self.css("background-image", "url('" + original + "')");
}
$self[settings.effect](settings.effect_speed);
self.loaded = true;
/* Remove image from array so it is not looped next time. */
var temp = $.grep(elements, function(element) {
return !element.loaded;
});
elements = $(temp);
if (settings.load) {
var elements_left = elements.length;
settings.load.call(self, elements_left, settings);
}
})
.attr("src", $self.attr("data-" + settings.data_attribute));
}
});
/* When wanted event is triggered load original image */
/* by triggering appear. */
if (0 !== settings.event.indexOf("scroll")) {
$self.bind(settings.event, function() {
if (!self.loaded) {
$self.trigger("appear");
}
});
}
});
/* Check if something appears when window is resized. */
$window.bind("resize", function() {
update();
});
/* With IOS5 force loading images when navigating with back button. */
/* Non optimal workaround. */
if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) {
$window.bind("pageshow", function(event) {
if (event.originalEvent && event.originalEvent.persisted) {
elements.each(function() {
$(this).trigger("appear");
});
}
});
}
/* Force initial check if images should appear. */
$(document).ready(function() {
update();
});
return this;
};
/* Convenience methods in jQuery namespace. */
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */
$.belowthefold = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
} else {
fold = $(settings.container).offset().top + $(settings.container).height();
}
return fold <= $(element).offset().top - settings.threshold;
};
$.rightoffold = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.width() + $window.scrollLeft();
} else {
fold = $(settings.container).offset().left + $(settings.container).width();
}
return fold <= $(element).offset().left - settings.threshold;
};
$.abovethetop = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.scrollTop();
} else {
fold = $(settings.container).offset().top;
}
return fold >= $(element).offset().top + settings.threshold + $(element).height();
};
$.leftofbegin = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.scrollLeft();
} else {
fold = $(settings.container).offset().left;
}
return fold >= $(element).offset().left + settings.threshold + $(element).width();
};
$.inviewport = function(element, settings) {
return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
!$.belowthefold(element, settings) && !$.abovethetop(element, settings);
};
/* Custom selectors for your convenience. */
/* Use as $("img:below-the-fold").something() or */
/* $("img").filter(":below-the-fold").something() which is faster */
$.extend($.expr[":"], {
"below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },
"above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
"right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },
"left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },
"in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); },
/* Maintain BC for couple of versions. */
"above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
"right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); },
"left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); }
});
})(jQuery, window, document);

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +0,0 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);

View File

@@ -0,0 +1,64 @@
!function(){/*
Copyright (C) 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Copyright (C) 2006 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function(){function aa(g){function r(){try{L.doScroll("left")}catch(ba){k.setTimeout(r,50);return}x("poll")}function x(r){if("readystatechange"!=r.type||"complete"==z.readyState)("load"==r.type?k:z)[B](n+r.type,x,!1),!l&&(l=!0)&&g.call(k,r.type||r)}var X=z.addEventListener,l=!1,E=!0,v=X?"addEventListener":"attachEvent",B=X?"removeEventListener":"detachEvent",n=X?"":"on";if("complete"==z.readyState)g.call(k,"lazy");else{if(z.createEventObject&&L.doScroll){try{E=!k.frameElement}catch(ba){}E&&r()}z[v](n+
"DOMContentLoaded",x,!1);z[v](n+"readystatechange",x,!1);k[v](n+"load",x,!1)}}function T(){U&&aa(function(){var g=M.length;ca(g?function(){for(var r=0;r<g;++r)(function(g){k.setTimeout(function(){k.exports[M[g]].apply(k,arguments)},0)})(r)}:void 0)})}for(var k=window,z=document,L=z.documentElement,N=z.head||z.getElementsByTagName("head")[0]||L,B="",F=z.getElementsByTagName("script"),l=F.length;0<=--l;){var O=F[l],Y=O.src.match(/^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);if(Y){B=Y[1]||"";O.parentNode.removeChild(O);
break}}var U=!0,H=[],P=[],M=[];B.replace(/[?&]([^&=]+)=([^&]+)/g,function(g,r,x){x=decodeURIComponent(x);r=decodeURIComponent(r);"autorun"==r?U=!/^[0fn]/i.test(x):"lang"==r?H.push(x):"skin"==r?P.push(x):"callback"==r&&M.push(x)});l=0;for(B=H.length;l<B;++l)(function(){var g=z.createElement("script");g.onload=g.onerror=g.onreadystatechange=function(){!g||g.readyState&&!/loaded|complete/.test(g.readyState)||(g.onerror=g.onload=g.onreadystatechange=null,--S,S||k.setTimeout(T,0),g.parentNode&&g.parentNode.removeChild(g),
g=null)};g.type="text/javascript";g.src="https://cdn.rawgit.com/google/code-prettify/master/loader/lang-"+encodeURIComponent(H[l])+".js";N.insertBefore(g,N.firstChild)})(H[l]);for(var S=H.length,F=[],l=0,B=P.length;l<B;++l)F.push("https://cdn.rawgit.com/google/code-prettify/master/loader/skins/"+encodeURIComponent(P[l])+".css");F.push("https://cdn.rawgit.com/google/code-prettify/master/loader/prettify.css");(function(g){function r(l){if(l!==x){var k=z.createElement("link");k.rel="stylesheet";k.type=
"text/css";l+1<x&&(k.error=k.onerror=function(){r(l+1)});k.href=g[l];N.appendChild(k)}}var x=g.length;r(0)})(F);var ca=function(){"undefined"!==typeof window&&(window.PR_SHOULD_USE_CONTINUATION=!0);var g;(function(){function r(a){function d(e){var a=e.charCodeAt(0);if(92!==a)return a;var c=e.charAt(1);return(a=k[c])?a:"0"<=c&&"7">=c?parseInt(e.substring(1),8):"u"===c||"x"===c?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);
return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function c(e){var c=e.substring(1,e.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));e=[];var a="^"===c[0],b=["["];a&&b.push("^");for(var a=a?1:0,h=c.length;a<h;++a){var m=c[a];if(/\\[bdsw]/i.test(m))b.push(m);else{var m=d(m),p;a+2<h&&"-"===c[a+1]?(p=d(c[a+2]),a+=2):p=m;e.push([m,p]);65>p||122<m||(65>p||90<m||e.push([Math.max(65,m)|32,Math.min(p,90)|32]),97>p||122<m||
e.push([Math.max(97,m)&-33,Math.min(p,122)&-33]))}}e.sort(function(e,a){return e[0]-a[0]||a[1]-e[1]});c=[];h=[];for(a=0;a<e.length;++a)m=e[a],m[0]<=h[1]+1?h[1]=Math.max(h[1],m[1]):c.push(h=m);for(a=0;a<c.length;++a)m=c[a],b.push(f(m[0])),m[1]>m[0]&&(m[1]+1>m[0]&&b.push("-"),b.push(f(m[1])));b.push("]");return b.join("")}function g(e){for(var a=e.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)",
"g")),b=a.length,d=[],h=0,m=0;h<b;++h){var p=a[h];"("===p?++m:"\\"===p.charAt(0)&&(p=+p.substring(1))&&(p<=m?d[p]=-1:a[h]=f(p))}for(h=1;h<d.length;++h)-1===d[h]&&(d[h]=++r);for(m=h=0;h<b;++h)p=a[h],"("===p?(++m,d[m]||(a[h]="(?:")):"\\"===p.charAt(0)&&(p=+p.substring(1))&&p<=m&&(a[h]="\\"+d[p]);for(h=0;h<b;++h)"^"===a[h]&&"^"!==a[h+1]&&(a[h]="");if(e.ignoreCase&&A)for(h=0;h<b;++h)p=a[h],e=p.charAt(0),2<=p.length&&"["===e?a[h]=c(p):"\\"!==e&&(a[h]=p.replace(/[a-zA-Z]/g,function(a){a=a.charCodeAt(0);
return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var r=0,A=!1,q=!1,I=0,b=a.length;I<b;++I){var t=a[I];if(t.ignoreCase)q=!0;else if(/[a-z]/i.test(t.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){A=!0;q=!1;break}}for(var k={b:8,t:9,n:10,v:11,f:12,r:13},u=[],I=0,b=a.length;I<b;++I){t=a[I];if(t.global||t.multiline)throw Error(""+t);u.push("(?:"+g(t)+")")}return new RegExp(u.join("|"),q?"gi":"g")}function l(a,d){function f(a){var b=a.nodeType;if(1==b){if(!c.test(a.className)){for(b=
a.firstChild;b;b=b.nextSibling)f(b);b=a.nodeName.toLowerCase();if("br"===b||"li"===b)g[q]="\n",A[q<<1]=r++,A[q++<<1|1]=a}}else if(3==b||4==b)b=a.nodeValue,b.length&&(b=d?b.replace(/\r\n?/g,"\n"):b.replace(/[ \t\r\n]+/g," "),g[q]=b,A[q<<1]=r,r+=b.length,A[q++<<1|1]=a)}var c=/(?:^|\s)nocode(?:\s|$)/,g=[],r=0,A=[],q=0;f(a);return{a:g.join("").replace(/\n$/,""),c:A}}function k(a,d,f,c,g){f&&(a={h:a,l:1,j:null,m:null,a:f,c:null,i:d,g:null},c(a),g.push.apply(g,a.g))}function z(a){for(var d=void 0,f=a.firstChild;f;f=
f.nextSibling)var c=f.nodeType,d=1===c?d?a:f:3===c?S.test(f.nodeValue)?a:d:d;return d===a?void 0:d}function E(a,d){function f(a){for(var q=a.i,r=a.h,b=[q,"pln"],t=0,A=a.a.match(g)||[],u={},e=0,l=A.length;e<l;++e){var D=A[e],w=u[D],h=void 0,m;if("string"===typeof w)m=!1;else{var p=c[D.charAt(0)];if(p)h=D.match(p[1]),w=p[0];else{for(m=0;m<n;++m)if(p=d[m],h=D.match(p[1])){w=p[0];break}h||(w="pln")}!(m=5<=w.length&&"lang-"===w.substring(0,5))||h&&"string"===typeof h[1]||(m=!1,w="src");m||(u[D]=w)}p=t;
t+=D.length;if(m){m=h[1];var C=D.indexOf(m),G=C+m.length;h[2]&&(G=D.length-h[2].length,C=G-m.length);w=w.substring(5);k(r,q+p,D.substring(0,C),f,b);k(r,q+p+C,m,F(w,m),b);k(r,q+p+G,D.substring(G),f,b)}else b.push(q+p,w)}a.g=b}var c={},g;(function(){for(var f=a.concat(d),q=[],k={},b=0,t=f.length;b<t;++b){var n=f[b],u=n[3];if(u)for(var e=u.length;0<=--e;)c[u.charAt(e)]=n;n=n[1];u=""+n;k.hasOwnProperty(u)||(q.push(n),k[u]=null)}q.push(/[\0-\uffff]/);g=r(q)})();var n=d.length;return f}function v(a){var d=
[],f=[];a.tripleQuotedStrings?d.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""]):a.multiLineStrings?d.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):d.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);a.verbatimStrings&&
f.push(["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);var c=a.hashComments;c&&(a.cStyleComments?(1<c?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]),f.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,
null]));if(c=a.regexLiterals){var g=(c=1<c?"":"\n\r")?".":"[\\S\\s]";f.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+c+"])(?:[^/\\x5B\\x5C"+c+"]|\\x5C"+g+"|\\x5B(?:[^\\x5C\\x5D"+c+"]|\\x5C"+g+")*(?:\\x5D|$))+/")+")")])}(c=a.types)&&f.push(["typ",c]);c=(""+a.keywords).replace(/^ | $/g,"");c.length&&f.push(["kwd",
new RegExp("^(?:"+c.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);c="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(c+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i,null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(c),null]);return E(d,f)}function B(a,d,f){function c(a){var b=
a.nodeType;if(1==b&&!r.test(a.className))if("br"===a.nodeName.toLowerCase())g(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)c(a);else if((3==b||4==b)&&f){var e=a.nodeValue,d=e.match(n);d&&(b=e.substring(0,d.index),a.nodeValue=b,(e=e.substring(d.index+d[0].length))&&a.parentNode.insertBefore(q.createTextNode(e),a.nextSibling),g(a),b||a.parentNode.removeChild(a))}}function g(a){function c(a,b){var e=b?a.cloneNode(!1):a,p=a.parentNode;if(p){var p=c(p,1),d=a.nextSibling;
p.appendChild(e);for(var f=d;f;f=d)d=f.nextSibling,p.appendChild(f)}return e}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=c(a.nextSibling,0);for(var e;(e=a.parentNode)&&1===e.nodeType;)a=e;b.push(a)}for(var r=/(?:^|\s)nocode(?:\s|$)/,n=/\r\n?|\n/,q=a.ownerDocument,k=q.createElement("li");a.firstChild;)k.appendChild(a.firstChild);for(var b=[k],t=0;t<b.length;++t)c(b[t]);d===(d|0)&&b[0].setAttribute("value",d);var l=q.createElement("ol");l.className="linenums";d=Math.max(0,d-1|0)||0;for(var t=
0,u=b.length;t<u;++t)k=b[t],k.className="L"+(t+d)%10,k.firstChild||k.appendChild(q.createTextNode("\u00a0")),l.appendChild(k);a.appendChild(l)}function n(a,d){for(var f=d.length;0<=--f;){var c=d[f];V.hasOwnProperty(c)?Q.console&&console.warn("cannot override language handler %s",c):V[c]=a}}function F(a,d){a&&V.hasOwnProperty(a)||(a=/^\s*</.test(d)?"default-markup":"default-code");return V[a]}function H(a){var d=a.j;try{var f=l(a.h,a.l),c=f.a;a.a=c;a.c=f.c;a.i=0;F(d,c)(a);var g=/\bMSIE\s(\d+)/.exec(navigator.userAgent),
g=g&&8>=+g[1],d=/\n/g,r=a.a,k=r.length,f=0,q=a.c,n=q.length,c=0,b=a.g,t=b.length,v=0;b[t]=k;var u,e;for(e=u=0;e<t;)b[e]!==b[e+2]?(b[u++]=b[e++],b[u++]=b[e++]):e+=2;t=u;for(e=u=0;e<t;){for(var x=b[e],z=b[e+1],w=e+2;w+2<=t&&b[w+1]===z;)w+=2;b[u++]=x;b[u++]=z;e=w}b.length=u;var h=a.h;a="";h&&(a=h.style.display,h.style.display="none");try{for(;c<n;){var m=q[c+2]||k,p=b[v+2]||k,w=Math.min(m,p),C=q[c+1],G;if(1!==C.nodeType&&(G=r.substring(f,w))){g&&(G=G.replace(d,"\r"));C.nodeValue=G;var Z=C.ownerDocument,
W=Z.createElement("span");W.className=b[v+1];var B=C.parentNode;B.replaceChild(W,C);W.appendChild(C);f<m&&(q[c+1]=C=Z.createTextNode(r.substring(w,m)),B.insertBefore(C,W.nextSibling))}f=w;f>=m&&(c+=2);f>=p&&(v+=2)}}finally{h&&(h.style.display=a)}}catch(y){Q.console&&console.log(y&&y.stack||y)}}var Q="undefined"!==typeof window?window:{},J=["break,continue,do,else,for,if,return,while"],K=[[J,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],R=[K,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],L=[K,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],
M=[K,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"],K=[K,"abstract,async,await,constructor,debugger,enum,eval,export,function,get,implements,instanceof,interface,let,null,set,undefined,var,with,yield,Infinity,NaN"],
N=[J,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],O=[J,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],J=[J,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],P=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,
S=/\S/,T=v({keywords:[R,M,L,K,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",N,O,J],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),V={};n(T,["default-code"]);n(E([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",
/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));n(E([["pln",/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);n(E([],[["atv",/^[\s\S]+/]]),["uq.val"]);n(v({keywords:R,hashComments:!0,cStyleComments:!0,types:P}),"c cc cpp cxx cyc m".split(" "));n(v({keywords:"null,true,false"}),["json"]);n(v({keywords:M,hashComments:!0,cStyleComments:!0,
verbatimStrings:!0,types:P}),["cs"]);n(v({keywords:L,cStyleComments:!0}),["java"]);n(v({keywords:J,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);n(v({keywords:N,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);n(v({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),
["perl","pl","pm"]);n(v({keywords:O,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);n(v({keywords:K,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);n(v({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);n(E([],[["str",/^[\s\S]+/]]),
["regex"]);var U=Q.PR={createSimpleLexer:E,registerLangHandler:n,sourceDecorator:v,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:function(a,d,f){f=f||!1;d=d||null;var c=document.createElement("div");c.innerHTML="<pre>"+a+"</pre>";c=c.firstChild;f&&B(c,f,!0);H({j:d,m:f,h:c,l:1,a:null,i:null,c:null,g:null});
return c.innerHTML},prettyPrint:g=function(a,d){function f(){for(var c=Q.PR_SHOULD_USE_CONTINUATION?b.now()+250:Infinity;t<r.length&&b.now()<c;t++){for(var d=r[t],k=h,n=d;n=n.previousSibling;){var q=n.nodeType,l=(7===q||8===q)&&n.nodeValue;if(l?!/^\??prettify\b/.test(l):3!==q||/\S/.test(n.nodeValue))break;if(l){k={};l.replace(/\b(\w+)=([\w:.%+-]+)/g,function(a,b,c){k[b]=c});break}}n=d.className;if((k!==h||u.test(n))&&!e.test(n)){q=!1;for(l=d.parentNode;l;l=l.parentNode)if(w.test(l.tagName)&&l.className&&
u.test(l.className)){q=!0;break}if(!q){d.className+=" prettyprinted";q=k.lang;if(!q){var q=n.match(v),A;!q&&(A=z(d))&&D.test(A.tagName)&&(q=A.className.match(v));q&&(q=q[1])}if(x.test(d.tagName))l=1;else var l=d.currentStyle,y=g.defaultView,l=(l=l?l.whiteSpace:y&&y.getComputedStyle?y.getComputedStyle(d,null).getPropertyValue("white-space"):0)&&"pre"===l.substring(0,3);y=k.linenums;(y="true"===y||+y)||(y=(y=n.match(/\blinenums\b(?::(\d+))?/))?y[1]&&y[1].length?+y[1]:!0:!1);y&&B(d,y,l);H({j:q,h:d,m:y,
l:l,a:null,i:null,c:null,g:null})}}}t<r.length?Q.setTimeout(f,250):"function"===typeof a&&a()}for(var c=d||document.body,g=c.ownerDocument||document,c=[c.getElementsByTagName("pre"),c.getElementsByTagName("code"),c.getElementsByTagName("xmp")],r=[],k=0;k<c.length;++k)for(var n=0,l=c[k].length;n<l;++n)r.push(c[k][n]);var c=null,b=Date;b.now||(b={now:function(){return+new Date}});var t=0,v=/\blang(?:uage)?-([\w.]+)(?!\S)/,u=/\bprettyprint\b/,e=/\bprettyprinted\b/,x=/pre|xmp/i,D=/^code$/i,w=/^(?:pre|code|xmp)$/i,
h={};f()}},R=Q.define;"function"===typeof R&&R.amd&&R("google-code-prettify",[],function(){return U})})();return g}();S||k.setTimeout(T,0)})();}()

View File

@@ -20,7 +20,7 @@
width: 0%; width: 0%;
left: 0; left: 0;
height: 100%; height: 100%;
background-color: #9FCF6C; background-color: var(--highlight_color);;
overflow: hidden; overflow: hidden;
color: #000; color: #000;
white-space: nowrap; white-space: nowrap;

View File

@@ -6,14 +6,14 @@
body{ body{
background-color: #111; background-color: #111;
background-repeat: repeat; background-repeat: repeat;
color: #c0c0c0;
font-size: 16px; font-size: 16px;
font-family: 'Ubuntu', sans-serif; font-family: 'Ubuntu', sans-serif;
margin: 0; margin: 0;
text-align: center; text-align: center; /* Center the header and body */
line-height: 140%; line-height: 140%;
height: 100%; height: 100%;
overflow-x: hidden; overflow-x: hidden;
color: var(--text_color);
} }
html{ html{
@@ -50,7 +50,7 @@ html{
} }
/* Body elements */ /* Layout elements */
.body{ .body{
position: relative; position: relative;
@@ -61,16 +61,21 @@ html{
height: auto; height: auto;
padding: 0px 8px 0px 8px; padding: 0px 8px 0px 8px;
box-sizing: border-box; box-sizing: border-box;
background-color: #1A1A1A; background-color: #242424;
margin-top: 30px; margin-top: 30px;
margin-bottom: 30px; margin-bottom: 30px;
text-align: left; text-align: left;
box-shadow: #000 0px 0px 40px; box-shadow: #000 8px 8px 50px;
z-index: 1; z-index: 1;
word-break: break-word; word-break: break-word;
} }
.highlight{ .highlight_dark,
.highlight_middle,
.highlight_light,
.highlight_green,
.highlight_blue,
.highlight_red {
position: relative; position: relative;
width: auto; width: auto;
height: auto; height: auto;
@@ -81,27 +86,28 @@ html{
padding: 4px 0px 4px 0px; padding: 4px 0px 4px 0px;
z-index: 101; z-index: 101;
} }
.bg-light { .highlight_light {background-color: #484848;}
background-color: #404040; .highlight_middle {background-color: #3a3a3a;}
} .highlight_dark {background-color: #303030;}
.bg-middle {
background-color: #303030; .border-top {border-top: #686868 1px solid;}
} .border-bottom {border-bottom: #686868 1px solid;}
.bg-dark {
background-color: #222222;
}
.border-top {
border-top: #686868 1px solid;
}
.border-bottom {
border-bottom: #686868 1px solid;
}
.menu{ .menu{
font-family: "Lato", sans-serif; font-family: "Lato", sans-serif;
font-weight: bold; font-weight: bold;
font-size: 26px; font-size: 26px;
} }
/* Common elements */
hr{
height: 8px;
border: none;
background: linear-gradient(#101010, #303030);
margin: 16px -8px 16px -8px;
}
::-webkit-scrollbar{ ::-webkit-scrollbar{
width: 12px; /* for vertical scrollbars */ width: 12px; /* for vertical scrollbars */
height: 12px; /* for horizontal scrollbars */ height: 12px; /* for horizontal scrollbars */
@@ -117,59 +123,141 @@ html{
background: transparent; background: transparent;
} }
/* Common elements */
a{ a{
color: #9FCF6C; color: var(--highlight_color);
text-decoration: none; text-decoration: none;
} }
a:hover{ a:hover{
text-decoration: underline; text-decoration: underline;
color: #9FCF6C; color: var(--highlight_color);
} }
.big-button{ .big_button{
position: relative;
height: 40px; height: 40px;
width: 40%; width: 40%;
min-width: 200px; min-width: 200px;
max-width: 400px; max-width: 400px;
background-color: #9FCF6C; margin: 10px !important;
border-radius: 10px; border-radius: 10px;
border: none;
color: #333;
font-size: 30px; font-size: 30px;
margin: 6px; font-weight: normal;
cursor: pointer; line-height: 8px;
box-shadow: #000 3px 3px 1px; }
.progress-bar{
position: relative;
width: 100%;
height: 0;
background-color: #555;
overflow: hidden;
color: #eeeeee;
text-align: left;
white-space: nowrap;
}
.progressbar-inner{
position: absolute;
top: 0;
width: 0%;
left: 0;
height: 100%;
background-color: var(--highlight_color);;
overflow: hidden;
color: #000;
white-space: nowrap;
}
.progress-text{
overflow: hidden;
width: 100%;
white-space: nowrap;
} }
/* Form fields */ /* Form fields */
input[type="text"], input[type="password"], input[type="email"]{ /* BUTTONS */
border: #9FCF6C ridge 2px; button,
background: #626262; input[type="submit"],
color: #eeeeee; input[type="button"],
height: 20px; input[type="color"],
select{
border-radius: 4px;
border: 1px hidden transparent;
background: linear-gradient(#606060, #404040);
padding: 6px 10px 6px 10px;
margin: 2px;
box-shadow: 2px 2px 8px #000000;
font-weight: bold;
color: #FFFFFF;
outline: 0;
vertical-align: middle;
cursor: pointer;
}
button:hover,
input[type="submit"]:hover,
input[type="button"]:hover,
input[type="color"]:hover,
select:hover,
button:focus,
input[type="submit"]:focus,
input[type="button"]:focus,
input[type="color"]:focus,
select:focus{
border: 1px solid var(--highlight_color);
margin: 1px;
}
button:active,
input[type="submit"]:active,
input[type="button"]:active,
input[type="color"]:active,
select:active{
border: 1px solid var(--highlight_color);
margin: 1px;
background: linear-gradient(#404040, #606060);
box-shadow: inset 3px 3px 6px #000000;
padding: 8px 8px 4px 12px;
}
.button_full_width {width: calc(100% - 4px);}
.button_highlight {background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));}
.button_highlight:active{background: linear-gradient(var(--highlight_color_dark), var(--highlight_color));}
.button_red {background: linear-gradient(#821C40, #61152F);}
.button_red:active {background: linear-gradient(#61152F, #821C40);}
/* Dropdown list of the select tag */
option{
background-color: #404040;
color: #FFFFFF;
}
/* TEXT FIELDS */
textarea,
input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"]{
border: none;
box-sizing: border-box;
border-radius: 4px;
background: linear-gradient(#404040, #606060);
box-shadow: inset 3px 3px 6px #000000;
padding: 3px 5px;
color: var(--text_color);
height: 26px;
font-size: 18px; font-size: 18px;
font-family: 'Ubuntu', sans-serif; font-family: 'Ubuntu', sans-serif;
vertical-align: bottom; vertical-align: bottom;
outline: 0;
} }
textarea:active,
input[type="submit"], input[type="button"]{ input[type="text"]:active,
background-color: #222; input[type="password"]:active,
border: #9FCF6C solid 1px; input[type="email"]:active,
color: #eeeeee; input[type="number"]:active,
font-size: 16px; textarea:focus,
font-family: 'Ubuntu', sans-serif; input[type="text"]:focus,
cursor: pointer; input[type="password"]:focus,
vertical-align: bottom; input[type="email"]:focus,
margin: 0; input[type="number"]:focus{
} border: 1px solid var(--highlight_color);
padding: 3px 4px;
input[type="submit"]:hover, input[type="button"]:hover{
background-color: #444;
} }
input[type=file]{ input[type=file]{

View File

@@ -28,11 +28,12 @@
top: -100px; top: -100px;
height: 98px; height: 98px;
background-color: #000; background-color: #000;
border-bottom: 2px ridge #9FCF6C; box-shadow: 2px 2px 8px #000000;
border-bottom: 2px ridge var(--highlight_color);
text-align: center; text-align: center;
overflow-x: hidden; overflow-x: hidden;
overflow-y: hidden; overflow-y: hidden;
z-index: 1000; z-index: 50;
} }
#listNavigatorItems{ #listNavigatorItems{
@@ -46,8 +47,6 @@
overflow-y: hidden; overflow-y: hidden;
border: none; border: none;
padding: 0 40px; padding: 0 40px;
z-index: 1001;
} }
.listItem{ .listItem{
@@ -70,18 +69,22 @@
margin: 0; margin: 0;
} }
#arrow-left{ #arrow-left,
position: fixed;
height: 92px;
width: 35px;
left: 0;
z-index: 1002;
}
#arrow-right{ #arrow-right{
position: fixed; position: absolute;
height: 92px; display: block;
width: 35px; border-top: 30px solid transparent;
right: 0; border-bottom: 30px solid transparent;
z-index: 1002; height: 0;
width: 0;
top: 20px;
cursor: pointer;
}
#arrow-left{
border-right: 40px solid var(--highlight_color);
left: 10px;
}
#arrow-right{
border-left: 40px solid var(--highlight_color);
right: 10px;
} }

View File

@@ -7,13 +7,8 @@
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%;
height: 100%; height: 100%;
border: none; width: 100%;
box-sizing: border-box; border: none !important;
padding: 10px; background: #202020;
background-color: #222;
color: #eee;
font-family: 'Ubuntu Mono' , sans-serif;
font-size: 18px;
} }

View File

@@ -4,60 +4,9 @@
*/ */
body{ body{
background-color: #111;
/*background-image: url("img/checker3.png"); Defined in viewer.html*/
background-repeat: repeat;
color: #eeeeee;
font-size: 16px;
font-family: 'Ubuntu', sans-serif;
margin: 0;
overflow: hidden; overflow: hidden;
} }
a{
color: #9FCF6C;
text-decoration: none;
}
a:hover{
text-decoration: underline;
color: #9FCF6C;
}
::-webkit-scrollbar{
width: 10px; /* for vertical scrollbars */
height: 10px; /* for horizontal scrollbars */
}
::-webkit-scrollbar-track{
background: #000;
}
::-webkit-scrollbar-thumb{
background-color: #444;
}
::-webkit-scrollbar-corner{
background: transparent;
}
button{
background-color: #333;
border: #777 outset 2px;
color: #eeeeee;
font-size: 16px;
font-family: 'Ubuntu', sans-serif;
cursor: pointer;
padding: 2px;
}
button:active{
background-color: #111;
}
button:hover{
background-color: #444;
}
button:focus{
background-color: #444;
outline: none;
}
#filepreview{ #filepreview{
position: absolute; position: absolute;
display: inline-block; display: inline-block;
@@ -147,7 +96,7 @@ button:focus{
#toolbar { #toolbar {
position: absolute; position: absolute;
width: 120px; width: 120px;
z-index: 12; z-index: 52;
overflow: hidden; overflow: hidden;
float: left; float: left;
background-color: #000; background-color: #000;
@@ -155,8 +104,9 @@ button:focus{
bottom: 0; bottom: 0;
top: 0; top: 0;
padding: 0; padding: 0;
text-align: center; text-align: left;
border-right: 2px ridge #9FCF6C; border-right: 2px ridge var(--highlight_color);
box-shadow: 2px 2px 8px #000000;
} }
/* Workaround to hide the scrollbar in non webkit browsers, it's really ugly' */ /* Workaround to hide the scrollbar in non webkit browsers, it's really ugly' */
@@ -177,19 +127,24 @@ button:focus{
height: auto; height: auto;
} }
.toolbar-button { #button-expand-toolbar{
text-align: left; position: absolute;
width: 100%; visibility: hidden;
margin-bottom: 3px; left: 0;
top: 0;
cursor: pointer;
z-index: 51;
} }
.toolbar-button > img { .toolbar_button{
text-align: left;
}
.toolbar_button > img {
width: 24px; width: 24px;
height: 24px; height: 24px;
} }
.toolbar_button > span {
.toolbar-button > span { vertical-align: 6px;
vertical-align: 5px;
} }
#sponsors{ #sponsors{
@@ -215,17 +170,13 @@ button:focus{
overflow-x: hidden; overflow-x: hidden;
float: left; float: left;
background-color: #000; background-color: #000;
box-shadow: 2px 2px 8px #000000;
text-align: center; text-align: center;
border-right: 2px ridge #9FCF6C; border-right: 2px ridge var(--highlight_color);
z-index: 11; z-index: 50;
overflow: hidden; overflow: hidden;
} }
.sharebar-button {text-align: center;}
.sharebar-button {
text-align: center;
width: 100%;
margin-bottom: 3px;
}
/* ===================== /* =====================
|| MISC COMPONENTS || || MISC COMPONENTS ||
@@ -242,7 +193,7 @@ button:focus{
overflow-y: scroll; overflow-y: scroll;
padding: 10px; padding: 10px;
box-sizing: border-box; box-sizing: border-box;
text-align: left;
box-shadow: #eee 0px 0px 50px; box-shadow: #eee 0px 0px 50px;
z-index: 100; z-index: 100;
} }
@@ -275,15 +226,6 @@ button:focus{
position: fixed; position: fixed;
} }
.button-collapse{
width: 100px;
left: 0;
height: 12px;
position: relative;
display: block;
cursor: pointer;
}
.bytecounter{ .bytecounter{
color: #eeeeee; color: #eeeeee;
font-size: 16px; font-size: 16px;

View File

@@ -5,6 +5,7 @@
<title>PixelDrain ~ API Documentation</title> <title>PixelDrain ~ API Documentation</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/> <link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/apidoc.css"/> <link rel="stylesheet" href="/res/style/apidoc.css"/>
<link href='http://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/> <link href='http://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>

View File

@@ -5,6 +5,7 @@
<title>PixelDrain ~ Error</title> <title>PixelDrain ~ Error</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/> <link rel="stylesheet" href="/res/style/layout.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/> <link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>

View File

@@ -5,8 +5,9 @@
<title>{{.Title}}</title> <title>{{.Title}}</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/viewer.css"/> <link rel="stylesheet" href="/res/style/viewer.css"/>
<link rel="stylesheet" href="/res/style/season.css"/> <link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/listview.css"/> <link rel="stylesheet" href="/res/style/listview.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link rel="shortcut icon" href="/res/img/tray32.png"/> <link rel="shortcut icon" href="/res/img/tray32.png"/>
@@ -35,45 +36,42 @@
<body> <body>
<div id="listNavigator"> <div id="listNavigator">
<img src="/res/img/arrow-left.png" id="arrow-left" alt="Previous Item" onClick="ListNavigator.previousItem();" />
<img src="/res/img/arrow-right.png" id="arrow-right" alt="Next Item" onClick="ListNavigator.nextItem();" />
<div id="listNavigatorItems"></div> <div id="listNavigatorItems"></div>
<div id="arrow-left" alt="Previous Item" onClick="ListNavigator.previousItem();"></div>
<div id="arrow-right" alt="Next Item" onClick="ListNavigator.nextItem();"></div>
</div> </div>
<button id="button-expand-toolbar" onClick="Toolbar.toggle();">Show Toolbar</button>
<div id="toolbar"> <div id="toolbar">
<!-- Ugly workaround to get rid of the scrollbar in non-webkit browsers --> <!-- Ugly workaround to get rid of the scrollbar in non-webkit browsers -->
<div> <div>
<div> <div>
<img id="button-expand-toolbar" src="/res/img/toolbar_show.png" alt="Expand Menu" <button class="toolbar_button button_full_width" onClick="Toolbar.toggle();">Hide Toolbar</button>
onClick="Toolbar.toggle();"
style="position: fixed; visibility:hidden; left: 0px; cursor: pointer" />
<button class="toolbar-button" onClick="Toolbar.toggle();">Hide Toolbar</button>
<!--Views: <span id="views" th:text="${data.views}">0</span>--><br/> <!--Views: <span id="views" th:text="${data.views}">0</span>--><br/>
<button id="btnDownload" class="toolbar-button" onClick="Toolbar.download();"> <form action="/" target="_self">
<img src="/res/img/floppy_small.png" alt="Download this file"/> <button id="btnHome" class="toolbar_button button_full_width">
<span>Download</span>
</button>
<button id="btnCopy" class="toolbar-button" onClick="Toolbar.copyUrl();">
<img src="/res/img/clipboard_small.png" alt="Copy file URL to clipboard"/>
<span>Copy</span>
</button>
<button id="btnShare" onClick="Sharebar.toggle();" class="toolbar-button">
<img src="/res/img/share_small.png" alt="Share this file on social media"/>
<span>Share</span>
</button>
<form action="/" target="_blank">
<button id="btnHome" class="toolbar-button">
<img src="/res/img/pixeldrain_small.png" alt="Back to the Home page"/> <img src="/res/img/pixeldrain_small.png" alt="Back to the Home page"/>
<span>Home</span> <span>Home</span>
</button> </button>
</form> </form>
<button id="btnDetails" class="toolbar-button" onClick="DetailsWindow.toggle();"> <button id="btnDownload" class="toolbar_button button_full_width" onClick="Toolbar.download();">
<img src="/res/img/floppy_small.png" alt="Download this file"/>
<span>Download</span>
</button>
<button id="btnCopy" class="toolbar_button button_full_width" onClick="Toolbar.copyUrl();">
<img src="/res/img/clipboard_small.png" alt="Copy file URL to clipboard"/>
<span>Copy</span>
</button>
<button id="btnShare" class="toolbar_button button_full_width" onClick="Sharebar.toggle();">
<img src="/res/img/share_small.png" alt="Share this file on social media"/>
<span>Share</span>
</button>
<button id="btnDetails" class="toolbar_button button_full_width" onClick="DetailsWindow.toggle();">
<img src="/res/img/info_small.png" alt="Help"/> <img src="/res/img/info_small.png" alt="Help"/>
<span>Details</span> <span>Details</span>
</button> </button>
@@ -91,39 +89,36 @@
</div> </div>
<div id="sharebar" class="sidebar"> <div id="sharebar" class="sidebar">
<img src="/res/img/arrows-collapse.png" alt="Slide Menu"
onClick="Sharebar.toggle();" class="button-collapse"/>
Share on:<br/> Share on:<br/>
<button class="sharebar-button" onclick="window.open('https://www.reddit.com/submit?url=' + window.location.href);"> <button class="sharebar-button button_full_width" onclick="window.open('https://www.reddit.com/submit?url=' + window.location.href);">
<img src="/res/img/social_reddit.png" alt="Share on Reddit" style="width:40px; height: 40px;"/> <img src="/res/img/social_reddit.png" alt="Share on Reddit" style="width:40px; height: 40px;"/>
<br/>Reddit <br/>Reddit
</button> </button>
<button class="sharebar-button" onClick="window.open('https://voat.co/submit?linkpost=true&url=' + window.location.href);"> <button class="sharebar-button button_full_width" onClick="window.open('https://voat.co/submit?linkpost=true&url=' + window.location.href);">
<img src="/res/img/social_voat.png" alt="Share on Voat" style="width:40px; height: 40px;"/> <img src="/res/img/social_voat.png" alt="Share on Voat" style="width:40px; height: 40px;"/>
<br/>Voat <br/>Voat
</button> </button>
<button class="sharebar-button" onClick="window.open('http://www.facebook.com/sharer.php?u=' + window.location.href);"> <button class="sharebar-button button_full_width" onClick="window.open('http://www.facebook.com/sharer.php?u=' + window.location.href);">
<img src="/res/img/social_facebook.png" alt="Share on Facebook" style="width:40px; height: 40px;"/> <img src="/res/img/social_facebook.png" alt="Share on Facebook" style="width:40px; height: 40px;"/>
<br/>Facebook <br/>Facebook
</button> </button>
<button class="sharebar-button" onClick="window.open('https://twitter.com/share?text=Check%20out%20this%20file%20on%20%23Pixeldrain&url=' + window.location.href);"> <button class="sharebar-button button_full_width" onClick="window.open('https://twitter.com/share?text=Check%20out%20this%20file%20on%20%23Pixeldrain&url=' + window.location.href);">
<img src="/res/img/social_twitter.png" alt="Share on Twitter" style="width:40px; height: 40px;"/> <img src="/res/img/social_twitter.png" alt="Share on Twitter" style="width:40px; height: 40px;"/>
<br/>Twitter <br/>Twitter
</button> </button>
<button class="sharebar-button" onClick="window.open('https://plus.google.com/share?url=' + window.location.href);"> <button class="sharebar-button button_full_width" onClick="window.open('https://plus.google.com/share?url=' + window.location.href);">
<img src="/res/img/social_googleplus.png" alt="Share on Google Plus" style="width:40px; height: 40px;"/> <img src="/res/img/social_googleplus.png" alt="Share on Google Plus" style="width:40px; height: 40px;"/>
<br/>Google+ <br/>Google+
</button> </button>
<button class="sharebar-button" onClick="window.open('http://www.tumblr.com/share/link?url=' + window.location.href);"> <button class="sharebar-button button_full_width" onClick="window.open('http://www.tumblr.com/share/link?url=' + window.location.href);">
<img src="/res/img/social_tumblr.png" alt="Share on Tumblr" style="width:40px; height: 40px;"/> <img src="/res/img/social_tumblr.png" alt="Share on Tumblr" style="width:40px; height: 40px;"/>
<br/>Tumblr <br/>Tumblr
</button> </button>
<button class="sharebar-button" onClick="window.open('http://www.stumbleupon.com/submit?url=' + window.location.href);"> <button class="sharebar-button button_full_width" onClick="window.open('http://www.stumbleupon.com/submit?url=' + window.location.href);">
<img src="/res/img/social_stumbleupon.png" alt="Share on StumbleUpon" style="width:40px; height: 40px;"/> <img src="/res/img/social_stumbleupon.png" alt="Share on StumbleUpon" style="width:40px; height: 40px;"/>
<br/>StumbleUpon <br/>StumbleUpon
</button> </button>
<button class="sharebar-button" onClick="window.open('mailto:please@set.address?subject=File%20on%20PixelDrain&body=You%20can%20view%20it%20here%20' + window.location.href);"> <button class="sharebar-button button_full_width" onClick="window.open('mailto:please@set.address?subject=File%20on%20PixelDrain&body=You%20can%20view%20it%20here%20' + window.location.href);">
<img src="/res/img/social_email.png" alt="Share on E-Mail" style="width:40px; height: 40px;"/> <img src="/res/img/social_email.png" alt="Share on E-Mail" style="width:40px; height: 40px;"/>
<br/>E-Mail <br/>E-Mail
</button> </button>
@@ -144,7 +139,7 @@
Loading... Loading...
</div> </div>
<script src="/res/script/jquery-2.1.4.min.js"></script> <script src="/res/script/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="/res/script/Keyboard.js"></script> <script src="/res/script/Keyboard.js"></script>
<script src="/res/script/Toolbar.js"></script> <script src="/res/script/Toolbar.js"></script>

View File

@@ -32,7 +32,6 @@
"file_name": "screenshot.png", "file_name": "screenshot.png",
"date_upload": 1485894987, // Timestamp "date_upload": 1485894987, // Timestamp
"date_last_view": 1485894987, // Timestamp "date_last_view": 1485894987, // Timestamp
"days_valid": 60, // Days of inactivity until it gets deleted
"file_size": 5694837, // Bytes "file_size": 5694837, // Bytes
"views" 1234, // Amount of unique file views "views" 1234, // Amount of unique file views
"mime_type" "image/png", "mime_type" "image/png",

View File

@@ -32,41 +32,39 @@
</p> </p>
<pre>HTTP 200: OK <pre>HTTP 200: OK
{ {
{ "success": true,
"success": true, "id": "L8bhwx",
"id": "L8bhwx", "title": "Rust in Peace",
"title": "Rust in Peace", "date_created": 1513033315,
"date_created": 1513033315, "files": [
"files": [ {
{ "detail_href": "/file/_SqVWi/info",
"detail_href": "/file/_SqVWi/info", "id": "_SqVWi",
"id": "_SqVWi", "file_name": "01 Holy Wars... The Punishment Due.mp3",
"file_name": "01 Holy Wars... The Punishment Due.mp3", "description": "",
"description": "", "date_created": 1513033304,
"date_created": 1513033304, "date_last_view": 1513033304,
"date_last_view": 1513033304, "list_description": ""
"list_description": "" },
}, {
{ "detail_href": "/file/RKwgZb/info",
"detail_href": "/file/RKwgZb/info", "id": "RKwgZb",
"id": "RKwgZb", "file_name": "02 Hangar 18.mp3",
"file_name": "02 Hangar 18.mp3", "description": "",
"description": "", "date_created": 1513033304,
"date_created": 1513033304, "date_last_view": 1513033304,
"date_last_view": 1513033304, "list_description": ""
"list_description": "" },
}, {
{ "detail_href": "/file/DRaL_e/info",
"detail_href": "/file/DRaL_e/info", "id": "DRaL_e",
"id": "DRaL_e", "file_name": "03 Take No Prisoners.mp3",
"file_name": "03 Take No Prisoners.mp3", "description": "",
"description": "", "date_created": 1513033304,
"date_created": 1513033304, "date_last_view": 1513033304,
"date_last_view": 1513033304, "list_description": ""
"list_description": "" }
} ]
]
}
} }
</pre> </pre>
<pre>HTTP 404: Not Found <pre>HTTP 404: Not Found

View File

@@ -1,6 +1,6 @@
{{define "footer"}} {{define "footer"}}
<br/> <br/>
<div class="highlight bg-dark border-top border-bottom"> <div class="highlight_dark border-top border-bottom">
Pixeldrain is a product by <a href="//fornaxian.com" target="_blank">Fornaxian Technologies</a>. Pixeldrain is a product by <a href="//fornaxian.com" target="_blank">Fornaxian Technologies</a>.
</div> </div>
{{end}} {{end}}

View File

@@ -1,5 +1,5 @@
{{define "menu"}} {{define "menu"}}
<div class="highlight bg-light border-top border-bottom menu"> <div class="highlight_light border-top border-bottom menu">
<a href="/">Home</a> ~ <a href="/">Home</a> ~
<a href="/history">My&nbsp;Files</a> ~ <a href="/history">My&nbsp;Files</a> ~
<a href="/api">API&nbsp;Documentation</a> <a href="/api">API&nbsp;Documentation</a>

View File

@@ -5,8 +5,8 @@
<title>Upload History ~ PixelDrain</title> <title>Upload History ~ PixelDrain</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/> <link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/season.css"/>
<link rel="stylesheet" href="/res/style/history.css"/> <link rel="stylesheet" href="/res/style/history.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/> <link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
@@ -17,7 +17,7 @@
{{template "bgpattern"}} {{template "bgpattern"}}
<script src="res/script/jquery-2.1.4.min.js"></script> <script src="res/script/jquery.js"></script>
<script src="res/script/jquery-cookie.js"></script> <script src="res/script/jquery-cookie.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"/> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

View File

@@ -5,6 +5,7 @@
<title>PixelDrain ~ Free file sharing service</title> <title>PixelDrain ~ Free file sharing service</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/home.css"/> <link rel="stylesheet" href="/res/style/home.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/> <link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/history.css"/> <link rel="stylesheet" href="/res/style/history.css"/>
@@ -36,10 +37,10 @@
<img id="header-image" src="/res/img/header_blackchancery.png" alt="Header image"/> <img id="header-image" src="/res/img/header_blackchancery.png" alt="Header image"/>
<div id="body" class="body"> <div id="body" class="body">
{{template "menu"}} {{template "menu"}}
<div class="highlight bg-middle border-bottom"> <div class="highlight_middle border-bottom">
<input id="fileInputField" type="file" name="file" multiple='multiple'/> <input id="fileInputField" type="file" name="file" multiple='multiple'/>
<button id="selectFileButton" class="big-button">Upload Files</button> <button id="selectFileButton" class="big_button button_highlight">Upload Files</button>
<button id="textButton" class="big-button" onClick="window.location.href = '/t/'">Upload Text</button><br/> <button id="textButton" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/>
<div id="progress-bar" class="progress-bar"> <div id="progress-bar" class="progress-bar">
<span class="progress-text"></span> <span class="progress-text"></span>
@@ -50,8 +51,8 @@
<div id="uploads-completed"></div> <div id="uploads-completed"></div>
</div> </div>
<div class="highlight bg-dark border-bottom"> <div class="highlight_dark border-bottom">
<a id="btnCreateList" href="#">Create list with uploaded files</a> <button id="btnCreateList">Create list with uploaded files</button>
</div> </div>
<h1>Pixeldrain Public Beta<img src="/res/img/sia.png" style="height: 40px;"/></h1> <h1>Pixeldrain Public Beta<img src="/res/img/sia.png" style="height: 40px;"/></h1>
@@ -75,8 +76,8 @@
The upload restrictions that the main site has haven't been The upload restrictions that the main site has haven't been
implemented in this version yet, so you can upload as much as implemented in this version yet, so you can upload as much as
you want. The server only has 256 GiB of space available, if it you want. The server only has 256 GiB of space available, if it
runs out before the Sia integration is stable I won't hesitate starts running out os space files will be purged from the local
to wipe the database and start over. filesystem and served from Sia on the next request.
</p> </p>
<h2>Legality</h2> <h2>Legality</h2>
<p> <p>
@@ -130,7 +131,6 @@
These will be added soon enough. These will be added soon enough.
</p> </p>
<ul> <ul>
<li>File lists</li>
<li>Zip explorer</li> <li>Zip explorer</li>
<li>Text file viewer (yes, you can upload text but not view it yet)</li> <li>Text file viewer (yes, you can upload text but not view it yet)</li>
<li>Some video formats (mime type detection is not complete)</li> <li>Some video formats (mime type detection is not complete)</li>

View File

@@ -6,6 +6,7 @@
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/res/style/viewer.css"/> <link rel="stylesheet" href="/res/style/viewer.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/season.css"/> <link rel="stylesheet" href="/res/style/season.css"/>
<link rel="stylesheet" href="/res/style/paste.css"/> <link rel="stylesheet" href="/res/style/paste.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
@@ -29,21 +30,18 @@
<body> <body>
<div id="filepreview"> <div id="filepreview">
<textarea id="textarea" <textarea id="textarea" class="textarea" placeholder="Your text here..." autofocus="autofocus"></textarea>
class="textarea"
placeholder="Your text here..."
autofocus="autofocus"></textarea>
</div> </div>
<div id="toolbar"> <div id="toolbar">
<!-- Ugly workaround to get rid of the scrollbar in non-webkit browsers --> <!-- Ugly workaround to get rid of the scrollbar in non-webkit browsers -->
<div> <div>
<div> <div>
<button class="toolbar-button" onClick="uploadText();"> <button class="toolbar_button button_full_width" onClick="uploadText();">
<img src="/res/img/upload_small.png" alt="Start Upload"/> <img src="/res/img/upload_small.png" alt="Start Upload"/>
<span>Upload</span> <span>Upload</span>
</button> </button>
<form action="/"> <form action="/">
<button class="toolbar-button"> <button class="toolbar_button button_full_width">
<img src="/res/img/pixeldrain_small.png" alt="Visit the home page" style="width:22px; height: 22px;"/> <img src="/res/img/pixeldrain_small.png" alt="Visit the home page" style="width:22px; height: 22px;"/>
<span>Home</span> <span>Home</span>
</button> </button>

View File

@@ -2,16 +2,20 @@ package webcontroller
import ( import (
"fmt" "fmt"
"html"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"path/filepath" "path/filepath"
"strings" "strings"
"fornaxian.com/pixeldrain-api/log"
"fornaxian.com/pixeldrain-web/conf" "fornaxian.com/pixeldrain-web/conf"
"fornaxian.com/pixeldrain-web/pixelapi" "fornaxian.com/pixeldrain-web/pixelapi"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"github.com/timakin/gonvert"
) )
// ServeFilePreview controller for GET /u/:id/preview // ServeFilePreview controller for GET /u/:id/preview
@@ -51,6 +55,9 @@ func (f FilePreview) Run(inf *pixelapi.FileInfo) string {
if strings.HasPrefix(f.FileInfo.MimeType, "audio") { if strings.HasPrefix(f.FileInfo.MimeType, "audio") {
return f.audio() return f.audio()
} }
if strings.HasPrefix(f.FileInfo.MimeType, "text") {
return f.text()
}
switch f.FileInfo.MimeType { switch f.FileInfo.MimeType {
case case
@@ -121,6 +128,53 @@ func (f FilePreview) pdf() string {
return f.frame("/res/misc/pdf-viewer/web/viewer.html?file=" + u.String()) return f.frame("/res/misc/pdf-viewer/web/viewer.html?file=" + u.String())
} }
func (f FilePreview) text() string {
htmlOut := `<div class="text-container">
<pre class="pre-container %s" style="width: 100%%;">%s</pre>
</div>`
if f.FileInfo.FileSize > 1e6 { // Prevent out of memory errors
return fmt.Sprintf(htmlOut, "",
"File is too large to view online.\nPlease download and view it locally.",
)
}
body, err := pixelapi.GetFile(f.FileInfo.ID)
if err != nil {
log.Error("Can't download text file for preview: %s", err)
return fmt.Sprintf(htmlOut, "",
"An error occurred while downloading this file.",
)
}
defer body.Close()
bodyBytes, err := ioutil.ReadAll(body)
if err != nil {
log.Error("Can't read text file for preview: %s", err)
return fmt.Sprintf(htmlOut, "",
"An error occurred while reading this file.",
)
}
converter := gonvert.New(string(bodyBytes), gonvert.UTF8)
result, err := converter.Convert()
if err != nil {
log.Debug("Unable to decode text file: %s", err)
return fmt.Sprintf(htmlOut, "",
"This file is using an unknown character encoding.\nPlease download it and view it locally.",
)
}
result = html.EscapeString(result)
var prettyPrint string
if f.FileInfo.MimeType != "text/plain" {
prettyPrint = "prettyprint linenums"
htmlOut += `<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>`
}
return fmt.Sprintf(htmlOut, prettyPrint, result)
}
func (f FilePreview) frame(url string) string { func (f FilePreview) frame(url string) string {
return fmt.Sprintf(`<iframe src="%s" class="image-container" return fmt.Sprintf(`<iframe src="%s" class="image-container"
seamless="seamless" frameborder="0" allowtransparency="true" seamless="seamless" frameborder="0" allowtransparency="true"

37
webcontroller/style.go Normal file
View File

@@ -0,0 +1,37 @@
package webcontroller
import (
"fmt"
"net/http"
"strings"
"github.com/julienschmidt/httprouter"
)
func GlobalCSSHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Header().Add("COntent-Type", "text/css; charset=utf-8")
var textColor = "c0c0c0"
// Originals
var highlightColor = "9FCF6C"
var highlightColorDark = "5F7747"
// Purple scheme
// var highlightColor = "843384"
// var highlightColorDark = "672867"
var response = fmt.Sprintf(
`:root {
--text_color: #%s;
--highlight_color: #%s;
--highlight_color_dark: #%s;
}
`,
textColor,
highlightColor,
highlightColorDark,
)
strings.NewReader(response).WriteTo(w)
}