Add homepage, architecture changes
* Create homepage * Page data is automatically reloaded (except when compiling) * Entrypoint is breezewiki.rkt for running and dist.rkt for compiling * Include stack trace when sending error messages
This commit is contained in:
parent
db4691f56c
commit
301636d597
10 changed files with 486 additions and 13 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -10,6 +10,9 @@
|
||||||
|
|
||||||
# Compiled
|
# Compiled
|
||||||
compiled
|
compiled
|
||||||
|
/breezewiki
|
||||||
|
/dist
|
||||||
|
/breezewiki-dist
|
||||||
|
|
||||||
# Personal
|
# Personal
|
||||||
/config.ini
|
/config.ini
|
||||||
|
|
|
@ -10,23 +10,33 @@
|
||||||
(prefix-in filter: web-server/dispatchers/dispatch-filter)
|
(prefix-in filter: web-server/dispatchers/dispatch-filter)
|
||||||
(prefix-in files: web-server/dispatchers/dispatch-files)
|
(prefix-in files: web-server/dispatchers/dispatch-files)
|
||||||
"src/config.rkt"
|
"src/config.rkt"
|
||||||
"src/page-category.rkt"
|
"src/reloadable.rkt"
|
||||||
"src/page-not-found.rkt"
|
"src/server-utils.rkt")
|
||||||
"src/page-proxy.rkt"
|
|
||||||
"src/page-wiki.rkt"
|
(define-syntax-rule (require-reloadable filename varname)
|
||||||
"src/page-search.rkt")
|
(define varname
|
||||||
|
(reloadable-entry-point->procedure
|
||||||
|
(make-reloadable-entry-point (quote varname) filename))))
|
||||||
|
|
||||||
|
(require-reloadable "src/page-category.rkt" page-category)
|
||||||
|
(require-reloadable "src/page-home.rkt" page-home)
|
||||||
|
(require-reloadable "src/page-not-found.rkt" page-not-found)
|
||||||
|
(require-reloadable "src/page-proxy.rkt" page-proxy)
|
||||||
|
(require-reloadable "src/page-search.rkt" page-search)
|
||||||
|
(require-reloadable "src/page-wiki.rkt" page-wiki)
|
||||||
|
|
||||||
|
(when (not (config-true? 'debug))
|
||||||
|
(set-reload-poll-interval! #f))
|
||||||
|
(reload!)
|
||||||
|
|
||||||
(define-runtime-path path-static "static")
|
(define-runtime-path path-static "static")
|
||||||
|
|
||||||
(define mime-types
|
|
||||||
(hash #".css" #"text/css"
|
|
||||||
#".svg" #"image/svg+xml"))
|
|
||||||
|
|
||||||
(serve/launch/wait
|
(serve/launch/wait
|
||||||
#:listen-ip (if (config-true? 'debug) "127.0.0.1" #f)
|
#:listen-ip (if (config-true? 'debug) "127.0.0.1" #f)
|
||||||
#:port (string->number (config-get 'port))
|
#:port (string->number (config-get 'port))
|
||||||
(λ (quit)
|
(λ (quit)
|
||||||
(sequencer:make
|
(sequencer:make
|
||||||
|
(pathprocedure:make "/" page-home)
|
||||||
(pathprocedure:make "/proxy" page-proxy)
|
(pathprocedure:make "/proxy" page-proxy)
|
||||||
(filter:make #rx"^/[a-z-]+/wiki/Category:.+$" (lift:make page-category))
|
(filter:make #rx"^/[a-z-]+/wiki/Category:.+$" (lift:make page-category))
|
||||||
(filter:make #rx"^/[a-z-]+/wiki/.+$" (lift:make page-wiki))
|
(filter:make #rx"^/[a-z-]+/wiki/.+$" (lift:make page-wiki))
|
||||||
|
@ -38,6 +48,6 @@
|
||||||
(struct-copy url u [path (cdr (url-path u))])))
|
(struct-copy url u [path (cdr (url-path u))])))
|
||||||
#:path->mime-type
|
#:path->mime-type
|
||||||
(lambda (u)
|
(lambda (u)
|
||||||
(hash-ref mime-types (path-get-extension u)))
|
(ext->mime-type (path-get-extension u)))
|
||||||
#:cache-no-cache (config-true? 'debug) #;"browser applies heuristics if unset"))
|
#:cache-no-cache (config-true? 'debug) #;"browser applies heuristics if unset"))
|
||||||
(lift:make page-not-found))))
|
(lift:make page-not-found))))
|
||||||
|
|
43
dist.rkt
Normal file
43
dist.rkt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#lang racket/base
|
||||||
|
(require racket/path
|
||||||
|
racket/runtime-path
|
||||||
|
net/url
|
||||||
|
web-server/servlet-dispatch
|
||||||
|
web-server/dispatchers/filesystem-map
|
||||||
|
(prefix-in pathprocedure: web-server/dispatchers/dispatch-pathprocedure)
|
||||||
|
(prefix-in sequencer: web-server/dispatchers/dispatch-sequencer)
|
||||||
|
(prefix-in lift: web-server/dispatchers/dispatch-lift)
|
||||||
|
(prefix-in filter: web-server/dispatchers/dispatch-filter)
|
||||||
|
(prefix-in files: web-server/dispatchers/dispatch-files)
|
||||||
|
"src/config.rkt"
|
||||||
|
"src/server-utils.rkt")
|
||||||
|
|
||||||
|
(require (only-in "src/page-category.rkt" page-category))
|
||||||
|
(require (only-in "src/page-home.rkt" page-home))
|
||||||
|
(require (only-in "src/page-not-found.rkt" page-not-found))
|
||||||
|
(require (only-in "src/page-proxy.rkt" page-proxy))
|
||||||
|
(require (only-in "src/page-search.rkt" page-search))
|
||||||
|
(require (only-in "src/page-wiki.rkt" page-wiki))
|
||||||
|
|
||||||
|
(define-runtime-path path-static "static")
|
||||||
|
|
||||||
|
(serve/launch/wait
|
||||||
|
#:listen-ip (if (config-true? 'debug) "127.0.0.1" #f)
|
||||||
|
#:port (string->number (config-get 'port))
|
||||||
|
(λ (quit)
|
||||||
|
(sequencer:make
|
||||||
|
(pathprocedure:make "/" page-home)
|
||||||
|
(pathprocedure:make "/proxy" page-proxy)
|
||||||
|
(filter:make #rx"^/[a-z-]+/wiki/Category:.+$" (lift:make page-category))
|
||||||
|
(filter:make #rx"^/[a-z-]+/wiki/.+$" (lift:make page-wiki))
|
||||||
|
(filter:make #rx"^/[a-z-]+/search$" (lift:make page-search))
|
||||||
|
(filter:make #rx"^/static/" (files:make
|
||||||
|
#:url->path
|
||||||
|
(lambda (u)
|
||||||
|
((make-url->path path-static)
|
||||||
|
(struct-copy url u [path (cdr (url-path u))])))
|
||||||
|
#:path->mime-type
|
||||||
|
(lambda (u)
|
||||||
|
(ext->mime-type (path-get-extension u)))
|
||||||
|
#:cache-no-cache (config-true? 'debug) #;"browser applies heuristics if unset"))
|
||||||
|
(lift:make page-not-found))))
|
77
src/page-home.rkt
Normal file
77
src/page-home.rkt
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require html-writing
|
||||||
|
web-server/http
|
||||||
|
"xexpr-utils.rkt"
|
||||||
|
"config.rkt")
|
||||||
|
|
||||||
|
(provide
|
||||||
|
page-home)
|
||||||
|
|
||||||
|
(module+ test
|
||||||
|
(require rackunit))
|
||||||
|
|
||||||
|
(define examples
|
||||||
|
'(("crosscode" "CrossCode_Wiki")
|
||||||
|
("minecraft" "Bricks")
|
||||||
|
("undertale" "Hot_Dog...%3F")
|
||||||
|
("tardis" "Eleanor_Blake")
|
||||||
|
("fireemblem" "God-Shattering_Star")
|
||||||
|
("fallout" "Pip-Boy_3000")))
|
||||||
|
|
||||||
|
(define content
|
||||||
|
`((h2 "BreezeWiki makes wiki pages on Fandom readable")
|
||||||
|
(p "It removes ads, videos, and suggested content, leaving you with a clean page that doesn't consume all your data.")
|
||||||
|
(p "If you're looking for an \"alternative\" to Fandom for writing pages, you should look elsewhere. BreezeWiki only lets you read existing pages.")
|
||||||
|
(p "BreezeWiki can also be called an \"alternative frontend for Fandom\".")
|
||||||
|
(h2 "Example pages")
|
||||||
|
(ul
|
||||||
|
,@(map (λ (x)
|
||||||
|
`(li (a (@ (href ,(apply format "/~a/wiki/~a" x)))
|
||||||
|
,(apply format "~a: ~a" x))))
|
||||||
|
examples))
|
||||||
|
(h2 "How to use")
|
||||||
|
(p "While browsing any page on Fandom, you can replace \"fandom.com\" in the address bar with \"breezewiki.com\" to see the BreezeWiki version of that page.")
|
||||||
|
(p "After that, you can click the links to navigate around the pages.")
|
||||||
|
(p "To get back to Fandom, click the link that's at the bottom of the page.")))
|
||||||
|
|
||||||
|
(define body
|
||||||
|
`(html
|
||||||
|
(head
|
||||||
|
(meta (@ (name ")viewport") (content "width=device-width, initial-scale=1")))
|
||||||
|
(title "About | BreezeWiki")
|
||||||
|
(link (@ (rel "stylesheet") (type "text/css") (href "/static/internal.css")))
|
||||||
|
(link (@ (rel "stylesheet") (type "text/css") (href "/static/main.css"))))
|
||||||
|
(body (@ (class "skin-fandomdesktop theme-fandomdesktop-light internal"))
|
||||||
|
(div (@ (class "main-container"))
|
||||||
|
(div (@ (class "fandom-community-header__background tileBoth header")))
|
||||||
|
(div (@ (class "page"))
|
||||||
|
(main (@ (class "page__main"))
|
||||||
|
(div (@ (class "custom-top"))
|
||||||
|
(h1 (@ (class "page-title"))
|
||||||
|
"About BreezeWiki"))
|
||||||
|
(div (@ (id "content") #;(class "page-content"))
|
||||||
|
(div (@ (id "mw-content-text"))
|
||||||
|
,@content))
|
||||||
|
(footer (@ (class "custom-footer"))
|
||||||
|
(div (@ (class "internal-footer"))
|
||||||
|
(img (@ (class "my-logo") (src "/static/breezewiki.svg")))
|
||||||
|
,(if (config-get 'instance-is-official)
|
||||||
|
`(p ,(format "This instance is run by the ~a developer, " (config-get 'application-name))
|
||||||
|
(a (@ (href "https://cadence.moe/contact"))
|
||||||
|
"Cadence."))
|
||||||
|
`(p
|
||||||
|
,(format "This unofficial instance is based off the ~a source code, but is not controlled by the code developer." (config-get 'application-name))))
|
||||||
|
(p "Text content on wikis run by Fandom is available under the Creative Commons Attribution-Share Alike License 3.0 (Unported), "
|
||||||
|
(a (@ (href "https://www.fandom.com/licensing")) "see license info.")
|
||||||
|
" Media files and official Fandom documents have different copying restrictions.")
|
||||||
|
(p ,(format "Fandom is a trademark of Fandom, Inc. ~a is not affiliated with Fandom." (config-get 'application-name)))))))))))
|
||||||
|
(module+ test
|
||||||
|
(check-not-false (xexp->html body)))
|
||||||
|
|
||||||
|
(define (page-home req)
|
||||||
|
(response/output
|
||||||
|
#:code 200
|
||||||
|
(λ (out)
|
||||||
|
(write-html body out))))
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
(define data (easy:response-json dest-res))
|
(define data (easy:response-json dest-res))
|
||||||
|
|
||||||
(define body (generate-results-page dest-url wikiname query data))
|
(define body (generate-results-page dest-url wikiname query data))
|
||||||
(when (config-get 'debug)
|
(when (config-true? 'debug)
|
||||||
; used for its side effects
|
; used for its side effects
|
||||||
; convert to string with error checking, error will be raised if xexp is invalid
|
; convert to string with error checking, error will be raised if xexp is invalid
|
||||||
(xexp->html body))
|
(xexp->html body))
|
||||||
|
|
150
src/reloadable.rkt
Normal file
150
src/reloadable.rkt
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
;;; Source: https://github.com/tonyg/racket-reloadable/blob/master/reloadable/main.rkt
|
||||||
|
;;; Source commit: cae2a14 from 24 May 2015
|
||||||
|
;;; Source license: LGPL 3 or later
|
||||||
|
|
||||||
|
(provide (struct-out reloadable-entry-point)
|
||||||
|
reload-poll-interval
|
||||||
|
set-reload-poll-interval!
|
||||||
|
reload-failure-retry-delay
|
||||||
|
reload!
|
||||||
|
make-reloadable-entry-point
|
||||||
|
lookup-reloadable-entry-point
|
||||||
|
reloadable-entry-point->procedure
|
||||||
|
make-persistent-state)
|
||||||
|
|
||||||
|
(require racket/set)
|
||||||
|
(require racket/string)
|
||||||
|
(require racket/match)
|
||||||
|
(require racket/rerequire)
|
||||||
|
|
||||||
|
(define reload-poll-interval 0.5) ;; seconds
|
||||||
|
(define reload-failure-retry-delay (make-parameter 5)) ;; seconds
|
||||||
|
|
||||||
|
(struct reloadable-entry-point (name
|
||||||
|
module-path
|
||||||
|
identifier-symbol
|
||||||
|
on-absent
|
||||||
|
[value #:mutable])
|
||||||
|
#:prefab)
|
||||||
|
|
||||||
|
(define reloadable-entry-points (make-hash))
|
||||||
|
(define persistent-state (make-hash))
|
||||||
|
|
||||||
|
(define (set-reload-poll-interval! v)
|
||||||
|
(set! reload-poll-interval v))
|
||||||
|
|
||||||
|
(define (reloader-main)
|
||||||
|
(let loop ()
|
||||||
|
(match (sync (handle-evt (thread-receive-evt)
|
||||||
|
(lambda (_) (thread-receive)))
|
||||||
|
(if reload-poll-interval
|
||||||
|
(handle-evt (alarm-evt (+ (current-inexact-milliseconds)
|
||||||
|
(* reload-poll-interval 1000)))
|
||||||
|
(lambda (_) (list #f 'reload)))
|
||||||
|
never-evt))
|
||||||
|
[(list ch 'reload)
|
||||||
|
(define result (do-reload!))
|
||||||
|
(when (not result) (sleep (reload-failure-retry-delay)))
|
||||||
|
(when ch (channel-put ch result))])
|
||||||
|
(loop)))
|
||||||
|
|
||||||
|
(define reloader-thread (thread reloader-main))
|
||||||
|
|
||||||
|
(define (reloader-rpc . request)
|
||||||
|
(define ch (make-channel))
|
||||||
|
(thread-send reloader-thread (cons ch request))
|
||||||
|
(channel-get ch))
|
||||||
|
|
||||||
|
(define (reload!) (reloader-rpc 'reload))
|
||||||
|
|
||||||
|
(define first-load? #t)
|
||||||
|
(define (say-loading-once! port)
|
||||||
|
(when first-load?
|
||||||
|
(display "loading support files" port)
|
||||||
|
(set! first-load? #f)))
|
||||||
|
|
||||||
|
(define (handle-loader-output)
|
||||||
|
(define i (thread-receive))
|
||||||
|
(define real-error-port (thread-receive))
|
||||||
|
(say-loading-once! real-error-port)
|
||||||
|
(let loop ()
|
||||||
|
(let ([line (read-line i)])
|
||||||
|
(cond
|
||||||
|
[(eof-object? line)
|
||||||
|
(void)]
|
||||||
|
[(string-contains? line "[load")
|
||||||
|
(display "." real-error-port)
|
||||||
|
(loop)]
|
||||||
|
[#t
|
||||||
|
(displayln line real-error-port)
|
||||||
|
(loop)]))))
|
||||||
|
|
||||||
|
;; Only to be called from reloader-main
|
||||||
|
(define (do-reload!)
|
||||||
|
(define module-paths (for/set ((e (in-hash-values reloadable-entry-points)))
|
||||||
|
(reloadable-entry-point-module-path e)))
|
||||||
|
(with-handlers ((exn:fail?
|
||||||
|
(lambda (e)
|
||||||
|
(log-error "*** WHILE RELOADING CODE***\n~a"
|
||||||
|
(parameterize ([current-error-port (open-output-string)])
|
||||||
|
((error-display-handler) (exn-message e) e)
|
||||||
|
(get-output-string (current-error-port))))
|
||||||
|
#f)))
|
||||||
|
(for ((module-path (in-set module-paths)))
|
||||||
|
(let ([real-error-port (current-error-port)])
|
||||||
|
(define-values (i o) (make-pipe))
|
||||||
|
(parameterize ([current-error-port o])
|
||||||
|
(define new-thread (thread handle-loader-output))
|
||||||
|
(thread-send new-thread i)
|
||||||
|
(thread-send new-thread real-error-port)
|
||||||
|
(dynamic-rerequire module-path #:verbosity 'all))))
|
||||||
|
(for ((e (in-hash-values reloadable-entry-points)))
|
||||||
|
(match-define (reloadable-entry-point _ module-path identifier-symbol on-absent _) e)
|
||||||
|
(define new-value (if on-absent
|
||||||
|
(dynamic-require module-path identifier-symbol on-absent)
|
||||||
|
(dynamic-require module-path identifier-symbol)))
|
||||||
|
(set-reloadable-entry-point-value! e new-value))
|
||||||
|
#t))
|
||||||
|
|
||||||
|
(define (make-reloadable-entry-point name module-path [identifier-symbol name]
|
||||||
|
#:on-absent [on-absent #f])
|
||||||
|
(define key (list module-path name))
|
||||||
|
(hash-ref reloadable-entry-points
|
||||||
|
key
|
||||||
|
(lambda ()
|
||||||
|
(define e (reloadable-entry-point name module-path identifier-symbol on-absent #f))
|
||||||
|
(hash-set! reloadable-entry-points key e)
|
||||||
|
e)))
|
||||||
|
|
||||||
|
(define (lookup-reloadable-entry-point name module-path)
|
||||||
|
(hash-ref reloadable-entry-points
|
||||||
|
(list module-path name)
|
||||||
|
(lambda ()
|
||||||
|
(error 'lookup-reloadable-entry-point
|
||||||
|
"Reloadable-entry-point ~a not found in module ~a"
|
||||||
|
name
|
||||||
|
module-path))))
|
||||||
|
|
||||||
|
(define (reloadable-entry-point->procedure e)
|
||||||
|
(make-keyword-procedure
|
||||||
|
(lambda (keywords keyword-values . positionals)
|
||||||
|
(keyword-apply (reloadable-entry-point-value e)
|
||||||
|
keywords
|
||||||
|
keyword-values
|
||||||
|
positionals))))
|
||||||
|
|
||||||
|
(define (make-persistent-state name initial-value-thunk)
|
||||||
|
(hash-ref persistent-state
|
||||||
|
name
|
||||||
|
(lambda ()
|
||||||
|
(define value (initial-value-thunk))
|
||||||
|
(define handler
|
||||||
|
(case-lambda
|
||||||
|
[() value]
|
||||||
|
[(new-value)
|
||||||
|
(set! value new-value)
|
||||||
|
value]))
|
||||||
|
(hash-set! persistent-state name handler)
|
||||||
|
handler)))
|
16
src/server-utils.rkt
Normal file
16
src/server-utils.rkt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(provide
|
||||||
|
ext->mime-type)
|
||||||
|
|
||||||
|
(module+ test
|
||||||
|
(require rackunit))
|
||||||
|
|
||||||
|
(define hash-ext-mime-type
|
||||||
|
(hash #".css" #"text/css"
|
||||||
|
#".svg" #"image/svg+xml"
|
||||||
|
#".png" #"image/png"))
|
||||||
|
(define (ext->mime-type ext)
|
||||||
|
(hash-ref hash-ext-mime-type ext))
|
||||||
|
(module+ test
|
||||||
|
(check-equal? (ext->mime-type #".png") #"image/png"))
|
|
@ -195,6 +195,7 @@
|
||||||
#:mime-type #"text/plain"
|
#:mime-type #"text/plain"
|
||||||
(λ (out)
|
(λ (out)
|
||||||
(for ([port (list (current-output-port) out)])
|
(for ([port (list (current-output-port) out)])
|
||||||
(displayln "Exception raised in Racket code at response generation time:" port)
|
(parameterize ([current-error-port out])
|
||||||
(displayln (exn-message e) port)))))])
|
(displayln "Exception raised in Racket code at response generation time:" (current-error-port))
|
||||||
|
((error-display-handler) (exn-message e) e))))))])
|
||||||
body ...))
|
body ...))
|
||||||
|
|
BIN
static/internal-background.png
Normal file
BIN
static/internal-background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
173
static/internal.css
Normal file
173
static/internal.css
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
:root {
|
||||||
|
--theme-body-dynamic-color-1: #fff;
|
||||||
|
--theme-body-dynamic-color-1--rgb: 255,255,255;
|
||||||
|
--theme-body-dynamic-color-2: #e6e6e6;
|
||||||
|
--theme-body-dynamic-color-2--rgb: 230,230,230;
|
||||||
|
--theme-page-dynamic-color-1: #000;
|
||||||
|
--theme-page-dynamic-color-1--rgb: 0,0,0;
|
||||||
|
--theme-page-dynamic-color-1--inverted: #fff;
|
||||||
|
--theme-page-dynamic-color-1--inverted--rgb: 255,255,255;
|
||||||
|
--theme-page-dynamic-color-2: #3a3a3a;
|
||||||
|
--theme-page-dynamic-color-2--rgb: 58,58,58;
|
||||||
|
--theme-sticky-nav-dynamic-color-1: #000;
|
||||||
|
--theme-sticky-nav-dynamic-color-1--rgb: 0,0,0;
|
||||||
|
--theme-sticky-nav-dynamic-color-2: #3a3a3a;
|
||||||
|
--theme-sticky-nav-dynamic-color-2--rgb: 58,58,58;
|
||||||
|
--theme-link-dynamic-color-1: #000;
|
||||||
|
--theme-link-dynamic-color-1--rgb: 0,0,0;
|
||||||
|
--theme-link-dynamic-color-2: #3a3a3a;
|
||||||
|
--theme-link-dynamic-color-2--rgb: 58,58,58;
|
||||||
|
--theme-accent-dynamic-color-1: #fff;
|
||||||
|
--theme-accent-dynamic-color-1--rgb: 255,255,255;
|
||||||
|
--theme-accent-dynamic-color-2: #e6e6e6;
|
||||||
|
--theme-accent-dynamic-color-2--rgb: 230,230,230;
|
||||||
|
--theme-body-background-color: #286cab;
|
||||||
|
--theme-body-background-color--rgb: 40,108,171;
|
||||||
|
|
||||||
|
--theme-body-text-color: #fff;
|
||||||
|
--theme-body-text-color--rgb: 255,255,255;
|
||||||
|
--theme-body-text-color--hover: #cccccc;
|
||||||
|
--theme-sticky-nav-background-color: #ffffff;
|
||||||
|
--theme-sticky-nav-background-color--rgb: 255,255,255;
|
||||||
|
--theme-sticky-nav-text-color: #000;
|
||||||
|
--theme-sticky-nav-text-color--hover: #333333;
|
||||||
|
--theme-page-background-color: #ffffff;
|
||||||
|
--theme-page-background-color--rgb: 255,255,255;
|
||||||
|
--theme-page-background-color--secondary: #f2f2f2;
|
||||||
|
--theme-page-background-color--secondary--rgb: 242,242,242;
|
||||||
|
--theme-page-text-color: #3a3a3a;
|
||||||
|
--theme-page-text-color--rgb: 58,58,58;
|
||||||
|
--theme-page-text-color--hover: #6d6d6d;
|
||||||
|
--theme-page-text-mix-color: #9d9d9d;
|
||||||
|
--theme-page-text-mix-color-95: #f5f5f5;
|
||||||
|
--theme-page-accent-mix-color: #b6b6b6;
|
||||||
|
--theme-page-headings-font: 'Rubik';
|
||||||
|
--theme-link-color: #8a8a8a;
|
||||||
|
--theme-link-color--rgb: 138,138,138;
|
||||||
|
--theme-link-color--hover: #565656;
|
||||||
|
--theme-link-label-color: #000;
|
||||||
|
--theme-accent-color: #6c6c6c;
|
||||||
|
--theme-accent-color--rgb: 108,108,108;
|
||||||
|
--theme-accent-color--hover: #9f9f9f;
|
||||||
|
--theme-accent-label-color: #fff;
|
||||||
|
--theme-border-color: #cecece;
|
||||||
|
--theme-border-color--rgb: 206,206,206;
|
||||||
|
--theme-alert-color: #bf0017;
|
||||||
|
--theme-alert-color--rgb: 191,0,23;
|
||||||
|
--theme-alert-color--hover: #59000a;
|
||||||
|
--theme-alert-color--secondary: #bf0017;
|
||||||
|
--theme-alert-label: #fff;
|
||||||
|
--theme-warning-color: #cf721c;
|
||||||
|
--theme-warning-color--rgb: 207,114,28;
|
||||||
|
--theme-warning-color--secondary: #ce711b;
|
||||||
|
--theme-warning-label: #000;
|
||||||
|
--theme-success-color: #0c742f;
|
||||||
|
--theme-success-color--rgb: 12,116,47;
|
||||||
|
--theme-success-color--secondary: #0c742f;
|
||||||
|
--theme-success-label: #fff;
|
||||||
|
--theme-message-color: #753369;
|
||||||
|
--theme-message-label: #fff;
|
||||||
|
--theme-community-header-color: #000000;
|
||||||
|
--theme-community-header-color--hover: #333333;
|
||||||
|
--theme-background-image-opacity: 100%;
|
||||||
|
--theme-page-text-opacity-factor: 0.85;
|
||||||
|
--theme-body-text-opacity-factor: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-fandomdesktop .CodeMirror{
|
||||||
|
--codemirror-yellow: #a88d00;
|
||||||
|
--codemirror-light-blue: #0096fb;
|
||||||
|
--codemirror-blue: #08f;
|
||||||
|
--codemirror-green: #290;
|
||||||
|
--codemirror-red: #f50;
|
||||||
|
--codemirror-dark-red: #a11;
|
||||||
|
--codemirror-purple: #80c;
|
||||||
|
--codemirror-pink: #e0e;
|
||||||
|
--codemirror-light-gray: #929292;
|
||||||
|
--codemirror-gray: #789797;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mw-highlight {
|
||||||
|
--pygments-background: #f4f3f4;
|
||||||
|
--pygments-err: #f00;
|
||||||
|
--pygments-c: #408080;
|
||||||
|
--pygments-k: #008000;
|
||||||
|
--pygments-o: #666;
|
||||||
|
--pygments-ch: #408080;
|
||||||
|
--pygments-cm: #408080;
|
||||||
|
--pygments-cp: #b17300;
|
||||||
|
--pygments-cpf: #408080;
|
||||||
|
--pygments-c1: #408080;
|
||||||
|
--pygments-cs: #408080;
|
||||||
|
--pygments-gd: #a00000;
|
||||||
|
--pygments-gr: #f00;
|
||||||
|
--pygments-gh: #000080;
|
||||||
|
--pygments-gi: #009500;
|
||||||
|
--pygments-go: #808080;
|
||||||
|
--pygments-gp: #000080;
|
||||||
|
--pygments-gu: #800080;
|
||||||
|
--pygments-gt: #04d;
|
||||||
|
--pygments-kc: #008000;
|
||||||
|
--pygments-kd: #008000;
|
||||||
|
--pygments-kn: #008000;
|
||||||
|
--pygments-kp: #008000;
|
||||||
|
--pygments-kr: #008000;
|
||||||
|
--pygments-kt: #b00040;
|
||||||
|
--pygments-m: #666;
|
||||||
|
--pygments-s: #ba2121;
|
||||||
|
--pygments-na: #768826;
|
||||||
|
--pygments-nb: #008000;
|
||||||
|
--pygments-nc: #00f;
|
||||||
|
--pygments-no: #800;
|
||||||
|
--pygments-nd: #a2f;
|
||||||
|
--pygments-ni: #7f7f7f;
|
||||||
|
--pygments-ne: #d2413a;
|
||||||
|
--pygments-nf: #00f;
|
||||||
|
--pygments-nl: #818100;
|
||||||
|
--pygments-nn: #00f;
|
||||||
|
--pygments-nt: #008000;
|
||||||
|
--pygments-nv: #19177c;
|
||||||
|
--pygments-ow: #a2f;
|
||||||
|
--pygments-w: #808080;
|
||||||
|
--pygments-mb: #666;
|
||||||
|
--pygments-mf: #666;
|
||||||
|
--pygments-mh: #666;
|
||||||
|
--pygments-mi: #666;
|
||||||
|
--pygments-mo: #666;
|
||||||
|
--pygments-sa: #ba2121;
|
||||||
|
--pygments-sb: #ba2121;
|
||||||
|
--pygments-sc: #ba2121;
|
||||||
|
--pygments-dl: #ba2121;
|
||||||
|
--pygments-sd: #ba2121;
|
||||||
|
--pygments-s2: #ba2121;
|
||||||
|
--pygments-se: #b62;
|
||||||
|
--pygments-sh: #ba2121;
|
||||||
|
--pygments-si: #b68;
|
||||||
|
--pygments-sx: #008000;
|
||||||
|
--pygments-sr: #b68;
|
||||||
|
--pygments-s1: #ba2121;
|
||||||
|
--pygments-ss: #19177c;
|
||||||
|
--pygments-bp: #008000;
|
||||||
|
--pygments-fm: #00f;
|
||||||
|
--pygments-vc: #19177c;
|
||||||
|
--pygments-vg: #19177c;
|
||||||
|
--pygments-vi: #19177c;
|
||||||
|
--pygments-vm: #19177c;
|
||||||
|
--pygments-il: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: linear-gradient(to bottom, rgba(225, 133, 155, 0) 15%, rgba(225, 133, 155, 0.8)), url(/static/internal-background.png);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page__main {
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 24px 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.internal-footer {
|
||||||
|
max-width: 700px;
|
||||||
|
}
|
Loading…
Reference in a new issue