diff --git a/inc/captcha/captcha.php b/inc/captcha/captcha.php
new file mode 100644
index 00000000..7c54fa3c
--- /dev/null
+++ b/inc/captcha/captcha.php
@@ -0,0 +1,357 @@
+width = $left;
+ $this->height = $top;
+
+ $this->charset = preg_split('//u', $charset);
+
+ $this->style = "";
+
+ for ($i = 0; $i < $len; $i++) {
+ $this->content[] = array(mb_substr($text, $i, 1, 'utf-8'), "top" => $top / 2 - $top / 4,
+ "left" => $left/10 + 9*$left*$i/10/$len,
+ "position" => "absolute");
+ }
+
+ $this->color = "hsla(".rand(1,360).", 76%, 78%, 1)";
+
+ $this->add_junk();
+ $this->mutate_sizes();
+ $this->mutate_positions();
+ $this->mutate_transform();
+ $this->mutate_anchors();
+ $this->randomize();
+ $this->mutate_containers();
+ $this->mutate_margins();
+ $this->mutate_styles();
+ $this->randomize();
+ }
+
+ function mutate_sizes() {
+ foreach ($this->content as &$v) {
+ if (!isset ($v['font-size']))
+ $v['font-size'] = rand($this->height/3 - 4, $this->height/3 + 8);
+ }
+ }
+ function mutate_positions() {
+ foreach ($this->content as &$v) {
+ $v['top'] += rand(-10,10);
+ $v['left'] += rand(-10,10);
+ }
+ }
+ function mutate_transform() {
+ $fromto = array('6'=>'9', '9'=>'6', '8'=>'8', '0'=>'0',
+ 'z'=>'z', 's'=>'s', 'n'=>'u', 'u'=>'n',
+ 'a'=>'ɐ', 'e'=>'ə', 'p'=>'d', 'd'=>'p',
+ 'A'=>'∀', 'E'=>'∃', 'H'=>'H', 'o'=>'o',
+ 'O'=>'O');
+
+ foreach ($this->content as &$v) {
+ $basefrom = -20;
+ $baseto = 20;
+
+ if (isset($fromto[$v[0]]) && rand(0,1)) {
+ $v[0] = $fromto[$v[0]];
+ $basefrom = 160;
+ $baseto = 200;
+ }
+
+ $v['transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
+ $v['-ms-transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
+ $v['-webkit-transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
+ }
+ }
+ function randomize(&$a = false) {
+ if ($a === false) {
+ $a = &$this->content;
+ }
+
+ shuffle($a);
+
+ foreach ($a as &$v) {
+ $this->shuffle_assoc($v);
+
+ if (is_array ($v[0])) {
+ $this->randomize($v[0]);
+ }
+ }
+ }
+
+ function add_junk() {
+ $count = rand(200, 300);
+
+ while ($count--) {
+ $elem = array();
+
+ $elem['top'] = rand(0, $this->height);
+ $elem['left'] = rand(0, $this->width);
+
+ $elem['position'] = 'absolute';
+
+ $elem[0] = $this->charset[rand(0, count($this->charset)-1)];
+
+ switch($t = rand (0,9)) {
+ case 0:
+ $elem['display'] = 'none'; break;
+ case 1:
+ $elem['top'] = rand(-60, -90); break;
+ case 2:
+ $elem['left'] = rand(-40, -70); break;
+ case 3:
+ $elem['top'] = $this->height + rand(10, 60); break;
+ case 4:
+ $elem['left'] = $this->width + rand(10, 60); break;
+ case 5:
+ $elem['color'] = $this->color; break;
+ case 6:
+ $elem['visibility'] = 'hidden'; break;
+ case 7:
+ $elem['height'] = rand(0,2);
+ $elem['overflow'] = 'hidden'; break;
+ case 8:
+ $elem['width'] = rand(0,1);
+ $elem['overflow'] = 'hidden'; break;
+ case 9:
+ $elem['font-size'] = rand(2, 6); break;
+ }
+
+ $this->content[] = $elem;
+ }
+ }
+
+ function mutate_anchors() {
+ foreach ($this->content as &$elem) {
+ if (rand(0,1)) {
+ $elem['right'] = $this->width - $elem['left'] - (int)(0.5*$elem['font-size']);
+ unset($elem['left']);
+ }
+ if (rand(0,1)) {
+ $elem['bottom'] = $this->height - $elem['top'] - (int)(1.5*$elem['font-size']);
+ unset($elem['top']);
+ }
+ }
+ }
+
+ function mutate_containers() {
+ for ($i = 0; $i <= 80; $i++) {
+ $new = [];
+ $new['width'] = rand(0, $this->width*2);
+ $new['height'] = rand(0, $this->height*2);
+ $new['top'] = rand(-$this->height * 2, $this->height * 2);
+ $new['bottom'] = $this->height - ($new['top'] + $new['height']);
+ $new['left'] = rand(-$this->width * 2, $this->width * 2);
+ $new['right'] = $this->width - ($new['left'] + $new['width']);
+
+ $new['position'] = 'absolute';
+
+ $new[0] = [];
+
+ $cnt = rand(0,10);
+ for ($j = 0; $j < $cnt; $j++) {
+ $elem = array_pop($this->content);
+ if (!$elem) break;
+
+ if (isset($elem['top'])) $elem['top'] -= $new['top'];
+ if (isset($elem['bottom'])) $elem['bottom'] -= $new['bottom'];
+ if (isset($elem['left'])) $elem['left'] -= $new['left'];
+ if (isset($elem['right'])) $elem['right'] -= $new['right'];
+
+ $new[0][] = $elem;
+ }
+
+ if (rand (0,1)) unset($new['top']);
+ else unset($new['bottom']);
+ if (rand (0,1)) unset($new['left']);
+ else unset($new['right']);
+
+ $this->content[] = $new;
+
+ shuffle($this->content);
+ }
+ }
+
+ function mutate_margins(&$a = false) {
+ if ($a === false) {
+ $a = &$this->content;
+ }
+
+ foreach ($a as &$v) {
+ $ary = ['top', 'left', 'bottom', 'right'];
+ shuffle($ary);
+ $cnt = rand(0,4);
+ $ary = array_slice($ary, 0, $cnt);
+
+ foreach ($ary as $prop) {
+ $margin = rand(-1000, 1000);
+
+ $v['margin-'.$prop] = $margin;
+
+ if (isset($v[$prop])) {
+ $v[$prop] -= $margin;
+ }
+ }
+
+ if (is_array($v[0])) {
+ $this->mutate_margins($v[0]);
+ }
+ }
+ }
+
+ function mutate_styles(&$a = false) {
+ if ($a === false) {
+ $a = &$this->content;
+ }
+
+ foreach ($a as &$v) {
+ $content = $v[0];
+ unset($v[0]);
+ $styles = array_splice($v, 0, rand(0, 6));
+ $v[0] = $content;
+
+ $id_or_class = rand(0,1);
+ $param = $id_or_class ? "id" : "class";
+ $prefix = $id_or_class ? "#" : ".";
+ $genname = "zz-".base_convert(rand(1,999999999), 10, 36);
+
+ if ($styles || rand(0,1)) {
+ $this->style .= $prefix.$genname."{";
+ $this->style .= $this->rand_whitespace();
+
+ foreach ($styles as $k => $val) {
+ if (is_int($val)) {
+ $val = "".$val."px";
+ }
+
+ $this->style .= "$k:";
+ $this->style .= $this->rand_whitespace();
+ $this->style .= "$val;";
+ $this->style .= $this->rand_whitespace();
+ }
+ $this->style .= "}";
+ $this->style .= $this->rand_whitespace();
+ }
+
+ $v[$param] = $genname;
+
+ if (is_array($v[0])) {
+ $this->mutate_styles($v[0]);
+ }
+ }
+ }
+
+ function to_html(&$a = false) {
+ $inside = true;
+
+ if ($a === false) {
+ if ($this->style) {
+ echo "";
+ }
+
+ echo "
";
+ $a = &$this->content;
+ $inside = false;
+ }
+
+ foreach ($a as &$v) {
+ $letter = $v[0];
+
+ unset ($v[0]);
+
+ echo "
rand_whitespace(1);
+
+ if (isset ($v['id'])) {
+ echo "id='$v[id]'";
+ echo $this->rand_whitespace(1);
+
+ unset ($v['id']);
+ }
+ if (isset ($v['class'])) {
+ echo "class='$v[class]'";
+ echo $this->rand_whitespace(1);
+
+ unset ($v['class']);
+ }
+
+ echo "style='";
+
+ foreach ($v as $k => $val) {
+ if (is_int($val)) {
+ $val = "".$val."px";
+ }
+
+ echo "$k:";
+ echo $this->rand_whitespace();
+ echo "$val;";
+ echo $this->rand_whitespace();
+
+ }
+
+ echo "'>";
+ echo $this->rand_whitespace();
+
+ if (is_array ($letter)) {
+ $this->to_html($letter);
+ }
+ else {
+ echo $letter;
+ }
+
+ echo "
";
+ }
+
+ if (!$inside) {
+ echo "
";
+ }
+
+ }
+
+ function rand_whitespace($r = 0) {
+ switch (rand($r,4)) {
+ case 0:
+ return "";
+ case 1:
+ return "\n";
+ case 2:
+ return "\t";
+ case 3:
+ return " ";
+ case 4:
+ return " ";
+ }
+ }
+
+
+
+ function shuffle_assoc(&$array) {
+ $keys = array_keys($array);
+
+ shuffle($keys);
+
+ foreach($keys as $key) {
+ $new[$key] = $array[$key];
+ }
+
+ $array = $new;
+
+ return true;
+ }
+}
+
+//$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789卐";
+
+//(new CzaksCaptcha("hotwheels", 300, 80, $charset))->to_html();
+?>
diff --git a/inc/captcha/config.php b/inc/captcha/config.php
new file mode 100644
index 00000000..568c06c5
--- /dev/null
+++ b/inc/captcha/config.php
@@ -0,0 +1,16 @@
+ 'SET NAMES utf8'));
+
+
+// Captcha expiration:
+$expires_in = 120; // 120 seconds
+
+// Captcha dimensions:
+$width = 250;
+$height = 80;
+
+// Captcha length:
+$length = 6;
diff --git a/inc/captcha/dbschema.sql b/inc/captcha/dbschema.sql
new file mode 100644
index 00000000..504ea10c
--- /dev/null
+++ b/inc/captcha/dbschema.sql
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+
+CREATE TABLE `captchas` (
+ `cookie` VARCHAR(50),
+ `extra` VARCHAR(200),
+ `text` VARCHAR(255),
+ `created_at` INT(11),
+ PRIMARY KEY (cookie, extra)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
diff --git a/inc/captcha/entrypoint.php b/inc/captcha/entrypoint.php
new file mode 100644
index 00000000..3b468a2a
--- /dev/null
+++ b/inc/captcha/entrypoint.php
@@ -0,0 +1,85 @@
+prepare("DELETE FROM `captchas` WHERE `created_at` < ?")->execute([time() - $expires_in]);
+}
+
+switch ($mode) {
+// Request: GET entrypoint.php?mode=get&extra=1234567890
+// Response: JSON: cookie => "generatedcookie", captchahtml => "captchahtml", expires_in => 120
+case "get":
+ if (!isset ($_GET['extra'])) {
+ die();
+ }
+
+ header("Content-type: application/json");
+
+ $extra = $_GET['extra'];
+
+ require_once("config.php");
+
+ $text = rand_string($length, $extra);
+
+ $captcha = new CzaksCaptcha($text, $width, $height, $extra);
+
+ $cookie = rand_string(20, "abcdefghijklmnopqrstuvwxyz");
+
+ ob_start();
+ $captcha->to_html();
+ $html = ob_get_contents();
+ ob_end_clean();
+
+ $query = $pdo->prepare("INSERT INTO `captchas` (`cookie`, `extra`, `text`, `created_at`) VALUES (?, ?, ?, ?)");
+ $query->execute( [$cookie, $extra, $text, time()]);
+
+ echo json_encode(["cookie" => $cookie, "captchahtml" => $html, "expires_in" => $expires_in]);
+
+ break;
+
+// Request: GET entrypoint.php?mode=check&cookie=generatedcookie&extra=1234567890&text=captcha
+// Response: 0 OR 1
+case "check":
+ if (!isset ($_GET['mode'])
+ || !isset ($_GET['cookie'])
+ || !isset ($_GET['extra'])
+ || !isset ($_GET['text'])) {
+ die();
+ }
+
+ require_once("config.php");
+
+ cleanup($pdo, $expires_in);
+
+ $query = $pdo->prepare("SELECT * FROM `captchas` WHERE `cookie` = ? AND `extra` = ?");
+ $query->execute([$_GET['cookie'], $_GET['extra']]);
+
+ $ary = $query->fetchAll();
+
+ if (!$ary) {
+ echo "0";
+ }
+ else {
+ $query = $pdo->prepare("DELETE FROM `captchas` WHERE `cookie` = ? AND `extra` = ?");
+ $query->execute([$_GET['cookie'], $_GET['extra']]);
+
+ if ($ary[0]['text'] !== $_GET['text']) {
+ echo "0";
+ }
+ else {
+ echo "1";
+ }
+ }
+
+ break;
+}
diff --git a/inc/captcha/readme.md b/inc/captcha/readme.md
new file mode 100644
index 00000000..8b1f538a
--- /dev/null
+++ b/inc/captcha/readme.md
@@ -0,0 +1,10 @@
+I integrated this from: https://github.com/ctrlcctrlv/infinity/commit/62a6dac022cb338f7b719d0c35a64ab3efc64658
+
+First import the captcha/dbschema.sql in your database it is no longer required.
+
+In inc/captcha/config.php change the database_name database_user database_password to your own settings.
+
+Add js/captcha.js in your instance-config.php or config.php
+
+Go to Line 305 in the /inc/config file and copy the settings in instance config, while changing the url to your website.
+Go to the line beneath it if you only want to enable it when posting a new thread.
diff --git a/inc/config.php b/inc/config.php
index db424e36..38375554 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -196,7 +196,11 @@
// Prevents most Tor exit nodes from making posts. Recommended, as a lot of abuse comes from Tor because
// of the strong anonymity associated with it.
- $config['dnsbl'][] = array('tor.dnsbl.sectoor.de', 1);
+ // Example: $config['dnsbl'][] = 'another.blacklist.net'; //
+ // $config['dnsbl'][] = array('tor.dnsbl.sectoor.de', 1); //sectoor.de site is dead. the number stands for (an) ip adress(es) I guess.
+
+ // Replacement for sectoor.de
+ $config['dnsbl'][] = 'torexit.dan.me.uk';
// http://www.sorbs.net/using.shtml
// $config['dnsbl'][] = array('dnsbl.sorbs.net', array(2, 3, 4, 5, 6, 7, 8, 9));
@@ -284,6 +288,8 @@
'embed',
'recaptcha_challenge_field',
'recaptcha_response_field',
+ 'captcha_cookie',
+ 'captcha_text',
'spoiler',
'page',
'file_url',
@@ -299,6 +305,26 @@
// Public and private key pair from https://www.google.com/recaptcha/admin/create
$config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f';
$config['recaptcha_private'] = '6LcXTcUSAAAAAOGVbVdhmEM1_SyRF4xTKe8jbzf_';
+
+ // Enable Custom Captcha you need to change a couple of settings
+ //Read more at: /captcha/instructions.md
+ $config['captcha'] = array();
+
+ // Enable custom captcha provider
+ $config['captcha']['enabled'] = false;
+
+ //New thread captcha
+ //Require solving a captcha to post a thread.
+ //Default off.
+ $config['new_thread_capt'] = false;
+
+ // Custom captcha get provider path (if not working get the absolute path aka your url.)
+ $config['captcha']['provider_get'] = '../inc/captcha/entrypoint.php';
+ // Custom captcha check provider path
+ $config['captcha']['provider_check'] = '../inc/captcha/entrypoint.php';
+
+ // Custom captcha extra field (eg. charset)
+ $config['captcha']['extra'] = 'abcdefghijklmnopqrstuvwxyz';
// Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board
$config['board_locked'] = false;
@@ -1015,6 +1041,7 @@
// $config['additional_javascript'][] = 'js/auto-reload.js';
// $config['additional_javascript'][] = 'js/post-hover.js';
// $config['additional_javascript'][] = 'js/style-select.js';
+ // $config['additional_javascript'][] = 'js/captcha.js';
// Where these script files are located on the web. Defaults to $config['root'].
// $config['additional_javascript_url'] = 'http://static.example.org/tinyboard-javascript-stuff/';
@@ -1104,6 +1131,7 @@
$config['error']['toomanycross'] = _('Too many cross-board links; post discarded.');
$config['error']['nodelete'] = _('You didn\'t select anything to delete.');
$config['error']['noreport'] = _('You didn\'t select anything to report.');
+ $config['error']['invalidreport'] = _('The reason was too long.');
$config['error']['toomanyreports'] = _('You can\'t report that many posts at once.');
$config['error']['invalidpassword'] = _('Wrong password…');
$config['error']['invalidimg'] = _('Invalid image.');
@@ -1641,6 +1669,9 @@
// Enable the search form
$config['search']['enable'] = false;
+ // Enable search in the board index.
+ $config['board_search'] = false;
+
// Maximal number of queries per IP address per minutes
$config['search']['queries_per_minutes'] = Array(15, 2);
diff --git a/install.php b/install.php
index 6f1617a8..ff994010 100644
--- a/install.php
+++ b/install.php
@@ -1,7 +1,7 @@
vichan upgrade path.
query("CREATE TABLE IF NOT EXISTS ``search_queries`` ( `ip` varchar(39) NOT NULL, `time` int(11) NOT NULL, `query` text NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;") or error(db_error());
diff --git a/install.sql b/install.sql
index 1acc849f..ca60a58a 100644
--- a/install.sql
+++ b/install.sql
@@ -303,7 +303,7 @@ CREATE TABLE IF NOT EXISTS `ban_appeals` (
-- Table structure for table `pages`
--
-CREATE TABLE `pages` (
+CREATE TABLE IF NOT EXISTS `pages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`board` varchar(58) CHARACTER SET utf8 DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 NOT NULL,
@@ -320,7 +320,7 @@ CREATE TABLE `pages` (
-- Table structure for table `nntp_references`
--
-CREATE TABLE `nntp_references` (
+CREATE TABLE IF NOT EXISTS `nntp_references` (
`board` varchar(30) NOT NULL,
`id` int(11) unsigned NOT NULL,
`message_id` varchar(255) CHARACTER SET ascii NOT NULL,
@@ -332,6 +332,20 @@ CREATE TABLE `nntp_references` (
UNIQUE KEY `u_board_id` (`board`, `id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `captchas`
+--
+
+CREATE TABLE IF NOT EXISTS `captchas` (
+ `cookie` VARCHAR(50),
+ `extra` VARCHAR(200),
+ `text` VARCHAR(255),
+ `created_at` INT(11),
+ PRIMARY KEY (`cookie`,`extra`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
+
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
diff --git a/js/captcha.js b/js/captcha.js
new file mode 100644
index 00000000..018588b7
--- /dev/null
+++ b/js/captcha.js
@@ -0,0 +1,43 @@
+var tout;
+
+function redo_events(provider, extra) {
+ $('.captcha .captcha_text, textarea[id="body"]').off("focus").one("focus", function() { actually_load_captcha(provider, extra); });
+}
+
+function actually_load_captcha(provider, extra) {
+ $('.captcha .captcha_text, textarea[id="body"]').off("focus");
+
+ if (tout !== undefined) {
+ clearTimeout(tout);
+ }
+
+ $.getJSON(provider, {mode: 'get', extra: extra}, function(json) {
+ $(".captcha .captcha_cookie").val(json.cookie);
+ $(".captcha .captcha_html").html(json.captchahtml);
+
+ setTimeout(function() {
+ redo_events(provider, extra);
+ }, json.expires_in * 1000);
+ });
+}
+
+function load_captcha(provider, extra) {
+ $(function() {
+ $(".captcha>td").html(""+
+ ""+
+ "");
+
+ $("#quick-reply .captcha .captcha_text").prop("placeholder", _("Verification"));
+
+ $(".captcha .captcha_html").on("click", function() { actually_load_captcha(provider, extra); });
+ $(document).on("ajax_after_post", function() { actually_load_captcha(provider, extra); });
+ redo_events(provider, extra);
+
+ $(window).on("quick-reply", function() {
+ redo_events(provider, extra);
+ $("#quick-reply .captcha .captcha_html").html($("form:not(#quick-reply) .captcha .captcha_html").html());
+ $("#quick-reply .captcha .captcha_cookie").val($("form:not(#quick-reply) .captcha .captcha_cookie").html());
+ $("#quick-reply .captcha .captcha_html").on("click", function() { actually_load_captcha(provider, extra); });
+ });
+ });
+}
\ No newline at end of file
diff --git a/js/quick-reply.js b/js/quick-reply.js
index 408de410..cd1b9e8a 100644
--- a/js/quick-reply.js
+++ b/js/quick-reply.js
@@ -281,7 +281,7 @@
$postForm.find('textarea[name="body"]').removeAttr('id').removeAttr('cols').attr('placeholder', _('Comment'));
- $postForm.find('textarea:not([name="body"]),input[type="hidden"]').removeAttr('id').appendTo($dummyStuff);
+ $postForm.find('textarea:not([name="body"]),input[type="hidden"]:not(.captcha_cookie)').removeAttr('id').appendTo($dummyStuff);
$postForm.find('br').remove();
$postForm.find('table').prepend('\
diff --git a/post.php b/post.php
index 3d0e618d..f3c2c6e2 100644
--- a/post.php
+++ b/post.php
@@ -287,6 +287,9 @@ if (isset($_POST['delete'])) {
if (empty($report))
error($config['error']['noreport']);
+
+ if (strlen($report) > 30)
+ error($config['error']['invalidreport']);
if (count($report) > $config['report_limit'])
error($config['error']['toomanyreports']);
@@ -390,7 +393,20 @@ if (isset($_POST['delete'])) {
if (!$resp->is_valid) {
error($config['error']['captcha']);
}
+ // Same, but now with our custom captcha provider
+ if (($config['captcha']['enabled']) || (($post['op']) && ($config['new_thread_capt'])) ) {
+ $resp = file_get_contents($config['captcha']['provider_check'] . "?" . http_build_query([
+ 'mode' => 'check',
+ 'text' => $_POST['captcha_text'],
+ 'extra' => $config['captcha']['extra'],
+ 'cookie' => $_POST['captcha_cookie']
+ ]));
+ if ($resp !== '1') {
+ error($config['error']['captcha'] .
+ '');
}
+ }
+}
if (!(($post['op'] && $_POST['post'] == $config['button_newtopic']) ||
(!$post['op'] && $_POST['post'] == $config['button_reply'])))
diff --git a/search.php b/search.php
index 71f4ae5e..394aa3ff 100644
--- a/search.php
+++ b/search.php
@@ -15,7 +15,7 @@
$boards = listBoards(TRUE);
}
- $body = Element('search_form.html', Array('boards' => $boards, 'b' => isset($_GET['board']) ? $_GET['board'] : false, 'search' => isset($_GET['search']) ? str_replace('"', '"', utf8tohtml($_GET['search'])) : false));
+ $body = Element('search_form.html', Array('boards' => $boards, 'board' => isset($_GET['board']) ? $_GET['board'] : false, 'search' => isset($_GET['search']) ? str_replace('"', '"', utf8tohtml($_GET['search'])) : false));
if(isset($_GET['search']) && !empty($_GET['search']) && isset($_GET['board']) && in_array($_GET['board'], $boards)) {
$phrase = $_GET['search'];
diff --git a/stylesheets/greendark.css b/stylesheets/greendark.css
new file mode 100644
index 00000000..ccec5c13
--- /dev/null
+++ b/stylesheets/greendark.css
@@ -0,0 +1,222 @@
+/* greenddark.css by Z Blanche */
+body {
+ background:#1b1b1b;
+ background-image: url(''), url('');
+ background-repeat: no-repeat;
+ background-attachment: fixed, scroll;
+ background-position: right bottom, 100% 100%;
+ font-family: arial,helvetica,sans-serif;
+ font-size: 12pt;
+ color: #C0C0C0;
+ cursor: default;
+ margin: 0 8px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+div.boardlist {
+ text-align: center;
+}
+div.post.reply {
+ margin-right: px;
+ margin-bottom: px;
+ background: #222;
+ border: 0;
+ padding: 6px;
+ border-radius: 6px;
+ box-shadow:
+ display:
+}
+/*media screen*/
+a, a:visited {
+ text-decoration: underline;
+ color:#008080
+}
+button, input[type=submit], input[type=button] {
+ cursor: pointer;
+ border-radius: 5px;
+ border: 0;
+ padding: 6px;
+}
+h1, .subtitle a, .subtitle {
+ color: #0df211!important;
+}
+input[type="text"], textarea, input[type=password] {
+ background: #32d23;
+ border-radius: 25px;
+}
+form table tr th {
+ background: transparent;
+}
+.post {
+ padding: 6px;
+}
+img {
+ border-radius: 22px; }
+hr {
+ opacity:0.2;
+}
+label, .subject{
+ color:#AAA!important;
+}
+.name{
+ color:#!important;
+}
+div.pages {
+ border:0;
+ background:none;
+ color: #fff!important;
+}
+div.pages a.selected {
+ color: #ff69b4!important;
+ padding: 4px;
+ text-decoration: none;
+}
+div.pages a {
+ color: #fafafa!important;
+ padding: 4px;
+ text-decoration: none;
+}
+.subtitle a {
+ display: block;
+ margin: 7px auto 7px auto;
+ font-size: 15px;
+ text-decoration: none;
+ border: 1px solid #0df211;
+ padding: 5px;
+ border-radius: 7px;
+ max-width: 100px;
+}
+input[type=text], input[type=password] {
+ padding: 5px;
+ font-size: 15px;
+}
+textarea {
+ resize:vertical;
+ max-height: 400px;
+ width: 250px;
+ padding: 5px;
+ font-size: 15px;
+}
+@-webkit-keyframes Pulse {
+ from { background-color: #007d9a;
+ -webkit-box-shadow: 0 0 9px #333; }
+ 50% { background-color: #2daebf;
+ -webkit-box-shadow: 0 0 18px #2daebf; }
+ to { background-color: #007d9a;
+ -webkit-box-shadow: 0 0 9px #333; }
+}
+.board_image {
+ -webkit-animation-name: Pulse;
+ -webkit-animation-duration: 3s;
+ -webkit-animation-iteration-count: infinite;
+ -webkit-transform: rotate(5deg);
+}
+@-webkit-keyframes shakey {
+ 0% { -webkit-transform: translate(2px, 1px) rotate(0deg); }
+ 10% { -webkit-transform: translate(-1px, -2px) rotate(-1deg); }
+ 20% { -webkit-transform: translate(-3px, 0px) rotate(1deg); }
+ 30% { -webkit-transform: translate(0px, 2px) rotate(0deg); }
+ 40% { -webkit-transform: translate(1px, -1px) rotate(1deg); }
+ 50% { -webkit-transform: translate(-1px, 2px) rotate(-1deg); }
+ 60% { -webkit-transform: translate(-3px, 1px) rotate(0deg); }
+ 70% { -webkit-transform: translate(2px, 1px) rotate(-1deg); }
+ 80% { -webkit-transform: translate(-1px, -1px) rotate(1deg); }
+ 90% { -webkit-transform: translate(2px, 2px) rotate(0deg); }
+ 100% { -webkit-transform: translate(1px, -2px) rotate(-1deg); }
+}
+button:hover, input[type=submit]:hover, input[type=button]:hover,
+button:focus, input[type=submit]:focus, input[type=button]:focus
+{
+ -webkit-animation-name: shakey;
+ -webkit-animation-duration: 0.1s;
+ -webkit-transform-origin:50% 50%;
+ -webkit-animation-iteration-count: infinite;
+ -webkit-animation-timing-function: linear;
+ background-color: #2daebf;
+}
+button, input[type=submit], input[type=button] {
+ -webkit-animation-name: Pulse;
+ -webkit-animation-duration: 2s;
+ -webkit-animation-iteration-count: infinite;
+ color: #ffd;
+}
+div.ban {
+ background: #222;
+ background-image: url(''), url('');
+ background-repeat: no-repeat;
+ background-attachment: fixed, scroll;
+ background-position: right bottom, 100% 100%;
+ color:#fff;
+ border: 0;
+ border-radius: 6px;
+ padding: 6px;
+}
+.desktop-style div.boardlist, .desktop-style div.boardlist:hover {
+ background:#333!important;
+ border: 0!important;
+}
+.theme-catalog div.grid-size-small:hover {
+ background: #333!important;
+}
+#options_div {
+ background: #222!important;
+}
+select {
+ background:#333;
+ color:#eee;
+ cursor:pointer;
+ border-radius: 4px;
+ border: 1px #222 solid;
+ padding: 4px;
+}
+ ::-webkit-scrollbar {
+ width: 6px;
+ height: 8px;
+ background: #333;
+ box-shadow: none;
+}
+ ::-webkit-scrollbar-track {
+ -webkit-box-shadow: none;
+ background: none;
+}
+ ::-webkit-scrollbar-thumb {
+ background: #ddd;
+ width: 6px;
+ padding: 4px;
+ border-radius: 10px;
+ -webkit-box-shadow: 0 0 6px rgba(0,0,0,0.5);
+}
+header div.subtitle {
+ font-size: 12pt
+}
+.desktop-style div.boardlist, .desktop-style div.boardlist:hover {
+ background: #1b1b1b!important;
+}
+div.post.reply.highlighted {
+ background: #FFFFFF;
+}
+div.banner {
+ background-color: #1b1b1b;
+}
+
+div.blotter {
+ color: green;
+ font-weight: bold;
+ text-align: center;
+}
+div.post.reply div.body a {
+ color: #AAA;
+}
+p.intro a.email span.name {
+ color: #cdaf95;
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
+ color: #32DD72;
+}
+p.intro span.capcode,p.intro a.capcode,p.intro a.nametag {
+ color: #F00000;
+ margin-left: 0;
+}
+table tbody tr:nth-of-type( even ) {
+ background-color: #1b1b1b;
+}
diff --git a/templates/index.html b/templates/index.html
index 1be614e3..e18279eb 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -57,6 +57,17 @@
{% if config.global_message %}
{{ config.global_message }} {% endif %}
+
+ {% if config.board_search %}
+
+ {% endif %}
+
|
{% endif %}
+ {% if config.captcha.enabled %}
+
+
+ {% trans %}Verification{% endtrans %}
+ |
+
+
+ |
+
+ {% elseif config.new_thread_capt %}
+ {% if not id %}
+
+
+ {% trans %}Verification{% endtrans %}
+ |
+
+
+ |
+
+ {% endif %}
+ {% endif %}
{% if config.user_flag %}
{% trans %}Flag{% endtrans %} |
diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php
index a826048f..a8aad5d1 100644
--- a/templates/themes/recent/theme.php
+++ b/templates/themes/recent/theme.php
@@ -80,6 +80,8 @@
}
else {
$post['src'] = $config['uri_thumb'] . $files[0]->thumb;
+ $post['thumbwidth'] = $files[0]->thumbwidth;
+ $post['thumbheight'] = $files[0]->thumbheight;
}
}