Compare commits
No commits in common. 'da33a8c38b5ff937c61fc194ae6c7e019a577b68' and '603f7f861ebb33966899971dc390e87f3239eb23' have entirely different histories.
da33a8c38b
...
603f7f861e
@ -1,7 +1,10 @@
|
||||
# zola trash
|
||||
zola
|
||||
public
|
||||
static/processed_images
|
||||
|
||||
# os trash
|
||||
*.log
|
||||
.cache
|
||||
.DS_Store
|
||||
src/.temp
|
||||
node_modules
|
||||
dist
|
||||
.env
|
||||
.env.*
|
||||
.vitepress/cache
|
||||
.vitepress/dist
|
||||
|
@ -0,0 +1,72 @@
|
||||
import { defineConfig } from 'vitepress'
|
||||
import { defineConfigWithTheme } from 'vitepress'
|
||||
import type { ThemeConfig } from './theme/Config'
|
||||
|
||||
export default defineConfigWithTheme<ThemeConfig>({
|
||||
title: "k0r.386",
|
||||
description: "Norman Köhrings Homepage",
|
||||
lang: 'en',
|
||||
head: [
|
||||
['link', { rel: 'icon', href: '/favicon.png' }],
|
||||
['link', { rel: 'alternate', href: 'https://k0r.in' }],
|
||||
['link', { rel: 'alternate', href: 'https://koehr.in' }],
|
||||
['link', { rel: 'alternate', href: 'https://koehr.ing' }],
|
||||
['link', { rel: 'canonical', href: 'https://koehr.ing' }],
|
||||
['meta', { content: "The personal page and weblog of Norman Köhring", name: "description" }],
|
||||
['meta', { content: "Norman Köhring", name: "author" }],
|
||||
['meta', { content: "the codeartist — programmer and engineer based in Berlin", name: "DC.title" }],
|
||||
['meta', { content: "52.4595, 13.5335", name: "ICBM" }],
|
||||
['meta', { content: "52.4595; 13.5335", name: "geo.position" }],
|
||||
['meta', { content: "DE-BE", name: "geo.region" }],
|
||||
['meta', { content: "Berlin", name: "geo.plac,ename" }],
|
||||
['meta', { content: "width=device-width,initial-scale=1.0", name: "viewport" }],
|
||||
],
|
||||
themeConfig: {
|
||||
commands: [{
|
||||
command: 'about',
|
||||
aliases: ['info'],
|
||||
help: 'Who is Norman Köhring?',
|
||||
message: 'Norman Köhring is a programmer, hacker and open source enthusiast based in Berlin. He is the Principal Frontend Engineer at Code Gaia, where he is a proud part of revolutionizing carbon emission reporting.',
|
||||
uris: [{
|
||||
label: 'Berlin', uri: 'https://www.openstreetmap.org/#map=12/52.4595/13.5335'
|
||||
}, {
|
||||
label: 'CodeGaia', uri: 'https://codegaia.io/'
|
||||
}, {
|
||||
label: 'Hacker?', uri: 'https://en.wikipedia.org/wiki/Hacker'
|
||||
}]
|
||||
}, {
|
||||
command: 'contact',
|
||||
aliases: ['email', 'homepage', 'www'],
|
||||
help: 'How to contact Norman Köhring?',
|
||||
message: [
|
||||
'# other servers',
|
||||
'email - n@koehr.in OR norman.koehring@mailbox.org',
|
||||
'mastodon - mstdn.io/@koehr',
|
||||
'twitter - twitter.com/koehr_in',
|
||||
'github - github.com/nkoehring',
|
||||
'instagram - instagram.com/coffee_n_code',
|
||||
'500px - 500px.com/koehr',
|
||||
'# my server',
|
||||
'sourcecode - git.k0r.in/ (forgejo)',
|
||||
'fediverse - m.k0r.in/@n (misskey)',
|
||||
].join('\n'),
|
||||
uris: [{
|
||||
label: 'email', uri: 'mailto:n@koehr.in'
|
||||
}, {
|
||||
label: 'mastodon', uri: 'https://mstdn.io/@koehr'
|
||||
}, {
|
||||
label: 'twitter', uri: 'https://twitter.com/koehr_in'
|
||||
}, {
|
||||
label: 'github', uri: 'https://github.com/nkoehring'
|
||||
}, {
|
||||
label: 'instagram', uri: 'https://instagram.com/coffee_n_code'
|
||||
}, {
|
||||
label: '500px', uri: 'https://500px.com/koehr'
|
||||
}, {
|
||||
label: 'sourcecode', uri: 'https://git.k0r.in/'
|
||||
}, {
|
||||
label: 'fediverse', uri: 'https://m.k0r.in/@n'
|
||||
}]
|
||||
}],
|
||||
}
|
||||
})
|
@ -0,0 +1,16 @@
|
||||
export type Uri = {
|
||||
label: string
|
||||
uri: string
|
||||
}
|
||||
|
||||
export type SimpleCommand = {
|
||||
command: string,
|
||||
aliases?: string[],
|
||||
help?: string,
|
||||
message: string,
|
||||
uris: Uri[],
|
||||
}
|
||||
|
||||
export interface ThemeConfig {
|
||||
commands: SimpleCommand[]
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { useData } from 'vitepress'
|
||||
import useTerminal from './useTerminal'
|
||||
import titleArt from './titles'
|
||||
|
||||
const { site, page, frontmatter } = useData()
|
||||
const enhancedReadability = ref(false)
|
||||
|
||||
const title = computed(() => {
|
||||
const titleKey = frontmatter.value.title
|
||||
const title = titleArt[titleKey] || titleArt['not_found']
|
||||
|
||||
return title.join('\n')
|
||||
})
|
||||
const content = computed(() => frontmatter.value.content ?? ['this page does not exist'])
|
||||
const commands = computed(() => site.value.themeConfig.commands)
|
||||
|
||||
const prompt = '\n$> '
|
||||
const lines = ref(title.value + '\n\n' + content.value.join('\n') + '\n' + prompt)
|
||||
|
||||
const textArea = ref<HTMLTextAreaElement | null>(null)
|
||||
const footer = ref([])
|
||||
|
||||
onMounted(() => {
|
||||
if (textArea.value === null) {
|
||||
console.error('textarea is missing')
|
||||
return
|
||||
}
|
||||
|
||||
const { addText, addLine, clear, footerLinks } = useTerminal(textArea.value, commands.value)
|
||||
|
||||
watch(frontmatter, () => {
|
||||
addText(title.value + '\n', false)
|
||||
addLine(content.value.join('\n'))
|
||||
}, { immediate: true })
|
||||
|
||||
watch(footerLinks, () => {
|
||||
footer.value = footerLinks.value
|
||||
}, { immediate: true })
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="screen" :class="{ 'enhanced-readability': enhancedReadability }">
|
||||
<div id="wrap">
|
||||
<div id="interlace" />
|
||||
<div id="scanline" />
|
||||
<div id="inner">
|
||||
<textarea ref="textArea"
|
||||
spellcheck="false"
|
||||
autocorrect="false"
|
||||
autocapitalize="false"
|
||||
autocomplete="false"
|
||||
autofocus
|
||||
></textarea>
|
||||
<footer>
|
||||
<a v-for="({ uri, label}) in footer"
|
||||
:href="uri"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
{{ label }}
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -0,0 +1,15 @@
|
||||
// https://vitepress.dev/guide/custom-theme
|
||||
import Layout from './Layout.vue'
|
||||
import type { Theme } from 'vitepress'
|
||||
|
||||
import '@fontsource/vt323'
|
||||
import './reset.css'
|
||||
import './style.css'
|
||||
|
||||
export default {
|
||||
Layout,
|
||||
enhanceApp({ app, router, siteData }) {
|
||||
// ...
|
||||
}
|
||||
} satisfies Theme
|
||||
|
@ -0,0 +1,114 @@
|
||||
/***
|
||||
The new CSS reset - version 1.11.2 (last updated 15.11.2023)
|
||||
GitHub page: https://github.com/elad2412/the-new-css-reset
|
||||
***/
|
||||
|
||||
/*
|
||||
Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property
|
||||
- The "symbol *" part is to solve Firefox SVG sprite bug
|
||||
- The "html" element is excluded, otherwise a bug in Chrome breaks the CSS hyphens property (https://github.com/elad2412/the-new-css-reset/issues/36)
|
||||
*/
|
||||
*:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) {
|
||||
all: unset;
|
||||
display: revert;
|
||||
}
|
||||
|
||||
/* Preferred box-sizing value */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Fix mobile Safari increase font-size on landscape mode */
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
/* Reapply the pointer cursor for anchor tags */
|
||||
a,
|
||||
button {
|
||||
cursor: revert;
|
||||
}
|
||||
|
||||
/* Remove list styles (bullets/numbers) */
|
||||
ol,
|
||||
ul,
|
||||
menu,
|
||||
summary {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* For images to not be able to exceed their container */
|
||||
img {
|
||||
max-inline-size: 100%;
|
||||
max-block-size: 100%;
|
||||
}
|
||||
|
||||
/* removes spacing between cells in tables */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* Safari - solving issue when using user-select:none on the <body> text input doesn't working */
|
||||
input,
|
||||
textarea {
|
||||
-webkit-user-select: auto;
|
||||
}
|
||||
|
||||
/* revert the 'white-space' property for textarea elements on Safari */
|
||||
textarea {
|
||||
white-space: revert;
|
||||
}
|
||||
|
||||
/* minimum style to allow to style meter element */
|
||||
meter {
|
||||
-webkit-appearance: revert;
|
||||
appearance: revert;
|
||||
}
|
||||
|
||||
/* preformatted text - use only for this feature */
|
||||
:where(pre) {
|
||||
all: revert;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* reset default text opacity of input placeholder */
|
||||
::placeholder {
|
||||
color: unset;
|
||||
}
|
||||
|
||||
/* fix the feature of 'hidden' attribute.
|
||||
display:revert; revert to element instead of attribute */
|
||||
:where([hidden]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* revert for bug in Chromium browsers
|
||||
- fix for the content editable attribute will work properly.
|
||||
- webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/
|
||||
:where([contenteditable]:not([contenteditable="false"])) {
|
||||
-moz-user-modify: read-write;
|
||||
-webkit-user-modify: read-write;
|
||||
overflow-wrap: break-word;
|
||||
-webkit-line-break: after-white-space;
|
||||
-webkit-user-select: auto;
|
||||
}
|
||||
|
||||
/* apply back the draggable feature - exist only in Chromium and Safari */
|
||||
:where([draggable="true"]) {
|
||||
-webkit-user-drag: element;
|
||||
}
|
||||
|
||||
/* Revert Modal native behavior */
|
||||
:where(dialog:modal) {
|
||||
all: revert;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Remove details summary webkit styles */
|
||||
::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
:root {
|
||||
--black: #000;
|
||||
--white: #FFF;
|
||||
--red: #800;
|
||||
--cyan: #AFE;
|
||||
--violet: #C4C;
|
||||
--green: #0C5;
|
||||
--blue: #00A;
|
||||
--yellow: #EE7;
|
||||
--orange: #D85;
|
||||
--brown: #640;
|
||||
--light-red: #F77;
|
||||
--light-green: #AF6;
|
||||
--light-blue: #08F;
|
||||
--grey-1: #333;
|
||||
--grey-2: #777;
|
||||
--grey-3: #BBB;
|
||||
--crt-frame: #BFBCAD;
|
||||
}
|
||||
|
||||
@keyframes scanline {
|
||||
0% {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
30% {
|
||||
top: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
|
||||
body {
|
||||
background: var(--cyan);
|
||||
color: var(--blue);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
#app {
|
||||
width: 90vw;
|
||||
height: 90vh;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: VT323, monospace;
|
||||
font-size: 24px;
|
||||
background: var(--black);
|
||||
}
|
||||
|
||||
#app {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
background: var(--crt-frame);
|
||||
width: 1280px;
|
||||
height: 900px;
|
||||
max-width: 1280px;
|
||||
max-height: 1024px;
|
||||
box-shadow: inset 0.25em 0.25em 2px rgba(255, 255, 255, 0.4), inset -0.25em -0.25em 2px rgba(0, 0, 0, 0.4);
|
||||
user-select: none;
|
||||
transform: translate3d(0, 0, 0);
|
||||
backface-visibility: hidden;
|
||||
perspective: 1000;
|
||||
color: var(--cyan);
|
||||
text-shadow: 0 0 2px yellow;
|
||||
}
|
||||
|
||||
#screen.enhanced-readability {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
#screen {
|
||||
width: calc(100% - 2.4em);
|
||||
height: calc(100% - 2.4em);
|
||||
overflow: hidden;
|
||||
margin: 1.2em;
|
||||
z-index: 20;
|
||||
box-shadow: 0 0 1px 3px #0A0A0AB2;
|
||||
background: var(--blue);
|
||||
}
|
||||
|
||||
#app,
|
||||
#screen {
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
#wrap {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
padding: 1.5em;
|
||||
background: radial-gradient(ellipse at center, #FFF2 0%, #0003 100%);
|
||||
}
|
||||
|
||||
#interlace {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: linear-gradient(#888 50%, #000 0);
|
||||
background-repeat: repeat-y;
|
||||
background-size: 100% 4px;
|
||||
opacity: .1;
|
||||
z-index: 21;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#scanline {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1em;
|
||||
background: linear-gradient(180deg, transparent 0, #EEE 50%, navy 0, transparent);
|
||||
opacity: .1;
|
||||
animation: scanline 6s linear infinite;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#inner {
|
||||
height: 100%;
|
||||
background: #0003;
|
||||
border-radius: .5em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#inner::selection {
|
||||
color: var(--blue);
|
||||
background: var(--cyan);
|
||||
}
|
||||
|
||||
#inner>textarea {
|
||||
width: 100%;
|
||||
height: calc(100% - 1.5em);
|
||||
padding: 0 1em;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
#inner>footer {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
height: 1.5em;
|
||||
line-height: 1.5em;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
#inner>footer>a {
|
||||
padding: 0 1em;
|
||||
margin-right: 1em;
|
||||
background: var(--cyan);
|
||||
color: var(--blue);
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
export default {
|
||||
welcome: [
|
||||
" ________ __ ",
|
||||
"| | | |.-----.| |.----.-----.--------.-----.",
|
||||
"| | | || -__|| || __| _ | | -__|",
|
||||
"|________||_____||__||____|_____|__|__|__|_____|",
|
||||
],
|
||||
|
||||
aboutMe: [
|
||||
" _______ __ __ _______ ",
|
||||
"| _ | |--.-----.--.--.| |_ | | |.-----.",
|
||||
"| | _ | _ | | || _| | || -__|",
|
||||
"|___|___|_____|_____|_____||____| |__|_|__||_____|",
|
||||
],
|
||||
|
||||
resume: [
|
||||
" ______ ",
|
||||
"| __ \.-----.-----.--.--.--------.-----.",
|
||||
"| <| -__|__ --| | | | -__|",
|
||||
"|___|__||_____|_____|_____|__|__|__|_____|",
|
||||
],
|
||||
|
||||
not_found: [
|
||||
" _____ ______ _____ ",
|
||||
"| | || | | | ",
|
||||
"|__ | -- |__ |",
|
||||
" |__||______| |__| ",
|
||||
]
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
import { ref } from 'vue'
|
||||
import type { SimpleCommand, Uri } from './Config'
|
||||
import { useRouter } from 'vitepress'
|
||||
|
||||
export default function useTerminal(inputEl: HTMLTextAreaElement, commands: SimpleCommand[]) {
|
||||
const prompt = '\n$> '
|
||||
const footerLinks = ref([])
|
||||
|
||||
const router = useRouter()
|
||||
console.log('router', router)
|
||||
|
||||
function moveCursorToEnd() {
|
||||
const pos = inputEl.value.length
|
||||
|
||||
// allow text selection
|
||||
if (inputEl.selectionStart !== inputEl.selectionEnd) {
|
||||
console.debug('allowing text selection', inputEl.selectionStart, inputEl.selectionEnd)
|
||||
return
|
||||
}
|
||||
inputEl.setSelectionRange(pos, pos)
|
||||
}
|
||||
|
||||
function setFocus() {
|
||||
inputEl.focus()
|
||||
}
|
||||
|
||||
function addText(text: string, addPrompt=true) {
|
||||
const line = addPrompt ? text + prompt : text
|
||||
inputEl.value = inputEl.value + line
|
||||
inputEl.scrollTop = inputEl.scrollTopMax
|
||||
}
|
||||
|
||||
function addLine(line: string) {
|
||||
addText('\n'+line)
|
||||
}
|
||||
|
||||
function clear() {
|
||||
footerLinks.value = []
|
||||
inputEl.value = ''
|
||||
addText('')
|
||||
}
|
||||
|
||||
type SYS_OUT = 'NOT_FOUND' | 'USAGE' | 'INFO' | '404'
|
||||
|
||||
const SHELL = 'k0rSH'
|
||||
const INFO = 'k0rSH v0.1: the k0r SHell, fiddled together by k0r -- https://k0r.in'
|
||||
const PAD = 16
|
||||
const USAGE = [
|
||||
...commands.map(cmd => {
|
||||
const command = `${(cmd.command+':').padEnd(PAD)}`
|
||||
const help = `${cmd.help ?? 'no helptext provided'}`
|
||||
const aliases = cmd.aliases ? ` (aliases: ${cmd.aliases?.join(', ')})` : ''
|
||||
return `${command}${help}${aliases}`
|
||||
}),
|
||||
`${'help:'.padEnd(PAD)}This help text. (aliases: usage)`,
|
||||
`${'version:'.padEnd(PAD)}Print version information.`,
|
||||
`${'clear:'.padEnd(PAD)}Clear the screen.`,
|
||||
].join('\n')
|
||||
|
||||
function systemOutput(output: SYS_OUT, arg = '') {
|
||||
switch (output) {
|
||||
case 'NOT_FOUND':
|
||||
console.debug('command not found')
|
||||
addLine(`${SHELL}: ${arg}: command not found...`)
|
||||
break
|
||||
case 'USAGE':
|
||||
console.log('help is underway')
|
||||
addLine(`${SHELL} - available commands:\n\n${USAGE}`)
|
||||
break
|
||||
case 'INFO':
|
||||
console.log('explaining myself')
|
||||
addLine(`${SHELL}: ${INFO}`)
|
||||
break
|
||||
case '404':
|
||||
console.log('page not found', arg)
|
||||
addLine(`${SHELL}: ${arg}: this page does not exist`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function cursorAtPrompt() {
|
||||
return inputEl.value.endsWith(prompt)
|
||||
}
|
||||
|
||||
function setFooter(uris: Uri[]) {
|
||||
footerLinks.value = uris
|
||||
}
|
||||
|
||||
/// returns current command written in the command line
|
||||
/// in the format: [command, arg1, arg2, ..., argN]
|
||||
function getCurrentCommand() {
|
||||
const value = inputEl.value
|
||||
const start = value.lastIndexOf(prompt) + prompt.length
|
||||
const end = value.length
|
||||
|
||||
return value.slice(start, end).trim().split(' ')
|
||||
}
|
||||
|
||||
function execUserCommand(cmd: string) {
|
||||
const userCommand = commands.find(c => {
|
||||
const commandMatch = c.command === cmd
|
||||
const aliasesMatch = c.aliases.includes(cmd)
|
||||
return commandMatch || aliasesMatch
|
||||
})
|
||||
if (!userCommand) return systemOutput('NOT_FOUND', cmd)
|
||||
|
||||
addLine(userCommand.message)
|
||||
setFooter(userCommand.uris)
|
||||
}
|
||||
|
||||
function listPages() {
|
||||
addLine('TODO: list pages')
|
||||
}
|
||||
|
||||
async function openPage(page: string) {
|
||||
await router.go(page)
|
||||
}
|
||||
|
||||
function handleCurrentCommand() {
|
||||
const [cmd, ...args] = getCurrentCommand()
|
||||
|
||||
if (!cmd) {
|
||||
addText('')
|
||||
return
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 'help':
|
||||
case 'usage':
|
||||
systemOutput('USAGE')
|
||||
break
|
||||
case 'version':
|
||||
systemOutput('INFO')
|
||||
break
|
||||
case 'clear':
|
||||
clear()
|
||||
break
|
||||
case 'ls':
|
||||
case 'list':
|
||||
listPages()
|
||||
break
|
||||
case 'go':
|
||||
case 'open':
|
||||
addText('\n', false)
|
||||
if (!args.length) addText('USAGE: go page_name')
|
||||
else router.go(args[0])
|
||||
break
|
||||
default:
|
||||
execUserCommand(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
function handleInput(ev) {
|
||||
switch (ev.key) {
|
||||
case 'Enter':
|
||||
handleCurrentCommand()
|
||||
ev.preventDefault()
|
||||
break
|
||||
case 'Backspace':
|
||||
if (cursorAtPrompt()) ev.preventDefault()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
inputEl.addEventListener('focus', () => moveCursorToEnd())
|
||||
inputEl.addEventListener('blur', () => inputEl.focus())
|
||||
inputEl.addEventListener('click', () => moveCursorToEnd())
|
||||
inputEl.addEventListener('keydown', handleInput)
|
||||
|
||||
return { addText, addLine, setFocus, clear, footerLinks }
|
||||
}
|
@ -1,10 +1,25 @@
|
||||
pipeline:
|
||||
ntfy:
|
||||
image: codeberg.org/l-x/woodpecker-ntfy
|
||||
settings:
|
||||
url: https://ntfy.sh/k0r
|
||||
title: build finished
|
||||
click: https://ci.k0r.in
|
||||
icon: https://woodpecker-ci.org/img/logo.svg
|
||||
tags: robot,${CI_BUILD_EVENT},${CI_REPO_NAME}
|
||||
message: >
|
||||
📝 Commit by ${CI_COMMIT_AUTHOR} on ${CI_COMMIT_BRANCH}:
|
||||
|
||||
${CI_COMMIT_MESSAGE}
|
||||
|
||||
build:
|
||||
image: jauderho/zola:latest
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- zola check
|
||||
- npm install
|
||||
- npm run docs:build
|
||||
- chmod -R a+rw /mnt
|
||||
- zola build -o /mnt/dist --force
|
||||
- rm -fr /mnt/dist
|
||||
- cp -R .vitepress/dist /mnt/dist
|
||||
|
||||
volumes:
|
||||
- /home/n/CI/k0r_in:/mnt/
|
||||
- /home/n/CI/koehr_ing:/mnt/
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: 'not_found'
|
||||
content: [
|
||||
'This page does not exist.',
|
||||
]
|
||||
---
|
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 José Lopes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,11 +0,0 @@
|
||||
# k0r.386
|
||||
|
||||
![k0r.386 screenshot](https://git.k0r.in/n/k0r.386/raw/branch/main/screenshot.png)
|
||||
|
||||
## [k0r.in](https://k0r.in/)
|
||||
|
||||
## Theme
|
||||
|
||||
The Zola theme is heavily inspired and partially based on [ZOLA.386](https://github.com/lopes/zola.386).
|
||||
|
||||
The font used is FixedSys300 from [fixedsys-css](https://github.com/javanile/fixedsys-css), which was modified and optimized via the [FontSquirrel WebFont Generator](https://www.fontsquirrel.com/tools/webfont-generator).
|
@ -1,80 +0,0 @@
|
||||
base_url = "https://ng.k0r.in"
|
||||
compile_sass = true
|
||||
build_search_index = false
|
||||
generate_rss = true
|
||||
highlight_code = true
|
||||
# theme = "k0r.386"
|
||||
default_language = "en"
|
||||
title = "k0r"
|
||||
description = "programmer and engineer based in Berlin"
|
||||
|
||||
taxonomies = [
|
||||
{name="categories", rss=true},
|
||||
{name="tags", rss=true},
|
||||
]
|
||||
|
||||
[markdown]
|
||||
# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola
|
||||
highlight_code = true
|
||||
|
||||
[extra]
|
||||
author = "Norman Köhring"
|
||||
year = "2023"
|
||||
keywords = "homepage, personal, programming, webdev, retro, hacking"
|
||||
theme_color = "#190084"
|
||||
menu_items = [
|
||||
{path="", name="Home"},
|
||||
{path="categories", name="Categories"},
|
||||
{path="tags", name="Tags"},
|
||||
{path="about", name="About"},
|
||||
]
|
||||
|
||||
sidebars = [
|
||||
{title="Main Menu", internal=true, items=[
|
||||
{path="/", name="Home"},
|
||||
{path="/cv", name="CV / Résumé"},
|
||||
{path="/til", name="Today I Learned"},
|
||||
{path="/articles", name="Articles"},
|
||||
{path="/log", name="Microblog"},
|
||||
{path="/slides", name="Slides"},
|
||||
]},
|
||||
{title="Selfhosted", internal=false, items=[
|
||||
{path="https://m.k0r.in/@n", name="Fediverse/Mastodon"},
|
||||
{path="https://git.k0r.in", name="Code"},
|
||||
{path="https://ci.k0r.in", name="CI"},
|
||||
{path="https://koehr.pw", name="Passwords"},
|
||||
{path="https://url.k0r.in", name="Bookmarks"},
|
||||
{path="https://srx.k0r.in", name="Search"},
|
||||
]},
|
||||
{title="Elsewhere", internal=false, items=[
|
||||
{path="https://mstdn.io/@koehr", name="Fediverse/Mastodon"},
|
||||
{path="https://twitter.com/koehr_in", name="Twitter"},
|
||||
{path="https://github.com/nkoehring", name="Github"},
|
||||
{path="https://sr.ht/~koehr", name="Sourcehut"},
|
||||
{path="https://instagram.com/coffee_n_code", name="Instagram"},
|
||||
{path="https://500px.com/koehr", name="Photography"},
|
||||
{path="mailto:n[at]koehr.in", name="Mail"},
|
||||
]}
|
||||
]
|
||||
|
||||
### THIRD PARTY
|
||||
# google_analytics = "UA-012345-67"
|
||||
# disqus = "disqus-user"
|
||||
|
||||
### SOCIAL MEDIA
|
||||
image = "https://raw.githubusercontent.com/lopes/zola.386/master/screenshot.png"
|
||||
twitter_user = "koehr_in"
|
||||
linkedin_user = "nkoehring"
|
||||
github_user = "nkoehring"
|
||||
# gitlab_user = ""
|
||||
|
||||
### I18N WORDS
|
||||
label_tags = "Tags"
|
||||
label_tag = "Tag"
|
||||
label_categories = "Categories"
|
||||
label_category = "Category"
|
||||
label_author = "Author"
|
||||
label_date = "Date"
|
||||
label_taxonomy = "Taxonomy"
|
||||
label_reading = "Reading time"
|
||||
label_read_more = "Read more"
|
@ -1,11 +0,0 @@
|
||||
+++
|
||||
title = "k0r"
|
||||
description = "programmer and engineer based in Berlin"
|
||||
template = "home.html"
|
||||
sort_by = "weight"
|
||||
|
||||
[taxonomies]
|
||||
categories = ["home"]
|
||||
tags = []
|
||||
+++
|
||||
|
@ -1,6 +0,0 @@
|
||||
+++
|
||||
paginate_by = 20
|
||||
sort_by = "date"
|
||||
sort_direction = "decending"
|
||||
insert_anchor_links = "none"
|
||||
+++
|
@ -1,6 +0,0 @@
|
||||
+++
|
||||
paginate_by = 20
|
||||
sort_by = "date"
|
||||
sort_direction = "decending"
|
||||
insert_anchor_links = "none"
|
||||
+++
|
@ -1,6 +0,0 @@
|
||||
+++
|
||||
paginate_by = 20
|
||||
sort_by = "date"
|
||||
sort_direction = "decending"
|
||||
insert_anchor_links = "none"
|
||||
+++
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 'resume'
|
||||
content: [
|
||||
'This is my CV',
|
||||
'stuff',
|
||||
'foo',
|
||||
'bar',
|
||||
]
|
||||
---
|
@ -0,0 +1,16 @@
|
||||
---
|
||||
title: 'welcome'
|
||||
content: [
|
||||
'This is the homepage of Norman Köhring,',
|
||||
'a programmer, OpenSource enthusiast and hacker based in Berlin, Germany.',
|
||||
'',
|
||||
'I call myself a code artist because programming can and should be seen as a creative process. Therefore code is art. I love to craft pieces of art with code that are beautiful and elegant in their simplicity, readability and architecture.',
|
||||
'',
|
||||
'Type "help" to see a list of available commands.',
|
||||
'Some commands might update the footer with useful links.'
|
||||
]
|
||||
---
|
||||
|
||||
Some testcontent for testing.
|
||||
|
||||
It is a *paragraph*!
|
@ -1,12 +0,0 @@
|
||||
# based on:
|
||||
# https://www.getzola.org/documentation/deployment/netlify/
|
||||
|
||||
[build]
|
||||
publish = "public"
|
||||
command = "zola build"
|
||||
|
||||
[build.environment]
|
||||
ZOLA_VERSION = "0.14.0"
|
||||
|
||||
[context.deploy-preview]
|
||||
command = "zola build --base-url $DEPLOY_PRIME_URL"
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"scripts": {
|
||||
"docs:dev": "vitepress dev",
|
||||
"docs:build": "vitepress build",
|
||||
"docs:preview": "vitepress preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vitepress": "1.0.0-rc.31",
|
||||
"vue": "^3.3.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/vt323": "^5.0.8"
|
||||
}
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
// fixing font path
|
||||
@font-face {
|
||||
font-family: 'Fixed';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('☺'), url('./fonts/fixedsys.woff') format('woff');
|
||||
}
|
||||
|
||||
:root {
|
||||
font: 20px / 1.1 'Fixed';
|
||||
background-color: #190084;
|
||||
color: #BBB;
|
||||
}
|
||||
|
||||
body {
|
||||
visibility: shown;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body>nav {
|
||||
background-color: #BBB;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
body>nav>.container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
body>nav h1 {
|
||||
margin: 0 1rem;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
body>nav a {
|
||||
color: inherit;
|
||||
display: inline-block;
|
||||
padding: 0 .5em;
|
||||
}
|
||||
|
||||
body>nav ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body>nav li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: auto;
|
||||
max-width: 980px;
|
||||
}
|
||||
|
||||
body>main>header {
|
||||
padding: 1rem 1rem;
|
||||
margin: 1rem 0 1rem;
|
||||
background: #0AA;
|
||||
}
|
||||
|
||||
body>main>header>h1 {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1rem;
|
||||
color: #FFF;
|
||||
font-weight: 300;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1>small {
|
||||
font-size: 1rem;
|
||||
color: #DDD;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #fefe54;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
.gap {
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.w-1\/4 {
|
||||
flex: auto;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.w-2\/4 {
|
||||
flex: auto;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.w-3\/4 {
|
||||
flex: auto;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.w-4\/4 {
|
||||
flex: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.box {
|
||||
border: 2px solid black;
|
||||
box-shadow: 0 0 0 5px, 11px 13px 0 4px black;
|
||||
}
|
||||
|
||||
.bg-error {
|
||||
background-color: #B00;
|
||||
}
|
||||
|
||||
.text-white {
|
||||
color: white;
|
||||
}
|
||||
|
||||
nav {
|
||||
background: #BBB;
|
||||
margin: 0 0 2rem;
|
||||
}
|
||||
|
||||
nav>header {
|
||||
background: black;
|
||||
color: #BBB;
|
||||
margin: .5rem .5rem 0;
|
||||
padding: 0 .5rem;
|
||||
}
|
||||
|
||||
nav>menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: black;
|
||||
margin: 0 .5rem .5rem;
|
||||
}
|
||||
|
||||
nav>menu>li>a {
|
||||
display: inline-block;
|
||||
width: calc(100% - 1rem);
|
||||
padding: 0 .5rem;
|
||||
}
|
||||
|
||||
nav li:hover,
|
||||
nav li.active {
|
||||
background-color: #000;
|
||||
color: #BBB;
|
||||
}
|
||||
|
||||
nav li>a {
|
||||
color: black;
|
||||
}
|
||||
|
||||
nav li:hover>a,
|
||||
nav li.active>a {
|
||||
color: #BBB;
|
||||
}
|
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 22 KiB |
@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 1.1 KiB |
@ -1,41 +0,0 @@
|
||||
{
|
||||
"name": "App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 6.4 KiB |
@ -1,111 +0,0 @@
|
||||
self._386 = self._386 || {};
|
||||
|
||||
$(function(){
|
||||
var character = { height: 20, width: 12.4 };
|
||||
|
||||
function scrollLock() {
|
||||
var last = 0;
|
||||
$(window).bind('scroll', function(e) {
|
||||
var func, off = $(window).scrollTop();
|
||||
|
||||
console.log(off, last, off < last ? "up" : "down");
|
||||
|
||||
// this determines whether the user is intending to go up or down.
|
||||
func = off < last ? "floor" : "ceil";
|
||||
|
||||
// make sure we don't run this from ourselves
|
||||
if(off % character.height === 0) {
|
||||
return;
|
||||
}
|
||||
last = off;
|
||||
|
||||
window.scrollTo(
|
||||
0,
|
||||
Math[func](off / character.height) * character.height
|
||||
);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function loading() {
|
||||
|
||||
if(_386.fastLoad) {
|
||||
document.body.style.visibility='visible';
|
||||
return;
|
||||
}
|
||||
|
||||
var
|
||||
onePass = _386.onePass,
|
||||
speedFactor = 1 / (_386.speedFactor || 1) * 165000;
|
||||
wrap = document.createElement('div'),
|
||||
bar = wrap.appendChild(document.createElement('div')),
|
||||
|
||||
cursor = document.createElement('div'),
|
||||
// If the user specified that the visibility is hidden, then we
|
||||
// start at the first pass ... otherwise we just do the
|
||||
// cursor fly-by
|
||||
pass = ($(document.body).css('visibility') == 'visible') ? 1 : 0,
|
||||
height = $(window).height(),
|
||||
width = $(window).width(),
|
||||
|
||||
// this makes the loading of the screen proportional to the real-estate of the window.
|
||||
// it helps keep the cool sequence there while not making it waste too much time.
|
||||
rounds = (height * width / speedFactor),
|
||||
column = width, row = height - character.height;
|
||||
|
||||
wrap.id = "wrap386";
|
||||
bar.id = "bar386";
|
||||
cursor.id = "cursor386";
|
||||
|
||||
cursor.innerHTML = bar.innerHTML = '▄';
|
||||
|
||||
// only inject the wrap if the pass is 0
|
||||
if(pass === 0) {
|
||||
document.body.appendChild(wrap);
|
||||
document.body.style.visibility='visible';
|
||||
} else {
|
||||
document.body.appendChild(cursor);
|
||||
rounds /= 2;
|
||||
character.height *= 4;
|
||||
}
|
||||
|
||||
var ival = setInterval(function(){
|
||||
for(var m = 0; m < rounds; m++) {
|
||||
column -= character.width;
|
||||
|
||||
if(column <= 0) {
|
||||
column = width;
|
||||
row -= character.height;
|
||||
}
|
||||
if(row <= 0) {
|
||||
pass++;
|
||||
row = height - character.height;
|
||||
|
||||
if(pass == 2) {
|
||||
document.body.removeChild(cursor);
|
||||
clearInterval(ival);
|
||||
} else {
|
||||
wrap.parentNode.removeChild(wrap);
|
||||
if(onePass) {
|
||||
clearInterval(ival);
|
||||
} else {
|
||||
document.body.appendChild(cursor);
|
||||
rounds /= 2;
|
||||
character.height *= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pass === 0) {
|
||||
bar.style.width = column + "px";
|
||||
wrap.style.height = row + "px";
|
||||
} else {
|
||||
cursor.style.right = column + "px";
|
||||
cursor.style.bottom = row + "px";
|
||||
}
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
loading();
|
||||
});
|
||||
|
@ -1,117 +0,0 @@
|
||||
/* ==========================================================
|
||||
* bootstrap-affix.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#affix
|
||||
* ==========================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* AFFIX CLASS DEFINITION
|
||||
* ====================== */
|
||||
|
||||
var Affix = function (element, options) {
|
||||
this.options = $.extend({}, $.fn.affix.defaults, options)
|
||||
this.$window = $(window)
|
||||
.on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
|
||||
.on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
|
||||
this.$element = $(element)
|
||||
this.checkPosition()
|
||||
}
|
||||
|
||||
Affix.prototype.checkPosition = function () {
|
||||
if (!this.$element.is(':visible')) return
|
||||
|
||||
var scrollHeight = $(document).height()
|
||||
, scrollTop = this.$window.scrollTop()
|
||||
, position = this.$element.offset()
|
||||
, offset = this.options.offset
|
||||
, offsetBottom = offset.bottom
|
||||
, offsetTop = offset.top
|
||||
, reset = 'affix affix-top affix-bottom'
|
||||
, affix
|
||||
|
||||
if (typeof offset != 'object') offsetBottom = offsetTop = offset
|
||||
if (typeof offsetTop == 'function') offsetTop = offset.top()
|
||||
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
|
||||
|
||||
affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
|
||||
false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
|
||||
'bottom' : offsetTop != null && scrollTop <= offsetTop ?
|
||||
'top' : false
|
||||
|
||||
if (this.affixed === affix) return
|
||||
|
||||
this.affixed = affix
|
||||
this.unpin = affix == 'bottom' ? position.top - scrollTop : null
|
||||
|
||||
this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
|
||||
}
|
||||
|
||||
|
||||
/* AFFIX PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
var old = $.fn.affix
|
||||
|
||||
$.fn.affix = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('affix')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('affix', (data = new Affix(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.affix.Constructor = Affix
|
||||
|
||||
$.fn.affix.defaults = {
|
||||
offset: 0
|
||||
}
|
||||
|
||||
|
||||
/* AFFIX NO CONFLICT
|
||||
* ================= */
|
||||
|
||||
$.fn.affix.noConflict = function () {
|
||||
$.fn.affix = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* AFFIX DATA-API
|
||||
* ============== */
|
||||
|
||||
$(window).on('load', function () {
|
||||
$('[data-spy="affix"]').each(function () {
|
||||
var $spy = $(this)
|
||||
, data = $spy.data()
|
||||
|
||||
data.offset = data.offset || {}
|
||||
|
||||
data.offsetBottom && (data.offset.bottom = data.offsetBottom)
|
||||
data.offsetTop && (data.offset.top = data.offsetTop)
|
||||
|
||||
$spy.affix(data)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
}(window.jQuery);
|
@ -1,99 +0,0 @@
|
||||
/* ==========================================================
|
||||
* bootstrap-alert.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#alerts
|
||||
* ==========================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* ALERT CLASS DEFINITION
|
||||
* ====================== */
|
||||
|
||||
var dismiss = '[data-dismiss="alert"]'
|
||||
, Alert = function (el) {
|
||||
$(el).on('click', dismiss, this.close)
|
||||
}
|
||||
|
||||
Alert.prototype.close = function (e) {
|
||||
var $this = $(this)
|
||||
, selector = $this.attr('data-target')
|
||||
, $parent
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
$parent = $(selector)
|
||||
|
||||
e && e.preventDefault()
|
||||
|
||||
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
|
||||
|
||||
$parent.trigger(e = $.Event('close'))
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$parent.removeClass('in')
|
||||
|
||||
function removeElement() {
|
||||
$parent
|
||||
.trigger('closed')
|
||||
.remove()
|
||||
}
|
||||
|
||||
$.support.transition && $parent.hasClass('fade') ?
|
||||
$parent.on($.support.transition.end, removeElement) :
|
||||
removeElement()
|
||||
}
|
||||
|
||||
|
||||
/* ALERT PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
var old = $.fn.alert
|
||||
|
||||
$.fn.alert = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('alert')
|
||||
if (!data) $this.data('alert', (data = new Alert(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.alert.Constructor = Alert
|
||||
|
||||
|
||||
/* ALERT NO CONFLICT
|
||||
* ================= */
|
||||
|
||||
$.fn.alert.noConflict = function () {
|
||||
$.fn.alert = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* ALERT DATA-API
|
||||
* ============== */
|
||||
|
||||
$(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
|
||||
|
||||
}(window.jQuery);
|
@ -1,105 +0,0 @@
|
||||
/* ============================================================
|
||||
* bootstrap-button.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#buttons
|
||||
* ============================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* BUTTON PUBLIC CLASS DEFINITION
|
||||
* ============================== */
|
||||
|
||||
var Button = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.button.defaults, options)
|
||||
}
|
||||
|
||||
Button.prototype.setState = function (state) {
|
||||
var d = 'disabled'
|
||||
, $el = this.$element
|
||||
, data = $el.data()
|
||||
, val = $el.is('input') ? 'val' : 'html'
|
||||
|
||||
state = state + 'Text'
|
||||
data.resetText || $el.data('resetText', $el[val]())
|
||||
|
||||
$el[val](data[state] || this.options[state])
|
||||
|
||||
// push to event loop to allow forms to submit
|
||||
setTimeout(function () {
|
||||
state == 'loadingText' ?
|
||||
$el.addClass(d).attr(d, d) :
|
||||
$el.removeClass(d).removeAttr(d)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
Button.prototype.toggle = function () {
|
||||
var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
|
||||
|
||||
$parent && $parent
|
||||
.find('.active')
|
||||
.removeClass('active')
|
||||
|
||||
this.$element.toggleClass('active')
|
||||
}
|
||||
|
||||
|
||||
/* BUTTON PLUGIN DEFINITION
|
||||
* ======================== */
|
||||
|
||||
var old = $.fn.button
|
||||
|
||||
$.fn.button = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('button')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('button', (data = new Button(this, options)))
|
||||
if (option == 'toggle') data.toggle()
|
||||
else if (option) data.setState(option)
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.button.defaults = {
|
||||
loadingText: 'loading...'
|
||||
}
|
||||
|
||||
$.fn.button.Constructor = Button
|
||||
|
||||
|
||||
/* BUTTON NO CONFLICT
|
||||
* ================== */
|
||||
|
||||
$.fn.button.noConflict = function () {
|
||||
$.fn.button = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* BUTTON DATA-API
|
||||
* =============== */
|
||||
|
||||
$(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
|
||||
var $btn = $(e.target)
|
||||
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
|
||||
$btn.button('toggle')
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,207 +0,0 @@
|
||||
/* ==========================================================
|
||||
* bootstrap-carousel.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#carousel
|
||||
* ==========================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* CAROUSEL CLASS DEFINITION
|
||||
* ========================= */
|
||||
|
||||
var Carousel = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.$indicators = this.$element.find('.carousel-indicators')
|
||||
this.options = options
|
||||
this.options.pause == 'hover' && this.$element
|
||||
.on('mouseenter', $.proxy(this.pause, this))
|
||||
.on('mouseleave', $.proxy(this.cycle, this))
|
||||
}
|
||||
|
||||
Carousel.prototype = {
|
||||
|
||||
cycle: function (e) {
|
||||
if (!e) this.paused = false
|
||||
if (this.interval) clearInterval(this.interval);
|
||||
this.options.interval
|
||||
&& !this.paused
|
||||
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
|
||||
return this
|
||||
}
|
||||
|
||||
, getActiveIndex: function () {
|
||||
this.$active = this.$element.find('.item.active')
|
||||
this.$items = this.$active.parent().children()
|
||||
return this.$items.index(this.$active)
|
||||
}
|
||||
|
||||
, to: function (pos) {
|
||||
var activeIndex = this.getActiveIndex()
|
||||
, that = this
|
||||
|
||||
if (pos > (this.$items.length - 1) || pos < 0) return
|
||||
|
||||
if (this.sliding) {
|
||||
return this.$element.one('slid', function () {
|
||||
that.to(pos)
|
||||
})
|
||||
}
|
||||
|
||||
if (activeIndex == pos) {
|
||||
return this.pause().cycle()
|
||||
}
|
||||
|
||||
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
|
||||
}
|
||||
|
||||
, pause: function (e) {
|
||||
if (!e) this.paused = true
|
||||
if (this.$element.find('.next, .prev').length && $.support.transition.end) {
|
||||
this.$element.trigger($.support.transition.end)
|
||||
this.cycle(true)
|
||||
}
|
||||
clearInterval(this.interval)
|
||||
this.interval = null
|
||||
return this
|
||||
}
|
||||
|
||||
, next: function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('next')
|
||||
}
|
||||
|
||||
, prev: function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('prev')
|
||||
}
|
||||
|
||||
, slide: function (type, next) {
|
||||
var $active = this.$element.find('.item.active')
|
||||
, $next = next || $active[type]()
|
||||
, isCycling = this.interval
|
||||
, direction = type == 'next' ? 'left' : 'right'
|
||||
, fallback = type == 'next' ? 'first' : 'last'
|
||||
, that = this
|
||||
, e
|
||||
|
||||
this.sliding = true
|
||||
|
||||
isCycling && this.pause()
|
||||
|
||||
$next = $next.length ? $next : this.$element.find('.item')[fallback]()
|
||||
|
||||
e = $.Event('slide', {
|
||||
relatedTarget: $next[0]
|
||||
, direction: direction
|
||||
})
|
||||
|
||||
if ($next.hasClass('active')) return
|
||||
|
||||
if (this.$indicators.length) {
|
||||
this.$indicators.find('.active').removeClass('active')
|
||||
this.$element.one('slid', function () {
|
||||
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
|
||||
$nextIndicator && $nextIndicator.addClass('active')
|
||||
})
|
||||
}
|
||||
|
||||
if ($.support.transition && this.$element.hasClass('slide')) {
|
||||
this.$element.trigger(e)
|
||||
if (e.isDefaultPrevented()) return
|
||||
$next.addClass(type)
|
||||
$next[0].offsetWidth // force reflow
|
||||
$active.addClass(direction)
|
||||
$next.addClass(direction)
|
||||
this.$element.one($.support.transition.end, function () {
|
||||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||||
$active.removeClass(['active', direction].join(' '))
|
||||
that.sliding = false
|
||||
setTimeout(function () { that.$element.trigger('slid') }, 0)
|
||||
})
|
||||
} else {
|
||||
this.$element.trigger(e)
|
||||
if (e.isDefaultPrevented()) return
|
||||
$active.removeClass('active')
|
||||
$next.addClass('active')
|
||||
this.sliding = false
|
||||
this.$element.trigger('slid')
|
||||
}
|
||||
|
||||
isCycling && this.cycle()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* CAROUSEL PLUGIN DEFINITION
|
||||
* ========================== */
|
||||
|
||||
var old = $.fn.carousel
|
||||
|
||||
$.fn.carousel = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('carousel')
|
||||
, options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
|
||||
, action = typeof option == 'string' ? option : options.slide
|
||||
if (!data) $this.data('carousel', (data = new Carousel(this, options)))
|
||||
if (typeof option == 'number') data.to(option)
|
||||
else if (action) data[action]()
|
||||
else if (options.interval) data.pause().cycle()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.carousel.defaults = {
|
||||
interval: 5000
|
||||
, pause: 'hover'
|
||||
}
|
||||
|
||||
$.fn.carousel.Constructor = Carousel
|
||||
|
||||
|
||||
/* CAROUSEL NO CONFLICT
|
||||
* ==================== */
|
||||
|
||||
$.fn.carousel.noConflict = function () {
|
||||
$.fn.carousel = old
|
||||
return this
|
||||
}
|
||||
|
||||
/* CAROUSEL DATA-API
|
||||
* ================= */
|
||||
|
||||
$(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
|
||||
var $this = $(this), href
|
||||
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|
||||
, options = $.extend({}, $target.data(), $this.data())
|
||||
, slideIndex
|
||||
|
||||
$target.carousel(options)
|
||||
|
||||
if (slideIndex = $this.attr('data-slide-to')) {
|
||||
$target.data('carousel').pause().to(slideIndex).cycle()
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,167 +0,0 @@
|
||||
/* =============================================================
|
||||
* bootstrap-collapse.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#collapse
|
||||
* =============================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* COLLAPSE PUBLIC CLASS DEFINITION
|
||||
* ================================ */
|
||||
|
||||
var Collapse = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.collapse.defaults, options)
|
||||
|
||||
if (this.options.parent) {
|
||||
this.$parent = $(this.options.parent)
|
||||
}
|
||||
|
||||
this.options.toggle && this.toggle()
|
||||
}
|
||||
|
||||
Collapse.prototype = {
|
||||
|
||||
constructor: Collapse
|
||||
|
||||
, dimension: function () {
|
||||
var hasWidth = this.$element.hasClass('width')
|
||||
return hasWidth ? 'width' : 'height'
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var dimension
|
||||
, scroll
|
||||
, actives
|
||||
, hasData
|
||||
|
||||
if (this.transitioning || this.$element.hasClass('in')) return
|
||||
|
||||
dimension = this.dimension()
|
||||
scroll = $.camelCase(['scroll', dimension].join('-'))
|
||||
actives = this.$parent && this.$parent.find('> .accordion-group > .in')
|
||||
|
||||
if (actives && actives.length) {
|
||||
hasData = actives.data('collapse')
|
||||
if (hasData && hasData.transitioning) return
|
||||
actives.collapse('hide')
|
||||
hasData || actives.data('collapse', null)
|
||||
}
|
||||
|
||||
this.$element[dimension](0)
|
||||
this.transition('addClass', $.Event('show'), 'shown')
|
||||
$.support.transition && this.$element[dimension](this.$element[0][scroll])
|
||||
}
|
||||
|
||||
, hide: function () {
|
||||
var dimension
|
||||
if (this.transitioning || !this.$element.hasClass('in')) return
|
||||
dimension = this.dimension()
|
||||
this.reset(this.$element[dimension]())
|
||||
this.transition('removeClass', $.Event('hide'), 'hidden')
|
||||
this.$element[dimension](0)
|
||||
}
|
||||
|
||||
, reset: function (size) {
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element
|
||||
.removeClass('collapse')
|
||||
[dimension](size || 'auto')
|
||||
[0].offsetWidth
|
||||
|
||||
this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
, transition: function (method, startEvent, completeEvent) {
|
||||
var that = this
|
||||
, complete = function () {
|
||||
if (startEvent.type == 'show') that.reset()
|
||||
that.transitioning = 0
|
||||
that.$element.trigger(completeEvent)
|
||||
}
|
||||
|
||||
this.$element.trigger(startEvent)
|
||||
|
||||
if (startEvent.isDefaultPrevented()) return
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
this.$element[method]('in')
|
||||
|
||||
$.support.transition && this.$element.hasClass('collapse') ?
|
||||
this.$element.one($.support.transition.end, complete) :
|
||||
complete()
|
||||
}
|
||||
|
||||
, toggle: function () {
|
||||
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* COLLAPSE PLUGIN DEFINITION
|
||||
* ========================== */
|
||||
|
||||
var old = $.fn.collapse
|
||||
|
||||
$.fn.collapse = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('collapse')
|
||||
, options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option)
|
||||
if (!data) $this.data('collapse', (data = new Collapse(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.collapse.defaults = {
|
||||
toggle: true
|
||||
}
|
||||
|
||||
$.fn.collapse.Constructor = Collapse
|
||||
|
||||
|
||||
/* COLLAPSE NO CONFLICT
|
||||
* ==================== */
|
||||
|
||||
$.fn.collapse.noConflict = function () {
|
||||
$.fn.collapse = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* COLLAPSE DATA-API
|
||||
* ================= */
|
||||
|
||||
$(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
|
||||
var $this = $(this), href
|
||||
, target = $this.attr('data-target')
|
||||
|| e.preventDefault()
|
||||
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
|
||||
, option = $(target).data('collapse') ? 'toggle' : $this.data()
|
||||
$this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
|
||||
$(target).collapse(option)
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,165 +0,0 @@
|
||||
/* ============================================================
|
||||
* bootstrap-dropdown.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#dropdowns
|
||||
* ============================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* DROPDOWN CLASS DEFINITION
|
||||
* ========================= */
|
||||
|
||||
var toggle = '[data-toggle=dropdown]'
|
||||
, Dropdown = function (element) {
|
||||
var $el = $(element).on('click.dropdown.data-api', this.toggle)
|
||||
$('html').on('click.dropdown.data-api', function () {
|
||||
$el.parent().removeClass('open')
|
||||
})
|
||||
}
|
||||
|
||||
Dropdown.prototype = {
|
||||
|
||||
constructor: Dropdown
|
||||
|
||||
, toggle: function (e) {
|
||||
var $this = $(this)
|
||||
, $parent
|
||||
, isActive
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
$parent = getParent($this)
|
||||
|
||||
isActive = $parent.hasClass('open')
|
||||
|
||||
clearMenus()
|
||||
|
||||
if (!isActive) {
|
||||
$parent.toggleClass('open')
|
||||
}
|
||||
|
||||
$this.focus()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
, keydown: function (e) {
|
||||
var $this
|
||||
, $items
|
||||
, $active
|
||||
, $parent
|
||||
, isActive
|
||||
, index
|
||||
|
||||
if (!/(38|40|27)/.test(e.keyCode)) return
|
||||
|
||||
$this = $(this)
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
$parent = getParent($this)
|
||||
|
||||
isActive = $parent.hasClass('open')
|
||||
|
||||
if (!isActive || (isActive && e.keyCode == 27)) {
|
||||
if (e.which == 27) $parent.find(toggle).focus()
|
||||
return $this.click()
|
||||
}
|
||||
|
||||
$items = $('[role=menu] li:not(.divider):visible a', $parent)
|
||||
|
||||
if (!$items.length) return
|
||||
|
||||
index = $items.index($items.filter(':focus'))
|
||||
|
||||
if (e.keyCode == 38 && index > 0) index-- // up
|
||||
if (e.keyCode == 40 && index < $items.length - 1) index++ // down
|
||||
if (!~index) index = 0
|
||||
|
||||
$items
|
||||
.eq(index)
|
||||
.focus()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function clearMenus() {
|
||||
$(toggle).each(function () {
|
||||
getParent($(this)).removeClass('open')
|
||||
})
|
||||
}
|
||||
|
||||
function getParent($this) {
|
||||
var selector = $this.attr('data-target')
|
||||
, $parent
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
$parent = selector && $(selector)
|
||||
|
||||
if (!$parent || !$parent.length) $parent = $this.parent()
|
||||
|
||||
return $parent
|
||||
}
|
||||
|
||||
|
||||
/* DROPDOWN PLUGIN DEFINITION
|
||||
* ========================== */
|
||||
|
||||
var old = $.fn.dropdown
|
||||
|
||||
$.fn.dropdown = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('dropdown')
|
||||
if (!data) $this.data('dropdown', (data = new Dropdown(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.dropdown.Constructor = Dropdown
|
||||
|
||||
|
||||
/* DROPDOWN NO CONFLICT
|
||||
* ==================== */
|
||||
|
||||
$.fn.dropdown.noConflict = function () {
|
||||
$.fn.dropdown = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* APPLY TO STANDARD DROPDOWN ELEMENTS
|
||||
* =================================== */
|
||||
|
||||
$(document)
|
||||
.on('click.dropdown.data-api', clearMenus)
|
||||
.on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
|
||||
.on('click.dropdown-menu', function (e) { e.stopPropagation() })
|
||||
.on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
|
||||
.on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
|
||||
|
||||
}(window.jQuery);
|
@ -1,247 +0,0 @@
|
||||
/* =========================================================
|
||||
* bootstrap-modal.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#modals
|
||||
* =========================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* MODAL CLASS DEFINITION
|
||||
* ====================== */
|
||||
|
||||
var Modal = function (element, options) {
|
||||
this.options = options
|
||||
this.$element = $(element)
|
||||
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
|
||||
this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
|
||||
}
|
||||
|
||||
Modal.prototype = {
|
||||
|
||||
constructor: Modal
|
||||
|
||||
, toggle: function () {
|
||||
return this[!this.isShown ? 'show' : 'hide']()
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var that = this
|
||||
, e = $.Event('show')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
this.isShown = true
|
||||
|
||||
this.escape()
|
||||
|
||||
this.backdrop(function () {
|
||||
var transition = $.support.transition && that.$element.hasClass('fade')
|
||||
|
||||
if (!that.$element.parent().length) {
|
||||
that.$element.appendTo(document.body) //don't move modals dom position
|
||||
}
|
||||
|
||||
that.$element.show()
|
||||
|
||||
if (transition) {
|
||||
that.$element[0].offsetWidth // force reflow
|
||||
}
|
||||
|
||||
that.$element
|
||||
.addClass('in')
|
||||
.attr('aria-hidden', false)
|
||||
|
||||
that.enforceFocus()
|
||||
|
||||
transition ?
|
||||
that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
|
||||
that.$element.focus().trigger('shown')
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
, hide: function (e) {
|
||||
e && e.preventDefault()
|
||||
|
||||
var that = this
|
||||
|
||||
e = $.Event('hide')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (!this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
this.isShown = false
|
||||
|
||||
this.escape()
|
||||
|
||||
$(document).off('focusin.modal')
|
||||
|
||||
this.$element
|
||||
.removeClass('in')
|
||||
.attr('aria-hidden', true)
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
this.hideWithTransition() :
|
||||
this.hideModal()
|
||||
}
|
||||
|
||||
, enforceFocus: function () {
|
||||
var that = this
|
||||
$(document).on('focusin.modal', function (e) {
|
||||
if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
|
||||
that.$element.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
, escape: function () {
|
||||
var that = this
|
||||
if (this.isShown && this.options.keyboard) {
|
||||
this.$element.on('keyup.dismiss.modal', function ( e ) {
|
||||
e.which == 27 && that.hide()
|
||||
})
|
||||
} else if (!this.isShown) {
|
||||
this.$element.off('keyup.dismiss.modal')
|
||||
}
|
||||
}
|
||||
|
||||
, hideWithTransition: function () {
|
||||
var that = this
|
||||
, timeout = setTimeout(function () {
|
||||
that.$element.off($.support.transition.end)
|
||||
that.hideModal()
|
||||
}, 500)
|
||||
|
||||
this.$element.one($.support.transition.end, function () {
|
||||
clearTimeout(timeout)
|
||||
that.hideModal()
|
||||
})
|
||||
}
|
||||
|
||||
, hideModal: function () {
|
||||
var that = this
|
||||
this.$element.hide()
|
||||
this.backdrop(function () {
|
||||
that.removeBackdrop()
|
||||
that.$element.trigger('hidden')
|
||||
})
|
||||
}
|
||||
|
||||
, removeBackdrop: function () {
|
||||
this.$backdrop && this.$backdrop.remove()
|
||||
this.$backdrop = null
|
||||
}
|
||||
|
||||
, backdrop: function (callback) {
|
||||
var that = this
|
||||
, animate = this.$element.hasClass('fade') ? 'fade' : ''
|
||||
|
||||
if (this.isShown && this.options.backdrop) {
|
||||
var doAnimate = $.support.transition && animate
|
||||
|
||||
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
|
||||
.appendTo(document.body)
|
||||
|
||||
this.$backdrop.click(
|
||||
this.options.backdrop == 'static' ?
|
||||
$.proxy(this.$element[0].focus, this.$element[0])
|
||||
: $.proxy(this.hide, this)
|
||||
)
|
||||
|
||||
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||||
|
||||
this.$backdrop.addClass('in')
|
||||
|
||||
if (!callback) return
|
||||
|
||||
doAnimate ?
|
||||
this.$backdrop.one($.support.transition.end, callback) :
|
||||
callback()
|
||||
|
||||
} else if (!this.isShown && this.$backdrop) {
|
||||
this.$backdrop.removeClass('in')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade')?
|
||||
this.$backdrop.one($.support.transition.end, callback) :
|
||||
callback()
|
||||
|
||||
} else if (callback) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* MODAL PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
var old = $.fn.modal
|
||||
|
||||
$.fn.modal = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('modal')
|
||||
, options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
|
||||
if (!data) $this.data('modal', (data = new Modal(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
else if (options.show) data.show()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.modal.defaults = {
|
||||
backdrop: true
|
||||
, keyboard: true
|
||||
, show: true
|
||||
}
|
||||
|
||||
$.fn.modal.Constructor = Modal
|
||||
|
||||
|
||||
/* MODAL NO CONFLICT
|
||||
* ================= */
|
||||
|
||||
$.fn.modal.noConflict = function () {
|
||||
$.fn.modal = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* MODAL DATA-API
|
||||
* ============== */
|
||||
|
||||
$(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
|
||||
var $this = $(this)
|
||||
, href = $this.attr('href')
|
||||
, $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
|
||||
, option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
$target
|
||||
.modal(option)
|
||||
.one('hide', function () {
|
||||
$this.focus()
|
||||
})
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,114 +0,0 @@
|
||||
/* ===========================================================
|
||||
* bootstrap-popover.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#popovers
|
||||
* ===========================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* POPOVER PUBLIC CLASS DEFINITION
|
||||
* =============================== */
|
||||
|
||||
var Popover = function (element, options) {
|
||||
this.init('popover', element, options)
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
|
||||
========================================== */
|
||||
|
||||
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
|
||||
|
||||
constructor: Popover
|
||||
|
||||
, setContent: function () {
|
||||
var $tip = this.tip()
|
||||
, title = this.getTitle()
|
||||
, content = this.getContent()
|
||||
|
||||
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
|
||||
$tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
|
||||
|
||||
$tip.removeClass('fade top bottom left right in')
|
||||
}
|
||||
|
||||
, hasContent: function () {
|
||||
return this.getTitle() || this.getContent()
|
||||
}
|
||||
|
||||
, getContent: function () {
|
||||
var content
|
||||
, $e = this.$element
|
||||
, o = this.options
|
||||
|
||||
content = (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
|
||||
|| $e.attr('data-content')
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
, tip: function () {
|
||||
if (!this.$tip) {
|
||||
this.$tip = $(this.options.template)
|
||||
}
|
||||
return this.$tip
|
||||
}
|
||||
|
||||
, destroy: function () {
|
||||
this.hide().$element.off('.' + this.type).removeData(this.type)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
/* POPOVER PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
var old = $.fn.popover
|
||||
|
||||
$.fn.popover = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('popover')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('popover', (data = new Popover(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.popover.Constructor = Popover
|
||||
|
||||
$.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
|
||||
placement: 'right'
|
||||
, trigger: 'click'
|
||||
, content: ''
|
||||
, template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
||||
})
|
||||
|
||||
|
||||
/* POPOVER NO CONFLICT
|
||||
* =================== */
|
||||
|
||||
$.fn.popover.noConflict = function () {
|
||||
$.fn.popover = old
|
||||
return this
|
||||
}
|
||||
|
||||
}(window.jQuery);
|
@ -1,162 +0,0 @@
|
||||
/* =============================================================
|
||||
* bootstrap-scrollspy.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#scrollspy
|
||||
* =============================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* SCROLLSPY CLASS DEFINITION
|
||||
* ========================== */
|
||||
|
||||
function ScrollSpy(element, options) {
|
||||
var process = $.proxy(this.process, this)
|
||||
, $element = $(element).is('body') ? $(window) : $(element)
|
||||
, href
|
||||
this.options = $.extend({}, $.fn.scrollspy.defaults, options)
|
||||
this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
|
||||
this.selector = (this.options.target
|
||||
|| ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|
||||
|| '') + ' .nav li > a'
|
||||
this.$body = $('body')
|
||||
this.refresh()
|
||||
this.process()
|
||||
}
|
||||
|
||||
ScrollSpy.prototype = {
|
||||
|
||||
constructor: ScrollSpy
|
||||
|
||||
, refresh: function () {
|
||||
var self = this
|
||||
, $targets
|
||||
|
||||
this.offsets = $([])
|
||||
this.targets = $([])
|
||||
|
||||
$targets = this.$body
|
||||
.find(this.selector)
|
||||
.map(function () {
|
||||
var $el = $(this)
|
||||
, href = $el.data('target') || $el.attr('href')
|
||||
, $href = /^#\w/.test(href) && $(href)
|
||||
return ( $href
|
||||
&& $href.length
|
||||
&& [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null
|
||||
})
|
||||
.sort(function (a, b) { return a[0] - b[0] })
|
||||
.each(function () {
|
||||
self.offsets.push(this[0])
|
||||
self.targets.push(this[1])
|
||||
})
|
||||
}
|
||||
|
||||
, process: function () {
|
||||
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
|
||||
, scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
|
||||
, maxScroll = scrollHeight - this.$scrollElement.height()
|
||||
, offsets = this.offsets
|
||||
, targets = this.targets
|
||||
, activeTarget = this.activeTarget
|
||||
, i
|
||||
|
||||
if (scrollTop >= maxScroll) {
|
||||
return activeTarget != (i = targets.last()[0])
|
||||
&& this.activate ( i )
|
||||
}
|
||||
|
||||
for (i = offsets.length; i--;) {
|
||||
activeTarget != targets[i]
|
||||
&& scrollTop >= offsets[i]
|
||||
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
|
||||
&& this.activate( targets[i] )
|
||||
}
|
||||
}
|
||||
|
||||
, activate: function (target) {
|
||||
var active
|
||||
, selector
|
||||
|
||||
this.activeTarget = target
|
||||
|
||||
$(this.selector)
|
||||
.parent('.active')
|
||||
.removeClass('active')
|
||||
|
||||
selector = this.selector
|
||||
+ '[data-target="' + target + '"],'
|
||||
+ this.selector + '[href="' + target + '"]'
|
||||
|
||||
active = $(selector)
|
||||
.parent('li')
|
||||
.addClass('active')
|
||||
|
||||
if (active.parent('.dropdown-menu').length) {
|
||||
active = active.closest('li.dropdown').addClass('active')
|
||||
}
|
||||
|
||||
active.trigger('activate')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* SCROLLSPY PLUGIN DEFINITION
|
||||
* =========================== */
|
||||
|
||||
var old = $.fn.scrollspy
|
||||
|
||||
$.fn.scrollspy = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('scrollspy')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.scrollspy.Constructor = ScrollSpy
|
||||
|
||||
$.fn.scrollspy.defaults = {
|
||||
offset: 10
|
||||
}
|
||||
|
||||
|
||||
/* SCROLLSPY NO CONFLICT
|
||||
* ===================== */
|
||||
|
||||
$.fn.scrollspy.noConflict = function () {
|
||||
$.fn.scrollspy = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* SCROLLSPY DATA-API
|
||||
* ================== */
|
||||
|
||||
$(window).on('load', function () {
|
||||
$('[data-spy="scroll"]').each(function () {
|
||||
var $spy = $(this)
|
||||
$spy.scrollspy($spy.data())
|
||||
})
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,144 +0,0 @@
|
||||
/* ========================================================
|
||||
* bootstrap-tab.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#tabs
|
||||
* ========================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* TAB CLASS DEFINITION
|
||||
* ==================== */
|
||||
|
||||
var Tab = function (element) {
|
||||
this.element = $(element)
|
||||
}
|
||||
|
||||
Tab.prototype = {
|
||||
|
||||
constructor: Tab
|
||||
|
||||
, show: function () {
|
||||
var $this = this.element
|
||||
, $ul = $this.closest('ul:not(.dropdown-menu)')
|
||||
, selector = $this.attr('data-target')
|
||||
, previous
|
||||
, $target
|
||||
, e
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
if ( $this.parent('li').hasClass('active') ) return
|
||||
|
||||
previous = $ul.find('.active:last a')[0]
|
||||
|
||||
e = $.Event('show', {
|
||||
relatedTarget: previous
|
||||
})
|
||||
|
||||
$this.trigger(e)
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$target = $(selector)
|
||||
|
||||
this.activate($this.parent('li'), $ul)
|
||||
this.activate($target, $target.parent(), function () {
|
||||
$this.trigger({
|
||||
type: 'shown'
|
||||
, relatedTarget: previous
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
, activate: function ( element, container, callback) {
|
||||
var $active = container.find('> .active')
|
||||
, transition = callback
|
||||
&& $.support.transition
|
||||
&& $active.hasClass('fade')
|
||||
|
||||
function next() {
|
||||
$active
|
||||
.removeClass('active')
|
||||
.find('> .dropdown-menu > .active')
|
||||
.removeClass('active')
|
||||
|
||||
element.addClass('active')
|
||||
|
||||
if (transition) {
|
||||
element[0].offsetWidth // reflow for transition
|
||||
element.addClass('in')
|
||||
} else {
|
||||
element.removeClass('fade')
|
||||
}
|
||||
|
||||
if ( element.parent('.dropdown-menu') ) {
|
||||
element.closest('li.dropdown').addClass('active')
|
||||
}
|
||||
|
||||
callback && callback()
|
||||
}
|
||||
|
||||
transition ?
|
||||
$active.one($.support.transition.end, next) :
|
||||
next()
|
||||
|
||||
$active.removeClass('in')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TAB PLUGIN DEFINITION
|
||||
* ===================== */
|
||||
|
||||
var old = $.fn.tab
|
||||
|
||||
$.fn.tab = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('tab')
|
||||
if (!data) $this.data('tab', (data = new Tab(this)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.tab.Constructor = Tab
|
||||
|
||||
|
||||
/* TAB NO CONFLICT
|
||||
* =============== */
|
||||
|
||||
$.fn.tab.noConflict = function () {
|
||||
$.fn.tab = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* TAB DATA-API
|
||||
* ============ */
|
||||
|
||||
$(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
|
||||
e.preventDefault()
|
||||
$(this).tab('show')
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,361 +0,0 @@
|
||||
/* ===========================================================
|
||||
* bootstrap-tooltip.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#tooltips
|
||||
* Inspired by the original jQuery.tipsy by Jason Frame
|
||||
* ===========================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* TOOLTIP PUBLIC CLASS DEFINITION
|
||||
* =============================== */
|
||||
|
||||
var Tooltip = function (element, options) {
|
||||
this.init('tooltip', element, options)
|
||||
}
|
||||
|
||||
Tooltip.prototype = {
|
||||
|
||||
constructor: Tooltip
|
||||
|
||||
, init: function (type, element, options) {
|
||||
var eventIn
|
||||
, eventOut
|
||||
, triggers
|
||||
, trigger
|
||||
, i
|
||||
|
||||
this.type = type
|
||||
this.$element = $(element)
|
||||
this.options = this.getOptions(options)
|
||||
this.enabled = true
|
||||
|
||||
triggers = this.options.trigger.split(' ')
|
||||
|
||||
for (i = triggers.length; i--;) {
|
||||
trigger = triggers[i]
|
||||
if (trigger == 'click') {
|
||||
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
|
||||
} else if (trigger != 'manual') {
|
||||
eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
|
||||
eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
|
||||
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
|
||||
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
|
||||
}
|
||||
}
|
||||
|
||||
this.options.selector ?
|
||||
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
|
||||
this.fixTitle()
|
||||
}
|
||||
|
||||
, getOptions: function (options) {
|
||||
options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)
|
||||
|
||||
if (options.delay && typeof options.delay == 'number') {
|
||||
options.delay = {
|
||||
show: options.delay
|
||||
, hide: options.delay
|
||||
}
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
, enter: function (e) {
|
||||
var defaults = $.fn[this.type].defaults
|
||||
, options = {}
|
||||
, self
|
||||
|
||||
this._options && $.each(this._options, function (key, value) {
|
||||
if (defaults[key] != value) options[key] = value
|
||||
}, this)
|
||||
|
||||
self = $(e.currentTarget)[this.type](options).data(this.type)
|
||||
|
||||
if (!self.options.delay || !self.options.delay.show) return self.show()
|
||||
|
||||
clearTimeout(this.timeout)
|
||||
self.hoverState = 'in'
|
||||
this.timeout = setTimeout(function() {
|
||||
if (self.hoverState == 'in') self.show()
|
||||
}, self.options.delay.show)
|
||||
}
|
||||
|
||||
, leave: function (e) {
|
||||
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
|
||||
|
||||
if (this.timeout) clearTimeout(this.timeout)
|
||||
if (!self.options.delay || !self.options.delay.hide) return self.hide()
|
||||
|
||||
self.hoverState = 'out'
|
||||
this.timeout = setTimeout(function() {
|
||||
if (self.hoverState == 'out') self.hide()
|
||||
}, self.options.delay.hide)
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var $tip
|
||||
, pos
|
||||
, actualWidth
|
||||
, actualHeight
|
||||
, placement
|
||||
, tp
|
||||
, e = $.Event('show')
|
||||
|
||||
if (this.hasContent() && this.enabled) {
|
||||
this.$element.trigger(e)
|
||||
if (e.isDefaultPrevented()) return
|
||||
$tip = this.tip()
|
||||
this.setContent()
|
||||
|
||||
if (this.options.animation) {
|
||||
$tip.addClass('fade')
|
||||
}
|
||||
|
||||
placement = typeof this.options.placement == 'function' ?
|
||||
this.options.placement.call(this, $tip[0], this.$element[0]) :
|
||||
this.options.placement
|
||||
|
||||
$tip
|
||||
.detach()
|
||||
.css({ top: 0, left: 0, display: 'block' })
|
||||
|
||||
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
|
||||
|
||||
pos = this.getPosition()
|
||||
|
||||
actualWidth = $tip[0].offsetWidth
|
||||
actualHeight = $tip[0].offsetHeight
|
||||
|
||||
switch (placement) {
|
||||
case 'bottom':
|
||||
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
|
||||
break
|
||||
case 'top':
|
||||
tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
|
||||
break
|
||||
case 'left':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
|
||||
break
|
||||
case 'right':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
|
||||
break
|
||||
}
|
||||
|
||||
this.applyPlacement(tp, placement)
|
||||
this.$element.trigger('shown')
|
||||
}
|
||||
}
|
||||
|
||||
, applyPlacement: function(offset, placement){
|
||||
var $tip = this.tip()
|
||||
, width = $tip[0].offsetWidth
|
||||
, height = $tip[0].offsetHeight
|
||||
, actualWidth
|
||||
, actualHeight
|
||||
, delta
|
||||
, replace
|
||||
|
||||
$tip
|
||||
.offset(offset)
|
||||
.addClass(placement)
|
||||
.addClass('in')
|
||||
|
||||
actualWidth = $tip[0].offsetWidth
|
||||
actualHeight = $tip[0].offsetHeight
|
||||
|
||||
if (placement == 'top' && actualHeight != height) {
|
||||
offset.top = offset.top + height - actualHeight
|
||||
replace = true
|
||||
}
|
||||
|
||||
if (placement == 'bottom' || placement == 'top') {
|
||||
delta = 0
|
||||
|
||||
if (offset.left < 0){
|
||||
delta = offset.left * -2
|
||||
offset.left = 0
|
||||
$tip.offset(offset)
|
||||
actualWidth = $tip[0].offsetWidth
|
||||
actualHeight = $tip[0].offsetHeight
|
||||
}
|
||||
|
||||
this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
|
||||
} else {
|
||||
this.replaceArrow(actualHeight - height, actualHeight, 'top')
|
||||
}
|
||||
|
||||
if (replace) $tip.offset(offset)
|
||||
}
|
||||
|
||||
, replaceArrow: function(delta, dimension, position){
|
||||
this
|
||||
.arrow()
|
||||
.css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
|
||||
}
|
||||
|
||||
, setContent: function () {
|
||||
var $tip = this.tip()
|
||||
, title = this.getTitle()
|
||||
|
||||
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
|
||||
$tip.removeClass('fade in top bottom left right')
|
||||
}
|
||||
|
||||
, hide: function () {
|
||||
var that = this
|
||||
, $tip = this.tip()
|
||||
, e = $.Event('hide')
|
||||
|
||||
this.$element.trigger(e)
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$tip.removeClass('in')
|
||||
|
||||
function removeWithAnimation() {
|
||||
var timeout = setTimeout(function () {
|
||||
$tip.off($.support.transition.end).detach()
|
||||
}, 500)
|
||||
|
||||
$tip.one($.support.transition.end, function () {
|
||||
clearTimeout(timeout)
|
||||
$tip.detach()
|
||||
})
|
||||
}
|
||||
|
||||
$.support.transition && this.$tip.hasClass('fade') ?
|
||||
removeWithAnimation() :
|
||||
$tip.detach()
|
||||
|
||||
this.$element.trigger('hidden')
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
, fixTitle: function () {
|
||||
var $e = this.$element
|
||||
if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
|
||||
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
|
||||
}
|
||||
}
|
||||
|
||||
, hasContent: function () {
|
||||
return this.getTitle()
|
||||
}
|
||||
|
||||
, getPosition: function () {
|
||||
var el = this.$element[0]
|
||||
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
|
||||
width: el.offsetWidth
|
||||
, height: el.offsetHeight
|
||||
}, this.$element.offset())
|
||||
}
|
||||
|
||||
, getTitle: function () {
|
||||
var title
|
||||
, $e = this.$element
|
||||
, o = this.options
|
||||
|
||||
title = $e.attr('data-original-title')
|
||||
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
|
||||
|
||||
return title
|
||||
}
|
||||
|
||||
, tip: function () {
|
||||
return this.$tip = this.$tip || $(this.options.template)
|
||||
}
|
||||
|
||||
, arrow: function(){
|
||||
return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
|
||||
}
|
||||
|
||||
, validate: function () {
|
||||
if (!this.$element[0].parentNode) {
|
||||
this.hide()
|
||||
this.$element = null
|
||||
this.options = null
|
||||
}
|
||||
}
|
||||
|
||||
, enable: function () {
|
||||
this.enabled = true
|
||||
}
|
||||
|
||||
, disable: function () {
|
||||
this.enabled = false
|
||||
}
|
||||
|
||||
, toggleEnabled: function () {
|
||||
this.enabled = !this.enabled
|
||||
}
|
||||
|
||||
, toggle: function (e) {
|
||||
var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
|
||||
self.tip().hasClass('in') ? self.hide() : self.show()
|
||||
}
|
||||
|
||||
, destroy: function () {
|
||||
this.hide().$element.off('.' + this.type).removeData(this.type)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* TOOLTIP PLUGIN DEFINITION
|
||||
* ========================= */
|
||||
|
||||
var old = $.fn.tooltip
|
||||
|
||||
$.fn.tooltip = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('tooltip')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.tooltip.Constructor = Tooltip
|
||||
|
||||
$.fn.tooltip.defaults = {
|
||||
animation: true
|
||||
, placement: 'top'
|
||||
, selector: false
|
||||
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
|
||||
, trigger: 'hover focus'
|
||||
, title: ''
|
||||
, delay: 0
|
||||
, html: false
|
||||
, container: false
|
||||
}
|
||||
|
||||
|
||||
/* TOOLTIP NO CONFLICT
|
||||
* =================== */
|
||||
|
||||
$.fn.tooltip.noConflict = function () {
|
||||
$.fn.tooltip = old
|
||||
return this
|
||||
}
|
||||
|
||||
}(window.jQuery);
|
@ -1,60 +0,0 @@
|
||||
/* ===================================================
|
||||
* bootstrap-transition.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#transitions
|
||||
* ===================================================
|
||||
* Copyright 2012 Twitter, 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 ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
|
||||
* ======================================================= */
|
||||
|
||||
$(function () {
|
||||
|
||||
$.support.transition = (function () {
|
||||
|
||||
var transitionEnd = (function () {
|
||||
|
||||
var el = document.createElement('bootstrap')
|
||||
, transEndEventNames = {
|
||||
'WebkitTransition' : 'webkitTransitionEnd'
|
||||
, 'MozTransition' : 'transitionend'
|
||||
, 'OTransition' : 'oTransitionEnd otransitionend'
|
||||
, 'transition' : 'transitionend'
|
||||
}
|
||||
, name
|
||||
|
||||
for (name in transEndEventNames){
|
||||
if (el.style[name] !== undefined) {
|
||||
return transEndEventNames[name]
|
||||
}
|
||||
}
|
||||
|
||||
}())
|
||||
|
||||
return transitionEnd && {
|
||||
end: transitionEnd
|
||||
}
|
||||
|
||||
})()
|
||||
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,335 +0,0 @@
|
||||
/* =============================================================
|
||||
* bootstrap-typeahead.js v2.3.1
|
||||
* http://twitter.github.com/bootstrap/javascript.html#typeahead
|
||||
* =============================================================
|
||||
* Copyright 2012 Twitter, 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($){
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* TYPEAHEAD PUBLIC CLASS DEFINITION
|
||||
* ================================= */
|
||||
|
||||
var Typeahead = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.typeahead.defaults, options)
|
||||
this.matcher = this.options.matcher || this.matcher
|
||||
this.sorter = this.options.sorter || this.sorter
|
||||
this.highlighter = this.options.highlighter || this.highlighter
|
||||
this.updater = this.options.updater || this.updater
|
||||
this.source = this.options.source
|
||||
this.$menu = $(this.options.menu)
|
||||
this.shown = false
|
||||
this.listen()
|
||||
}
|
||||
|
||||
Typeahead.prototype = {
|
||||
|
||||
constructor: Typeahead
|
||||
|
||||
, select: function () {
|
||||
var val = this.$menu.find('.active').attr('data-value')
|
||||
this.$element
|
||||
.val(this.updater(val))
|
||||
.change()
|
||||
return this.hide()
|
||||
}
|
||||
|
||||
, updater: function (item) {
|
||||
return item
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var pos = $.extend({}, this.$element.position(), {
|
||||
height: this.$element[0].offsetHeight
|
||||
})
|
||||
|
||||
this.$menu
|
||||
.insertAfter(this.$element)
|
||||
.css({
|
||||
top: pos.top + pos.height
|
||||
, left: pos.left
|
||||
})
|
||||
.show()
|
||||
|
||||
this.shown = true
|
||||
return this
|
||||
}
|
||||
|
||||
, hide: function () {
|
||||
this.$menu.hide()
|
||||
this.shown = false
|
||||
return this
|
||||
}
|
||||
|
||||
, lookup: function (event) {
|
||||
var items
|
||||
|
||||
this.query = this.$element.val()
|
||||
|
||||
if (!this.query || this.query.length < this.options.minLength) {
|
||||
return this.shown ? this.hide() : this
|
||||
}
|
||||
|
||||
items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
|
||||
|
||||
return items ? this.process(items) : this
|
||||
}
|
||||
|
||||
, process: function (items) {
|
||||
var that = this
|
||||
|
||||
items = $.grep(items, function (item) {
|
||||
return that.matcher(item)
|
||||
})
|
||||
|
||||
items = this.sorter(items)
|
||||
|
||||
if (!items.length) {
|
||||
return this.shown ? this.hide() : this
|
||||
}
|
||||
|
||||
return this.render(items.slice(0, this.options.items)).show()
|
||||
}
|
||||
|
||||
, matcher: function (item) {
|
||||
return ~item.toLowerCase().indexOf(this.query.toLowerCase())
|
||||
}
|
||||
|
||||
, sorter: function (items) {
|
||||
var beginswith = []
|
||||
, caseSensitive = []
|
||||
, caseInsensitive = []
|
||||
, item
|
||||
|
||||
while (item = items.shift()) {
|
||||
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
|
||||
else if (~item.indexOf(this.query)) caseSensitive.push(item)
|
||||
else caseInsensitive.push(item)
|
||||
}
|
||||
|
||||
return beginswith.concat(caseSensitive, caseInsensitive)
|
||||
}
|
||||
|
||||
, highlighter: function (item) {
|
||||
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
|
||||
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
|
||||
return '<strong>' + match + '</strong>'
|
||||
})
|
||||
}
|
||||
|
||||
, render: function (items) {
|
||||
var that = this
|
||||
|
||||
items = $(items).map(function (i, item) {
|
||||
i = $(that.options.item).attr('data-value', item)
|
||||
i.find('a').html(that.highlighter(item))
|
||||
return i[0]
|
||||
})
|
||||
|
||||
items.first().addClass('active')
|
||||
this.$menu.html(items)
|
||||
return this
|
||||
}
|
||||
|
||||
, next: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, next = active.next()
|
||||
|
||||
if (!next.length) {
|
||||
next = $(this.$menu.find('li')[0])
|
||||
}
|
||||
|
||||
next.addClass('active')
|
||||
}
|
||||
|
||||
, prev: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, prev = active.prev()
|
||||
|
||||
if (!prev.length) {
|
||||
prev = this.$menu.find('li').last()
|
||||
}
|
||||
|
||||
prev.addClass('active')
|
||||
}
|
||||
|
||||
, listen: function () {
|
||||
this.$element
|
||||
.on('focus', $.proxy(this.focus, this))
|
||||
.on('blur', $.proxy(this.blur, this))
|
||||
.on('keypress', $.proxy(this.keypress, this))
|
||||
.on('keyup', $.proxy(this.keyup, this))
|
||||
|
||||
if (this.eventSupported('keydown')) {
|
||||
this.$element.on('keydown', $.proxy(this.keydown, this))
|
||||
}
|
||||
|
||||
this.$menu
|
||||
.on('click', $.proxy(this.click, this))
|
||||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||||
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
|
||||
}
|
||||
|
||||
, eventSupported: function(eventName) {
|
||||
var isSupported = eventName in this.$element
|
||||
if (!isSupported) {
|
||||
this.$element.setAttribute(eventName, 'return;')
|
||||
isSupported = typeof this.$element[eventName] === 'function'
|
||||
}
|
||||
return isSupported
|
||||
}
|
||||
|
||||
, move: function (e) {
|
||||
if (!this.shown) return
|
||||
|
||||
switch(e.keyCode) {
|
||||
case 9: // tab
|
||||
case 13: // enter
|
||||
case 27: // escape
|
||||
e.preventDefault()
|
||||
break
|
||||
|
||||
case 38: // up arrow
|
||||
e.preventDefault()
|
||||
this.prev()
|
||||
break
|
||||
|
||||
case 40: // down arrow
|
||||
e.preventDefault()
|
||||
this.next()
|
||||
break
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
, keydown: function (e) {
|
||||
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
|
||||
this.move(e)
|
||||
}
|
||||
|
||||
, keypress: function (e) {
|
||||
if (this.suppressKeyPressRepeat) return
|
||||
this.move(e)
|
||||
}
|
||||
|
||||
, keyup: function (e) {
|
||||
switch(e.keyCode) {
|
||||
case 40: // down arrow
|
||||
case 38: // up arrow
|
||||
case 16: // shift
|
||||
case 17: // ctrl
|
||||
case 18: // alt
|
||||
break
|
||||
|
||||
case 9: // tab
|
||||
case 13: // enter
|
||||
if (!this.shown) return
|
||||
this.select()
|
||||
break
|
||||
|
||||
case 27: // escape
|
||||
if (!this.shown) return
|
||||
this.hide()
|
||||
break
|
||||
|
||||
default:
|
||||
this.lookup()
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
, focus: function (e) {
|
||||
this.focused = true
|
||||
}
|
||||
|
||||
, blur: function (e) {
|
||||
this.focused = false
|
||||
if (!this.mousedover && this.shown) this.hide()
|
||||
}
|
||||
|
||||
, click: function (e) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.select()
|
||||
this.$element.focus()
|
||||
}
|
||||
|
||||
, mouseenter: function (e) {
|
||||
this.mousedover = true
|
||||
this.$menu.find('.active').removeClass('active')
|
||||
$(e.currentTarget).addClass('active')
|
||||
}
|
||||
|
||||
, mouseleave: function (e) {
|
||||
this.mousedover = false
|
||||
if (!this.focused && this.shown) this.hide()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* TYPEAHEAD PLUGIN DEFINITION
|
||||
* =========================== */
|
||||
|
||||
var old = $.fn.typeahead
|
||||
|
||||
$.fn.typeahead = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('typeahead')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.typeahead.defaults = {
|
||||
source: []
|
||||
, items: 8
|
||||
, menu: '<ul class="typeahead dropdown-menu"></ul>'
|
||||
, item: '<li><a href="#"></a></li>'
|
||||
, minLength: 1
|
||||
}
|
||||
|
||||
$.fn.typeahead.Constructor = Typeahead
|
||||
|
||||
|
||||
/* TYPEAHEAD NO CONFLICT
|
||||
* =================== */
|
||||
|
||||
$.fn.typeahead.noConflict = function () {
|
||||
$.fn.typeahead = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* TYPEAHEAD DATA-API
|
||||
* ================== */
|
||||
|
||||
$(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
|
||||
var $this = $(this)
|
||||
if ($this.data('typeahead')) return
|
||||
$this.typeahead($this.data())
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
@ -1,182 +0,0 @@
|
||||
// https://raw.githubusercontent.com/getzola/zola/master/docs/static/search.js
|
||||
|
||||
function debounce(func, wait) {
|
||||
var timeout;
|
||||
|
||||
return function () {
|
||||
var context = this;
|
||||
var args = arguments;
|
||||
clearTimeout(timeout);
|
||||
|
||||
timeout = setTimeout(function () {
|
||||
timeout = null;
|
||||
func.apply(context, args);
|
||||
}, wait);
|
||||
};
|
||||
}
|
||||
|
||||
// Taken from mdbook
|
||||
// The strategy is as follows:
|
||||
// First, assign a value to each word in the document:
|
||||
// Words that correspond to search terms (stemmer aware): 40
|
||||
// Normal words: 2
|
||||
// First word in a sentence: 8
|
||||
// Then use a sliding window with a constant number of words and count the
|
||||
// sum of the values of the words within the window. Then use the window that got the
|
||||
// maximum sum. If there are multiple maximas, then get the last one.
|
||||
// Enclose the terms in <b>.
|
||||
function makeTeaser(body, terms) {
|
||||
var TERM_WEIGHT = 40;
|
||||
var NORMAL_WORD_WEIGHT = 2;
|
||||
var FIRST_WORD_WEIGHT = 8;
|
||||
var TEASER_MAX_WORDS = 30;
|
||||
|
||||
var stemmedTerms = terms.map(function (w) {
|
||||
return elasticlunr.stemmer(w.toLowerCase());
|
||||
});
|
||||
var termFound = false;
|
||||
var index = 0;
|
||||
var weighted = []; // contains elements of ["word", weight, index_in_document]
|
||||
|
||||
// split in sentences, then words
|
||||
var sentences = body.toLowerCase().split(". ");
|
||||
|
||||
for (var i in sentences) {
|
||||
var words = sentences[i].split(" ");
|
||||
var value = FIRST_WORD_WEIGHT;
|
||||
|
||||
for (var j in words) {
|
||||
var word = words[j];
|
||||
|
||||
if (word.length > 0) {
|
||||
for (var k in stemmedTerms) {
|
||||
if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
|
||||
value = TERM_WEIGHT;
|
||||
termFound = true;
|
||||
}
|
||||
}
|
||||
weighted.push([word, value, index]);
|
||||
value = NORMAL_WORD_WEIGHT;
|
||||
}
|
||||
|
||||
index += word.length;
|
||||
index += 1; // ' ' or '.' if last word in sentence
|
||||
}
|
||||
|
||||
index += 1; // because we split at a two-char boundary '. '
|
||||
}
|
||||
|
||||
if (weighted.length === 0) {
|
||||
return body;
|
||||
}
|
||||
|
||||
var windowWeights = [];
|
||||
var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
|
||||
// We add a window with all the weights first
|
||||
var curSum = 0;
|
||||
for (var i = 0; i < windowSize; i++) {
|
||||
curSum += weighted[i][1];
|
||||
}
|
||||
windowWeights.push(curSum);
|
||||
|
||||
for (var i = 0; i < weighted.length - windowSize; i++) {
|
||||
curSum -= weighted[i][1];
|
||||
curSum += weighted[i + windowSize][1];
|
||||
windowWeights.push(curSum);
|
||||
}
|
||||
|
||||
// If we didn't find the term, just pick the first window
|
||||
var maxSumIndex = 0;
|
||||
if (termFound) {
|
||||
var maxFound = 0;
|
||||
// backwards
|
||||
for (var i = windowWeights.length - 1; i >= 0; i--) {
|
||||
if (windowWeights[i] > maxFound) {
|
||||
maxFound = windowWeights[i];
|
||||
maxSumIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var teaser = [];
|
||||
var startIndex = weighted[maxSumIndex][2];
|
||||
for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
|
||||
var word = weighted[i];
|
||||
if (startIndex < word[2]) {
|
||||
// missing text from index to start of `word`
|
||||
teaser.push(body.substring(startIndex, word[2]));
|
||||
startIndex = word[2];
|
||||
}
|
||||
|
||||
// add <em/> around search terms
|
||||
if (word[1] === TERM_WEIGHT) {
|
||||
teaser.push("<b>");
|
||||
}
|
||||
startIndex = word[2] + word[0].length;
|
||||
teaser.push(body.substring(word[2], startIndex));
|
||||
|
||||
if (word[1] === TERM_WEIGHT) {
|
||||
teaser.push("</b>");
|
||||
}
|
||||
}
|
||||
teaser.push("…");
|
||||
return teaser.join("");
|
||||
}
|
||||
|
||||
function formatSearchResultItem(item, terms) {
|
||||
return '<div class="search-results__item">'
|
||||
+ `<a href="${item.ref}">${item.doc.title}</a>`
|
||||
+ `<div>${makeTeaser(item.doc.body, terms)}</div>`
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
function initSearch() {
|
||||
var $searchInput = document.getElementById("search");
|
||||
var $searchResults = document.querySelector(".search-results");
|
||||
var $searchResultsItems = document.querySelector(".search-results__items");
|
||||
var MAX_ITEMS = 10;
|
||||
|
||||
var options = {
|
||||
bool: "AND",
|
||||
fields: {
|
||||
title: {boost: 2},
|
||||
body: {boost: 1},
|
||||
}
|
||||
};
|
||||
var currentTerm = "";
|
||||
var index = elasticlunr.Index.load(window.searchIndex);
|
||||
|
||||
$searchInput.addEventListener("keyup", debounce(function() {
|
||||
var term = $searchInput.value.trim();
|
||||
if (term === currentTerm || !index) {
|
||||
return;
|
||||
}
|
||||
$searchResults.style.display = term === "" ? "none" : "block";
|
||||
$searchResultsItems.innerHTML = "";
|
||||
if (term === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
var results = index.search(term, options);
|
||||
if (results.length === 0) {
|
||||
$searchResults.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
currentTerm = term;
|
||||
for (var i = 0; i < Math.min(results.length, MAX_ITEMS); i++) {
|
||||
var item = document.createElement("li");
|
||||
item.innerHTML = formatSearchResultItem(results[i], term.split(" "));
|
||||
$searchResultsItems.appendChild(item);
|
||||
}
|
||||
}, 150));
|
||||
}
|
||||
|
||||
|
||||
if (document.readyState === "complete" ||
|
||||
(document.readyState !== "loading" && !document.documentElement.doScroll)
|
||||
) {
|
||||
initSearch();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", initSearch);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
_386 = {
|
||||
fastLoad: false,
|
||||
onePass: true,
|
||||
speedFactor: 1
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ config.title }} - 404{% endblock title %}
|
||||
|
||||
{% block header %}
|
||||
<header class="bg-error">
|
||||
<h1 class="text-white">404 - Not found</h1>
|
||||
</header>
|
||||
{% endblock header %}
|
||||
|
||||
{% block main %}
|
||||
<p>
|
||||
The page you requested was not found.<br>
|
||||
You can try to find it by browsing the menus.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{ config.base_url }}" class="btn btn-info" role="button">Home</a>
|
||||
</p>
|
||||
{% endblock main %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% endblock sidebar %}
|
@ -1,19 +0,0 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ config.title }} - {{ config.extra.label_categories }}{% endblock title %}
|
||||
|
||||
{% block header %}
|
||||
<div class="page-header">
|
||||
<h1>{{ config.extra.label_categories }}</h1>
|
||||
</div>
|
||||
{% endblock header %}
|
||||
|
||||
{% block main %}
|
||||
<ul>
|
||||
{% for category in terms %}
|
||||
<li>
|
||||
<a href="{{ category.permalink }}">{{ category.name }}</a> ({{ category.pages | length }})
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock main %}
|
@ -1,17 +0,0 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ config.title }} - {{ config.extra.label_categories }}{% endblock title %}
|
||||
|
||||
{% block header %}
|
||||
<div class="page-header">
|
||||
<h1>{{ config.extra.label_category }}: {{ term.name }}</h1>
|
||||
</div>
|
||||
{% endblock header %}
|
||||
|
||||
{% block main %}
|
||||
<ul>
|
||||
{% for page in term.pages %}
|
||||
<li>{{ macro::post_min(page=page) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock main %}
|
@ -1,103 +0,0 @@
|
||||
{% import "macros.html" as macro %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="{% if page.extra.lang %}{{ page.extra.lang }}{% else %}{{ lang }}{% endif %}" itemscope
|
||||
itemtype="http://schema.org/Blog">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
|
||||
<link rel="stylesheet" href="{{ get_url(path='site.css', trailing_slash=false) | safe }}">
|
||||
<title>{% block title %}{{ config.title }}{% endblock title %}</title>
|
||||
|
||||
{% if config.generate_rss %}
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ get_url(path='rss.xml') }}">
|
||||
{% endif %}
|
||||
|
||||
<meta name="description" itemprop="about" content="{{ config.description }}">
|
||||
<meta name="keywords" itemprop="keywords" content="{{ config.extra.keywords }}">
|
||||
<meta name="author" itemprop="author" content="{{ config.extra.author }}">
|
||||
<meta itemprop="headline" content="{{ config.title }}">
|
||||
<meta itemprop="copyrightYear" content="{{ config.extra.year }}">
|
||||
|
||||
<link rel="icon" href="{{ get_url(path='images/favicon.ico') }}" type="image/x-icon">
|
||||
<link rel="manifest" href="{{ get_url(path='images/manifest.json') }}">
|
||||
<meta name="msapplication-TileColor" content="{{ config.extra.theme_color }}">
|
||||
<meta name="theme-color" content="{{ config.extra.theme_color }}">
|
||||
|
||||
<meta property="og:title" content="{% block ogtitle %}{{ config.title }}{% endblock ogtitle %}">
|
||||
<meta property="og:description" content="{% block ogdesc %}{{ config.description }}{% endblock ogdesc %}">
|
||||
<meta property="og:url" content="{% block ogurl %}{{ config.base_url }}{% endblock ogurl%}">
|
||||
<meta property="og:site_name" content="{{ config.title }}">
|
||||
{% if config.extra.image %}
|
||||
<meta property="og:image" content="{% block ogimg %}{{ config.extra.image }}{% endblock ogimg %}">
|
||||
{% endif %}
|
||||
<meta name="twitter:card" content="summary">
|
||||
{% if config.extra.twitter_user %}
|
||||
<meta name="twitter:site" content="{{ config.extra.twitter_user }}">
|
||||
<meta name="twitter:creator" content="{{ config.extra.twitter_user }}">
|
||||
<meta name="twitter:image:alt" content="{% block ogaltimg %}{{ config.title }}{% endblock ogaltimg %}">
|
||||
{% endif %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main class="container">
|
||||
{% block breadcrumb %}{% endblock breadcrumb %}
|
||||
{% block header %}
|
||||
<header>
|
||||
<h1>{{ config.title }} <small>{{ config.description }}</small></h1>
|
||||
</header>
|
||||
{% endblock header %}
|
||||
{% block meta %}{% endblock meta %}
|
||||
|
||||
<div class="flex-row gap">
|
||||
|
||||
<div class="w-3/4">
|
||||
{% block main %}
|
||||
{% for page in paginator.pages %}
|
||||
{{ macro::post_max(page=page) }}
|
||||
{% endfor %}
|
||||
|
||||
{{ macro::paginator(ref=paginator, extra=config.extra) }}
|
||||
{% endblock main %}
|
||||
</div>
|
||||
|
||||
<aside class="w-1/4">
|
||||
{% block sidebar %}
|
||||
|
||||
{% for page in config.extra.sidebars %}
|
||||
<nav class="box">
|
||||
<header>{{ page.title }}</header>
|
||||
<menu>
|
||||
{% for item in page.items %}
|
||||
<li class="{% if item.path == current_path %}active{% endif %}">
|
||||
{% if page.internal %}
|
||||
<a href="{{ item.path }}">{{ item.name }}</a>
|
||||
{% else %}
|
||||
<a href="{{ item.path }}" target="_blank" rel="noopener">{{ item.name }}</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</menu>
|
||||
</nav>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock sidebar %}
|
||||
</aside>
|
||||
|
||||
</div> <!-- row -->
|
||||
</main>
|
||||
|
||||
<footer class="container">
|
||||
<hr class="soften">
|
||||
<p>
|
||||
{{ config.extra.year }} ©
|
||||
<a href="{{ config.base_url }}">{{ config.extra.author }}</a>
|
||||
|
|
||||
Built on <a href="https://getzola.org" rel="noopener" target="_blank">Zola</a>
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,81 +0,0 @@
|
||||
{% macro post_max(page) %}
|
||||
<div>
|
||||
<h1><a href="{{ page.permalink }}">{{ page.title }}</a></h1>
|
||||
<p>{{ page.description }}</p>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{{ config.extra.label_date }}</dt>
|
||||
<dd>{{ page.date | date(format="%Y-%m-%d") }}</dd>
|
||||
|
||||
<dt>{{ config.extra.label_author }}</dt>
|
||||
<dd>
|
||||
{% if page.extra.author %}
|
||||
{{page.extra.author}}
|
||||
{% else %}
|
||||
{{config.extra.author}}
|
||||
{% endif %}
|
||||
</dd>
|
||||
|
||||
{% if page.taxonomies.categories %}
|
||||
<dt>{{ config.extra.label_taxonomy }}</dt>
|
||||
<dd>
|
||||
<a href="{{ get_taxonomy_url(kind="categories", name=page.taxonomies.categories[0]) }}">
|
||||
{{ page.taxonomies.categories[0] }}
|
||||
</a>
|
||||
{% if page.taxonomies.tags %}
|
||||
|
|
||||
{% for tag in page.taxonomies.tags %}
|
||||
<a href="{{ get_taxonomy_url(kind="tags", name=tag) }}">{{ tag }}</a>{% if page.taxonomies.tags | length > 1 %}{% if loop.index != page.taxonomies.tags | length %},{% endif %}{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</a>
|
||||
</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt>{{ config.extra.label_reading }}</dt>
|
||||
<dd>{{ page.reading_time }}'</dd>
|
||||
</dl>
|
||||
<p>
|
||||
<a href="{{ page.permalink }}" class="btn btn-info" role="button">{{ config.extra.label_read_more }}</a>
|
||||
</p>
|
||||
<hr class="soften">
|
||||
<p></p>
|
||||
</div>
|
||||
{% endmacro post_max %}
|
||||
|
||||
|
||||
{% macro post_min(page) %}
|
||||
<a href="{{ page.permalink }}">{{ page.date }} | {{ page.title }}</a>
|
||||
{% endmacro post_min %}
|
||||
|
||||
|
||||
{% macro paginator(ref, extra) %}
|
||||
<div class="pagination pagination-centered">
|
||||
<ul>
|
||||
{% if ref.current_index != 1 %}
|
||||
<li><a href="{{ ref.first }}">⇤</a></li>
|
||||
{% else %}
|
||||
<li class="disabled"><a href="{{ ref.first }}">⇤</a></li>
|
||||
{% endif %}
|
||||
|
||||
{% if ref.next %}
|
||||
<li><a href="{{ ref.previous }}">←</a></li>
|
||||
{% else %}
|
||||
<li class="disabled"><a href="#">←</a></li>
|
||||
{% endif %}
|
||||
|
||||
<li class="disabled"><a href="#">{{ ref.current_index }}/{{ ref.number_pagers }}</a></li>
|
||||
|
||||
{% if ref.next %}
|
||||
<li><a href="{{ ref.next }}">→</a></li>
|
||||
{% else %}
|
||||
<li class="disabled"><a href="#">→</a></li>
|
||||
{% endif %}
|
||||
|
||||
{% if ref.current_index != ref.number_pagers %}
|
||||
<li><a href="{{ ref.last }}">⇥</a></li>
|
||||
{% else %}
|
||||
<li class="disabled"><a href="{{ ref.last }}">⇥</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endmacro paginator %}
|
@ -1,67 +0,0 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ config.title}} - {{ page.title }}{% endblock title %}
|
||||
|
||||
{% block ogtitle %}{{ config.title}} - {{ page.title }}{% endblock ogtitle %}
|
||||
{% block ogdesc %}{{ page.description }}{% endblock ogdesc %}
|
||||
{% block ogurl %}{% if page.slug %}{{ config.base_url }}/{{ page.slug }}{% endif %}{% endblock ogurl %}
|
||||
{% block ogimg %}{% if page.extra.image %}{{ page.extra.image }}{% endif %}{% endblock ogimg %}
|
||||
|
||||
|
||||
{% block breadcrumb %}
|
||||
<p class="lead">
|
||||
<span>>></span>
|
||||
<a href="{{ config.base_url }}">Home</a>
|
||||
{% if page.taxonomies %}
|
||||
<span class="divider">/</span>
|
||||
{% if page.taxonomies.categories %}
|
||||
<a class="category" href="{{ get_taxonomy_url(kind="categories", name=page.taxonomies.categories[0]) }}">{{ page.taxonomies.categories[0] }}</a>
|
||||
{% endif %}
|
||||
{% if page.taxonomies.tags %}
|
||||
<span class="divider">/</span>
|
||||
{% for tag in page.taxonomies.tags %}
|
||||
<a href="{{ get_taxonomy_url(kind="tags", name=tag) }}">{{ tag }}</a>{% if page.taxonomies.tags | length > 1 %}{% if loop.index != page.taxonomies.tags | length %},{% endif %}{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endblock breadcrumb %}
|
||||
|
||||
{% block header %}
|
||||
<div class="page-header">
|
||||
<h1>{{ page.title }}</h1>
|
||||
</div>
|
||||
{% endblock header %}
|
||||
|
||||
{% block meta %}
|
||||
<p class="text-right">
|
||||
<span class="label label-success">
|
||||
∵
|
||||
{% if page.extra.author %}
|
||||
{{ page.extra.author }}
|
||||
{% else %}
|
||||
{{ config.extra.author }}
|
||||
{% endif %}
|
||||
</span>
|
||||
<span class="label label-success">∴ {{ page.date }}</span>
|
||||
<span class="label label-success">∞ {{ page.reading_time }}'</span>
|
||||
</p>
|
||||
{% endblock meta %}
|
||||
|
||||
{% block main %}
|
||||
{{ page.content | safe }}
|
||||
{% if config.extra.disqus and page.extra.comments %}
|
||||
<div id="disqus">
|
||||
<div id="disqus_thread"></div>
|
||||
<script>
|
||||
(function() { // DON'T EDIT BELOW THIS LINE
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'https://{{config.extra.disqus}}.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock main %}
|
@ -1,26 +0,0 @@
|
||||
{% if not width %}
|
||||
{% set width = 240 %}
|
||||
{% endif %}
|
||||
{% if not height %}
|
||||
{% if width %}
|
||||
{% set height = width %}
|
||||
{% else %}
|
||||
{% set height = 180 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if not op %}
|
||||
{% set op = 'fill' %}
|
||||
{% endif %}
|
||||
|
||||
{% if caption %}
|
||||
<figure>
|
||||
<a href="{{ get_url(path=path) }}"><img src="{{ resize_image(path=path, width=width, height=height, op=op) }}"/></a>
|
||||
<figcaption>{{ caption }}</figcaption>
|
||||
</figure>
|
||||
{% elif figure %}
|
||||
<figure>
|
||||
<img src="{{ resize_image(path=path, width=width, height=height, op=op) }}"/>
|
||||
</figure>
|
||||
{% else %}
|
||||
<img src="{{ resize_image(path=path, width=width, height=height, op=op) }}"/>
|
||||
{% endif %}
|
@ -1,19 +0,0 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ config.title }} - {{ config.extra.label_tags }}{% endblock title %}
|
||||
|
||||
{% block header %}
|
||||
<div class="page-header">
|
||||
<h1>{{ config.extra.label_tags }}</h1>
|
||||
</div>
|
||||
{% endblock header %}
|
||||
|
||||
{% block main %}
|
||||
<ul>
|
||||
{% for category in terms %}
|
||||
<li>
|
||||
<a href="{{ category.permalink }}">{{ category.name }}</a> ({{ category.pages | length }})
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock main %}
|
@ -1,17 +0,0 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ config.title }} - {{ config.extra.label_tags }}{% endblock title %}
|
||||
|
||||
{% block header %}
|
||||
<div class="page-header">
|
||||
<h1>{{ config.extra.label_tag }}: {{ term.name }}</h1>
|
||||
</div>
|
||||
{% endblock header %}
|
||||
|
||||
{% block main %}
|
||||
<ul>
|
||||
{% for page in term.pages %}
|
||||
<li>{{ macro::post_min(page=page) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock main %}
|
@ -1,10 +0,0 @@
|
||||
name = "zola.386"
|
||||
description = "Zola port of the BOOTSTRA.386 theme."
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/lopes/zola.386"
|
||||
min_version = "0.10.1"
|
||||
demo = "https://zola386.netlify.com"
|
||||
|
||||
[author]
|
||||
name = "José Lopes"
|
||||
homepage = "https://github.com/lopes"
|