generated from dellevin/template
新增阅读器功能,待优化
This commit is contained in:
2362
assets/foliate-js/src/book.js
Normal file
2362
assets/foliate-js/src/book.js
Normal file
File diff suppressed because it is too large
Load Diff
45
assets/foliate-js/src/comic-book.js
Normal file
45
assets/foliate-js/src/comic-book.js
Normal file
@@ -0,0 +1,45 @@
|
||||
export const makeComicBook = ({ entries, loadBlob, getSize }, file) => {
|
||||
const cache = new Map()
|
||||
const urls = new Map()
|
||||
const load = async name => {
|
||||
if (cache.has(name)) return cache.get(name)
|
||||
const src = URL.createObjectURL(await loadBlob(name))
|
||||
const page = URL.createObjectURL(
|
||||
new Blob([`<img src="${src}">`], { type: 'text/html' }))
|
||||
urls.set(name, [src, page])
|
||||
cache.set(name, page)
|
||||
return page
|
||||
}
|
||||
const unload = name => {
|
||||
urls.get(name)?.forEach?.(url => URL.revokeObjectURL(url))
|
||||
urls.delete(name)
|
||||
cache.delete(name)
|
||||
}
|
||||
|
||||
const exts = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.jxl', '.avif']
|
||||
const files = entries
|
||||
.map(entry => entry.filename)
|
||||
.filter(name => exts.some(ext => name.endsWith(ext)))
|
||||
.sort()
|
||||
if (!files.length) throw new Error('No supported image files in archive')
|
||||
|
||||
const book = {}
|
||||
book.getCover = () => loadBlob(files[0])
|
||||
book.metadata = { title: file.name }
|
||||
book.sections = files.map(name => ({
|
||||
id: name,
|
||||
load: () => load(name),
|
||||
unload: () => unload(name),
|
||||
size: getSize(name),
|
||||
}))
|
||||
book.toc = files.map(name => ({ label: name, href: name }))
|
||||
book.rendition = { layout: 'pre-paginated' }
|
||||
book.resolveHref = href => ({ index: book.sections.findIndex(s => s.id === href) })
|
||||
book.splitTOCHref = href => [href, null]
|
||||
book.getTOCFragment = doc => doc.documentElement
|
||||
book.destroy = () => {
|
||||
for (const arr of urls.values())
|
||||
for (const url of arr) URL.revokeObjectURL(url)
|
||||
}
|
||||
return book
|
||||
}
|
||||
241
assets/foliate-js/src/dict.js
Normal file
241
assets/foliate-js/src/dict.js
Normal file
@@ -0,0 +1,241 @@
|
||||
const decoder = new TextDecoder()
|
||||
const decode = decoder.decode.bind(decoder)
|
||||
|
||||
const concatTypedArray = (a, b) => {
|
||||
const result = new a.constructor(a.length + b.length)
|
||||
result.set(a)
|
||||
result.set(b, a.length)
|
||||
return result
|
||||
}
|
||||
|
||||
const strcmp = (a, b) => {
|
||||
a = a.toLowerCase(), b = b.toLowerCase()
|
||||
return a < b ? -1 : a > b ? 1 : 0
|
||||
}
|
||||
|
||||
class DictZip {
|
||||
#chlen
|
||||
#chunks
|
||||
#compressed
|
||||
inflate
|
||||
async load(file) {
|
||||
const header = new DataView(await file.slice(0, 12).arrayBuffer())
|
||||
if (header.getUint8(0) !== 31 || header.getUint8(1) !== 139
|
||||
|| header.getUint8(2) !== 8) throw new Error('Not a DictZip file')
|
||||
const flg = header.getUint8(3)
|
||||
if (!flg & 0b100) throw new Error('Missing FEXTRA flag')
|
||||
|
||||
const xlen = header.getUint16(10, true)
|
||||
const extra = new DataView(await file.slice(12, 12 + xlen).arrayBuffer())
|
||||
if (extra.getUint8(0) !== 82 || extra.getUint8(1) !== 65)
|
||||
throw new Error('Subfield ID should be RA')
|
||||
if (extra.getUint16(4, true) !== 1) throw new Error('Unsupported version')
|
||||
|
||||
this.#chlen = extra.getUint16(6, true)
|
||||
const chcnt = extra.getUint16(8, true)
|
||||
this.#chunks = []
|
||||
for (let i = 0, chunkOffset = 0; i < chcnt; i++) {
|
||||
const chunkSize = extra.getUint16(10 + 2 * i, true)
|
||||
this.#chunks.push([chunkOffset, chunkSize])
|
||||
chunkOffset = chunkOffset + chunkSize
|
||||
}
|
||||
|
||||
// skip to compressed data
|
||||
let offset = 12 + xlen
|
||||
const max = Math.min(offset + 512, file.size)
|
||||
const strArr = new Uint8Array(await file.slice(0, max).arrayBuffer())
|
||||
if (flg & 0b1000) { // fname
|
||||
const i = strArr.indexOf(0, offset)
|
||||
if (i < 0) throw new Error('Header too long')
|
||||
offset = i + 1
|
||||
}
|
||||
if (flg & 0b10000) { // fcomment
|
||||
const i = strArr.indexOf(0, offset)
|
||||
if (i < 0) throw new Error('Header too long')
|
||||
offset = i + 1
|
||||
}
|
||||
if (flg & 0b10) offset += 2 // fhcrc
|
||||
this.#compressed = file.slice(offset)
|
||||
}
|
||||
async read(offset, size) {
|
||||
const chunks = this.#chunks
|
||||
const startIndex = Math.trunc(offset / this.#chlen)
|
||||
const endIndex = Math.trunc((offset + size) / this.#chlen)
|
||||
const buf = await this.#compressed.slice(chunks[startIndex][0],
|
||||
chunks[endIndex][0] + chunks[endIndex][1]).arrayBuffer()
|
||||
let arr = new Uint8Array()
|
||||
for (let pos = 0, i = startIndex; i <= endIndex; i++) {
|
||||
const data = new Uint8Array(buf, pos, chunks[i][1])
|
||||
arr = concatTypedArray(arr, await this.inflate(data))
|
||||
pos += chunks[i][1]
|
||||
}
|
||||
const startOffset = offset - startIndex * this.#chlen
|
||||
return arr.subarray(startOffset, startOffset + size)
|
||||
}
|
||||
}
|
||||
|
||||
class Index {
|
||||
strcmp = strcmp
|
||||
// binary search
|
||||
bisect(query, start = 0, end = this.words.length - 1) {
|
||||
if (end - start === 1) {
|
||||
if (!this.strcmp(query, this.getWord(start))) return start
|
||||
if (!this.strcmp(query, this.getWord(end))) return end
|
||||
return null
|
||||
}
|
||||
const mid = Math.floor(start + (end - start) / 2)
|
||||
const cmp = this.strcmp(query, this.getWord(mid))
|
||||
if (cmp < 0) return this.bisect(query, start, mid)
|
||||
if (cmp > 0) return this.bisect(query, mid, end)
|
||||
return mid
|
||||
}
|
||||
// check for multiple definitions
|
||||
checkAdjacent(query, i) {
|
||||
if (i == null) return []
|
||||
let j = i
|
||||
const equals = i => {
|
||||
const word = this.getWord(i)
|
||||
return word ? this.strcmp(query, word) === 0 : false
|
||||
}
|
||||
while (equals(j - 1)) j--
|
||||
let k = i
|
||||
while (equals(k + 1)) k++
|
||||
return j === k ? [i] : Array.from({ length: k + 1 - j }, (_, i) => j + i)
|
||||
}
|
||||
lookup(query) {
|
||||
return this.checkAdjacent(query, this.bisect(query))
|
||||
}
|
||||
}
|
||||
|
||||
const decodeBase64Number = str => {
|
||||
const { length } = str
|
||||
let n = 0
|
||||
for (let i = 0; i < length; i++) {
|
||||
const c = str.charCodeAt(i)
|
||||
n += (c === 43 ? 62 // "+"
|
||||
: c === 47 ? 63 // "/"
|
||||
: c < 58 ? c + 4 // 0-9 -> 52-61
|
||||
: c < 91 ? c - 65 // A-Z -> 0-25
|
||||
: c - 71 // a-z -> 26-51
|
||||
) * 64 ** (length - 1 - i)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
class DictdIndex extends Index {
|
||||
getWord(i) {
|
||||
return this.words[i]
|
||||
}
|
||||
async load(file) {
|
||||
const words = []
|
||||
const offsets = []
|
||||
const sizes = []
|
||||
for (const line of decode(await file.arrayBuffer()).split('\n')) {
|
||||
const a = line.split('\t')
|
||||
words.push(a[0])
|
||||
offsets.push(decodeBase64Number(a[1]))
|
||||
sizes.push(decodeBase64Number(a[2]))
|
||||
}
|
||||
this.words = words
|
||||
this.offsets = offsets
|
||||
this.sizes = sizes
|
||||
}
|
||||
}
|
||||
|
||||
export class DictdDict {
|
||||
#dict = new DictZip()
|
||||
#idx = new DictdIndex()
|
||||
loadDict(file, inflate) {
|
||||
this.#dict.inflate = inflate
|
||||
return this.#dict.load(file)
|
||||
}
|
||||
async #readWord(i) {
|
||||
const word = this.#idx.getWord(i)
|
||||
const offset = this.#idx.offsets[i]
|
||||
const size = this.#idx.sizes[i]
|
||||
return { word, data: ['m', this.#dict.read(offset, size)] }
|
||||
}
|
||||
#readWords(arr) {
|
||||
return Promise.all(arr.map(this.#readWord.bind(this)))
|
||||
}
|
||||
lookup(query) {
|
||||
return this.#readWords(this.#idx.lookup(query))
|
||||
}
|
||||
}
|
||||
|
||||
class StarDictIndex extends Index {
|
||||
isSyn
|
||||
#arr
|
||||
getWord(i) {
|
||||
const word = this.words[i]
|
||||
if (!word) return
|
||||
return decode(this.#arr.subarray(word[0], word[1]))
|
||||
}
|
||||
async load(file) {
|
||||
const { isSyn } = this
|
||||
const buf = await file.arrayBuffer()
|
||||
const arr = new Uint8Array(buf)
|
||||
this.#arr = arr
|
||||
const view = new DataView(buf)
|
||||
const words = []
|
||||
const offsets = []
|
||||
const sizes = []
|
||||
for (let i = 0; i < arr.length;) {
|
||||
const newI = arr.subarray(0, i + 256).indexOf(0, i)
|
||||
if (newI < 0) throw new Error('Word too big')
|
||||
words.push([i, newI])
|
||||
offsets.push(view.getUint32(newI + 1))
|
||||
if (isSyn) i = newI + 5
|
||||
else {
|
||||
sizes.push(view.getUint32(newI + 5))
|
||||
i = newI + 9
|
||||
}
|
||||
}
|
||||
this.words = words
|
||||
this.offsets = offsets
|
||||
this.sizes = sizes
|
||||
}
|
||||
}
|
||||
|
||||
export class StarDict {
|
||||
#dict = new DictZip()
|
||||
#idx = new StarDictIndex()
|
||||
#syn = Object.assign(new StarDictIndex(), { isSyn: true })
|
||||
async loadIfo(file) {
|
||||
const str = decode(await file.arrayBuffer())
|
||||
this.ifo = Object.fromEntries(str.split('\n').map(line => {
|
||||
const sep = line.indexOf('=')
|
||||
if (sep < 0) return
|
||||
return [line.slice(0, sep), line.slice(sep + 1)]
|
||||
}).filter(x => x))
|
||||
}
|
||||
loadDict(file, inflate) {
|
||||
this.#dict.inflate = inflate
|
||||
return this.#dict.load(file)
|
||||
}
|
||||
loadIdx(file) {
|
||||
return this.#idx.load(file)
|
||||
}
|
||||
loadSyn(file) {
|
||||
if (file) return this.#syn.load(file)
|
||||
}
|
||||
async #readWord(i) {
|
||||
const word = this.#idx.getWord(i)
|
||||
const offset = this.#idx.offsets[i]
|
||||
const size = this.#idx.sizes[i]
|
||||
const data = await this.#dict.read(offset, size)
|
||||
const seq = this.ifo.sametypesequence
|
||||
if (!seq) throw new Error('TODO')
|
||||
if (seq.length === 1) return { word, data: [[seq[0], data]] }
|
||||
throw new Error('TODO')
|
||||
}
|
||||
#readWords(arr) {
|
||||
return Promise.all(arr.map(this.#readWord.bind(this)))
|
||||
}
|
||||
lookup(query) {
|
||||
return this.#readWords(this.#idx.lookup(query))
|
||||
}
|
||||
synonyms(query) {
|
||||
return this.#readWords(this.#syn.lookup(query).map(i => this.#syn.offsets[i]))
|
||||
}
|
||||
}
|
||||
1162
assets/foliate-js/src/epub.js
Normal file
1162
assets/foliate-js/src/epub.js
Normal file
File diff suppressed because it is too large
Load Diff
345
assets/foliate-js/src/epubcfi.js
Normal file
345
assets/foliate-js/src/epubcfi.js
Normal file
@@ -0,0 +1,345 @@
|
||||
const findIndices = (arr, f) => arr
|
||||
.map((x, i, a) => f(x, i, a) ? i : null).filter(x => x != null)
|
||||
const splitAt = (arr, is) => [-1, ...is, arr.length].reduce(({ xs, a }, b) =>
|
||||
({ xs: xs?.concat([arr.slice(a + 1, b)]) ?? [], a: b }), {}).xs
|
||||
const concatArrays = (a, b) =>
|
||||
a.slice(0, -1).concat([a[a.length - 1].concat(b[0])]).concat(b.slice(1))
|
||||
|
||||
const isNumber = /\d/
|
||||
export const isCFI = /^epubcfi\((.*)\)$/
|
||||
const escapeCFI = str => str.replace(/[\^[\](),;=]/g, '^$&')
|
||||
|
||||
const wrap = x => isCFI.test(x) ? x : `epubcfi(${x})`
|
||||
const unwrap = x => x.match(isCFI)?.[1] ?? x
|
||||
const lift = f => (...xs) =>
|
||||
`epubcfi(${f(...xs.map(x => x.match(isCFI)?.[1] ?? x))})`
|
||||
export const joinIndir = lift((...xs) => xs.join('!'))
|
||||
|
||||
const tokenizer = str => {
|
||||
const tokens = []
|
||||
let state, escape, value = ''
|
||||
const push = x => (tokens.push(x), state = null, value = '')
|
||||
const cat = x => (value += x, escape = false)
|
||||
for (const char of Array.from(str.trim()).concat('')) {
|
||||
if (char === '^' && !escape) {
|
||||
escape = true
|
||||
continue
|
||||
}
|
||||
if (state === '!') push(['!'])
|
||||
else if (state === ',') push([','])
|
||||
else if (state === '/' || state === ':') {
|
||||
if (isNumber.test(char)) {
|
||||
cat(char)
|
||||
continue
|
||||
} else push([state, parseInt(value)])
|
||||
} else if (state === '~') {
|
||||
if (isNumber.test(char) || char === '.') {
|
||||
cat(char)
|
||||
continue
|
||||
} else push(['~', parseFloat(value)])
|
||||
} else if (state === '@') {
|
||||
if (char === ':') {
|
||||
push(['@', parseFloat(value)])
|
||||
state = '@'
|
||||
continue
|
||||
}
|
||||
if (isNumber.test(char) || char === '.') {
|
||||
cat(char)
|
||||
continue
|
||||
} else push(['@', parseFloat(value)])
|
||||
} else if (state === '[') {
|
||||
if (char === ';' && !escape) {
|
||||
push(['[', value])
|
||||
state = ';'
|
||||
} else if (char === ',' && !escape) {
|
||||
push(['[', value])
|
||||
state = '['
|
||||
} else if (char === ']' && !escape) push(['[', value])
|
||||
else cat(char)
|
||||
continue
|
||||
} else if (state?.startsWith(';')) {
|
||||
if (char === '=' && !escape) {
|
||||
state = `;${value}`
|
||||
value = ''
|
||||
} else if (char === ';' && !escape) {
|
||||
push([state, value])
|
||||
state = ';'
|
||||
} else if (char === ']' && !escape) push([state, value])
|
||||
else cat(char)
|
||||
continue
|
||||
}
|
||||
if (char === '/' || char === ':' || char === '~' || char === '@'
|
||||
|| char === '[' || char === '!' || char === ',') state = char
|
||||
}
|
||||
return tokens
|
||||
}
|
||||
|
||||
const findTokens = (tokens, x) => findIndices(tokens, ([t]) => t === x)
|
||||
|
||||
const parser = tokens => {
|
||||
const parts = []
|
||||
let state
|
||||
for (const [type, val] of tokens) {
|
||||
if (type === '/') parts.push({ index: val })
|
||||
else {
|
||||
const last = parts[parts.length - 1]
|
||||
if (type === ':') last.offset = val
|
||||
else if (type === '~') last.temporal = val
|
||||
else if (type === '@') last.spatial = (last.spatial ?? []).concat(val)
|
||||
else if (type === ';s') last.side = val
|
||||
else if (type === '[') {
|
||||
if (state === '/' && val) last.id = val
|
||||
else {
|
||||
last.text = (last.text ?? []).concat(val)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
state = type
|
||||
}
|
||||
return parts
|
||||
}
|
||||
|
||||
// split at step indirections, then parse each part
|
||||
const parserIndir = tokens =>
|
||||
splitAt(tokens, findTokens(tokens, '!')).map(parser)
|
||||
|
||||
export const parse = cfi => {
|
||||
const tokens = tokenizer(unwrap(cfi))
|
||||
const commas = findTokens(tokens, ',')
|
||||
if (!commas.length) return parserIndir(tokens)
|
||||
const [parent, start, end] = splitAt(tokens, commas).map(parserIndir)
|
||||
return { parent, start, end }
|
||||
}
|
||||
|
||||
const partToString = ({ index, id, offset, temporal, spatial, text, side }) => {
|
||||
const param = side ? `;s=${side}` : ''
|
||||
return `/${index}`
|
||||
+ (id ? `[${escapeCFI(id)}${param}]` : '')
|
||||
// "CFI expressions [..] SHOULD include an explicit character offset"
|
||||
+ (offset != null && index % 2 ? `:${offset}` : '')
|
||||
+ (temporal ? `~${temporal}` : '')
|
||||
+ (spatial ? `@${spatial.join(':')}` : '')
|
||||
+ (text || (!id && side) ? '['
|
||||
+ (text?.map(escapeCFI)?.join(',') ?? '')
|
||||
+ param + ']' : '')
|
||||
}
|
||||
|
||||
const toInnerString = parsed => parsed.parent
|
||||
? [parsed.parent, parsed.start, parsed.end].map(toInnerString).join(',')
|
||||
: parsed.map(parts => parts.map(partToString).join('')).join('!')
|
||||
|
||||
const toString = parsed => wrap(toInnerString(parsed))
|
||||
|
||||
export const collapse = (x, toEnd) => typeof x === 'string'
|
||||
? toString(collapse(parse(x), toEnd))
|
||||
: x.parent ? concatArrays(x.parent, x[toEnd ? 'end' : 'start']) : x
|
||||
|
||||
// create range CFI from two CFIs
|
||||
const buildRange = (from, to) => {
|
||||
if (typeof from === 'string') from = parse(from)
|
||||
if (typeof to === 'string') to = parse(to)
|
||||
from = collapse(from)
|
||||
to = collapse(to, true)
|
||||
// ranges across multiple documents are not allowed; handle local paths only
|
||||
const localFrom = from[from.length - 1], localTo = to[to.length - 1]
|
||||
const localParent = [], localStart = [], localEnd = []
|
||||
let pushToParent = true
|
||||
const len = Math.max(localFrom.length, localTo.length)
|
||||
for (let i = 0; i < len; i++) {
|
||||
const a = localFrom[i], b = localTo[i]
|
||||
pushToParent &&= a?.index === b?.index && !a?.offset && !b?.offset
|
||||
if (pushToParent) localParent.push(a)
|
||||
else {
|
||||
if (a) localStart.push(a)
|
||||
if (b) localEnd.push(b)
|
||||
}
|
||||
}
|
||||
// copy non-local paths from `from`
|
||||
const parent = from.slice(0, -1).concat([localParent])
|
||||
return toString({ parent, start: [localStart], end: [localEnd] })
|
||||
}
|
||||
|
||||
export const compare = (a, b) => {
|
||||
if (typeof a === 'string') a = parse(a)
|
||||
if (typeof b === 'string') b = parse(b)
|
||||
if (a.start || b.start) return compare(collapse(a), collapse(b))
|
||||
|| compare(collapse(a, true), collapse(b, true))
|
||||
|
||||
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
||||
const p = a[i], q = b[i]
|
||||
const maxIndex = Math.max(p.length, q.length) - 1
|
||||
for (let i = 0; i <= maxIndex; i++) {
|
||||
const x = p[i], y = q[i]
|
||||
if (!x) return -1
|
||||
if (!y) return 1
|
||||
if (x.index > y.index) return 1
|
||||
if (x.index < y.index) return -1
|
||||
if (i === maxIndex) {
|
||||
// TODO: compare temporal & spatial offsets
|
||||
if (x.offset > y.offset) return 1
|
||||
if (x.offset < y.offset) return -1
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
const isTextNode = ({ nodeType }) => nodeType === 3 || nodeType === 4
|
||||
const isElementNode = ({ nodeType }) => nodeType === 1
|
||||
|
||||
const getChildNodes = (node, filter) => {
|
||||
const nodes = Array.from(node.childNodes)
|
||||
// "content other than element and character data is ignored"
|
||||
.filter(node => isTextNode(node) || isElementNode(node))
|
||||
return filter ? nodes.map(node => {
|
||||
const accept = filter(node)
|
||||
if (accept === NodeFilter.FILTER_REJECT) return null
|
||||
else if (accept === NodeFilter.FILTER_SKIP) return getChildNodes(node, filter)
|
||||
else return node
|
||||
}).flat().filter(x => x) : nodes
|
||||
}
|
||||
|
||||
// child nodes are organized such that the result is always
|
||||
// [element, text, element, text, ..., element],
|
||||
// regardless of the actual structure in the document;
|
||||
// so multiple text nodes need to be combined, and nonexistent ones counted;
|
||||
// see "Step Reference to Child Element or Character Data (/)" in EPUB CFI spec
|
||||
const indexChildNodes = (node, filter) => {
|
||||
const nodes = getChildNodes(node, filter)
|
||||
.reduce((arr, node) => {
|
||||
let last = arr[arr.length - 1]
|
||||
if (!last) arr.push(node)
|
||||
// "there is one chunk between each pair of child elements"
|
||||
else if (isTextNode(node)) {
|
||||
if (Array.isArray(last)) last.push(node)
|
||||
else if (isTextNode(last)) arr[arr.length - 1] = [last, node]
|
||||
else arr.push(node)
|
||||
} else {
|
||||
if (isElementNode(last)) arr.push(null, node)
|
||||
else arr.push(node)
|
||||
}
|
||||
return arr
|
||||
}, [])
|
||||
// "the first chunk is located before the first child element"
|
||||
if (isElementNode(nodes[0])) nodes.unshift('first')
|
||||
// "the last chunk is located after the last child element"
|
||||
if (isElementNode(nodes[nodes.length - 1])) nodes.push('last')
|
||||
// "'virtual' elements"
|
||||
nodes.unshift('before') // "0 is a valid index"
|
||||
nodes.push('after') // "n+2 is a valid index"
|
||||
return nodes
|
||||
}
|
||||
|
||||
const partsToNode = (node, parts, filter) => {
|
||||
const { id } = parts[parts.length - 1]
|
||||
if (id) {
|
||||
const el = node.ownerDocument.getElementById(id)
|
||||
if (el) return { node: el, offset: 0 }
|
||||
}
|
||||
for (const { index } of parts) {
|
||||
const newNode = node ? indexChildNodes(node, filter)[index] : null
|
||||
// handle non-existent nodes
|
||||
if (newNode === 'first') return { node: node.firstChild ?? node }
|
||||
if (newNode === 'last') return { node: node.lastChild ?? node }
|
||||
if (newNode === 'before') return { node, before: true }
|
||||
if (newNode === 'after') return { node, after: true }
|
||||
node = newNode
|
||||
}
|
||||
const { offset } = parts[parts.length - 1]
|
||||
if (!Array.isArray(node)) return { node, offset }
|
||||
// get underlying text node and offset from the chunk
|
||||
let sum = 0
|
||||
for (const n of node) {
|
||||
const { length } = n.nodeValue
|
||||
if (sum + length >= offset) return { node: n, offset: offset - sum }
|
||||
sum += length
|
||||
}
|
||||
}
|
||||
|
||||
const nodeToParts = (node, offset, filter) => {
|
||||
const { parentNode, id } = node
|
||||
const indexed = indexChildNodes(parentNode, filter)
|
||||
const index = indexed.findIndex(x =>
|
||||
Array.isArray(x) ? x.some(x => x === node) : x === node)
|
||||
// adjust offset as if merging the text nodes in the chunk
|
||||
const chunk = indexed[index]
|
||||
if (Array.isArray(chunk)) {
|
||||
let sum = 0
|
||||
for (const x of chunk) {
|
||||
if (x === node) {
|
||||
sum += offset
|
||||
break
|
||||
} else sum += x.nodeValue.length
|
||||
}
|
||||
offset = sum
|
||||
}
|
||||
const part = { id, index, offset }
|
||||
return (parentNode !== node.ownerDocument.documentElement
|
||||
? nodeToParts(parentNode, null, filter).concat(part) : [part])
|
||||
// remove ignored nodes
|
||||
.filter(x => x.index !== -1)
|
||||
}
|
||||
|
||||
export const fromRange = (range, filter) => {
|
||||
const { startContainer, startOffset, endContainer, endOffset } = range
|
||||
const start = nodeToParts(startContainer, startOffset, filter)
|
||||
if (range.collapsed) return toString([start])
|
||||
const end = nodeToParts(endContainer, endOffset, filter)
|
||||
return buildRange([start], [end])
|
||||
}
|
||||
|
||||
export const toRange = (doc, parts, filter) => {
|
||||
const startParts = collapse(parts)
|
||||
const endParts = collapse(parts, true)
|
||||
|
||||
const root = doc.documentElement
|
||||
const start = partsToNode(root, startParts[0], filter)
|
||||
const end = partsToNode(root, endParts[0], filter)
|
||||
|
||||
const range = doc.createRange()
|
||||
|
||||
if (start.before) range.setStartBefore(start.node)
|
||||
else if (start.after) range.setStartAfter(start.node)
|
||||
else range.setStart(start.node, start.offset)
|
||||
|
||||
if (end.before) range.setEndBefore(end.node)
|
||||
else if (end.after) range.setEndAfter(end.node)
|
||||
else range.setEnd(end.node, end.offset)
|
||||
return range
|
||||
}
|
||||
|
||||
// faster way of getting CFIs for sorted elements in a single parent
|
||||
export const fromElements = elements => {
|
||||
const results = []
|
||||
const { parentNode } = elements[0]
|
||||
const parts = nodeToParts(parentNode)
|
||||
for (const [index, node] of indexChildNodes(parentNode).entries()) {
|
||||
const el = elements[results.length]
|
||||
if (node === el)
|
||||
results.push(toString([parts.concat({ id: el.id, index })]))
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
export const toElement = (doc, parts) =>
|
||||
partsToNode(doc.documentElement, collapse(parts)).node
|
||||
|
||||
// turn indices into standard CFIs when you don't have an actual package document
|
||||
export const fake = {
|
||||
fromIndex: index => wrap(`/6/${(index + 1) * 2}`),
|
||||
toIndex: parts => parts?.at(-1).index / 2 - 1,
|
||||
}
|
||||
|
||||
// get CFI from Calibre bookmarks
|
||||
// see https://github.com/johnfactotum/foliate/issues/849
|
||||
export const fromCalibrePos = pos => {
|
||||
const [parts] = parse(pos)
|
||||
const item = parts.shift()
|
||||
parts.shift()
|
||||
return toString([[{ index: 6 }, item], parts])
|
||||
}
|
||||
export const fromCalibreHighlight = ({ spine_index, start_cfi, end_cfi }) => {
|
||||
const pre = fake.fromIndex(spine_index) + '!'
|
||||
return buildRange(pre + start_cfi.slice(2), pre + end_cfi.slice(2))
|
||||
}
|
||||
347
assets/foliate-js/src/fb2.js
Normal file
347
assets/foliate-js/src/fb2.js
Normal file
@@ -0,0 +1,347 @@
|
||||
const normalizeWhitespace = str => str ? str
|
||||
.replace(/[\t\n\f\r ]+/g, ' ')
|
||||
.replace(/^[\t\n\f\r ]+/, '')
|
||||
.replace(/[\t\n\f\r ]+$/, '') : ''
|
||||
const getElementText = el => normalizeWhitespace(el?.textContent)
|
||||
|
||||
const NS = {
|
||||
XLINK: 'http://www.w3.org/1999/xlink',
|
||||
EPUB: 'http://www.idpf.org/2007/ops',
|
||||
}
|
||||
|
||||
const MIME = {
|
||||
XML: 'application/xml',
|
||||
XHTML: 'application/xhtml+xml',
|
||||
}
|
||||
|
||||
const STYLE = {
|
||||
'strong': ['strong', 'self'],
|
||||
'emphasis': ['em', 'self'],
|
||||
'style': ['span', 'self'],
|
||||
'a': 'anchor',
|
||||
'strikethrough': ['s', 'self'],
|
||||
'sub': ['sub', 'self'],
|
||||
'sup': ['sup', 'self'],
|
||||
'code': ['code', 'self'],
|
||||
'image': 'image',
|
||||
}
|
||||
|
||||
const TABLE = {
|
||||
'tr': ['tr', ['align']],
|
||||
'th': ['th', ['colspan', 'rowspan', 'align', 'valign']],
|
||||
'td': ['td', ['colspan', 'rowspan', 'align', 'valign']],
|
||||
}
|
||||
|
||||
const POEM = {
|
||||
'epigraph': ['blockquote'],
|
||||
'subtitle': ['h2', STYLE],
|
||||
'text-author': ['p', STYLE],
|
||||
'date': ['p', STYLE],
|
||||
'stanza': 'stanza',
|
||||
}
|
||||
|
||||
const SECTION = {
|
||||
'title': ['header', {
|
||||
'p': ['h1', STYLE],
|
||||
'empty-line': ['br'],
|
||||
}],
|
||||
'epigraph': ['blockquote', 'self'],
|
||||
'image': 'image',
|
||||
'annotation': ['aside'],
|
||||
'section': ['section', 'self'],
|
||||
'p': ['p', STYLE],
|
||||
'poem': ['blockquote', POEM],
|
||||
'subtitle': ['h2', STYLE],
|
||||
'cite': ['blockquote', 'self'],
|
||||
'empty-line': ['br'],
|
||||
'table': ['table', TABLE],
|
||||
'text-author': ['p', STYLE],
|
||||
}
|
||||
POEM['epigraph'].push(SECTION)
|
||||
|
||||
const BODY = {
|
||||
'image': 'image',
|
||||
'title': ['section', {
|
||||
'p': ['h1', STYLE],
|
||||
'empty-line': ['br'],
|
||||
}],
|
||||
'epigraph': ['section', SECTION],
|
||||
'section': ['section', SECTION],
|
||||
}
|
||||
|
||||
const getImageSrc = el => {
|
||||
const href = el.getAttributeNS(NS.XLINK, 'href')
|
||||
const [, id] = href.split('#')
|
||||
const bin = el.getRootNode().getElementById(id)
|
||||
return bin
|
||||
? `data:${bin.getAttribute('content-type')};base64,${bin.textContent}`
|
||||
: href
|
||||
}
|
||||
|
||||
class FB2Converter {
|
||||
constructor(fb2) {
|
||||
this.fb2 = fb2
|
||||
this.doc = document.implementation.createDocument(NS.XHTML, 'html')
|
||||
}
|
||||
image(node) {
|
||||
const el = this.doc.createElement('img')
|
||||
el.alt = node.getAttribute('alt')
|
||||
el.title = node.getAttribute('title')
|
||||
el.setAttribute('src', getImageSrc(node))
|
||||
return el
|
||||
}
|
||||
anchor(node) {
|
||||
const el = this.convert(node, { 'a': ['a', STYLE] })
|
||||
el.setAttribute('href', node.getAttributeNS(NS.XLINK, 'href'))
|
||||
if (node.getAttribute('type') === 'note')
|
||||
el.setAttributeNS(NS.EPUB, 'epub:type', 'noteref')
|
||||
return el
|
||||
}
|
||||
stanza(node) {
|
||||
const el = this.convert(node, {
|
||||
'stanza': ['p', {
|
||||
'title': ['header', {
|
||||
'p': ['strong', STYLE],
|
||||
'empty-line': ['br'],
|
||||
}],
|
||||
'subtitle': ['p', STYLE],
|
||||
}],
|
||||
})
|
||||
for (const child of node.children) if (child.nodeName === 'v') {
|
||||
el.append(this.doc.createTextNode(child.textContent))
|
||||
el.append(this.doc.createElement('br'))
|
||||
}
|
||||
return el
|
||||
}
|
||||
convert(node, def) {
|
||||
// not an element; return text content
|
||||
if (node.nodeType === 3) return this.doc.createTextNode(node.textContent)
|
||||
if (node.nodeType === 4) return this.doc.createCDATASection(node.textContent)
|
||||
if (node.nodeType === 8) return this.doc.createComment(node.textContent)
|
||||
|
||||
const d = def?.[node.nodeName]
|
||||
if (!d) return null
|
||||
if (typeof d === 'string') return this[d](node)
|
||||
|
||||
const [name, opts] = d
|
||||
const el = this.doc.createElement(name)
|
||||
|
||||
// copy the ID, and set class name from original element name
|
||||
if (node.id) el.id = node.id
|
||||
el.classList.add(node.nodeName)
|
||||
|
||||
// copy attributes
|
||||
if (Array.isArray(opts)) for (const attr of opts)
|
||||
el.setAttribute(attr, node.getAttribute(attr))
|
||||
|
||||
// process child elements recursively
|
||||
const childDef = opts === 'self' ? def : Array.isArray(opts) ? null : opts
|
||||
let child = node.firstChild
|
||||
while (child) {
|
||||
const childEl = this.convert(child, childDef)
|
||||
if (childEl) el.append(childEl)
|
||||
child = child.nextSibling
|
||||
}
|
||||
return el
|
||||
}
|
||||
}
|
||||
|
||||
const parseXML = async blob => {
|
||||
const buffer = await blob.arrayBuffer()
|
||||
const str = new TextDecoder('utf-8').decode(buffer)
|
||||
const parser = new DOMParser()
|
||||
const doc = parser.parseFromString(str, MIME.XML)
|
||||
const encoding = doc.xmlEncoding
|
||||
// `Document.xmlEncoding` is deprecated, and already removed in Firefox
|
||||
// so parse the XML declaration manually
|
||||
|| str.match(/^<\?xml\s+version\s*=\s*["']1.\d+"\s+encoding\s*=\s*["']([A-Za-z0-9._-]*)["']/)?.[1]
|
||||
if (encoding && encoding.toLowerCase() !== 'utf-8') {
|
||||
const str = new TextDecoder(encoding).decode(buffer)
|
||||
return parser.parseFromString(str, MIME.XML)
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
const style = URL.createObjectURL(new Blob([`
|
||||
@namespace epub "http://www.idpf.org/2007/ops";
|
||||
body > img, section > img {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
.title h1 {
|
||||
text-align: center;
|
||||
}
|
||||
body > section > .title, body.notesBodyType > .title {
|
||||
margin: 3em 0;
|
||||
}
|
||||
body.notesBodyType > section .title h1 {
|
||||
text-align: start;
|
||||
}
|
||||
body.notesBodyType > section .title {
|
||||
margin: 1em 0;
|
||||
}
|
||||
p {
|
||||
text-indent: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
:not(p) + p, p:first-child {
|
||||
text-indent: 0;
|
||||
}
|
||||
.poem p {
|
||||
text-indent: 0;
|
||||
margin: 1em 0;
|
||||
}
|
||||
.text-author, .date {
|
||||
text-align: end;
|
||||
}
|
||||
.text-author:before {
|
||||
content: "—";
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
td, th {
|
||||
padding: .25em;
|
||||
}
|
||||
a[epub|type~="noteref"] {
|
||||
font-size: .75em;
|
||||
vertical-align: super;
|
||||
}
|
||||
body:not(.notesBodyType) > .title, body:not(.notesBodyType) > .epigraph {
|
||||
margin: 3em 0;
|
||||
}
|
||||
`], { type: 'text/css' }))
|
||||
|
||||
const template = html => `<?xml version="1.0" encoding="utf-8"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head><link href="${style}" rel="stylesheet" type="text/css"/></head>
|
||||
<body>${html}</body>
|
||||
</html>`
|
||||
|
||||
// name of custom ID attribute for TOC items
|
||||
const dataID = 'data-foliate-id'
|
||||
|
||||
export const makeFB2 = async blob => {
|
||||
const book = {}
|
||||
const doc = await parseXML(blob)
|
||||
const converter = new FB2Converter(doc)
|
||||
|
||||
const $ = x => doc.querySelector(x)
|
||||
const $$ = x => [...doc.querySelectorAll(x)]
|
||||
const getPerson = el => {
|
||||
const nick = getElementText(el.querySelector('nickname'))
|
||||
if (nick) return nick
|
||||
const first = getElementText(el.querySelector('first-name'))
|
||||
const middle = getElementText(el.querySelector('middle-name'))
|
||||
const last = getElementText(el.querySelector('last-name'))
|
||||
const name = [first, middle, last].filter(x => x).join(' ')
|
||||
const sortAs = last
|
||||
? [last, [first, middle].filter(x => x).join(' ')].join(', ')
|
||||
: null
|
||||
return { name, sortAs }
|
||||
}
|
||||
const getDate = el => el?.getAttribute('value') ?? getElementText(el)
|
||||
const annotation = $('title-info annotation')
|
||||
book.metadata = {
|
||||
title: getElementText($('title-info book-title')),
|
||||
identifier: getElementText($('document-info id')),
|
||||
language: getElementText($('title-info lang')),
|
||||
author: $$('title-info author').map(getPerson),
|
||||
translator: $$('title-info translator').map(getPerson),
|
||||
producer: $$('document-info author').map(getPerson)
|
||||
.concat($$('document-info program-used').map(getElementText)),
|
||||
publisher: getElementText($('publish-info publisher')),
|
||||
published: getDate($('title-info date')),
|
||||
modified: getDate($('document-info date')),
|
||||
description: annotation ? converter.convert(annotation,
|
||||
{ annotation: ['div', SECTION] }).innerHTML : null,
|
||||
subject: $$('title-info genre').map(getElementText),
|
||||
}
|
||||
if ($('coverpage image')) {
|
||||
const src = getImageSrc($('coverpage image'))
|
||||
book.getCover = () => fetch(src).then(res => res.blob())
|
||||
} else book.getCover = () => null
|
||||
|
||||
// get convert each body
|
||||
const bodyData = Array.from(doc.querySelectorAll('body'), body => {
|
||||
const converted = converter.convert(body, { body: ['body', BODY] })
|
||||
return [Array.from(converted.children, el => {
|
||||
// get list of IDs in the section
|
||||
const ids = [el, ...el.querySelectorAll('[id]')].map(el => el.id)
|
||||
return { el, ids }
|
||||
}), converted]
|
||||
})
|
||||
|
||||
const urls = []
|
||||
const sectionData = bodyData[0][0]
|
||||
// make a separate section for each section in the first body
|
||||
.map(({ el, ids }) => {
|
||||
// set up titles for TOC
|
||||
const titles = Array.from(
|
||||
el.querySelectorAll(':scope > section > .title'),
|
||||
(el, index) => {
|
||||
el.setAttribute(dataID, index)
|
||||
return { title: getElementText(el), index }
|
||||
})
|
||||
return { ids, titles, el }
|
||||
})
|
||||
// for additional bodies, only make one section for each body
|
||||
.concat(bodyData.slice(1).map(([sections, body]) => {
|
||||
const ids = sections.map(s => s.ids).flat()
|
||||
body.classList.add('notesBodyType')
|
||||
return { ids, el: body, linear: 'no' }
|
||||
}))
|
||||
.map(({ ids, titles, el, linear }) => {
|
||||
const str = template(el.outerHTML)
|
||||
const blob = new Blob([str], { type: MIME.XHTML })
|
||||
const url = URL.createObjectURL(blob)
|
||||
urls.push(url)
|
||||
const title = normalizeWhitespace(
|
||||
el.querySelector('.title, .subtitle, p')?.textContent
|
||||
?? (el.classList.contains('title') ? el.textContent : ''))
|
||||
return {
|
||||
ids, title, titles, load: () => url,
|
||||
createDocument: () => new DOMParser().parseFromString(str, MIME.XHTML),
|
||||
// doo't count image data as it'd skew the size too much
|
||||
size: blob.size - Array.from(el.querySelectorAll('[src]'),
|
||||
el => el.getAttribute('src')?.length ?? 0)
|
||||
.reduce((a, b) => a + b, 0),
|
||||
linear,
|
||||
}
|
||||
})
|
||||
|
||||
const idMap = new Map()
|
||||
book.sections = sectionData.map((section, index) => {
|
||||
const { ids, load, createDocument, size, linear } = section
|
||||
for (const id of ids) if (id) idMap.set(id, index)
|
||||
return { id: index, load, createDocument, size, linear }
|
||||
})
|
||||
|
||||
book.toc = sectionData.map(({ title, titles }, index) => {
|
||||
const id = index.toString()
|
||||
return {
|
||||
label: title,
|
||||
href: id,
|
||||
subitems: titles?.length ? titles.map(({ title, index }) => ({
|
||||
label: title,
|
||||
href: `${id}#${index}`,
|
||||
})) : null,
|
||||
}
|
||||
}).filter(item => item)
|
||||
|
||||
book.resolveHref = href => {
|
||||
const [a, b] = href.split('#')
|
||||
return a
|
||||
// the link is from the TOC
|
||||
? { index: Number(a), anchor: doc => doc.querySelector(`[${dataID}="${b}"]`) }
|
||||
// link from within the page
|
||||
: { index: idMap.get(b), anchor: doc => doc.getElementById(b) }
|
||||
}
|
||||
book.splitTOCHref = href => href?.split('#')?.map(x => Number(x)) ?? []
|
||||
book.getTOCFragment = (doc, id) => doc.querySelector(`[${dataID}="${id}"]`)
|
||||
|
||||
book.destroy = () => {
|
||||
for (const url of urls) URL.revokeObjectURL(url)
|
||||
}
|
||||
return book
|
||||
}
|
||||
297
assets/foliate-js/src/fixed-layout.js
Normal file
297
assets/foliate-js/src/fixed-layout.js
Normal file
@@ -0,0 +1,297 @@
|
||||
const parseViewport = str => str
|
||||
?.split(/[,;\s]/) // NOTE: technically, only the comma is valid
|
||||
?.filter(x => x)
|
||||
?.map(x => x.split('=').map(x => x.trim()))
|
||||
|
||||
const getViewport = (doc, viewport) => {
|
||||
// use `viewBox` for SVG
|
||||
if (doc.documentElement.localName === 'svg') {
|
||||
const [, , width, height] = doc.documentElement
|
||||
.getAttribute('viewBox')?.split(/\s/) ?? []
|
||||
return { width, height }
|
||||
}
|
||||
|
||||
// get `viewport` `meta` element
|
||||
const meta = parseViewport(doc.querySelector('meta[name="viewport"]')
|
||||
?.getAttribute('content'))
|
||||
if (meta) return Object.fromEntries(meta)
|
||||
|
||||
// fallback to book's viewport
|
||||
if (typeof viewport === 'string') return parseViewport(viewport)
|
||||
if (viewport) return viewport
|
||||
|
||||
// if no viewport (possibly with image directly in spine), get image size
|
||||
const img = doc.querySelector('img')
|
||||
if (img) return { width: img.naturalWidth, height: img.naturalHeight }
|
||||
|
||||
// just show *something*, i guess...
|
||||
console.warn(new Error('Missing viewport properties'))
|
||||
return { width: 1000, height: 2000 }
|
||||
}
|
||||
|
||||
export class FixedLayout extends HTMLElement {
|
||||
#root = this.attachShadow({ mode: 'closed' })
|
||||
#observer = new ResizeObserver(() => this.#render())
|
||||
#spreads
|
||||
#index = -1
|
||||
defaultViewport
|
||||
spread
|
||||
#portrait = false
|
||||
#left
|
||||
#right
|
||||
#center
|
||||
#side
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
const sheet = new CSSStyleSheet()
|
||||
this.#root.adoptedStyleSheets = [sheet]
|
||||
sheet.replaceSync(`:host {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}`)
|
||||
|
||||
this.#observer.observe(this)
|
||||
}
|
||||
async #createFrame(position, { index, src }) {
|
||||
const element = document.createElement('div')
|
||||
const iframe = document.createElement('iframe')
|
||||
element.append(iframe)
|
||||
Object.assign(iframe.style, {
|
||||
border: '0',
|
||||
display: 'none',
|
||||
overflow: 'hidden',
|
||||
})
|
||||
// `allow-scripts` is needed for events because of WebKit bug
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=218086
|
||||
iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts')
|
||||
iframe.setAttribute('scrolling', 'no')
|
||||
iframe.setAttribute('part', 'filter')
|
||||
this.#root.append(element)
|
||||
if (!src) return { blank: true, element, iframe }
|
||||
return new Promise(resolve => {
|
||||
const onload = () => {
|
||||
iframe.removeEventListener('load', onload)
|
||||
const doc = iframe.contentDocument
|
||||
doc.position = position
|
||||
this.dispatchEvent(new CustomEvent('load', { detail: { doc, index } }))
|
||||
const { width, height } = getViewport(doc, this.defaultViewport)
|
||||
resolve({
|
||||
element, iframe,
|
||||
width: parseFloat(width),
|
||||
height: parseFloat(height),
|
||||
})
|
||||
}
|
||||
iframe.addEventListener('load', onload)
|
||||
iframe.src = src
|
||||
})
|
||||
}
|
||||
#render(side = this.#side) {
|
||||
if (!side) return
|
||||
const left = this.#left ?? {}
|
||||
const right = this.#center ?? this.#right
|
||||
const target = side === 'left' ? left : right
|
||||
const { width, height } = this.getBoundingClientRect()
|
||||
const portrait = this.spread !== 'both' && this.spread !== 'portrait'
|
||||
&& height > width
|
||||
this.#portrait = portrait
|
||||
const blankWidth = left.width ?? right.width
|
||||
const blankHeight = left.height ?? right.height
|
||||
|
||||
const scale = portrait || this.#center
|
||||
? Math.min(
|
||||
width / (target.width ?? blankWidth),
|
||||
height / (target.height ?? blankHeight))
|
||||
: Math.min(
|
||||
width / ((left.width ?? blankWidth) + (right.width ?? blankWidth)),
|
||||
height / Math.max(
|
||||
left.height ?? blankHeight,
|
||||
right.height ?? blankHeight))
|
||||
|
||||
const transform = frame => {
|
||||
const { element, iframe, width, height, blank } = frame
|
||||
iframe.contentDocument.scale = scale
|
||||
Object.assign(iframe.style, {
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
transform: `scale(${scale})`,
|
||||
transformOrigin: 'top left',
|
||||
display: blank ? 'none' : 'block',
|
||||
})
|
||||
Object.assign(element.style, {
|
||||
width: `${(width ?? blankWidth) * scale}px`,
|
||||
height: `${(height ?? blankHeight) * scale}px`,
|
||||
overflow: 'hidden',
|
||||
display: 'block',
|
||||
})
|
||||
if (portrait && frame !== target) {
|
||||
element.style.display = 'none'
|
||||
}
|
||||
}
|
||||
if (this.#center) {
|
||||
transform(this.#center)
|
||||
} else {
|
||||
transform(left)
|
||||
transform(right)
|
||||
}
|
||||
}
|
||||
async #showSpread({ left, right, center, side }) {
|
||||
this.#root.replaceChildren()
|
||||
this.#left = null
|
||||
this.#right = null
|
||||
this.#center = null
|
||||
if (center) {
|
||||
this.#center = await this.#createFrame('center', center)
|
||||
this.#side = 'center'
|
||||
this.#render()
|
||||
} else {
|
||||
this.#left = await this.#createFrame('left', left)
|
||||
this.#right = await this.#createFrame('right', right)
|
||||
this.#side = this.#left.blank ? 'right'
|
||||
: this.#right.blank ? 'left' : side
|
||||
this.#render()
|
||||
}
|
||||
}
|
||||
#goLeft() {
|
||||
if (this.#center || this.#left?.blank) return
|
||||
if (this.#portrait && this.#left?.element?.style?.display === 'none') {
|
||||
this.#right.element.style.display = 'none'
|
||||
this.#left.element.style.display = 'block'
|
||||
this.#side = 'left'
|
||||
return true
|
||||
}
|
||||
}
|
||||
#goRight() {
|
||||
if (this.#center || this.#right?.blank) return
|
||||
if (this.#portrait && this.#right?.element?.style?.display === 'none') {
|
||||
this.#left.element.style.display = 'none'
|
||||
this.#right.element.style.display = 'block'
|
||||
this.#side = 'right'
|
||||
return true
|
||||
}
|
||||
}
|
||||
open(book) {
|
||||
this.book = book
|
||||
const { rendition } = book
|
||||
this.spread = rendition?.spread
|
||||
this.defaultViewport = rendition?.viewport
|
||||
|
||||
const rtl = book.dir === 'rtl'
|
||||
const ltr = !rtl
|
||||
this.rtl = rtl
|
||||
|
||||
if (rendition?.spread === 'none')
|
||||
this.#spreads = book.sections.map(section => ({ center: section }))
|
||||
else this.#spreads = book.sections.reduce((arr, section) => {
|
||||
const last = arr[arr.length - 1]
|
||||
const { linear, pageSpread } = section
|
||||
if (linear === 'no') return arr
|
||||
const newSpread = () => {
|
||||
const spread = {}
|
||||
arr.push(spread)
|
||||
return spread
|
||||
}
|
||||
if (pageSpread === 'center') {
|
||||
const spread = last.left || last.right ? newSpread() : last
|
||||
spread.center = section
|
||||
}
|
||||
else if (pageSpread === 'left') {
|
||||
const spread = last.center || last.left || ltr ? newSpread() : last
|
||||
spread.left = section
|
||||
}
|
||||
else if (pageSpread === 'right') {
|
||||
const spread = last.center || last.right || rtl ? newSpread() : last
|
||||
spread.right = section
|
||||
}
|
||||
else if (ltr) {
|
||||
if (last.center || last.right) newSpread().left = section
|
||||
else if (last.left) last.right = section
|
||||
else last.left = section
|
||||
}
|
||||
else {
|
||||
if (last.center || last.left) newSpread().right = section
|
||||
else if (last.right) last.left = section
|
||||
else last .right = section
|
||||
}
|
||||
return arr
|
||||
}, [{}])
|
||||
}
|
||||
get index() {
|
||||
const spread = this.#spreads[this.#index]
|
||||
const section = spread?.center ?? (this.side === 'left'
|
||||
? spread.left ?? spread.right : spread.right ?? spread.left)
|
||||
return this.book.sections.indexOf(section)
|
||||
}
|
||||
#reportLocation(reason) {
|
||||
this.dispatchEvent(new CustomEvent('relocate', { detail:
|
||||
{ reason, range: null, index: this.index, fraction: 0, size: 1 } }))
|
||||
}
|
||||
getSpreadOf(section) {
|
||||
const spreads = this.#spreads
|
||||
for (let index = 0; index < spreads.length; index++) {
|
||||
const { left, right, center } = spreads[index]
|
||||
if (left === section) return { index, side: 'left' }
|
||||
if (right === section) return { index, side: 'right' }
|
||||
if (center === section) return { index, side: 'center' }
|
||||
}
|
||||
}
|
||||
async goToSpread(index, side, reason) {
|
||||
if (index < 0 || index > this.#spreads.length - 1) return
|
||||
if (index === this.#index) {
|
||||
this.#render(side)
|
||||
return
|
||||
}
|
||||
this.#index = index
|
||||
const spread = this.#spreads[index]
|
||||
if (spread.center) {
|
||||
const index = this.book.sections.indexOf(spread.center)
|
||||
const src = await spread.center?.load?.()
|
||||
await this.#showSpread({ center: { index, src } })
|
||||
} else {
|
||||
const indexL = this.book.sections.indexOf(spread.left)
|
||||
const indexR = this.book.sections.indexOf(spread.right)
|
||||
const srcL = await spread.left?.load?.()
|
||||
const srcR = await spread.right?.load?.()
|
||||
const left = { index: indexL, src: srcL }
|
||||
const right = { index: indexR, src: srcR }
|
||||
await this.#showSpread({ left, right, side })
|
||||
}
|
||||
this.#reportLocation(reason)
|
||||
}
|
||||
async select(target) {
|
||||
await this.goTo(target)
|
||||
// TODO
|
||||
}
|
||||
async goTo(target) {
|
||||
const { book } = this
|
||||
const resolved = await target
|
||||
const section = book.sections[resolved.index]
|
||||
if (!section) return
|
||||
const { index, side } = this.getSpreadOf(section)
|
||||
await this.goToSpread(index, side)
|
||||
}
|
||||
async next() {
|
||||
const s = this.rtl ? this.#goLeft() : this.#goRight()
|
||||
if (s) this.#reportLocation('page')
|
||||
else return this.goToSpread(this.#index + 1, this.rtl ? 'right' : 'left', 'page')
|
||||
}
|
||||
async prev() {
|
||||
const s = this.rtl ? this.#goRight() : this.#goLeft()
|
||||
if (s) this.#reportLocation('page')
|
||||
else return this.goToSpread(this.#index - 1, this.rtl ? 'left' : 'right', 'page')
|
||||
}
|
||||
getContents() {
|
||||
return Array.from(this.#root.querySelectorAll('iframe'), frame => ({
|
||||
doc: frame.contentDocument,
|
||||
// TODO: index, overlayer
|
||||
}))
|
||||
}
|
||||
destroy() {
|
||||
this.#observer.unobserve(this)
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('foliate-fxl', FixedLayout)
|
||||
99
assets/foliate-js/src/footnotes.js
Normal file
99
assets/foliate-js/src/footnotes.js
Normal file
@@ -0,0 +1,99 @@
|
||||
const getTypes = el => new Set(el?.getAttributeNS?.('http://www.idpf.org/2007/ops', 'type')?.split(' '))
|
||||
const getRoles = el => new Set(el?.getAttribute?.('role')?.split(' '))
|
||||
|
||||
const isSuper = el => {
|
||||
const { verticalAlign } = getComputedStyle(el)
|
||||
return verticalAlign === 'super' || /^\d/.test(verticalAlign)
|
||||
}
|
||||
|
||||
const refTypes = ['biblioref', 'glossref', 'noteref']
|
||||
const refRoles = ['doc-biblioref', 'doc-glossref', 'doc-noteref']
|
||||
const isFootnoteReference = a => {
|
||||
const types = getTypes(a)
|
||||
const roles = getRoles(a)
|
||||
return {
|
||||
yes: refRoles.some(r => roles.has(r)) || refTypes.some(t => types.has(t)),
|
||||
maybe: () => !types.has('backlink') && !roles.has('doc-backlink')
|
||||
&& (isSuper(a) || a.children.length === 1 && isSuper(a.children[0])
|
||||
|| isSuper(a.parentElement)),
|
||||
}
|
||||
}
|
||||
|
||||
const getReferencedType = el => {
|
||||
const types = getTypes(el)
|
||||
const roles = getRoles(el)
|
||||
return roles.has('doc-biblioentry') || types.has('biblioentry') ? 'biblioentry'
|
||||
: roles.has('definition') || types.has('glossdef') ? 'definition'
|
||||
: roles.has('doc-endnote') || types.has('endnote') || types.has('rearnote') ? 'endnote'
|
||||
: roles.has('doc-footnote') || types.has('footnote') ? 'footnote'
|
||||
: roles.has('note') || types.has('note') ? 'note' : null
|
||||
}
|
||||
|
||||
const isInline = 'a, span, sup, sub, em, strong, i, b, small, big'
|
||||
const extractFootnote = (doc, anchor) => {
|
||||
let el = anchor(doc)
|
||||
const target = el
|
||||
while (el.matches(isInline)) {
|
||||
const parent = el.parentElement
|
||||
if (!parent) break
|
||||
el = parent
|
||||
}
|
||||
if (el === doc.body) {
|
||||
const sibling = target.nextElementSibling
|
||||
if (sibling && !sibling.matches(isInline)) return sibling
|
||||
throw new Error('Failed to extract footnote')
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
export class FootnoteHandler extends EventTarget {
|
||||
detectFootnotes = true
|
||||
#showFragment(book, { index, anchor }, href) {
|
||||
const view = document.createElement('foliate-view')
|
||||
return new Promise((resolve, reject) => {
|
||||
view.addEventListener('load', e => {
|
||||
try {
|
||||
const { doc } = e.detail
|
||||
const el = anchor(doc)
|
||||
const type = getReferencedType(el)
|
||||
const hidden = el?.matches?.('aside') && type === 'footnote'
|
||||
if (el) {
|
||||
const range = el.startContainer ? el : doc.createRange()
|
||||
if (!el.startContainer) {
|
||||
if (el.matches('li, aside')) range.selectNodeContents(el)
|
||||
else range.selectNode(el)
|
||||
}
|
||||
const frag = range.extractContents()
|
||||
doc.body.replaceChildren()
|
||||
doc.body.appendChild(frag)
|
||||
}
|
||||
const detail = { view, href, type, hidden, target: el }
|
||||
this.dispatchEvent(new CustomEvent('render', { detail }))
|
||||
resolve()
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
view.open(book)
|
||||
.then(() => this.dispatchEvent(new CustomEvent('before-render', { detail: { view } })))
|
||||
.then(() => view.goTo(index))
|
||||
.catch(reject)
|
||||
})
|
||||
}
|
||||
handle(book, e) {
|
||||
const { a, href } = e.detail
|
||||
const { yes, maybe } = isFootnoteReference(a)
|
||||
if (yes) {
|
||||
e.preventDefault()
|
||||
return Promise.resolve(book.resolveHref(href)).then(target =>
|
||||
this.#showFragment(book, target, href))
|
||||
}
|
||||
else if (this.detectFootnotes && maybe()) {
|
||||
e.preventDefault()
|
||||
return Promise.resolve(book.resolveHref(href)).then(({ index, anchor }) => {
|
||||
const target = { index, anchor: doc => extractFootnote(doc, anchor) }
|
||||
return this.#showFragment(book, target, href)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
1216
assets/foliate-js/src/mobi.js
Normal file
1216
assets/foliate-js/src/mobi.js
Normal file
File diff suppressed because it is too large
Load Diff
282
assets/foliate-js/src/opds.js
Normal file
282
assets/foliate-js/src/opds.js
Normal file
@@ -0,0 +1,282 @@
|
||||
const NS = {
|
||||
ATOM: 'http://www.w3.org/2005/Atom',
|
||||
OPDS: 'http://opds-spec.org/2010/catalog',
|
||||
THR: 'http://purl.org/syndication/thread/1.0',
|
||||
DC: 'http://purl.org/dc/elements/1.1/',
|
||||
DCTERMS: 'http://purl.org/dc/terms/',
|
||||
}
|
||||
|
||||
const MIME = {
|
||||
ATOM: 'application/atom+xml',
|
||||
OPDS2: 'application/opds+json',
|
||||
}
|
||||
|
||||
export const REL = {
|
||||
ACQ: 'http://opds-spec.org/acquisition',
|
||||
FACET: 'http://opds-spec.org/facet',
|
||||
GROUP: 'http://opds-spec.org/group',
|
||||
COVER: [
|
||||
'http://opds-spec.org/image',
|
||||
'http://opds-spec.org/cover',
|
||||
],
|
||||
THUMBNAIL: [
|
||||
'http://opds-spec.org/image/thumbnail',
|
||||
'http://opds-spec.org/thumbnail',
|
||||
],
|
||||
}
|
||||
|
||||
export const SYMBOL = {
|
||||
SUMMARY: Symbol('summary'),
|
||||
CONTENT: Symbol('content'),
|
||||
}
|
||||
|
||||
const FACET_GROUP = Symbol('facetGroup')
|
||||
|
||||
const groupByArray = (arr, f) => {
|
||||
const map = new Map()
|
||||
if (arr) for (const el of arr) {
|
||||
const keys = f(el)
|
||||
for (const key of [keys].flat()) {
|
||||
const group = map.get(key)
|
||||
if (group) group.push(el)
|
||||
else map.set(key, [el])
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
// https://www.rfc-editor.org/rfc/rfc7231#section-3.1.1
|
||||
const parseMediaType = str => {
|
||||
if (!str) return null
|
||||
const [mediaType, ...ps] = str.split(/ *; */)
|
||||
return {
|
||||
mediaType: mediaType.toLowerCase(),
|
||||
parameters: Object.fromEntries(ps.map(p => {
|
||||
const [name, val] = p.split('=')
|
||||
return [name.toLowerCase(), val?.replace(/(^"|"$)/g, '')]
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
export const isOPDSCatalog = str => {
|
||||
const parsed = parseMediaType(str)
|
||||
if (!parsed) return false
|
||||
const { mediaType, parameters } = parsed
|
||||
if (mediaType === MIME.OPDS2) return true
|
||||
return mediaType === MIME.ATOM && parameters.profile?.toLowerCase() === 'opds-catalog'
|
||||
}
|
||||
|
||||
// ignore the namespace if it doesn't appear in document at all
|
||||
const useNS = (doc, ns) =>
|
||||
doc.lookupNamespaceURI(null) === ns || doc.lookupPrefix(ns) ? ns : null
|
||||
|
||||
const filterNS = ns => ns
|
||||
? name => el => el.namespaceURI === ns && el.localName === name
|
||||
: name => el => el.localName === name
|
||||
|
||||
const getContent = el => {
|
||||
if (!el) return
|
||||
const type = el.getAttribute('type') ?? 'text'
|
||||
const value = type === 'xhtml' ? el.innerHTML
|
||||
: type === 'html' ? el.textContent
|
||||
.replaceAll('<', '<')
|
||||
.replaceAll('>', '>')
|
||||
.replaceAll('&', '&')
|
||||
: el.textContent
|
||||
return { value, type }
|
||||
}
|
||||
|
||||
const getTextContent = el => {
|
||||
const content = getContent(el)
|
||||
if (content?.type === 'text') return content?.value
|
||||
}
|
||||
|
||||
const getSummary = (a, b) => getTextContent(a) ?? getTextContent(b)
|
||||
|
||||
const getPrice = link => {
|
||||
const price = link.getElementsByTagNameNS(NS.OPDS, 'price')[0]
|
||||
return price ? {
|
||||
currency: price.getAttribute('currencycode'),
|
||||
value: price.textContent,
|
||||
} : null
|
||||
}
|
||||
|
||||
const getIndirectAcquisition = el => {
|
||||
const ia = el.getElementsByTagNameNS(NS.OPDS, 'indirectAcquisition')[0]
|
||||
if (!ia) return []
|
||||
return [{ type: ia.getAttribute('type') }, ...getIndirectAcquisition(ia)]
|
||||
}
|
||||
|
||||
const getLink = link => {
|
||||
const obj = {
|
||||
rel: link.getAttribute('rel')?.split(/ +/),
|
||||
href: link.getAttribute('href'),
|
||||
type: link.getAttribute('type'),
|
||||
title: link.getAttribute('title'),
|
||||
properties: {
|
||||
price: getPrice(link),
|
||||
indirectAcquisition: getIndirectAcquisition(link),
|
||||
numberOfItems: link.getAttributeNS(NS.THR, 'count'),
|
||||
},
|
||||
[FACET_GROUP]: link.getAttributeNS(NS.OPDS, 'facetGroup'),
|
||||
}
|
||||
if (link.getAttributeNS(NS.OPDS, 'activeFacet') === 'true')
|
||||
obj.rel = [obj.rel ?? []].flat().concat('self')
|
||||
return obj
|
||||
}
|
||||
|
||||
export const getPublication = entry => {
|
||||
const filter = filterNS(useNS(entry.ownerDocument, NS.ATOM))
|
||||
const children = Array.from(entry.children)
|
||||
const filterDCEL = filterNS(NS.DC)
|
||||
const filterDCTERMS = filterNS(NS.DCTERMS)
|
||||
const filterDC = x => {
|
||||
const a = filterDCEL(x), b = filterDCTERMS(x)
|
||||
return y => a(y) || b(y)
|
||||
}
|
||||
const links = children.filter(filter('link')).map(getLink)
|
||||
const linksByRel = groupByArray(links, link => link.rel)
|
||||
return {
|
||||
metadata: {
|
||||
title: children.find(filter('title'))?.textContent ?? '',
|
||||
author: children.filter(filter('author')).map(person => {
|
||||
const NS = person.namespaceURI
|
||||
const uri = person.getElementsByTagNameNS(NS, 'uri')[0]?.textContent
|
||||
return {
|
||||
name: person.getElementsByTagNameNS(NS, 'name')[0]?.textContent ?? '',
|
||||
links: uri ? [{ href: uri }] : [],
|
||||
}
|
||||
}),
|
||||
publisher: children.find(filterDC('publisher'))?.textContent,
|
||||
published: (children.find(filterDCTERMS('issued'))
|
||||
?? children.find(filterDC('date')))?.textContent,
|
||||
language: children.find(filterDC('language'))?.textContent,
|
||||
identifier: children.find(filterDC('identifier'))?.textContent,
|
||||
subject: children.filter(filter('category')).map(category => ({
|
||||
name: category.getAttribute('label'),
|
||||
code: category.getAttribute('term'),
|
||||
})),
|
||||
[SYMBOL.CONTENT]: getContent(children.find(filter('content'))
|
||||
?? children.find(filter('summary'))),
|
||||
},
|
||||
links,
|
||||
images: REL.COVER.concat(REL.THUMBNAIL)
|
||||
.map(R => linksByRel.get(R)?.[0]).filter(x => x),
|
||||
}
|
||||
}
|
||||
|
||||
export const getFeed = doc => {
|
||||
const ns = useNS(doc, NS.ATOM)
|
||||
const filter = filterNS(ns)
|
||||
const children = Array.from(doc.documentElement.children)
|
||||
const entries = children.filter(filter('entry'))
|
||||
const links = children.filter(filter('link')).map(getLink)
|
||||
const linksByRel = groupByArray(links, link => link.rel)
|
||||
|
||||
const groupedItems = new Map([[null, []]])
|
||||
const groupLinkMap = new Map()
|
||||
for (const entry of entries) {
|
||||
const children = Array.from(entry.children)
|
||||
const links = children.filter(filter('link')).map(getLink)
|
||||
const linksByRel = groupByArray(links, link => link.rel)
|
||||
const isPub = [...linksByRel.keys()]
|
||||
.some(rel => rel?.startsWith(REL.ACQ) || rel === 'preview')
|
||||
|
||||
const groupLinks = linksByRel.get(REL.GROUP) ?? linksByRel.get('collection')
|
||||
const groupLink = groupLinks?.length
|
||||
? groupLinks.find(link => groupedItems.has(link.href)) ?? groupLinks[0] : null
|
||||
if (groupLink && !groupLinkMap.has(groupLink.href))
|
||||
groupLinkMap.set(groupLink.href, groupLink)
|
||||
|
||||
const item = isPub
|
||||
? getPublication(entry)
|
||||
: Object.assign(links.find(link => isOPDSCatalog(link.type)) ?? links[0] ?? {}, {
|
||||
title: children.find(filter('title'))?.textContent,
|
||||
[SYMBOL.SUMMARY]: getSummary(children.find(filter('summary')),
|
||||
children.find(filter('content'))),
|
||||
})
|
||||
|
||||
const arr = groupedItems.get(groupLink?.href ?? null)
|
||||
if (arr) arr.push(item)
|
||||
else groupedItems.set(groupLink.href, [item])
|
||||
}
|
||||
const [items, ...groups] = Array.from(groupedItems, ([key, items]) => {
|
||||
const itemsKey = items[0]?.metadata ? 'publications' : 'navigation'
|
||||
if (key == null) return { [itemsKey]: items }
|
||||
const link = groupLinkMap.get(key)
|
||||
return {
|
||||
metadata: {
|
||||
title: link.title,
|
||||
numberOfItems: link.properties.numberOfItems,
|
||||
},
|
||||
links: [{ rel: 'self', href: link.href, type: link.type }],
|
||||
[itemsKey]: items,
|
||||
}
|
||||
})
|
||||
return {
|
||||
metadata: {
|
||||
title: children.find(filter('title'))?.textContent,
|
||||
subtitle: children.find(filter('subtitle'))?.textContent,
|
||||
},
|
||||
links,
|
||||
...items,
|
||||
groups,
|
||||
facets: Array.from(
|
||||
groupByArray(linksByRel.get(REL.FACET) ?? [], link => link[FACET_GROUP]),
|
||||
([facet, links]) => ({ metadata: { title: facet }, links })),
|
||||
}
|
||||
}
|
||||
|
||||
export const getSearch = async link => {
|
||||
const { replace, getVariables } = await import('./uri-template.js')
|
||||
return {
|
||||
metadata: {
|
||||
title: link.title,
|
||||
},
|
||||
search: map => replace(link.href, map.get(null)),
|
||||
params: Array.from(getVariables(link.href), name => ({ name })),
|
||||
}
|
||||
}
|
||||
|
||||
export const getOpenSearch = doc => {
|
||||
const defaultNS = doc.documentElement.namespaceURI
|
||||
const filter = filterNS(defaultNS)
|
||||
const children = Array.from(doc.documentElement.children)
|
||||
|
||||
const $$urls = children.filter(filter('Url'))
|
||||
const $url = $$urls.find(url => isOPDSCatalog(url.getAttribute('type'))) ?? $$urls[0]
|
||||
if (!$url) throw new Error('document must contain at least one Url element')
|
||||
|
||||
const regex = /{(?:([^}]+?):)?(.+?)(\?)?}/g
|
||||
const defaultMap = new Map([
|
||||
['count', '100'],
|
||||
['startIndex', $url.getAttribute('indexOffset') ?? '0'],
|
||||
['startPage', $url.getAttribute('pageOffset') ?? '0'],
|
||||
['language', '*'],
|
||||
['inputEncoding', 'UTF-8'],
|
||||
['outputEncoding', 'UTF-8'],
|
||||
])
|
||||
|
||||
const template = $url.getAttribute('template')
|
||||
return {
|
||||
metadata: {
|
||||
title: (children.find(filter('LongName')) ?? children.find(filter('ShortName')))?.textContent,
|
||||
description: children.find(filter('Description'))?.textContent,
|
||||
},
|
||||
search: map => template.replace(regex, (_, prefix, param) => {
|
||||
const namespace = prefix ? $url.lookupNamespaceURI(prefix) : null
|
||||
const ns = namespace === defaultNS ? null : namespace
|
||||
const val = map.get(ns)?.get(param)
|
||||
return encodeURIComponent(val ? val : (!ns ? defaultMap.get(param) ?? '' : ''))
|
||||
}),
|
||||
params: Array.from(template.matchAll(regex), ([, prefix, param, optional]) => {
|
||||
const namespace = prefix ? $url.lookupNamespaceURI(prefix) : null
|
||||
const ns = namespace === defaultNS ? null : namespace
|
||||
return {
|
||||
ns, name: param,
|
||||
required: !optional,
|
||||
value: ns && ns !== defaultNS ? '' : defaultMap.get(param) ?? '',
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
227
assets/foliate-js/src/overlayer.js
Normal file
227
assets/foliate-js/src/overlayer.js
Normal file
@@ -0,0 +1,227 @@
|
||||
const createSVGElement = tag =>
|
||||
document.createElementNS('http://www.w3.org/2000/svg', tag)
|
||||
|
||||
export class Overlayer {
|
||||
#svg = createSVGElement('svg')
|
||||
#map = new Map()
|
||||
#doc = null
|
||||
constructor(doc) {
|
||||
this.#doc = doc
|
||||
Object.assign(this.#svg.style, {
|
||||
position: 'absolute', top: '0', left: '0',
|
||||
width: '100%', height: '100%',
|
||||
pointerEvents: 'none',
|
||||
})
|
||||
}
|
||||
get element() {
|
||||
return this.#svg
|
||||
}
|
||||
get #zoom() {
|
||||
// Safari does not zoom the client rects, while Chrome, Edge and Firefox does
|
||||
if (/^((?!chrome|android).)*AppleWebKit/i.test(navigator.userAgent) && !window.chrome) {
|
||||
return window.getComputedStyle(this.#doc.body).zoom || 1.0
|
||||
}
|
||||
return 1.0
|
||||
}
|
||||
#splitRangeByParagraph(range) {
|
||||
const ancestor = range.commonAncestorContainer
|
||||
const paragraphs = Array.from(ancestor.querySelectorAll?.('p, h1, h2, h3, h4') || [])
|
||||
|
||||
const splitRanges = []
|
||||
paragraphs.forEach((p) => {
|
||||
const pRange = document.createRange()
|
||||
if (range.intersectsNode(p)) {
|
||||
pRange.selectNodeContents(p)
|
||||
if (pRange.compareBoundaryPoints(Range.START_TO_START, range) < 0) {
|
||||
pRange.setStart(range.startContainer, range.startOffset)
|
||||
}
|
||||
if (pRange.compareBoundaryPoints(Range.END_TO_END, range) > 0) {
|
||||
pRange.setEnd(range.endContainer, range.endOffset)
|
||||
}
|
||||
splitRanges.push(pRange)
|
||||
}
|
||||
})
|
||||
return splitRanges.length === 0 ? [range] : splitRanges
|
||||
}
|
||||
add(key, range, draw, options) {
|
||||
if (this.#map.has(key)) this.remove(key)
|
||||
if (typeof range === 'function') range = range(this.#svg.getRootNode())
|
||||
const zoom = this.#zoom
|
||||
let rects = []
|
||||
this.#splitRangeByParagraph(range).forEach((pRange) => {
|
||||
const pRects = Array.from(pRange.getClientRects()).map(rect => ({
|
||||
left: rect.left * zoom,
|
||||
top: rect.top * zoom,
|
||||
right: rect.right * zoom,
|
||||
bottom: rect.bottom * zoom,
|
||||
width: rect.width * zoom,
|
||||
height: rect.height * zoom,
|
||||
}))
|
||||
rects = rects.concat(pRects)
|
||||
})
|
||||
const element = draw(rects, options)
|
||||
this.#svg.append(element)
|
||||
this.#map.set(key, { range, draw, options, element, rects })
|
||||
}
|
||||
remove(key) {
|
||||
if (!this.#map.has(key)) return
|
||||
this.#svg.removeChild(this.#map.get(key).element)
|
||||
this.#map.delete(key)
|
||||
}
|
||||
redraw() {
|
||||
for (const obj of this.#map.values()) {
|
||||
const { range, draw, options, element } = obj
|
||||
this.#svg.removeChild(element)
|
||||
const zoom = this.#zoom
|
||||
let rects = []
|
||||
this.#splitRangeByParagraph(range).forEach((pRange) => {
|
||||
const pRects = Array.from(pRange.getClientRects()).map(rect => ({
|
||||
left: rect.left * zoom,
|
||||
top: rect.top * zoom,
|
||||
right: rect.right * zoom,
|
||||
bottom: rect.bottom * zoom,
|
||||
width: rect.width * zoom,
|
||||
height: rect.height * zoom,
|
||||
}))
|
||||
rects = rects.concat(pRects)
|
||||
})
|
||||
const el = draw(rects, options)
|
||||
this.#svg.append(el)
|
||||
obj.element = el
|
||||
obj.rects = rects
|
||||
}
|
||||
}
|
||||
hitTest({ x, y }) {
|
||||
const arr = Array.from(this.#map.entries())
|
||||
// loop in reverse to hit more recently added items first
|
||||
for (let i = arr.length - 1; i >= 0; i--) {
|
||||
const [key, obj] = arr[i]
|
||||
for (const { left, top, right, bottom } of obj.rects)
|
||||
if (top <= y && left <= x && bottom > y && right > x)
|
||||
return [key, obj.range]
|
||||
}
|
||||
return []
|
||||
}
|
||||
static underline(rects, options = {}) {
|
||||
const { color = 'red', width: strokeWidth = 2, padding = 0, writingMode } = options
|
||||
const g = createSVGElement('g')
|
||||
g.setAttribute('fill', color)
|
||||
if (writingMode === 'vertical-rl' || writingMode === 'vertical-lr')
|
||||
for (const { right, top, height } of rects) {
|
||||
const el = createSVGElement('rect')
|
||||
el.setAttribute('x', right - strokeWidth / 2 + padding)
|
||||
el.setAttribute('y', top)
|
||||
el.setAttribute('height', height)
|
||||
el.setAttribute('width', strokeWidth)
|
||||
g.append(el)
|
||||
}
|
||||
else for (const { left, bottom, width } of rects) {
|
||||
const el = createSVGElement('rect')
|
||||
el.setAttribute('x', left)
|
||||
el.setAttribute('y', bottom - strokeWidth / 2 + padding)
|
||||
el.setAttribute('height', strokeWidth)
|
||||
el.setAttribute('width', width)
|
||||
g.append(el)
|
||||
}
|
||||
return g
|
||||
}
|
||||
static strikethrough(rects, options = {}) {
|
||||
const { color = 'red', width: strokeWidth = 2, writingMode } = options
|
||||
const g = createSVGElement('g')
|
||||
g.setAttribute('fill', color)
|
||||
if (writingMode === 'vertical-rl' || writingMode === 'vertical-lr')
|
||||
for (const { right, left, top, height } of rects) {
|
||||
const el = createSVGElement('rect')
|
||||
el.setAttribute('x', (right + left) / 2)
|
||||
el.setAttribute('y', top)
|
||||
el.setAttribute('height', height)
|
||||
el.setAttribute('width', strokeWidth)
|
||||
g.append(el)
|
||||
}
|
||||
else for (const { left, top, bottom, width } of rects) {
|
||||
const el = createSVGElement('rect')
|
||||
el.setAttribute('x', left)
|
||||
el.setAttribute('y', (top + bottom) / 2)
|
||||
el.setAttribute('height', strokeWidth)
|
||||
el.setAttribute('width', width)
|
||||
g.append(el)
|
||||
}
|
||||
return g
|
||||
}
|
||||
static squiggly(rects, options = {}) {
|
||||
const { color = 'red', width: strokeWidth = 2, padding = 0, writingMode } = options
|
||||
const g = createSVGElement('g')
|
||||
g.setAttribute('fill', 'none')
|
||||
g.setAttribute('stroke', color)
|
||||
g.setAttribute('stroke-width', strokeWidth)
|
||||
const block = strokeWidth * 1.5
|
||||
if (writingMode === 'vertical-rl' || writingMode === 'vertical-lr')
|
||||
for (const { right, top, height } of rects) {
|
||||
const el = createSVGElement('path')
|
||||
const n = Math.round(height / block / 1.5)
|
||||
const inline = height / n
|
||||
const ls = Array.from({ length: n },
|
||||
(_, i) => `l${i % 2 ? -block : block} ${inline}`).join('')
|
||||
el.setAttribute('d', `M${right - strokeWidth / 2 + padding} ${top}${ls}`)
|
||||
g.append(el)
|
||||
}
|
||||
else for (const { left, bottom, width } of rects) {
|
||||
const el = createSVGElement('path')
|
||||
const n = Math.round(width / block / 1.5)
|
||||
const inline = width / n
|
||||
const ls = Array.from({ length: n },
|
||||
(_, i) => `l${inline} ${i % 2 ? block : -block}`).join('')
|
||||
el.setAttribute('d', `M${left} ${bottom + strokeWidth / 2 + padding}${ls}`)
|
||||
g.append(el)
|
||||
}
|
||||
return g
|
||||
}
|
||||
static highlight(rects, options = {}) {
|
||||
const { color = 'red', padding = 0 } = options
|
||||
const g = createSVGElement('g')
|
||||
g.setAttribute('fill', color)
|
||||
g.style.opacity = 'var(--overlayer-highlight-opacity, .3)'
|
||||
g.style.mixBlendMode = 'var(--overlayer-highlight-blend-mode, normal)'
|
||||
for (const { left, top, height, width } of rects) {
|
||||
const el = createSVGElement('rect')
|
||||
el.setAttribute('x', left - padding)
|
||||
el.setAttribute('y', top - padding)
|
||||
el.setAttribute('height', height + padding * 2)
|
||||
el.setAttribute('width', width + padding * 2)
|
||||
g.append(el)
|
||||
}
|
||||
return g
|
||||
}
|
||||
static outline(rects, options = {}) {
|
||||
const { color = 'red', width: strokeWidth = 3, padding = 0, radius = 3 } = options
|
||||
const g = createSVGElement('g')
|
||||
g.setAttribute('fill', 'none')
|
||||
g.setAttribute('stroke', color)
|
||||
g.setAttribute('stroke-width', strokeWidth)
|
||||
for (const { left, top, height, width } of rects) {
|
||||
const el = createSVGElement('rect')
|
||||
el.setAttribute('x', left - padding)
|
||||
el.setAttribute('y', top - padding)
|
||||
el.setAttribute('height', height + padding * 2)
|
||||
el.setAttribute('width', width + padding * 2)
|
||||
el.setAttribute('rx', radius)
|
||||
g.append(el)
|
||||
}
|
||||
return g
|
||||
}
|
||||
// make an exact copy of an image in the overlay
|
||||
// one can then apply filters to the entire element, without affecting them;
|
||||
// it's a bit silly and probably better to just invert images twice
|
||||
// (though the color will be off in that case if you do heu-rotate)
|
||||
static copyImage([rect], options = {}) {
|
||||
const { src } = options
|
||||
const image = createSVGElement('image')
|
||||
const { left, top, height, width } = rect
|
||||
image.setAttribute('href', src)
|
||||
image.setAttribute('x', left)
|
||||
image.setAttribute('y', top)
|
||||
image.setAttribute('height', height)
|
||||
image.setAttribute('width', width)
|
||||
return image
|
||||
}
|
||||
}
|
||||
1363
assets/foliate-js/src/paginator.js
Normal file
1363
assets/foliate-js/src/paginator.js
Normal file
File diff suppressed because it is too large
Load Diff
616
assets/foliate-js/src/pdf.js
Normal file
616
assets/foliate-js/src/pdf.js
Normal file
@@ -0,0 +1,616 @@
|
||||
/* global pdfjsLib */
|
||||
|
||||
// https://github.com/mozilla/pdf.js/blob/f04967017f22e46d70d11468dd928b4cdc2f6ea1/web/text_layer_builder.css
|
||||
const textLayerBuilderCSS = `
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--highlight-bg-color: rgb(180 0 170);
|
||||
--highlight-selected-bg-color: rgb(0 100 0);
|
||||
}
|
||||
|
||||
@media screen and (forced-colors: active) {
|
||||
:root {
|
||||
--highlight-bg-color: Highlight;
|
||||
--highlight-selected-bg-color: ButtonText;
|
||||
}
|
||||
}
|
||||
|
||||
.textLayer {
|
||||
position: absolute;
|
||||
text-align: initial;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0.25;
|
||||
line-height: 1;
|
||||
text-size-adjust: none;
|
||||
forced-color-adjust: none;
|
||||
transform-origin: 0 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.textLayer :is(span, br) {
|
||||
color: transparent;
|
||||
position: absolute;
|
||||
white-space: pre;
|
||||
cursor: text;
|
||||
transform-origin: 0% 0%;
|
||||
}
|
||||
|
||||
/* Only necessary in Google Chrome, see issue 14205, and most unfortunately
|
||||
* the problem doesn't show up in "text" reference tests. */
|
||||
/*#if !MOZCENTRAL*/
|
||||
.textLayer span.markedContent {
|
||||
top: 0;
|
||||
height: 0;
|
||||
}
|
||||
/*#endif*/
|
||||
|
||||
.textLayer .highlight {
|
||||
margin: -1px;
|
||||
padding: 1px;
|
||||
background-color: var(--highlight-bg-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.textLayer .highlight.appended {
|
||||
position: initial;
|
||||
}
|
||||
|
||||
.textLayer .highlight.begin {
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.textLayer .highlight.end {
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.textLayer .highlight.middle {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.textLayer .highlight.selected {
|
||||
background-color: var(--highlight-selected-bg-color);
|
||||
}
|
||||
|
||||
.textLayer ::selection {
|
||||
/*#if !MOZCENTRAL*/
|
||||
background: blue;
|
||||
/*#endif*/
|
||||
background: AccentColor; /* stylelint-disable-line declaration-block-no-duplicate-properties */
|
||||
}
|
||||
|
||||
/* Avoids https://github.com/mozilla/pdf.js/issues/13840 in Chrome */
|
||||
/*#if !MOZCENTRAL*/
|
||||
.textLayer br::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/*#endif*/
|
||||
|
||||
.textLayer .endOfContent {
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: 100% 0 0;
|
||||
z-index: -1;
|
||||
cursor: default;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.textLayer .endOfContent.active {
|
||||
top: 0;
|
||||
}
|
||||
`
|
||||
|
||||
//https://github.com/mozilla/pdf.js/blob/d64f223d034ad74fb62571c3acff566d25eca413/web/annotation_layer_builder.css
|
||||
const annotationLayerBuilderCSS = `
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>");
|
||||
--input-focus-border-color: Highlight;
|
||||
--input-focus-outline: 1px solid Canvas;
|
||||
--input-unfocused-border-color: transparent;
|
||||
--input-disabled-border-color: transparent;
|
||||
--input-hover-border-color: black;
|
||||
--link-outline: none;
|
||||
}
|
||||
|
||||
@media screen and (forced-colors: active) {
|
||||
:root {
|
||||
--input-focus-border-color: CanvasText;
|
||||
--input-unfocused-border-color: ActiveText;
|
||||
--input-disabled-border-color: GrayText;
|
||||
--input-hover-border-color: Highlight;
|
||||
--link-outline: 1.5px solid LinkText;
|
||||
--hcm-highligh-filter: invert(100%);
|
||||
}
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):required,
|
||||
.annotationLayer .choiceWidgetAnnotation select:required,
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input:required {
|
||||
outline: 1.5px solid selectedItem;
|
||||
}
|
||||
|
||||
.annotationLayer .linkAnnotation:hover {
|
||||
backdrop-filter: var(--hcm-highligh-filter);
|
||||
}
|
||||
|
||||
.annotationLayer .linkAnnotation > a:hover {
|
||||
opacity: 0 !important;
|
||||
background: none !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.annotationLayer .popupAnnotation .popup {
|
||||
outline: calc(1.5px * var(--scale-factor)) solid CanvasText !important;
|
||||
background-color: ButtonFace !important;
|
||||
color: ButtonText !important;
|
||||
}
|
||||
|
||||
.annotationLayer .highlightArea:hover::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
backdrop-filter: var(--hcm-highligh-filter);
|
||||
content: "";
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.annotationLayer .popupAnnotation.focused .popup {
|
||||
outline: calc(3px * var(--scale-factor)) solid Highlight !important;
|
||||
}
|
||||
}
|
||||
|
||||
.annotationLayer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
transform-origin: 0 0;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.annotationLayer[data-main-rotation="90"] .norotate {
|
||||
transform: rotate(270deg) translateX(-100%);
|
||||
}
|
||||
.annotationLayer[data-main-rotation="180"] .norotate {
|
||||
transform: rotate(180deg) translate(-100%, -100%);
|
||||
}
|
||||
.annotationLayer[data-main-rotation="270"] .norotate {
|
||||
transform: rotate(90deg) translateY(-100%);
|
||||
}
|
||||
|
||||
.annotationLayer canvas {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.annotationLayer section {
|
||||
position: absolute;
|
||||
text-align: initial;
|
||||
pointer-events: auto;
|
||||
box-sizing: border-box;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.annotationLayer .linkAnnotation {
|
||||
outline: var(--link-outline);
|
||||
}
|
||||
|
||||
.annotationLayer :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton) > a {
|
||||
position: absolute;
|
||||
font-size: 1em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.annotationLayer
|
||||
:is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder)
|
||||
> a:hover {
|
||||
opacity: 0.2;
|
||||
background-color: rgb(255 255 0);
|
||||
box-shadow: 0 2px 10px rgb(255 255 0);
|
||||
}
|
||||
|
||||
.annotationLayer .linkAnnotation.hasBorder:hover {
|
||||
background-color: rgb(255 255 0 / 0.2);
|
||||
}
|
||||
|
||||
.annotationLayer .hasBorder {
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.annotationLayer .textAnnotation img {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea),
|
||||
.annotationLayer .choiceWidgetAnnotation select,
|
||||
.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input {
|
||||
background-image: var(--annotation-unfocused-field-background);
|
||||
border: 2px solid var(--input-unfocused-border-color);
|
||||
box-sizing: border-box;
|
||||
font: calc(9px * var(--scale-factor)) sans-serif;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):required,
|
||||
.annotationLayer .choiceWidgetAnnotation select:required,
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input:required {
|
||||
outline: 1.5px solid red;
|
||||
}
|
||||
|
||||
.annotationLayer .choiceWidgetAnnotation select option {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation textarea {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea)[disabled],
|
||||
.annotationLayer .choiceWidgetAnnotation select[disabled],
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input[disabled] {
|
||||
background: none;
|
||||
border: 2px solid var(--input-disabled-border-color);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):hover,
|
||||
.annotationLayer .choiceWidgetAnnotation select:hover,
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input:hover {
|
||||
border: 2px solid var(--input-hover-border-color);
|
||||
}
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):hover,
|
||||
.annotationLayer .choiceWidgetAnnotation select:hover,
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:hover {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):focus,
|
||||
.annotationLayer .choiceWidgetAnnotation select:focus {
|
||||
background: none;
|
||||
border: 2px solid var(--input-focus-border-color);
|
||||
border-radius: 2px;
|
||||
outline: var(--input-focus-outline);
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) :focus {
|
||||
background-image: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox :focus {
|
||||
border: 2px solid var(--input-focus-border-color);
|
||||
border-radius: 2px;
|
||||
outline: var(--input-focus-outline);
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton :focus {
|
||||
border: 2px solid var(--input-focus-border-color);
|
||||
outline: var(--input-focus-outline);
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before,
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after,
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before {
|
||||
background-color: CanvasText;
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before,
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after {
|
||||
height: 80%;
|
||||
left: 45%;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before {
|
||||
border-radius: 50%;
|
||||
height: 50%;
|
||||
left: 30%;
|
||||
top: 20%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input.comb {
|
||||
font-family: monospace;
|
||||
padding-left: 2px;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input.comb:focus {
|
||||
/*
|
||||
* Letter spacing is placed on the right side of each character. Hence, the
|
||||
* letter spacing of the last character may be placed outside the visible
|
||||
* area, causing horizontal scrolling. We avoid this by extending the width
|
||||
* when the element has focus and revert this when it loses focus.
|
||||
*/
|
||||
width: 103%;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input {
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.annotationLayer .fileAttachmentAnnotation .popupTriggerArea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.annotationLayer .popupAnnotation {
|
||||
position: absolute;
|
||||
font-size: calc(9px * var(--scale-factor));
|
||||
pointer-events: none;
|
||||
width: max-content;
|
||||
max-width: 45%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.annotationLayer .popup {
|
||||
background-color: rgb(255 255 153);
|
||||
box-shadow: 0 calc(2px * var(--scale-factor)) calc(5px * var(--scale-factor))
|
||||
rgb(136 136 136);
|
||||
border-radius: calc(2px * var(--scale-factor));
|
||||
outline: 1.5px solid rgb(255 255 74);
|
||||
padding: calc(6px * var(--scale-factor));
|
||||
cursor: pointer;
|
||||
font: message-box;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.annotationLayer .popupAnnotation.focused .popup {
|
||||
outline-width: 3px;
|
||||
}
|
||||
|
||||
.annotationLayer .popup * {
|
||||
font-size: calc(9px * var(--scale-factor));
|
||||
}
|
||||
|
||||
.annotationLayer .popup > .header {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.annotationLayer .popup > .header h1 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.annotationLayer .popup > .header .popupDate {
|
||||
display: inline-block;
|
||||
margin-left: calc(5px * var(--scale-factor));
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.annotationLayer .popupContent {
|
||||
border-top: 1px solid rgb(51 51 51);
|
||||
margin-top: calc(2px * var(--scale-factor));
|
||||
padding-top: calc(2px * var(--scale-factor));
|
||||
}
|
||||
|
||||
.annotationLayer .richText > * {
|
||||
white-space: pre-wrap;
|
||||
font-size: calc(9px * var(--scale-factor));
|
||||
}
|
||||
|
||||
.annotationLayer .popupTriggerArea {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.annotationLayer section svg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.annotationLayer .annotationTextContent {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
color: transparent;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.annotationLayer .annotationTextContent span {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.annotationLayer svg.quadrilateralsContainer {
|
||||
contain: strict;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
`
|
||||
|
||||
const renderPage = async (page, getImageBlob) => {
|
||||
|
||||
const naturalPdfSize = page.getViewport({ scale: 1 })
|
||||
const naturalPdfRatio = naturalPdfSize.width / naturalPdfSize.height
|
||||
const appRatio = innerWidth / innerHeight
|
||||
const pdfToAppResolutionRatio = appRatio / naturalPdfRatio
|
||||
|
||||
const scale = devicePixelRatio * pdfToAppResolutionRatio
|
||||
const viewport = page.getViewport({ scale })
|
||||
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.height = viewport.height
|
||||
canvas.width = viewport.width
|
||||
const canvasContext = canvas.getContext('2d')
|
||||
await page.render({ canvasContext, viewport }).promise
|
||||
const blob = await new Promise(resolve => canvas.toBlob(resolve))
|
||||
if (getImageBlob) return blob
|
||||
|
||||
/*
|
||||
// with the SVG backend
|
||||
const operatorList = await page.getOperatorList()
|
||||
const svgGraphics = new pdfjsLib.SVGGraphics(page.commonObjs, page.objs)
|
||||
const svg = await svgGraphics.getSVG(operatorList, viewport)
|
||||
const str = new XMLSerializer().serializeToString(svg)
|
||||
const blob = new Blob([str], { type: 'image/svg+xml' })
|
||||
*/
|
||||
|
||||
const container = document.createElement('div')
|
||||
container.classList.add('textLayer')
|
||||
await pdfjsLib.renderTextLayer({
|
||||
textContentSource: await page.getTextContent(),
|
||||
container, viewport,
|
||||
}).promise
|
||||
|
||||
const div = document.createElement('div')
|
||||
div.classList.add('annotationLayer')
|
||||
await new pdfjsLib.AnnotationLayer({ page, viewport, div }).render({
|
||||
annotations: await page.getAnnotations(),
|
||||
linkService: {
|
||||
getDestinationHash: dest => JSON.stringify(dest),
|
||||
addLinkAttributes: (link, url) => link.href = url,
|
||||
},
|
||||
})
|
||||
|
||||
const src = URL.createObjectURL(blob)
|
||||
const url = URL.createObjectURL(new Blob([`
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
:root {
|
||||
--scale-factor: ${scale};
|
||||
}
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
${textLayerBuilderCSS}
|
||||
${annotationLayerBuilderCSS}
|
||||
</style>
|
||||
<img src="${src}">
|
||||
${container.outerHTML}
|
||||
${div.outerHTML}
|
||||
`], { type: 'text/html' }))
|
||||
return url
|
||||
}
|
||||
|
||||
const makeTOCItem = item => ({
|
||||
label: item.title,
|
||||
href: JSON.stringify(item.dest),
|
||||
subitems: item.items.length ? item.items.map(makeTOCItem) : null,
|
||||
})
|
||||
|
||||
export const makePDF = async file => {
|
||||
const data = new Uint8Array(await file.arrayBuffer())
|
||||
const pdf = await pdfjsLib.getDocument({ data }).promise
|
||||
|
||||
const book = { rendition: { layout: 'pre-paginated' } }
|
||||
|
||||
const info = (await pdf.getMetadata())?.info
|
||||
book.metadata = {
|
||||
title: info?.Title,
|
||||
author: info?.Author,
|
||||
}
|
||||
|
||||
const outline = await pdf.getOutline()
|
||||
book.toc = outline?.map(makeTOCItem)
|
||||
|
||||
const cache = new Map()
|
||||
book.sections = Array.from({ length: pdf.numPages }).map((_, i) => ({
|
||||
id: i,
|
||||
load: async () => {
|
||||
const cached = cache.get(i)
|
||||
if (cached) return cached
|
||||
const url = await renderPage(await pdf.getPage(i + 1))
|
||||
cache.set(i, url)
|
||||
return url
|
||||
},
|
||||
size: 1000,
|
||||
}))
|
||||
book.sections[0].pageSpread = 'right'
|
||||
book.isExternal = uri => /^\w+:/i.test(uri)
|
||||
book.resolveHref = async href => {
|
||||
const parsed = JSON.parse(href)
|
||||
const dest = typeof parsed === 'string'
|
||||
? await pdf.getDestination(parsed) : parsed
|
||||
if (!dest || !dest[0]) return { index: 0 }
|
||||
const index = await pdf.getPageIndex(dest[0])
|
||||
return { index }
|
||||
}
|
||||
book.splitTOCHref = async href => {
|
||||
const parsed = JSON.parse(href)
|
||||
const dest = typeof parsed === 'string'
|
||||
? await pdf.getDestination(parsed) : parsed
|
||||
if (!dest || !dest[0]) return [0, null]
|
||||
const index = await pdf.getPageIndex(dest[0])
|
||||
return [index, null]
|
||||
}
|
||||
book.getTOCFragment = doc => doc.documentElement
|
||||
book.getCover = async () => renderPage(await pdf.getPage(1), true)
|
||||
return book
|
||||
}
|
||||
113
assets/foliate-js/src/progress.js
Normal file
113
assets/foliate-js/src/progress.js
Normal file
@@ -0,0 +1,113 @@
|
||||
// assign a unique ID for each TOC item
|
||||
const assignIDs = toc => {
|
||||
let id = 0
|
||||
const assignID = item => {
|
||||
item.id = id++
|
||||
if (item.subitems) for (const subitem of item.subitems) assignID(subitem)
|
||||
}
|
||||
for (const item of toc) assignID(item)
|
||||
return toc
|
||||
}
|
||||
|
||||
const flatten = items => items
|
||||
.map(item => item.subitems?.length
|
||||
? [item, flatten(item.subitems)].flat()
|
||||
: item)
|
||||
.flat()
|
||||
|
||||
export class TOCProgress {
|
||||
async init({ toc, ids, splitHref, getFragment }) {
|
||||
assignIDs(toc)
|
||||
const items = flatten(toc)
|
||||
const grouped = new Map()
|
||||
for (const [i, item] of items.entries()) {
|
||||
const [id, fragment] = await splitHref(item?.href) ?? []
|
||||
const value = { fragment, item }
|
||||
if (grouped.has(id)) grouped.get(id).items.push(value)
|
||||
else grouped.set(id, { prev: items[i - 1], items: [value] })
|
||||
}
|
||||
const map = new Map()
|
||||
for (const [i, id] of ids.entries()) {
|
||||
if (grouped.has(id)) map.set(id, grouped.get(id))
|
||||
else map.set(id, map.get(ids[i - 1]))
|
||||
}
|
||||
this.ids = ids
|
||||
this.map = map
|
||||
this.getFragment = getFragment
|
||||
}
|
||||
getProgress(index, range) {
|
||||
if (!this.ids) return
|
||||
const id = this.ids[index]
|
||||
const obj = this.map.get(id)
|
||||
if (!obj) return null
|
||||
const { prev, items } = obj
|
||||
if (!items) return prev
|
||||
if (!range || items.length === 1 && !items[0].fragment) return items[0].item
|
||||
|
||||
const doc = range.startContainer.getRootNode()
|
||||
for (const [i, { fragment }] of items.entries()) {
|
||||
const el = this.getFragment(doc, fragment)
|
||||
if (!el) continue
|
||||
if (range.comparePoint(el, 0) > 0)
|
||||
return (items[i - 1]?.item ?? prev)
|
||||
}
|
||||
return items[items.length - 1].item
|
||||
}
|
||||
}
|
||||
|
||||
export class SectionProgress {
|
||||
constructor(sections, sizePerLoc, sizePerTimeUnit) {
|
||||
this.sizes = sections.map(s => s.linear != 'no' && s.size > 0 ? s.size : 0)
|
||||
this.sizePerLoc = sizePerLoc
|
||||
this.sizePerTimeUnit = sizePerTimeUnit
|
||||
this.sizeTotal = this.sizes.reduce((a, b) => a + b, 0)
|
||||
this.sectionFractions = this.#getSectionFractions()
|
||||
}
|
||||
#getSectionFractions() {
|
||||
const { sizeTotal } = this
|
||||
const results = [0]
|
||||
let sum = 0
|
||||
for (const size of this.sizes) results.push((sum += size) / sizeTotal)
|
||||
return results
|
||||
}
|
||||
// get progress given index of and fractions within a section
|
||||
getProgress(index, fractionInSection, pageFraction = 0) {
|
||||
const { sizes, sizePerLoc, sizePerTimeUnit, sizeTotal } = this
|
||||
const sizeInSection = sizes[index] ?? 0
|
||||
const sizeBefore = sizes.slice(0, index).reduce((a, b) => a + b, 0)
|
||||
const size = sizeBefore + fractionInSection * sizeInSection
|
||||
const nextSize = size + pageFraction * sizeInSection
|
||||
const remainingTotal = sizeTotal - size
|
||||
const remainingSection = (1 - fractionInSection) * sizeInSection
|
||||
return {
|
||||
fraction: nextSize / sizeTotal,
|
||||
section: {
|
||||
current: index,
|
||||
total: sizes.length,
|
||||
},
|
||||
location: {
|
||||
current: Math.floor(size / sizePerLoc),
|
||||
next: Math.floor(nextSize / sizePerLoc),
|
||||
total: Math.ceil(sizeTotal / sizePerLoc),
|
||||
},
|
||||
time: {
|
||||
section: remainingSection / sizePerTimeUnit,
|
||||
total: remainingTotal / sizePerTimeUnit,
|
||||
},
|
||||
}
|
||||
}
|
||||
// the inverse of `getProgress`
|
||||
// get index of and fraction in section based on total fraction
|
||||
getSection(fraction) {
|
||||
if (fraction <= 0) return [0, 0]
|
||||
if (fraction >= 1) return [this.sizes.length - 1, 1]
|
||||
fraction = fraction + Number.EPSILON
|
||||
const { sizeTotal } = this
|
||||
let index = this.sectionFractions.findIndex(x => x > fraction) - 1
|
||||
if (index < 0) return [0, 0]
|
||||
while (!this.sizes[index]) index++
|
||||
const fractionInSection = (fraction - this.sectionFractions[index])
|
||||
/ (this.sizes[index] / sizeTotal)
|
||||
return [index, fractionInSection]
|
||||
}
|
||||
}
|
||||
130
assets/foliate-js/src/search.js
Normal file
130
assets/foliate-js/src/search.js
Normal file
@@ -0,0 +1,130 @@
|
||||
// length for context in excerpts
|
||||
const CONTEXT_LENGTH = 50
|
||||
|
||||
const normalizeWhitespace = str => str.replace(/\s+/g, ' ')
|
||||
|
||||
const makeExcerpt = (strs, { startIndex, startOffset, endIndex, endOffset }) => {
|
||||
const start = strs[startIndex]
|
||||
const end = strs[endIndex]
|
||||
const match = start === end
|
||||
? start.slice(startOffset, endOffset)
|
||||
: start.slice(startOffset)
|
||||
+ strs.slice(start + 1, end).join('')
|
||||
+ end.slice(0, endOffset)
|
||||
const trimmedStart = normalizeWhitespace(start.slice(0, startOffset)).trimStart()
|
||||
const trimmedEnd = normalizeWhitespace(end.slice(endOffset)).trimEnd()
|
||||
const ellipsisPre = trimmedStart.length < CONTEXT_LENGTH ? '' : '…'
|
||||
const ellipsisPost = trimmedEnd.length < CONTEXT_LENGTH ? '' : '…'
|
||||
const pre = `${ellipsisPre}${trimmedStart.slice(-CONTEXT_LENGTH)}`
|
||||
const post = `${trimmedEnd.slice(0, CONTEXT_LENGTH)}${ellipsisPost}`
|
||||
return { pre, match, post }
|
||||
}
|
||||
|
||||
const simpleSearch = function* (strs, query, options = {}) {
|
||||
const { locales = 'en', sensitivity } = options
|
||||
const matchCase = sensitivity === 'variant'
|
||||
const haystack = strs.join('')
|
||||
const lowerHaystack = matchCase ? haystack : haystack.toLocaleLowerCase(locales)
|
||||
const needle = matchCase ? query : query.toLocaleLowerCase(locales)
|
||||
const needleLength = needle.length
|
||||
let index = -1
|
||||
let strIndex = -1
|
||||
let sum = 0
|
||||
do {
|
||||
index = lowerHaystack.indexOf(needle, index + 1)
|
||||
if (index > -1) {
|
||||
while (sum <= index) sum += strs[++strIndex].length
|
||||
const startIndex = strIndex
|
||||
const startOffset = index - (sum - strs[strIndex].length)
|
||||
const end = index + needleLength
|
||||
while (sum <= end) sum += strs[++strIndex].length
|
||||
const endIndex = strIndex
|
||||
const endOffset = end - (sum - strs[strIndex].length)
|
||||
const range = { startIndex, startOffset, endIndex, endOffset }
|
||||
yield { range, excerpt: makeExcerpt(strs, range) }
|
||||
}
|
||||
} while (index > -1)
|
||||
}
|
||||
|
||||
const segmenterSearch = function* (strs, query, options = {}) {
|
||||
const { locales = 'en', granularity = 'word', sensitivity = 'base' } = options
|
||||
let segmenter, collator
|
||||
try {
|
||||
segmenter = new Intl.Segmenter(locales, { usage: 'search', granularity })
|
||||
collator = new Intl.Collator(locales, { sensitivity })
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
segmenter = new Intl.Segmenter('en', { usage: 'search', granularity })
|
||||
collator = new Intl.Collator('en', { sensitivity })
|
||||
}
|
||||
const queryLength = Array.from(segmenter.segment(query)).length
|
||||
|
||||
const substrArr = []
|
||||
let strIndex = 0
|
||||
let segments = segmenter.segment(strs[strIndex])[Symbol.iterator]()
|
||||
main: while (strIndex < strs.length) {
|
||||
while (substrArr.length < queryLength) {
|
||||
const { done, value } = segments.next()
|
||||
if (done) {
|
||||
// the current string is exhausted
|
||||
// move on to the next string
|
||||
strIndex++
|
||||
if (strIndex < strs.length) {
|
||||
segments = segmenter.segment(strs[strIndex])[Symbol.iterator]()
|
||||
continue
|
||||
} else break main
|
||||
}
|
||||
const { index, segment } = value
|
||||
// ignore formatting characters
|
||||
if (!/[^\p{Format}]/u.test(segment)) continue
|
||||
// normalize whitespace
|
||||
if (/\s/u.test(segment)) {
|
||||
if (!/\s/u.test(substrArr[substrArr.length - 1]?.segment))
|
||||
substrArr.push({ strIndex, index, segment: ' ' })
|
||||
continue
|
||||
}
|
||||
value.strIndex = strIndex
|
||||
substrArr.push(value)
|
||||
}
|
||||
const substr = substrArr.map(x => x.segment).join('')
|
||||
if (collator.compare(query, substr) === 0) {
|
||||
const endIndex = strIndex
|
||||
const lastSeg = substrArr[substrArr.length - 1]
|
||||
const endOffset = lastSeg.index + lastSeg.segment.length
|
||||
const startIndex = substrArr[0].strIndex
|
||||
const startOffset = substrArr[0].index
|
||||
const range = { startIndex, startOffset, endIndex, endOffset }
|
||||
yield { range, excerpt: makeExcerpt(strs, range) }
|
||||
}
|
||||
substrArr.shift()
|
||||
}
|
||||
}
|
||||
|
||||
export const search = (strs, query, options) => {
|
||||
const { granularity = 'grapheme', sensitivity = 'base' } = options
|
||||
if (!Intl?.Segmenter || granularity === 'grapheme'
|
||||
&& (sensitivity === 'variant' || sensitivity === 'accent'))
|
||||
return simpleSearch(strs, query, options)
|
||||
return segmenterSearch(strs, query, options)
|
||||
}
|
||||
|
||||
export const searchMatcher = (textWalker, opts) => {
|
||||
const { defalutLocale, matchCase, matchDiacritics, matchWholeWords } = opts
|
||||
return function* (doc, query) {
|
||||
const iter = textWalker(doc, function* (strs, makeRange) {
|
||||
for (const result of search(strs, query, {
|
||||
locales: doc.body.lang || doc.documentElement.lang || defalutLocale || 'en',
|
||||
granularity: matchWholeWords ? 'word' : 'grapheme',
|
||||
sensitivity: matchDiacritics && matchCase ? 'variant'
|
||||
: matchDiacritics && !matchCase ? 'accent'
|
||||
: !matchDiacritics && matchCase ? 'case'
|
||||
: 'base',
|
||||
})) {
|
||||
const { startIndex, startOffset, endIndex, endOffset } = result.range
|
||||
result.range = makeRange(startIndex, startOffset, endIndex, endOffset)
|
||||
yield result
|
||||
}
|
||||
})
|
||||
for (const result of iter) yield result
|
||||
}
|
||||
}
|
||||
49
assets/foliate-js/src/text-walker.js
Normal file
49
assets/foliate-js/src/text-walker.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const walkRange = (range, walker) => {
|
||||
const nodes = []
|
||||
for (let node = walker.currentNode; node; node = walker.nextNode()) {
|
||||
const compare = range.comparePoint(node, 0)
|
||||
if (compare === 0) nodes.push(node)
|
||||
else if (compare > 0) break
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
const walkDocument = (_, walker) => {
|
||||
const nodes = []
|
||||
for (let node = walker.nextNode(); node; node = walker.nextNode())
|
||||
nodes.push(node)
|
||||
return nodes
|
||||
}
|
||||
|
||||
const filter = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT
|
||||
| NodeFilter.SHOW_CDATA_SECTION
|
||||
|
||||
const acceptNode = node => {
|
||||
if (node.nodeType === 1) {
|
||||
const name = node.tagName.toLowerCase()
|
||||
if (name === 'script' || name === 'style') return NodeFilter.FILTER_REJECT
|
||||
|
||||
// Skip translation elements to preserve CFI calculations
|
||||
if (node.classList && node.classList.contains('translated-text')) {
|
||||
return NodeFilter.FILTER_REJECT
|
||||
}
|
||||
|
||||
return NodeFilter.FILTER_SKIP
|
||||
}
|
||||
return NodeFilter.FILTER_ACCEPT
|
||||
}
|
||||
|
||||
export const textWalker = function* (x, func) {
|
||||
const root = x.commonAncestorContainer ?? x.body ?? x
|
||||
const walker = document.createTreeWalker(root, filter, { acceptNode })
|
||||
const walk = x.commonAncestorContainer ? walkRange : walkDocument
|
||||
const nodes = walk(x, walker)
|
||||
const strs = nodes.map(node => node.nodeValue)
|
||||
const makeRange = (startIndex, startOffset, endIndex, endOffset) => {
|
||||
const range = document.createRange()
|
||||
range.setStart(nodes[startIndex], startOffset)
|
||||
range.setEnd(nodes[endIndex], endOffset)
|
||||
return range
|
||||
}
|
||||
for (const match of func(strs, makeRange)) yield match
|
||||
}
|
||||
359
assets/foliate-js/src/translator.js
Normal file
359
assets/foliate-js/src/translator.js
Normal file
@@ -0,0 +1,359 @@
|
||||
// Translation modes
|
||||
export const TranslationMode = {
|
||||
OFF: 'off',
|
||||
TRANSLATION_ONLY: 'translation-only',
|
||||
ORIGINAL_ONLY: 'original-only',
|
||||
BILINGUAL: 'bilingual'
|
||||
}
|
||||
|
||||
// Make TranslationMode globally available for debugging
|
||||
if (typeof window !== 'undefined') {
|
||||
window.TranslationMode = TranslationMode
|
||||
}
|
||||
|
||||
// Translation function that calls Flutter's translation service
|
||||
const translate = async (text) => {
|
||||
try {
|
||||
// Call Flutter's translation handler
|
||||
const result = await window.flutter_inappwebview.callHandler('translateText', text)
|
||||
return result || `Translation failed: ${text}`
|
||||
} catch (error) {
|
||||
console.error('Translation failed:', error)
|
||||
return `Translation error: ${text}`
|
||||
}
|
||||
}
|
||||
|
||||
export class Translator {
|
||||
#translationMode = TranslationMode.OFF
|
||||
observedElements = new Set()
|
||||
#translatedElements = new WeakMap()
|
||||
#observer = null
|
||||
|
||||
constructor() {
|
||||
this.#initializeObserver()
|
||||
}
|
||||
|
||||
#initializeObserver() {
|
||||
this.#observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
// console.log(`IntersectionObserver triggered with ${entries.length} entries`)
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
// console.log('Element intersecting, translating:', entry.target.tagName, entry.target.textContent?.substring(0, 30))
|
||||
this.#translateElement(entry.target).catch(error =>
|
||||
console.warn('Translation failed in observer:', error)
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
rootMargin: '1280px',
|
||||
threshold: 0
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async setTranslationMode(mode) {
|
||||
if (!Object.values(TranslationMode).includes(mode)) {
|
||||
console.warn(`Invalid translation mode: ${mode}`)
|
||||
return
|
||||
}
|
||||
|
||||
const oldMode = this.#translationMode
|
||||
this.#translationMode = mode
|
||||
|
||||
if (oldMode !== mode) {
|
||||
// console.log(`Translation mode changed from ${oldMode} to ${mode}`)
|
||||
|
||||
if (mode === TranslationMode.OFF) {
|
||||
// Turn off translation
|
||||
this.#updateTranslationDisplay()
|
||||
} else if (oldMode === TranslationMode.OFF) {
|
||||
// Turn on translation - force translate visible elements and wait for completion
|
||||
await this.#forceTranslateVisibleElements()
|
||||
} else {
|
||||
// Just update display mode
|
||||
this.#updateTranslationDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
// Re-render annotations after translation mode change (and after translation completion)
|
||||
if (window.reader && window.reader.annotationsByValue) {
|
||||
const existingAnnotations = Array.from(window.reader.annotationsByValue.values())
|
||||
if (existingAnnotations.length > 0) {
|
||||
// console.log('Re-rendering annotations after translation mode change:', existingAnnotations.length)
|
||||
window.renderAnnotations(existingAnnotations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getTranslationMode() {
|
||||
return this.#translationMode
|
||||
}
|
||||
|
||||
observeDocument(doc) {
|
||||
// console.log('Observing document for translation, doc:', doc)
|
||||
if (!doc) {
|
||||
console.warn('No document provided to observeDocument')
|
||||
return
|
||||
}
|
||||
|
||||
const textElements = this.#walkTextNodes(doc.body || doc.documentElement)
|
||||
// console.log(`Found ${textElements.length} text elements to observe`)
|
||||
|
||||
textElements.forEach(element => {
|
||||
if (!this.observedElements.has(element)) {
|
||||
this.#observer.observe(element)
|
||||
this.observedElements.add(element)
|
||||
// console.log('Added element to observer:', element.tagName, element.textContent?.substring(0, 50))
|
||||
}
|
||||
})
|
||||
|
||||
// console.log(`Total observed elements: ${this.observedElements.size}`)
|
||||
}
|
||||
|
||||
clearTranslations() {
|
||||
// Remove all translation elements and restore original content
|
||||
this.observedElements.forEach(element => {
|
||||
const translationElements = element.querySelectorAll('.translated-text')
|
||||
translationElements.forEach(trans => trans.remove())
|
||||
|
||||
// Restore original text if hidden
|
||||
this.#restoreOriginalText(element)
|
||||
})
|
||||
|
||||
// Clear observer
|
||||
this.#observer.disconnect()
|
||||
this.observedElements.clear()
|
||||
this.#translatedElements = new WeakMap()
|
||||
|
||||
// Reinitialize observer
|
||||
this.#initializeObserver()
|
||||
}
|
||||
|
||||
#walkTextNodes(root, rejectTags = ['pre', 'code', 'math', 'style', 'script']) {
|
||||
const elements = []
|
||||
|
||||
const walk = (node, depth = 0) => {
|
||||
if (depth > 15) return
|
||||
|
||||
const children = Array.from(node.children || [])
|
||||
for (const child of children) {
|
||||
if (rejectTags.includes(child.tagName.toLowerCase())) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip translation elements
|
||||
if (child.classList.contains('translated-text')) {
|
||||
continue
|
||||
}
|
||||
|
||||
const hasDirectText = Array.from(child.childNodes).some(node => {
|
||||
if (node.nodeType === Node.TEXT_NODE && node.textContent?.trim()) {
|
||||
return true
|
||||
}
|
||||
if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'SPAN') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if (child.children.length === 0 && child.textContent?.trim()) {
|
||||
elements.push(child)
|
||||
} else if (hasDirectText) {
|
||||
elements.push(child)
|
||||
} else if (child.children.length > 0) {
|
||||
walk(child, depth + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walk(root)
|
||||
return elements
|
||||
}
|
||||
|
||||
async #translateElement(element) {
|
||||
if (this.#translationMode === TranslationMode.OFF) return
|
||||
if (this.#translatedElements.has(element)) return
|
||||
|
||||
const text = element.innerText?.trim()
|
||||
if (!text) return
|
||||
|
||||
try {
|
||||
const translatedText = await translate(text)
|
||||
|
||||
// Mark as translated to prevent re-processing
|
||||
this.#translatedElements.set(element, {
|
||||
originalText: text,
|
||||
translatedText: translatedText
|
||||
})
|
||||
|
||||
this.#applyTranslation(element, translatedText)
|
||||
} catch (error) {
|
||||
console.warn('Translation failed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
#applyTranslation(element, translatedText) {
|
||||
// Remove existing translation if any
|
||||
const existingTranslation = element.querySelector('.translated-text')
|
||||
if (existingTranslation) {
|
||||
existingTranslation.remove()
|
||||
}
|
||||
|
||||
// Create translation wrapper
|
||||
const wrapper = document.createElement('span')
|
||||
wrapper.className = 'translated-text'
|
||||
wrapper.setAttribute('data-translation-mark', '1')
|
||||
wrapper.style.display = 'block'
|
||||
// wrapper.style.fontSize = '0.9em'
|
||||
// wrapper.style.color = '#666'
|
||||
// wrapper.style.fontStyle = 'italic'
|
||||
wrapper.style.marginTop = '0.2em'
|
||||
wrapper.textContent = translatedText
|
||||
|
||||
// Apply based on current mode
|
||||
this.#updateElementDisplay(element, wrapper)
|
||||
|
||||
element.appendChild(wrapper)
|
||||
}
|
||||
|
||||
#updateElementDisplay(element, translationWrapper) {
|
||||
const data = this.#translatedElements.get(element)
|
||||
if (!data) return
|
||||
|
||||
switch (this.#translationMode) {
|
||||
case TranslationMode.TRANSLATION_ONLY:
|
||||
this.#hideOriginalText(element)
|
||||
translationWrapper.style.display = 'block'
|
||||
break
|
||||
|
||||
case TranslationMode.ORIGINAL_ONLY:
|
||||
this.#restoreOriginalText(element)
|
||||
translationWrapper.style.display = 'none'
|
||||
break
|
||||
|
||||
case TranslationMode.BILINGUAL:
|
||||
this.#restoreOriginalText(element)
|
||||
translationWrapper.style.display = 'block'
|
||||
break
|
||||
|
||||
case TranslationMode.OFF:
|
||||
default:
|
||||
this.#restoreOriginalText(element)
|
||||
translationWrapper.style.display = 'none'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
#hideOriginalText(element) {
|
||||
// Use CSS to hide original content instead of removing DOM nodes
|
||||
if (!element.hasAttribute('data-original-visibility')) {
|
||||
element.setAttribute('data-original-visibility', 'hidden')
|
||||
|
||||
// Hide all child nodes except translation elements using CSS
|
||||
Array.from(element.childNodes).forEach(node => {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
const el = node
|
||||
if (!el.classList || !el.classList.contains('translated-text')) {
|
||||
// Store and hide using CSS
|
||||
if (!el.hasAttribute('data-original-display')) {
|
||||
el.setAttribute('data-original-display', el.style.display || 'initial')
|
||||
el.style.display = 'none'
|
||||
}
|
||||
}
|
||||
} else if (node.nodeType === Node.TEXT_NODE) {
|
||||
// For text nodes, store content and make invisible
|
||||
if (!node.__originalContent) {
|
||||
node.__originalContent = node.textContent
|
||||
node.textContent = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Mark element as having hidden text
|
||||
element.classList.add('translation-source-hidden')
|
||||
}
|
||||
|
||||
#restoreOriginalText(element) {
|
||||
// Restore visibility by reversing the hide operations
|
||||
if (element.hasAttribute('data-original-visibility')) {
|
||||
// Restore all child nodes
|
||||
Array.from(element.childNodes).forEach(node => {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
const el = node
|
||||
if (!el.classList || !el.classList.contains('translated-text')) {
|
||||
// Restore original display
|
||||
if (el.hasAttribute('data-original-display')) {
|
||||
const originalDisplay = el.getAttribute('data-original-display')
|
||||
el.style.display = originalDisplay === 'initial' ? '' : originalDisplay
|
||||
el.removeAttribute('data-original-display')
|
||||
}
|
||||
}
|
||||
} else if (node.nodeType === Node.TEXT_NODE) {
|
||||
// Restore text content
|
||||
if (node.__originalContent !== undefined) {
|
||||
node.textContent = node.__originalContent
|
||||
delete node.__originalContent
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
element.removeAttribute('data-original-visibility')
|
||||
}
|
||||
|
||||
element.classList.remove('translation-source-hidden')
|
||||
}
|
||||
|
||||
async #forceTranslateVisibleElements() {
|
||||
// console.log('Force translating visible elements')
|
||||
|
||||
const translationPromises = []
|
||||
|
||||
// Find elements in viewport and translate them immediately
|
||||
this.observedElements.forEach(element => {
|
||||
const rect = element.getBoundingClientRect()
|
||||
const isVisible = rect.top < window.innerHeight && rect.bottom > 0
|
||||
|
||||
if (isVisible && !this.#translatedElements.has(element)) {
|
||||
// console.log('Force translating visible element:', element)
|
||||
const translationPromise = this.#translateElement(element).catch(error => {
|
||||
console.warn('Force translation failed:', error)
|
||||
})
|
||||
translationPromises.push(translationPromise)
|
||||
} else if (isVisible && this.#translatedElements.has(element)) {
|
||||
// Element already translated, just update display
|
||||
const translationWrapper = element.querySelector('.translated-text')
|
||||
if (translationWrapper) {
|
||||
this.#updateElementDisplay(element, translationWrapper)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Wait for all visible translations to complete
|
||||
if (translationPromises.length > 0) {
|
||||
// console.log(`Waiting for ${translationPromises.length} translations to complete`)
|
||||
await Promise.allSettled(translationPromises)
|
||||
// console.log('All visible translations completed')
|
||||
}
|
||||
}
|
||||
|
||||
#updateTranslationDisplay() {
|
||||
// console.log('Updating translation display for mode:', this.#translationMode, 'Elements:', this.observedElements.size)
|
||||
this.observedElements.forEach(element => {
|
||||
const translationWrapper = element.querySelector('.translated-text')
|
||||
if (translationWrapper) {
|
||||
// console.log('Updating display for element with translation:', element)
|
||||
this.#updateElementDisplay(element, translationWrapper)
|
||||
} else {
|
||||
// console.log('No translation wrapper found for element:', element)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.clearTranslations()
|
||||
this.#observer = null
|
||||
}
|
||||
}
|
||||
368
assets/foliate-js/src/tts.js
Normal file
368
assets/foliate-js/src/tts.js
Normal file
@@ -0,0 +1,368 @@
|
||||
const blockTags = new Set([
|
||||
'article', 'aside', 'audio', 'blockquote', 'caption',
|
||||
'details', 'dialog', 'div', 'dl', 'dt', 'dd',
|
||||
'figure', 'footer', 'form', 'figcaption',
|
||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li',
|
||||
'main', 'math', 'nav', 'ol', 'p', 'pre', 'section', 'tr',
|
||||
])
|
||||
|
||||
function rangeIsEmpty(range) {
|
||||
return range.collapsed || range.toString().trim() === ''
|
||||
}
|
||||
|
||||
const quoteChars = new Set(['"', "'", '“', '”', '‘', '’'])
|
||||
|
||||
const isLocalLink = href => {
|
||||
if (!href) return false
|
||||
const trimmed = href.trim()
|
||||
if (!trimmed) return false
|
||||
if (trimmed.startsWith('#')) return true
|
||||
return !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)
|
||||
}
|
||||
|
||||
const shouldSkipTextNode = node => {
|
||||
const parent = node.parentElement
|
||||
if (!parent) return false
|
||||
const anchor = parent.closest('a')
|
||||
if (!anchor) return false
|
||||
return isLocalLink(anchor.getAttribute('href'))
|
||||
}
|
||||
|
||||
const getRangeText = range => {
|
||||
const fragment = range.cloneContents()
|
||||
const walker = document.createTreeWalker(fragment, NodeFilter.SHOW_TEXT)
|
||||
let text = ''
|
||||
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
|
||||
if (shouldSkipTextNode(node)) continue
|
||||
text += node.textContent ?? ''
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
const findBlockAncestor = node => {
|
||||
let el = node.parentElement
|
||||
while (el && !blockTags.has(el.tagName?.toLowerCase?.())) {
|
||||
el = el.parentElement
|
||||
}
|
||||
return el ?? node.ownerDocument?.body ?? null
|
||||
}
|
||||
|
||||
const isSentenceTerminator = (char, nextChar) => {
|
||||
if (char === '.') {
|
||||
if (!nextChar) return true
|
||||
if (quoteChars.has(nextChar)) return true
|
||||
if (/\s/.test(nextChar)) return true
|
||||
return false
|
||||
}
|
||||
return char === '!' || char === '?' || char === '。' || char === '!' || char === '?'
|
||||
}
|
||||
|
||||
const advancePastQuotes = (text, index) => {
|
||||
let end = index
|
||||
while (end < text.length && quoteChars.has(text[end])) end++
|
||||
return end
|
||||
}
|
||||
|
||||
function* getBlocks(doc) {
|
||||
const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT)
|
||||
let startNode = null
|
||||
let startOffset = 0
|
||||
let currentBlock = null
|
||||
let lastNode = null
|
||||
let lastOffset = 0
|
||||
|
||||
const flushRange = () => {
|
||||
if (!startNode || !lastNode) return null
|
||||
const range = doc.createRange()
|
||||
range.setStart(startNode, startOffset)
|
||||
range.setEnd(lastNode, lastOffset)
|
||||
startNode = null
|
||||
startOffset = 0
|
||||
currentBlock = null
|
||||
lastNode = null
|
||||
lastOffset = 0
|
||||
if (rangeIsEmpty(range)) return null
|
||||
return range
|
||||
}
|
||||
|
||||
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
|
||||
if (!node.textContent) continue
|
||||
if (shouldSkipTextNode(node)) continue
|
||||
|
||||
const block = findBlockAncestor(node)
|
||||
|
||||
if (!startNode) {
|
||||
startNode = node
|
||||
startOffset = 0
|
||||
currentBlock = block
|
||||
} else if (block !== currentBlock) {
|
||||
const range = flushRange()
|
||||
if (range) yield range
|
||||
startNode = node
|
||||
startOffset = 0
|
||||
currentBlock = block
|
||||
}
|
||||
|
||||
const text = node.textContent
|
||||
let index = 0
|
||||
while (index < text.length) {
|
||||
const char = text[index]
|
||||
const nextChar = text[index + 1]
|
||||
if (isSentenceTerminator(char, nextChar)) {
|
||||
const endOffset = advancePastQuotes(text, index + 1)
|
||||
const range = doc.createRange()
|
||||
range.setStart(startNode, startOffset)
|
||||
range.setEnd(node, endOffset)
|
||||
if (!rangeIsEmpty(range)) yield range
|
||||
startNode = node
|
||||
startOffset = endOffset
|
||||
lastNode = node
|
||||
lastOffset = endOffset
|
||||
index = endOffset
|
||||
continue
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
|
||||
lastNode = node
|
||||
lastOffset = text.length
|
||||
|
||||
if (startNode === node && startOffset === text.length) {
|
||||
startNode = null
|
||||
startOffset = 0
|
||||
currentBlock = null
|
||||
}
|
||||
}
|
||||
|
||||
const remaining = flushRange()
|
||||
if (remaining) yield remaining
|
||||
}
|
||||
|
||||
class ListIterator {
|
||||
#arr = []
|
||||
#iter
|
||||
#index = -1
|
||||
#f
|
||||
constructor(iter, f = x => x) {
|
||||
this.#iter = iter
|
||||
this.#f = f
|
||||
}
|
||||
current() {
|
||||
if (this.#arr[this.#index]) return this.#f(this.#arr[this.#index])
|
||||
}
|
||||
first() {
|
||||
const newIndex = 0
|
||||
if (this.#arr[newIndex]) {
|
||||
this.#index = newIndex
|
||||
return this.#f(this.#arr[newIndex])
|
||||
}
|
||||
}
|
||||
last() {
|
||||
for (const value of this.#iter) this.#arr.push(value)
|
||||
const newIndex = this.#arr.length - 1
|
||||
if (this.#arr[newIndex]) {
|
||||
this.#index = newIndex
|
||||
return this.#f(this.#arr[newIndex])
|
||||
}
|
||||
}
|
||||
prev() {
|
||||
const newIndex = this.#index - 1
|
||||
if (this.#arr[newIndex]) {
|
||||
this.#index = newIndex
|
||||
return this.#f(this.#arr[newIndex])
|
||||
}
|
||||
}
|
||||
next() {
|
||||
const newIndex = this.#index + 1
|
||||
if (this.#arr[newIndex]) {
|
||||
this.#index = newIndex
|
||||
return this.#f(this.#arr[newIndex])
|
||||
}
|
||||
while (true) {
|
||||
const { done, value } = this.#iter.next()
|
||||
if (done) break
|
||||
this.#arr.push(value)
|
||||
if (this.#arr[newIndex]) {
|
||||
this.#index = newIndex
|
||||
return this.#f(this.#arr[newIndex])
|
||||
}
|
||||
}
|
||||
}
|
||||
#ensure(index) {
|
||||
while (this.#arr[index] == null) {
|
||||
const { done, value } = this.#iter.next()
|
||||
if (done) break
|
||||
this.#arr.push(value)
|
||||
if (this.#arr.length - 1 >= index) break
|
||||
}
|
||||
return this.#arr[index]
|
||||
}
|
||||
prepare() {
|
||||
const newIndex = this.#index + 1
|
||||
if (this.#arr[newIndex]) return this.#f(this.#arr[newIndex])
|
||||
while (true) {
|
||||
const { done, value } = this.#iter.next()
|
||||
if (done) break
|
||||
this.#arr.push(value)
|
||||
if (this.#arr[newIndex]) return this.#f(this.#arr[newIndex])
|
||||
}
|
||||
}
|
||||
peek(count = 1, offset = 1) {
|
||||
if (count <= 0) return []
|
||||
const startIndex = Math.max(this.#index + offset, 0)
|
||||
const results = []
|
||||
const endIndex = startIndex + count
|
||||
for (let idx = startIndex; idx < endIndex; idx++) {
|
||||
const value = this.#arr[idx] ?? this.#ensure(idx)
|
||||
if (!value) break
|
||||
results.push(this.#f(value))
|
||||
}
|
||||
return results
|
||||
}
|
||||
find(f) {
|
||||
const index = this.#arr.findIndex(x => f(x))
|
||||
if (index > -1) {
|
||||
this.#index = index
|
||||
return this.#f(this.#arr[index])
|
||||
}
|
||||
while (true) {
|
||||
const { done, value } = this.#iter.next()
|
||||
if (done) break
|
||||
this.#arr.push(value)
|
||||
if (f(value)) {
|
||||
this.#index = this.#arr.length - 1
|
||||
return this.#f(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class TTS {
|
||||
#list
|
||||
#lastMark
|
||||
#getCfi
|
||||
constructor(doc, textWalker, highlight, getCfi) {
|
||||
this.doc = doc
|
||||
this.highlight = highlight
|
||||
this.#getCfi = getCfi
|
||||
this.#list = new ListIterator(getBlocks(doc), range => {
|
||||
return [getRangeText(range), range]
|
||||
})
|
||||
}
|
||||
|
||||
#getText(text, getNode) {
|
||||
if (!text) return ''
|
||||
if (!getNode) return text
|
||||
const tempElement = document.createElement('div')
|
||||
tempElement.innerHTML = text
|
||||
let node = getNode(tempElement)?.previousSibling
|
||||
while (node) {
|
||||
const next = node.previousSibling ?? node.parentNode?.previousSibling
|
||||
node.parentNode.removeChild(node)
|
||||
node = next
|
||||
}
|
||||
return tempElement.textContent
|
||||
}
|
||||
|
||||
#ensureCurrentEntry() {
|
||||
const current = this.#list.current()
|
||||
if (current) return current
|
||||
return this.#list.first() ?? this.#list.next()
|
||||
}
|
||||
|
||||
#resultFrom(entry, { highlight = false } = {}) {
|
||||
if (!entry) return null
|
||||
const [text, range] = entry
|
||||
if (!text || !range) return null
|
||||
const plainText = this.#getText(text)
|
||||
let cfi = null
|
||||
if (highlight && this.highlight && range.cloneRange) {
|
||||
cfi = this.highlight(range.cloneRange()) ?? null
|
||||
}
|
||||
if (!cfi && this.#getCfi && range.cloneRange) {
|
||||
cfi = this.#getCfi(range.cloneRange())
|
||||
}
|
||||
return { text: plainText, cfi }
|
||||
}
|
||||
|
||||
start() {
|
||||
this.#lastMark = null
|
||||
const entry = this.#list.first()
|
||||
if (!entry) return this.next()
|
||||
return this.#resultFrom(entry, { highlight: true })?.text
|
||||
}
|
||||
|
||||
end() {
|
||||
this.#lastMark = null
|
||||
const entry = this.#list.last()
|
||||
if (!entry) return this.next()
|
||||
return this.#resultFrom(entry, { highlight: true })?.text
|
||||
}
|
||||
|
||||
resume() {
|
||||
const entry = this.#list.current()
|
||||
if (!entry) return this.next()
|
||||
return this.#resultFrom(entry)?.text
|
||||
}
|
||||
|
||||
prev(paused) {
|
||||
this.#lastMark = null
|
||||
const entry = this.#list.prev()
|
||||
if (paused && entry?.[1]) this.highlight(entry[1].cloneRange())
|
||||
return this.#resultFrom(entry)?.text
|
||||
}
|
||||
|
||||
next(paused) {
|
||||
this.#lastMark = null
|
||||
const entry = this.#list.next()
|
||||
if (paused && entry?.[1]) this.highlight(entry[1].cloneRange())
|
||||
return this.#resultFrom(entry)?.text
|
||||
}
|
||||
|
||||
// get next text without moving the iterator
|
||||
prepare() {
|
||||
const entry = this.#list.prepare()
|
||||
return this.#resultFrom(entry)?.text
|
||||
}
|
||||
|
||||
from(range) {
|
||||
this.#lastMark = null
|
||||
const entry = this.#list.find(range_ =>
|
||||
range.compareBoundaryPoints(Range.END_TO_START, range_) <= 0)
|
||||
if (entry?.[1]) this.highlight(entry[1].cloneRange())
|
||||
return this.#resultFrom(entry)?.text
|
||||
}
|
||||
|
||||
currentDetail() {
|
||||
const entry = this.#ensureCurrentEntry()
|
||||
return this.#resultFrom(entry)
|
||||
}
|
||||
|
||||
collectDetails(count = 1, { includeCurrent = false, offset = 1 } = {}) {
|
||||
if (!Number.isFinite(count) || count <= 0) return []
|
||||
const details = []
|
||||
if (includeCurrent) {
|
||||
const entry = this.#ensureCurrentEntry()
|
||||
const detail = this.#resultFrom(entry)
|
||||
if (detail) details.push(detail)
|
||||
}
|
||||
const needed = count - details.length
|
||||
if (needed <= 0) return details
|
||||
const entries = this.#list.peek(needed, offset)
|
||||
for (const entry of entries) {
|
||||
const detail = this.#resultFrom(entry)
|
||||
if (detail) details.push(detail)
|
||||
}
|
||||
return details
|
||||
}
|
||||
|
||||
highlightCfi(cfi) {
|
||||
if (!cfi) return null
|
||||
const entry = this.#list.find(range => {
|
||||
const candidate = this.#getCfi?.(range.cloneRange?.())
|
||||
return candidate === cfi
|
||||
})
|
||||
if (!entry) return null
|
||||
return this.#resultFrom(entry, { highlight: true })
|
||||
}
|
||||
}
|
||||
52
assets/foliate-js/src/uri-template.js
Normal file
52
assets/foliate-js/src/uri-template.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// URI Template: https://datatracker.ietf.org/doc/html/rfc6570
|
||||
|
||||
const regex = /{([+#./;?&])?([^}]+?)}/g
|
||||
const varspecRegex = /(.+?)(\*|:[1-9]\d{0,3})?$/
|
||||
|
||||
const table = {
|
||||
undefined: { first: '', sep: ',' },
|
||||
'+': { first: '', sep: ',', allowReserved: true },
|
||||
'.': { first: '.', sep: '.' },
|
||||
'/': { first: '/', sep: '/' },
|
||||
';': { first: ';', sep: ';', named: true, ifemp: '' },
|
||||
'?': { first: '?', sep: '&', named: true, ifemp: '=' },
|
||||
'&': { first: '&', sep: '&', named: true, ifemp: '=' },
|
||||
'#': { first: '&', sep: '&', allowReserved: true },
|
||||
}
|
||||
|
||||
// 2.4.1 Prefix Values, "Note that this numbering is in characters, not octets"
|
||||
const prefix = (maxLength, str) => {
|
||||
let result = ''
|
||||
for (const char of str) {
|
||||
const newResult = char
|
||||
if (newResult.length > maxLength) return result
|
||||
else result = newResult
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const replace = (str, map) => str.replace(regex, (_, operator, variableList) => {
|
||||
const { first, sep, named, ifemp, allowReserved } = table[operator]
|
||||
// TODO: this isn't spec compliant
|
||||
const encode = allowReserved ? encodeURI : encodeURIComponent
|
||||
const values = variableList.split(',').map(varspec => {
|
||||
const match = varspec.match(varspecRegex)
|
||||
if (!match) return
|
||||
const [, name, modifier] = match
|
||||
let value = map.get(name)
|
||||
if (modifier?.startsWith(':')) {
|
||||
const maxLength = parseInt(modifier.slice(1))
|
||||
value = prefix(maxLength, value)
|
||||
}
|
||||
return [name, value ? encode(value) : null]
|
||||
})
|
||||
if (!values.filter(([, value]) => value).length) return ''
|
||||
return first + values
|
||||
.map(([name, value]) => value
|
||||
? (named ? name + (value ? '=' + value : ifemp) : value) : '')
|
||||
.filter(x => x).join(sep)
|
||||
})
|
||||
|
||||
export const getVariables = str => new Set(Array.from(str.matchAll(regex),
|
||||
([,, variableList]) => variableList.split(',')
|
||||
.map(varspec => varspec.match(varspecRegex)?.[1])).flat())
|
||||
1
assets/foliate-js/src/vendor/fflate.js
vendored
Normal file
1
assets/foliate-js/src/vendor/fflate.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var r=Uint8Array,e=Uint16Array,a=Uint32Array,n=new r([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),t=new r([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),i=new r([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),f=function(r,n){for(var t=new e(31),i=0;i<31;++i)t[i]=n+=1<<r[i-1];var f=new a(t[30]);for(i=1;i<30;++i)for(var o=t[i];o<t[i+1];++o)f[o]=o-t[i]<<5|i;return[t,f]},o=f(n,2),v=o[0],l=o[1];v[28]=258,l[258]=28;for(var u=f(t,0)[0],c=new e(32768),d=0;d<32768;++d){var s=(43690&d)>>>1|(21845&d)<<1;s=(61680&(s=(52428&s)>>>2|(13107&s)<<2))>>>4|(3855&s)<<4,c[d]=((65280&s)>>>8|(255&s)<<8)>>>1}var w=function(r,a,n){for(var t=r.length,i=0,f=new e(a);i<t;++i)r[i]&&++f[r[i]-1];var o,v=new e(a);for(i=0;i<a;++i)v[i]=v[i-1]+f[i-1]<<1;if(n){o=new e(1<<a);var l=15-a;for(i=0;i<t;++i)if(r[i])for(var u=i<<4|r[i],d=a-r[i],s=v[r[i]-1]++<<d,w=s|(1<<d)-1;s<=w;++s)o[c[s]>>>l]=u}else for(o=new e(t),i=0;i<t;++i)r[i]&&(o[i]=c[v[r[i]-1]++]>>>15-r[i]);return o},b=new r(288);for(d=0;d<144;++d)b[d]=8;for(d=144;d<256;++d)b[d]=9;for(d=256;d<280;++d)b[d]=7;for(d=280;d<288;++d)b[d]=8;var h=new r(32);for(d=0;d<32;++d)h[d]=5;var E=w(b,9,1),p=w(h,5,1),g=function(r){for(var e=r[0],a=1;a<r.length;++a)r[a]>e&&(e=r[a]);return e},y=function(r,e,a){var n=e/8|0;return(r[n]|r[n+1]<<8)>>(7&e)&a},k=function(r,e){var a=e/8|0;return(r[a]|r[a+1]<<8|r[a+2]<<16)>>(7&e)},T=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],m=function(r,e,a){var n=new Error(e||T[r]);if(n.code=r,Error.captureStackTrace&&Error.captureStackTrace(n,m),!a)throw n;return n},x=function(f,o,l){var c=f.length;if(!c||l&&l.f&&!l.l)return o||new r(0);var d=!o||l,s=!l||l.i;l||(l={}),o||(o=new r(3*c));var b=function(e){var a=o.length;if(e>a){var n=new r(Math.max(2*a,e));n.set(o),o=n}},h=l.f||0,T=l.p||0,x=l.b||0,S=l.l,U=l.d,_=l.m,z=l.n,A=8*c;do{if(!S){h=y(f,T,1);var M=y(f,T+1,3);if(T+=3,!M){var B=f[(C=4+((T+7)/8|0))-4]|f[C-3]<<8,D=C+B;if(D>c){s&&m(0);break}d&&b(x+B),o.set(f.subarray(C,D),x),l.b=x+=B,l.p=T=8*D,l.f=h;continue}if(1==M)S=E,U=p,_=9,z=5;else if(2==M){var F=y(f,T,31)+257,L=y(f,T+10,15)+4,N=F+y(f,T+5,31)+1;T+=14;for(var P=new r(N),R=new r(19),Y=0;Y<L;++Y)R[i[Y]]=y(f,T+3*Y,7);T+=3*L;var O=g(R),j=(1<<O)-1,q=w(R,O,1);for(Y=0;Y<N;){var C,G=q[y(f,T,j)];if(T+=15&G,(C=G>>>4)<16)P[Y++]=C;else{var H=0,I=0;for(16==C?(I=3+y(f,T,3),T+=2,H=P[Y-1]):17==C?(I=3+y(f,T,7),T+=3):18==C&&(I=11+y(f,T,127),T+=7);I--;)P[Y++]=H}}var J=P.subarray(0,F),K=P.subarray(F);_=g(J),z=g(K),S=w(J,_,1),U=w(K,z,1)}else m(1);if(T>A){s&&m(0);break}}d&&b(x+131072);for(var Q=(1<<_)-1,V=(1<<z)-1,W=T;;W=T){var X=(H=S[k(f,T)&Q])>>>4;if((T+=15&H)>A){s&&m(0);break}if(H||m(2),X<256)o[x++]=X;else{if(256==X){W=T,S=null;break}var Z=X-254;if(X>264){var $=n[Y=X-257];Z=y(f,T,(1<<$)-1)+v[Y],T+=$}var rr=U[k(f,T)&V],er=rr>>>4;rr||m(3),T+=15&rr;K=u[er];if(er>3){$=t[er];K+=k(f,T)&(1<<$)-1,T+=$}if(T>A){s&&m(0);break}d&&b(x+131072);for(var ar=x+Z;x<ar;x+=4)o[x]=o[x-K],o[x+1]=o[x+1-K],o[x+2]=o[x+2-K],o[x+3]=o[x+3-K];x=ar}}l.l=S,l.p=W,l.b=x,l.f=h,S&&(h=1,l.m=_,l.d=U,l.n=z)}while(!h);return x==o.length?o:function(n,t,i){(null==t||t<0)&&(t=0),(null==i||i>n.length)&&(i=n.length);var f=new(2==n.BYTES_PER_ELEMENT?e:4==n.BYTES_PER_ELEMENT?a:r)(i-t);return f.set(n.subarray(t,i)),f}(o,0,x)},S=new r(0);function U(r,e){return x(((8!=(15&(a=r)[0])||a[0]>>>4>7||(a[0]<<8|a[1])%31)&&m(6,"invalid zlib data"),32&a[1]&&m(6,"invalid zlib data: preset dictionaries not supported"),r.subarray(2,-4)),e);var a}var _="undefined"!=typeof TextDecoder&&new TextDecoder;try{_.decode(S,{stream:!0}),1}catch(r){}export{U as unzlibSync};
|
||||
18146
assets/foliate-js/src/vendor/pdfjs/pdf.js
vendored
Normal file
18146
assets/foliate-js/src/vendor/pdfjs/pdf.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
58353
assets/foliate-js/src/vendor/pdfjs/pdf.worker.js
vendored
Normal file
58353
assets/foliate-js/src/vendor/pdfjs/pdf.worker.js
vendored
Normal file
File diff suppressed because one or more lines are too long
116
assets/foliate-js/src/vendor/prism/README.md
vendored
Normal file
116
assets/foliate-js/src/vendor/prism/README.md
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
# Prism.js Code Syntax Highlighting
|
||||
|
||||
This directory contains the Prism.js library for code syntax highlighting in Anx Reader.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
prism/
|
||||
├── prism-core.min.js # Core Prism.js library
|
||||
├── prism-autoloader.min.js # Automatic language loading plugin
|
||||
├── components/ # Language definition files (62 languages)
|
||||
│ ├── prism-javascript.min.js
|
||||
│ ├── prism-python.min.js
|
||||
│ ├── prism-java.min.js
|
||||
│ └── ... (62 files total)
|
||||
├── themes/ # CSS themes (12 themes)
|
||||
│ ├── prism-default.min.css
|
||||
│ ├── prism-vs-dark.min.css
|
||||
│ ├── prism-one-dark.min.css
|
||||
│ └── ... (12 files total)
|
||||
└── download_components.sh # Script to download additional languages
|
||||
```
|
||||
|
||||
## Supported Languages (62)
|
||||
|
||||
The following languages are included for offline use:
|
||||
|
||||
### Web Development
|
||||
- JavaScript, TypeScript, JSX, TSX
|
||||
- HTML/XML (markup), CSS, Sass, SCSS, Less
|
||||
- PHP, PHP-Extras
|
||||
- JSON, YAML, TOML
|
||||
- Markdown, LaTeX
|
||||
|
||||
### System & Scripting
|
||||
- Bash, Shell Session, PowerShell, Batch
|
||||
- Python, Ruby, Perl, Lua, R
|
||||
|
||||
### Compiled Languages
|
||||
- C, C++, C#, Objective-C
|
||||
- Java, Kotlin, Scala, Groovy
|
||||
- Go, Rust, Swift, Dart
|
||||
|
||||
### Functional Languages
|
||||
- Haskell, Elixir, Erlang, Julia
|
||||
|
||||
### Database
|
||||
- SQL, PL/SQL, MongoDB
|
||||
|
||||
### Configuration & DevOps
|
||||
- Docker, Git, Diff
|
||||
- Nginx, Makefile
|
||||
- INI, Properties
|
||||
|
||||
### Other
|
||||
- GraphQL, Protobuf
|
||||
- Regex, HTTP
|
||||
- Visual Basic, VB.NET
|
||||
|
||||
## Themes (12)
|
||||
|
||||
### Light Themes (4)
|
||||
1. **Default** - Classic Prism theme
|
||||
2. **GitHub** - GitHub-style highlighting
|
||||
3. **One Light** - Atom One Light theme
|
||||
4. **Material Light** - Material Design light theme
|
||||
|
||||
### Dark Themes (8)
|
||||
1. **VS Dark** - Visual Studio Code dark theme
|
||||
2. **One Dark** - Atom One Dark theme
|
||||
3. **Dracula** - Popular Dracula theme
|
||||
4. **Material Dark** - Material Design dark theme
|
||||
5. **Nord** - Nord color palette
|
||||
6. **Night Owl** - Night Owl theme
|
||||
7. **Solarized Dark** - Solarized dark variant
|
||||
8. **Atom Dark** - Atom editor dark theme
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Automatic Detection**: When a code block is detected, Prism.js automatically identifies the language
|
||||
2. **Local Loading**: The autoloader loads the required language file from `components/` folder
|
||||
3. **Offline Support**: All 62 language files are pre-downloaded for offline use
|
||||
4. **No Network Required**: Everything works without internet connection
|
||||
|
||||
## Adding More Languages
|
||||
|
||||
If you need additional languages not included in the default set:
|
||||
|
||||
1. Visit: https://github.com/PrismJS/prism/tree/master/components
|
||||
2. Download the required `prism-{language}.min.js` file
|
||||
3. Place it in the `components/` folder
|
||||
|
||||
Or use the included download script:
|
||||
|
||||
```bash
|
||||
cd assets/foliate-js/src/vendor/prism
|
||||
./download_components.sh
|
||||
```
|
||||
|
||||
## Version
|
||||
|
||||
Current version: **Prism.js 1.29.0**
|
||||
|
||||
## Total Size
|
||||
|
||||
- Core + Autoloader: ~13 KB
|
||||
- Themes (12 files): ~30 KB
|
||||
- Languages (62 files): ~272 KB
|
||||
- **Total: ~315 KB**
|
||||
|
||||
## References
|
||||
|
||||
- Official Website: https://prismjs.com/
|
||||
- GitHub: https://github.com/PrismJS/prism
|
||||
- Documentation: https://prismjs.com/docs/
|
||||
- Language List: https://prismjs.com/#supported-languages
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-bash.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-bash.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/components/prism-basic.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-basic.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.basic={comment:{pattern:/(?:!|REM\b).+/i,inside:{keyword:/^REM/i}},string:{pattern:/"(?:""|[!#$%&'()*,\/:;<=>?^\w +\-.])*"/,greedy:!0},number:/(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:E[+-]?\d+)?/i,keyword:/\b(?:AS|BEEP|BLOAD|BSAVE|CALL(?: ABSOLUTE)?|CASE|CHAIN|CHDIR|CLEAR|CLOSE|CLS|COM|COMMON|CONST|DATA|DECLARE|DEF(?: FN| SEG|DBL|INT|LNG|SNG|STR)|DIM|DO|DOUBLE|ELSE|ELSEIF|END|ENVIRON|ERASE|ERROR|EXIT|FIELD|FILES|FOR|FUNCTION|GET|GOSUB|GOTO|IF|INPUT|INTEGER|IOCTL|KEY|KILL|LINE INPUT|LOCATE|LOCK|LONG|LOOP|LSET|MKDIR|NAME|NEXT|OFF|ON(?: COM| ERROR| KEY| TIMER)?|OPEN|OPTION BASE|OUT|POKE|PUT|READ|REDIM|REM|RESTORE|RESUME|RETURN|RMDIR|RSET|RUN|SELECT CASE|SHARED|SHELL|SINGLE|SLEEP|STATIC|STEP|STOP|STRING|SUB|SWAP|SYSTEM|THEN|TIMER|TO|TROFF|TRON|TYPE|UNLOCK|UNTIL|USING|VIEW PRINT|WAIT|WEND|WHILE|WRITE)(?:\$|\b)/i,function:/\b(?:ABS|ACCESS|ACOS|ANGLE|AREA|ARITHMETIC|ARRAY|ASIN|ASK|AT|ATN|BASE|BEGIN|BREAK|CAUSE|CEIL|CHR|CLIP|COLLATE|COLOR|CON|COS|COSH|COT|CSC|DATE|DATUM|DEBUG|DECIMAL|DEF|DEG|DEGREES|DELETE|DET|DEVICE|DISPLAY|DOT|ELAPSED|EPS|ERASABLE|EXLINE|EXP|EXTERNAL|EXTYPE|FILETYPE|FIXED|FP|GO|GRAPH|HANDLER|IDN|IMAGE|IN|INT|INTERNAL|IP|IS|KEYED|LBOUND|LCASE|LEFT|LEN|LENGTH|LET|LINE|LINES|LOG|LOG10|LOG2|LTRIM|MARGIN|MAT|MAX|MAXNUM|MID|MIN|MISSING|MOD|NATIVE|NUL|NUMERIC|OF|OPTION|ORD|ORGANIZATION|OUTIN|OUTPUT|PI|POINT|POINTER|POINTS|POS|PRINT|PROGRAM|PROMPT|RAD|RADIANS|RANDOMIZE|RECORD|RECSIZE|RECTYPE|RELATIVE|REMAINDER|REPEAT|REST|RETRY|REWRITE|RIGHT|RND|ROUND|RTRIM|SAME|SEC|SELECT|SEQUENTIAL|SET|SETTER|SGN|SIN|SINH|SIZE|SKIP|SQR|STANDARD|STATUS|STR|STREAM|STYLE|TAB|TAN|TANH|TEMPLATE|TEXT|THERE|TIME|TIMEOUT|TRACE|TRANSFORM|TRUNCATE|UBOUND|UCASE|USE|VAL|VARIABLE|VIEWPORT|WHEN|WINDOW|WITH|ZER|ZONEWIDTH)(?:\$|\b)/i,operator:/<[=>]?|>=?|[+\-*\/^=&]|\b(?:AND|EQV|IMP|NOT|OR|XOR)\b/i,punctuation:/[,;:()]/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-batch.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-batch.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var r=/%%?[~:\w]+%?|!\S+!/,t={pattern:/\/[a-z?]+(?=[ :]|$):?|-[a-z]\b|--[a-z-]+\b/im,alias:"attr-name",inside:{punctuation:/:/}},n=/"(?:[\\"]"|[^"])*"(?!")/,i=/(?:\b|-)\d+\b/;e.languages.batch={comment:[/^::.*/m,{pattern:/((?:^|[&(])[ \t]*)rem\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0}],label:{pattern:/^:.*/m,alias:"property"},command:[{pattern:/((?:^|[&(])[ \t]*)for(?: \/[a-z?](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* \S+ in \([^)]+\) do/im,lookbehind:!0,inside:{keyword:/\b(?:do|in)\b|^for\b/i,string:n,parameter:t,variable:r,number:i,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*)if(?: \/[a-z?](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* (?:not )?(?:cmdextversion \d+|defined \w+|errorlevel \d+|exist \S+|(?:"[^"]*"|(?!")(?:(?!==)\S)+)?(?:==| (?:equ|geq|gtr|leq|lss|neq) )(?:"[^"]*"|[^\s"]\S*))/im,lookbehind:!0,inside:{keyword:/\b(?:cmdextversion|defined|errorlevel|exist|not)\b|^if\b/i,string:n,parameter:t,variable:r,number:i,operator:/\^|==|\b(?:equ|geq|gtr|leq|lss|neq)\b/i}},{pattern:/((?:^|[&()])[ \t]*)else\b/im,lookbehind:!0,inside:{keyword:/^else\b/i}},{pattern:/((?:^|[&(])[ \t]*)set(?: \/[a-z](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* (?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0,inside:{keyword:/^set\b/i,string:n,parameter:t,variable:[r,/\w+(?=(?:[*\/%+\-&^|]|<<|>>)?=)/],number:i,operator:/[*\/%+\-&^|]=?|<<=?|>>=?|[!~_=]/,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*@?)\w+\b(?:"(?:[\\"]"|[^"])*"(?!")|[^"^&)\r\n]|\^(?:\r\n|[\s\S]))*/m,lookbehind:!0,inside:{keyword:/^\w+\b/,string:n,parameter:t,label:{pattern:/(^\s*):\S+/m,lookbehind:!0,alias:"property"},variable:r,number:i,operator:/\^/}}],operator:/[&@]/,punctuation:/[()']/}}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-c.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-c.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.c=Prism.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),Prism.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],char:Prism.languages.c.char,comment:Prism.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}}}),Prism.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete Prism.languages.c.boolean;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-clike.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-clike.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-core.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-core.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/components/prism-cpp.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-cpp.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n="\\b(?!<keyword>)\\w+(?:\\s*\\.\\s*\\w+)*\\b".replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!<keyword>)\\w+".replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp('(\\b(?:import|module)\\s+)(?:"(?:\\\\(?:\r\n|[^])|[^"\\\\\r\n])*"|<[^<>\r\n]*>|'+"<mod-name>(?:\\s*:\\s*<mod-name>)?|:\\s*<mod-name>".replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-csharp.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-csharp.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/components/prism-css.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-css.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|"+e.source+")*?(?:;|(?=\\s*\\{))"),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-dart.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-dart.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var a=[/\b(?:async|sync|yield)\*/,/\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|covariant|default|deferred|do|dynamic|else|enum|export|extends|extension|external|factory|final|finally|for|get|hide|if|implements|import|in|interface|library|mixin|new|null|on|operator|part|rethrow|return|set|show|static|super|switch|sync|this|throw|try|typedef|var|void|while|with|yield)\b/],n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}}}};e.languages.dart=e.languages.extend("clike",{"class-name":[s,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()])"),lookbehind:!0,inside:s.inside}],keyword:a,operator:/\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/}),e.languages.insertBefore("dart","string",{"string-literal":{pattern:/r?(?:("""|''')[\s\S]*?\1|(["'])(?:\\.|(?!\2)[^\\\r\n])*\2(?!\2))/,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,lookbehind:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:e.languages.dart}}},string:/[\s\S]+/}},string:void 0}),e.languages.insertBefore("dart","class-name",{metadata:{pattern:/@\w+/,alias:"function"}}),e.languages.insertBefore("dart","class-name",{generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":s,keyword:a,punctuation:/[<>(),.:]/,operator:/[?&|]/}}})}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-diff.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-diff.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var n={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(n).forEach((function(a){var i=n[a],r=[];/^\w+$/.test(a)||r.push(/\w+/.exec(a)[0]),"diff"===a&&r.push("bold"),e.languages.diff[a]={pattern:RegExp("^(?:["+i+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:r,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(a)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:n})}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-docker.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-docker.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var n="(?:[ \t]+(?![ \t])(?:<SP_BS>)?|<SP_BS>)".replace(/<SP_BS>/g,(function(){return"\\\\[\r\n](?:\\s|\\\\[\r\n]|#.*(?!.))*(?![\\s#]|\\\\[\r\n])"})),r="\"(?:[^\"\\\\\r\n]|\\\\(?:\r\n|[^]))*\"|'(?:[^'\\\\\r\n]|\\\\(?:\r\n|[^]))*'",t="--[\\w-]+=(?:<STR>|(?![\"'])(?:[^\\s\\\\]|\\\\.)+)".replace(/<STR>/g,(function(){return r})),o={pattern:RegExp(r),greedy:!0},i={pattern:/(^[ \t]*)#.*/m,lookbehind:!0,greedy:!0};function a(e,r){return e=e.replace(/<OPT>/g,(function(){return t})).replace(/<SP>/g,(function(){return n})),RegExp(e,r)}e.languages.docker={instruction:{pattern:/(^[ \t]*)(?:ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|ONBUILD|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR)(?=\s)(?:\\.|[^\r\n\\])*(?:\\$(?:\s|#.*$)*(?![\s#])(?:\\.|[^\r\n\\])*)*/im,lookbehind:!0,greedy:!0,inside:{options:{pattern:a("(^(?:ONBUILD<SP>)?\\w+<SP>)<OPT>(?:<SP><OPT>)*","i"),lookbehind:!0,greedy:!0,inside:{property:{pattern:/(^|\s)--[\w-]+/,lookbehind:!0},string:[o,{pattern:/(=)(?!["'])(?:[^\s\\]|\\.)+/,lookbehind:!0}],operator:/\\$/m,punctuation:/=/}},keyword:[{pattern:a("(^(?:ONBUILD<SP>)?HEALTHCHECK<SP>(?:<OPT><SP>)*)(?:CMD|NONE)\\b","i"),lookbehind:!0,greedy:!0},{pattern:a("(^(?:ONBUILD<SP>)?FROM<SP>(?:<OPT><SP>)*(?!--)[^ \t\\\\]+<SP>)AS","i"),lookbehind:!0,greedy:!0},{pattern:a("(^ONBUILD<SP>)\\w+","i"),lookbehind:!0,greedy:!0},{pattern:/^\w+/,greedy:!0}],comment:i,string:o,variable:/\$(?:\w+|\{[^{}"'\\]*\})/,operator:/\\$/m}},comment:i},e.languages.dockerfile=e.languages.docker}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-elixir.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-elixir.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.elixir={doc:{pattern:/@(?:doc|moduledoc)\s+(?:("""|''')[\s\S]*?\1|("|')(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2)/,inside:{attribute:/^@\w+/,string:/['"][\s\S]+/}},comment:{pattern:/#.*/,greedy:!0},regex:{pattern:/~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/,greedy:!0},string:[{pattern:/~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|#(?!\{)|[^#\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/,greedy:!0,inside:{}},{pattern:/("""|''')[\s\S]*?\1/,greedy:!0,inside:{}},{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{}}],atom:{pattern:/(^|[^:]):\w+/,lookbehind:!0,alias:"symbol"},module:{pattern:/\b[A-Z]\w*\b/,alias:"class-name"},"attr-name":/\b\w+\??:(?!:)/,argument:{pattern:/(^|[^&])&\d+/,lookbehind:!0,alias:"variable"},attribute:{pattern:/@\w+/,alias:"variable"},function:/\b[_a-zA-Z]\w*[?!]?(?:(?=\s*(?:\.\s*)?\()|(?=\/\d))/,number:/\b(?:0[box][a-f\d_]+|\d[\d_]*)(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?\b/i,keyword:/\b(?:after|alias|and|case|catch|cond|def(?:callback|delegate|exception|impl|macro|module|n|np|p|protocol|struct)?|do|else|end|fn|for|if|import|not|or|quote|raise|require|rescue|try|unless|unquote|use|when)\b/,boolean:/\b(?:false|nil|true)\b/,operator:[/\bin\b|&&?|\|[|>]?|\\\\|::|\.\.\.?|\+\+?|-[->]?|<[-=>]|>=|!==?|\B!|=(?:==?|[>~])?|[*\/^]/,{pattern:/([^<])<(?!<)/,lookbehind:!0},{pattern:/([^>])>(?!>)/,lookbehind:!0}],punctuation:/<<|>>|[.,%\[\]{}()]/},Prism.languages.elixir.string.forEach((function(e){e.inside={interpolation:{pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"},rest:Prism.languages.elixir}}}}));
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-erlang.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-erlang.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.erlang={comment:/%.+/,string:{pattern:/"(?:\\.|[^\\"\r\n])*"/,greedy:!0},"quoted-function":{pattern:/'(?:\\.|[^\\'\r\n])+'(?=\()/,alias:"function"},"quoted-atom":{pattern:/'(?:\\.|[^\\'\r\n])+'/,alias:"atom"},boolean:/\b(?:false|true)\b/,keyword:/\b(?:after|begin|case|catch|end|fun|if|of|receive|try|when)\b/,number:[/\$\\?./,/\b\d+#[a-z0-9]+/i,/(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i],function:/\b[a-z][\w@]*(?=\()/,variable:{pattern:/(^|[^@])(?:\b|\?)[A-Z_][\w@]*/,lookbehind:!0},operator:[/[=\/<>:]=|=[:\/]=|\+\+?|--?|[=*\/!]|\b(?:and|andalso|band|bnot|bor|bsl|bsr|bxor|div|not|or|orelse|rem|xor)\b/,{pattern:/(^|[^<])<(?!<)/,lookbehind:!0},{pattern:/(^|[^>])>(?!>)/,lookbehind:!0}],atom:/\b[a-z][\w@]*/,punctuation:/[()[\]{}:;,.#|]|<<|>>/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-git.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-git.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.git={comment:/^#.*/m,deleted:/^[-–].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-go.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-go.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.go=Prism.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),Prism.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete Prism.languages.go["class-name"];
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-graphql.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-graphql.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:Prism.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},Prism.hooks.add("after-tokenize",(function(n){if("graphql"===n.language)for(var t=n.tokens.filter((function(n){return"string"!=typeof n&&"comment"!==n.type&&"scalar"!==n.type})),e=0;e<t.length;){var a=t[e++];if("keyword"===a.type&&"mutation"===a.content){var r=[];if(c(["definition-mutation","punctuation"])&&"("===l(1).content){e+=2;var i=f(/^\($/,/^\)$/);if(-1===i)continue;for(;e<i;e++){var o=l(0);"variable"===o.type&&(b(o,"variable-input"),r.push(o.content))}e=i+1}if(c(["punctuation","property-query"])&&"{"===l(0).content&&(e++,b(l(0),"property-mutation"),r.length>0)){var s=f(/^\{$/,/^\}$/);if(-1===s)continue;for(var u=e;u<s;u++){var p=t[u];"variable"===p.type&&r.indexOf(p.content)>=0&&b(p,"variable-input")}}}}function l(n){return t[e+n]}function c(n,t){t=t||0;for(var e=0;e<n.length;e++){var a=l(e+t);if(!a||a.type!==n[e])return!1}return!0}function f(n,a){for(var r=1,i=e;i<t.length;i++){var o=t[i],s=o.content;if("punctuation"===o.type&&"string"==typeof s)if(n.test(s))r++;else if(a.test(s)&&0==--r)return i}return-1}function b(n,t){var e=n.alias;e?Array.isArray(e)||(n.alias=e=[e]):n.alias=e=[],e.push(t)}}));
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-groovy.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-groovy.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var n={pattern:/((?:^|[^\\$])(?:\\{2})*)\$(?:\w+|\{[^{}]*\})/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:null}}};e.languages.groovy=e.languages.extend("clike",{string:{pattern:/'''(?:[^\\]|\\[\s\S])*?'''|'(?:\\.|[^\\'\r\n])*'/,greedy:!0},keyword:/\b(?:abstract|as|assert|boolean|break|byte|case|catch|char|class|const|continue|def|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|in|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,number:/\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?\d+)?)[glidf]?\b/i,operator:{pattern:/(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,lookbehind:!0},punctuation:/\.+|[{}[\];(),:$]/}),e.languages.insertBefore("groovy","string",{shebang:{pattern:/#!.+/,alias:"comment",greedy:!0},"interpolation-string":{pattern:/"""(?:[^\\]|\\[\s\S])*?"""|(["/])(?:\\.|(?!\1)[^\\\r\n])*\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,greedy:!0,inside:{interpolation:n,string:/[\s\S]+/}}}),e.languages.insertBefore("groovy","punctuation",{"spock-block":/\b(?:and|cleanup|expect|given|setup|then|when|where):/}),e.languages.insertBefore("groovy","function",{annotation:{pattern:/(^|[^.])@\w+/,lookbehind:!0,alias:"punctuation"}}),n.inside.expression.inside=e.languages.groovy}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-haskell.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-haskell.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.haskell={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(?:--(?:(?=.)[^-!#$%*+=?&@|~.:<>^\\\/].*|$)|\{-[\s\S]*?-\})/m,lookbehind:!0},char:{pattern:/'(?:[^\\']|\\(?:[abfnrtv\\"'&]|\^[A-Z@[\]^_]|ACK|BEL|BS|CAN|CR|DC1|DC2|DC3|DC4|DEL|DLE|EM|ENQ|EOT|ESC|ETB|ETX|FF|FS|GS|HT|LF|NAK|NUL|RS|SI|SO|SOH|SP|STX|SUB|SYN|US|VT|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,alias:"string"},string:{pattern:/"(?:[^\\"]|\\(?:\S|\s+\\))*"/,greedy:!0},keyword:/\b(?:case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/,"import-statement":{pattern:/(^[\t ]*)import\s+(?:qualified\s+)?(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*(?:\s+as\s+(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*)?(?:\s+hiding\b)?/m,lookbehind:!0,inside:{keyword:/\b(?:as|hiding|import|qualified)\b/,punctuation:/\./}},builtin:/\b(?:abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/,number:/\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0o[0-7]+|0x[0-9a-f]+)\b/i,operator:[{pattern:/`(?:[A-Z][\w']*\.)*[_a-z][\w']*`/,greedy:!0},{pattern:/(\s)\.(?=\s)/,lookbehind:!0},/[-!#$%*+=?&@|~:<>^\\\/][-!#$%*+=?&@|~.:<>^\\\/]*|\.[-!#$%*+=?&@|~.:<>^\\\/]+/],hvariable:{pattern:/\b(?:[A-Z][\w']*\.)*[_a-z][\w']*/,inside:{punctuation:/\./}},constant:{pattern:/\b(?:[A-Z][\w']*\.)*[A-Z][\w']*/,inside:{punctuation:/\./}},punctuation:/[{}[\];(),.:]/},Prism.languages.hs=Prism.languages.haskell;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-http.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-http.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(t){function a(t){return RegExp("(^(?:"+t+"):[ \t]*(?![ \t]))[^]+","i")}t.languages.http={"request-line":{pattern:/^(?:CONNECT|DELETE|GET|HEAD|OPTIONS|PATCH|POST|PRI|PUT|SEARCH|TRACE)\s(?:https?:\/\/|\/)\S*\sHTTP\/[\d.]+/m,inside:{method:{pattern:/^[A-Z]+\b/,alias:"property"},"request-target":{pattern:/^(\s)(?:https?:\/\/|\/)\S*(?=\s)/,lookbehind:!0,alias:"url",inside:t.languages.uri},"http-version":{pattern:/^(\s)HTTP\/[\d.]+/,lookbehind:!0,alias:"property"}}},"response-status":{pattern:/^HTTP\/[\d.]+ \d+ .+/m,inside:{"http-version":{pattern:/^HTTP\/[\d.]+/,alias:"property"},"status-code":{pattern:/^(\s)\d+(?=\s)/,lookbehind:!0,alias:"number"},"reason-phrase":{pattern:/^(\s).+/,lookbehind:!0,alias:"string"}}},header:{pattern:/^[\w-]+:.+(?:(?:\r\n?|\n)[ \t].+)*/m,inside:{"header-value":[{pattern:a("Content-Security-Policy"),lookbehind:!0,alias:["csp","languages-csp"],inside:t.languages.csp},{pattern:a("Public-Key-Pins(?:-Report-Only)?"),lookbehind:!0,alias:["hpkp","languages-hpkp"],inside:t.languages.hpkp},{pattern:a("Strict-Transport-Security"),lookbehind:!0,alias:["hsts","languages-hsts"],inside:t.languages.hsts},{pattern:a("[^:]+"),lookbehind:!0}],"header-name":{pattern:/^[^:]+/,alias:"keyword"},punctuation:/^:/}}};var e,n=t.languages,s={"application/javascript":n.javascript,"application/json":n.json||n.javascript,"application/xml":n.xml,"text/xml":n.xml,"text/html":n.html,"text/css":n.css,"text/plain":n.plain},i={"application/json":!0,"application/xml":!0};function r(t){var a=t.replace(/^[a-z]+\//,"");return"(?:"+t+"|\\w+/(?:[\\w.-]+\\+)+"+a+"(?![+\\w.-]))"}for(var p in s)if(s[p]){e=e||{};var l=i[p]?r(p):p;e[p.replace(/\//g,"-")]={pattern:RegExp("(content-type:\\s*"+l+"(?:(?:\r\n?|\n)[\\w-].*)*(?:\r(?:\n|(?!\n))|\n))[^ \t\\w-][^]*","i"),lookbehind:!0,inside:s[p]}}e&&t.languages.insertBefore("http","header",e)}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-ini.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-ini.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.ini={comment:{pattern:/(^[ \f\t\v]*)[#;][^\n\r]*/m,lookbehind:!0},section:{pattern:/(^[ \f\t\v]*)\[[^\n\r\]]*\]?/m,lookbehind:!0,inside:{"section-name":{pattern:/(^\[[ \f\t\v]*)[^ \f\t\v\]]+(?:[ \f\t\v]+[^ \f\t\v\]]+)*/,lookbehind:!0,alias:"selector"},punctuation:/\[|\]/}},key:{pattern:/(^[ \f\t\v]*)[^ \f\n\r\t\v=]+(?:[ \f\t\v]+[^ \f\n\r\t\v=]+)*(?=[ \f\t\v]*=)/m,lookbehind:!0,alias:"attr-name"},value:{pattern:/(=[ \f\t\v]*)[^ \f\n\r\t\v]+(?:[ \f\t\v]+[^ \f\n\r\t\v]+)*/,lookbehind:!0,alias:"attr-value",inside:{"inner-value":{pattern:/^("|').+(?=\1$)/,lookbehind:!0}}},punctuation:/=/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-java.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-java.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var n=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,t="(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp("(^|[^\\w.])"+t+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[s,{pattern:RegExp("(^|[^\\w.])"+t+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()]|\\s*(?:\\[[\\s,]*\\]\\s*)?::\\s*new\\b)"),lookbehind:!0,inside:s.inside},{pattern:RegExp("(\\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\\s+)"+t+"[A-Z]\\w*\\b"),lookbehind:!0,inside:s.inside}],keyword:n,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":s,keyword:n,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp("(\\bimport\\s+)"+t+"(?:[A-Z]\\w*|\\*)(?=\\s*;)"),lookbehind:!0,inside:{namespace:s.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp("(\\bimport\\s+static\\s+)"+t+"(?:\\w+|\\*)(?=\\s*;)"),lookbehind:!0,alias:"static",inside:{namespace:s.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(/<keyword>/g,(function(){return n.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-javascript.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-javascript.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))"),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-json.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-json.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-jsx.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-jsx.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(t){var n=t.util.clone(t.languages.javascript),e="(?:\\{<S>*\\.{3}(?:[^{}]|<BRACES>)*\\})";function a(t,n){return t=t.replace(/<S>/g,(function(){return"(?:\\s|//.*(?!.)|/\\*(?:[^*]|\\*(?!/))\\*/)"})).replace(/<BRACES>/g,(function(){return"(?:\\{(?:\\{(?:\\{[^{}]*\\}|[^{}])*\\}|[^{}])*\\})"})).replace(/<SPREAD>/g,(function(){return e})),RegExp(t,n)}e=a(e).source,t.languages.jsx=t.languages.extend("markup",n),t.languages.jsx.tag.pattern=a("</?(?:[\\w.:-]+(?:<S>+(?:[\\w.:$-]+(?:=(?:\"(?:\\\\[^]|[^\\\\\"])*\"|'(?:\\\\[^]|[^\\\\'])*'|[^\\s{'\"/>=]+|<BRACES>))?|<SPREAD>))*<S>*/?)?>"),t.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,t.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,t.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,t.languages.jsx.tag.inside.comment=n.comment,t.languages.insertBefore("inside","attr-name",{spread:{pattern:a("<SPREAD>"),inside:t.languages.jsx}},t.languages.jsx.tag),t.languages.insertBefore("inside","special-attr",{script:{pattern:a("=<BRACES>"),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:t.languages.jsx}}},t.languages.jsx.tag);var s=function(t){return t?"string"==typeof t?t:"string"==typeof t.content?t.content:t.content.map(s).join(""):""},g=function(n){for(var e=[],a=0;a<n.length;a++){var o=n[a],i=!1;if("string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?e.length>0&&e[e.length-1].tagName===s(o.content[0].content[1])&&e.pop():"/>"===o.content[o.content.length-1].content||e.push({tagName:s(o.content[0].content[1]),openedBraces:0}):e.length>0&&"punctuation"===o.type&&"{"===o.content?e[e.length-1].openedBraces++:e.length>0&&e[e.length-1].openedBraces>0&&"punctuation"===o.type&&"}"===o.content?e[e.length-1].openedBraces--:i=!0),(i||"string"==typeof o)&&e.length>0&&0===e[e.length-1].openedBraces){var r=s(o);a<n.length-1&&("string"==typeof n[a+1]||"plain-text"===n[a+1].type)&&(r+=s(n[a+1]),n.splice(a+1,1)),a>0&&("string"==typeof n[a-1]||"plain-text"===n[a-1].type)&&(r=s(n[a-1])+r,n.splice(a-1,1),a--),n[a]=new t.Token("plain-text",r,null,r)}o.content&&"string"!=typeof o.content&&g(o.content)}};t.hooks.add("after-tokenize",(function(t){"jsx"!==t.language&&"tsx"!==t.language||g(t.tokens)}))}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-julia.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-julia.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.julia={comment:{pattern:/(^|[^\\])(?:#=(?:[^#=]|=(?!#)|#(?!=)|#=(?:[^#=]|=(?!#)|#(?!=))*=#)*=#|#.*)/,lookbehind:!0},regex:{pattern:/r"(?:\\.|[^"\\\r\n])*"[imsx]{0,4}/,greedy:!0},string:{pattern:/"""[\s\S]+?"""|(?:\b\w+)?"(?:\\.|[^"\\\r\n])*"|`(?:[^\\`\r\n]|\\.)*`/,greedy:!0},char:{pattern:/(^|[^\w'])'(?:\\[^\r\n][^'\r\n]*|[^\\\r\n])'/,lookbehind:!0,greedy:!0},keyword:/\b(?:abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|in|let|local|macro|module|print|println|quote|return|struct|try|type|typealias|using|while)\b/,boolean:/\b(?:false|true)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[box])?(?:[\da-f]+(?:_[\da-f]+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[efp][+-]?\d+(?:_\d+)*)?j?/i,operator:/&&|\|\||[-+*^%÷⊻&$\\]=?|\/[\/=]?|!=?=?|\|[=>]?|<(?:<=?|[=:|])?|>(?:=|>>?=?)?|==?=?|[~≠≤≥'√∛]/,punctuation:/::?|[{}[\]();,.?]/,constant:/\b(?:(?:Inf|NaN)(?:16|32|64)?|im|pi)\b|[πℯ]/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-kotlin.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-kotlin.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(n){n.languages.kotlin=n.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete n.languages.kotlin["class-name"];var e={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:n.languages.kotlin}};n.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:e},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:e},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete n.languages.kotlin.string,n.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),n.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),n.languages.kt=n.languages.kotlin,n.languages.kts=n.languages.kotlin}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-latex.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-latex.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(a){var e=/\\(?:[^a-z()[\]]|[a-z*]+)/i,n={"equation-command":{pattern:e,alias:"regex"}};a.languages.latex={comment:/%.*/,cdata:{pattern:/(\\begin\{((?:lstlisting|verbatim)\*?)\})[\s\S]*?(?=\\end\{\2\})/,lookbehind:!0},equation:[{pattern:/\$\$(?:\\[\s\S]|[^\\$])+\$\$|\$(?:\\[\s\S]|[^\\$])+\$|\\\([\s\S]*?\\\)|\\\[[\s\S]*?\\\]/,inside:n,alias:"string"},{pattern:/(\\begin\{((?:align|eqnarray|equation|gather|math|multline)\*?)\})[\s\S]*?(?=\\end\{\2\})/,lookbehind:!0,inside:n,alias:"string"}],keyword:{pattern:/(\\(?:begin|cite|documentclass|end|label|ref|usepackage)(?:\[[^\]]+\])?\{)[^}]+(?=\})/,lookbehind:!0},url:{pattern:/(\\url\{)[^}]+(?=\})/,lookbehind:!0},headline:{pattern:/(\\(?:chapter|frametitle|paragraph|part|section|subparagraph|subsection|subsubparagraph|subsubsection|subsubsubparagraph)\*?(?:\[[^\]]+\])?\{)[^}]+(?=\})/,lookbehind:!0,alias:"class-name"},function:{pattern:e,alias:"selector"},punctuation:/[[\]{}&]/},a.languages.tex=a.languages.latex,a.languages.context=a.languages.latex}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-less.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-less.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.less=Prism.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),Prism.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}});
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-lua.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-lua.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-makefile.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-makefile.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-markdown.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-markdown.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/components/prism-markup-templating.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-markup-templating.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){function n(e,n){return"___"+e.toUpperCase()+n+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(t,a,r,o){if(t.language===a){var c=t.tokenStack=[];t.code=t.code.replace(r,(function(e){if("function"==typeof o&&!o(e))return e;for(var r,i=c.length;-1!==t.code.indexOf(r=n(a,i));)++i;return c[i]=e,r})),t.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(t,a){if(t.language===a&&t.tokenStack){t.grammar=e.languages[a];var r=0,o=Object.keys(t.tokenStack);!function c(i){for(var u=0;u<i.length&&!(r>=o.length);u++){var g=i[u];if("string"==typeof g||g.content&&"string"==typeof g.content){var l=o[r],s=t.tokenStack[l],f="string"==typeof g?g:g.content,p=n(a,l),k=f.indexOf(p);if(k>-1){++r;var m=f.substring(0,k),d=new e.Token(a,e.tokenize(s,t.grammar),"language-"+a,s),h=f.substring(k+p.length),v=[];m&&v.push.apply(v,c([m])),v.push(d),h&&v.push.apply(v,c([h])),"string"==typeof g?i.splice.apply(i,[u,1].concat(v)):g.content=v}}else g.content&&c(g.content)}return i}(t.tokens)}}}})}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-markup.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-markup.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\[CDATA\[|\]\]>$/i;var t={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)".replace(/__/g,(function(){return a})),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-mongodb.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-mongodb.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function($){var e=["$eq","$gt","$gte","$in","$lt","$lte","$ne","$nin","$and","$not","$nor","$or","$exists","$type","$expr","$jsonSchema","$mod","$regex","$text","$where","$geoIntersects","$geoWithin","$near","$nearSphere","$all","$elemMatch","$size","$bitsAllClear","$bitsAllSet","$bitsAnyClear","$bitsAnySet","$comment","$elemMatch","$meta","$slice","$currentDate","$inc","$min","$max","$mul","$rename","$set","$setOnInsert","$unset","$addToSet","$pop","$pull","$push","$pullAll","$each","$position","$slice","$sort","$bit","$addFields","$bucket","$bucketAuto","$collStats","$count","$currentOp","$facet","$geoNear","$graphLookup","$group","$indexStats","$limit","$listLocalSessions","$listSessions","$lookup","$match","$merge","$out","$planCacheStats","$project","$redact","$replaceRoot","$replaceWith","$sample","$set","$skip","$sort","$sortByCount","$unionWith","$unset","$unwind","$setWindowFields","$abs","$accumulator","$acos","$acosh","$add","$addToSet","$allElementsTrue","$and","$anyElementTrue","$arrayElemAt","$arrayToObject","$asin","$asinh","$atan","$atan2","$atanh","$avg","$binarySize","$bsonSize","$ceil","$cmp","$concat","$concatArrays","$cond","$convert","$cos","$dateFromParts","$dateToParts","$dateFromString","$dateToString","$dayOfMonth","$dayOfWeek","$dayOfYear","$degreesToRadians","$divide","$eq","$exp","$filter","$first","$floor","$function","$gt","$gte","$hour","$ifNull","$in","$indexOfArray","$indexOfBytes","$indexOfCP","$isArray","$isNumber","$isoDayOfWeek","$isoWeek","$isoWeekYear","$last","$last","$let","$literal","$ln","$log","$log10","$lt","$lte","$ltrim","$map","$max","$mergeObjects","$meta","$min","$millisecond","$minute","$mod","$month","$multiply","$ne","$not","$objectToArray","$or","$pow","$push","$radiansToDegrees","$range","$reduce","$regexFind","$regexFindAll","$regexMatch","$replaceOne","$replaceAll","$reverseArray","$round","$rtrim","$second","$setDifference","$setEquals","$setIntersection","$setIsSubset","$setUnion","$size","$sin","$slice","$split","$sqrt","$stdDevPop","$stdDevSamp","$strcasecmp","$strLenBytes","$strLenCP","$substr","$substrBytes","$substrCP","$subtract","$sum","$switch","$tan","$toBool","$toDate","$toDecimal","$toDouble","$toInt","$toLong","$toObjectId","$toString","$toLower","$toUpper","$trim","$trunc","$type","$week","$year","$zip","$count","$dateAdd","$dateDiff","$dateSubtract","$dateTrunc","$getField","$rand","$sampleRate","$setField","$unsetField","$comment","$explain","$hint","$max","$maxTimeMS","$min","$orderby","$query","$returnKey","$showDiskLoc","$natural"],t="(?:"+(e=e.map((function($){return $.replace("$","\\$")}))).join("|")+")\\b";$.languages.mongodb=$.languages.extend("javascript",{}),$.languages.insertBefore("mongodb","string",{property:{pattern:/(?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)(?=\s*:)/,greedy:!0,inside:{keyword:RegExp("^(['\"])?"+t+"(?:\\1)?$")}}}),$.languages.mongodb.string.inside={url:{pattern:/https?:\/\/[-\w@:%.+~#=]{1,256}\.[a-z0-9()]{1,6}\b[-\w()@:%+.~#?&/=]*/i,greedy:!0},entity:{pattern:/\b(?:(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d\d?|2[0-4]\d|25[0-5])\b/,greedy:!0}},$.languages.insertBefore("mongodb","constant",{builtin:{pattern:RegExp("\\b(?:"+["ObjectId","Code","BinData","DBRef","Timestamp","NumberLong","NumberDecimal","MaxKey","MinKey","RegExp","ISODate","UUID"].join("|")+")\\b"),alias:"keyword"}})}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-nginx.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-nginx.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var n=/\$(?:\w[a-z\d]*(?:_[^\x00-\x1F\s"'\\()$]*)?|\{[^}\s"'\\]+\})/i;e.languages.nginx={comment:{pattern:/(^|[\s{};])#.*/,lookbehind:!0,greedy:!0},directive:{pattern:/(^|\s)\w(?:[^;{}"'\\\s]|\\.|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\s+(?:#.*(?!.)|(?![#\s])))*?(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:{string:{pattern:/((?:^|[^\\])(?:\\\\)*)(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/,lookbehind:!0,greedy:!0,inside:{escape:{pattern:/\\["'\\nrt]/,alias:"entity"},variable:n}},comment:{pattern:/(\s)#.*/,lookbehind:!0,greedy:!0},keyword:{pattern:/^\S+/,greedy:!0},boolean:{pattern:/(\s)(?:off|on)(?!\S)/,lookbehind:!0},number:{pattern:/(\s)\d+[a-z]*(?!\S)/i,lookbehind:!0},variable:n}},punctuation:/[{};]/}}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-objectivec.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-objectivec.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.objectivec=Prism.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete Prism.languages.objectivec["class-name"],Prism.languages.objc=Prism.languages.objectivec;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-perl.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-perl.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var n="(?:\\((?:[^()\\\\]|\\\\[^])*\\)|\\{(?:[^{}\\\\]|\\\\[^])*\\}|\\[(?:[^[\\]\\\\]|\\\\[^])*\\]|<(?:[^<>\\\\]|\\\\[^])*>)";e.languages.perl={comment:[{pattern:/(^\s*)=\w[\s\S]*?=cut.*/m,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\$])#.*/,lookbehind:!0,greedy:!0}],string:[{pattern:RegExp("\\b(?:q|qq|qw|qx)(?![a-zA-Z0-9])\\s*(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","([a-zA-Z0-9])(?:(?!\\2)[^\\\\]|\\\\[^])*\\2",n].join("|")+")"),greedy:!0},{pattern:/("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0},{pattern:/'(?:[^'\\\r\n]|\\.)*'/,greedy:!0}],regex:[{pattern:RegExp("\\b(?:m|qr)(?![a-zA-Z0-9])\\s*(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","([a-zA-Z0-9])(?:(?!\\2)[^\\\\]|\\\\[^])*\\2",n].join("|")+")[msixpodualngc]*"),greedy:!0},{pattern:RegExp("(^|[^-])\\b(?:s|tr|y)(?![a-zA-Z0-9])\\s*(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\2)[^\\\\]|\\\\[^])*\\2(?:(?!\\2)[^\\\\]|\\\\[^])*\\2","([a-zA-Z0-9])(?:(?!\\3)[^\\\\]|\\\\[^])*\\3(?:(?!\\3)[^\\\\]|\\\\[^])*\\3",n+"\\s*"+n].join("|")+")[msixpodualngcer]*"),lookbehind:!0,greedy:!0},{pattern:/\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|x|xor)\b))/,greedy:!0}],variable:[/[&*$@%]\{\^[A-Z]+\}/,/[&*$@%]\^[A-Z_]/,/[&*$@%]#?(?=\{)/,/[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+(?![\w$]))+(?:::)*/,/[&*$@%]\d+/,/(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/],filehandle:{pattern:/<(?![<=])\S*?>|\b_\b/,alias:"symbol"},"v-string":{pattern:/v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,alias:"string"},function:{pattern:/(\bsub[ \t]+)\w+/,lookbehind:!0},keyword:/\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|return|say|state|sub|switch|undef|unless|until|use|when|while)\b/,number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,operator:/-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\b/,punctuation:/[{}[\];(),:]/}}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-php-extras.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-php-extras.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.insertBefore("php","variable",{this:{pattern:/\$this\b/,alias:"keyword"},global:/\$(?:GLOBALS|HTTP_RAW_POST_DATA|_(?:COOKIE|ENV|FILES|GET|POST|REQUEST|SERVER|SESSION)|argc|argv|http_response_header|php_errormsg)\b/,scope:{pattern:/\b[\w\\]+::/,inside:{keyword:/\b(?:parent|self|static)\b/,punctuation:/::|\\/}}});
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-php.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-php.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/components/prism-plsql.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-plsql.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.plsql=Prism.languages.extend("sql",{comment:{pattern:/\/\*[\s\S]*?\*\/|--.*/,greedy:!0},keyword:/\b(?:A|ACCESSIBLE|ADD|AGENT|AGGREGATE|ALL|ALTER|AND|ANY|ARRAY|AS|ASC|AT|ATTRIBUTE|AUTHID|AVG|BEGIN|BETWEEN|BFILE_BASE|BINARY|BLOB_BASE|BLOCK|BODY|BOTH|BOUND|BULK|BY|BYTE|C|CALL|CALLING|CASCADE|CASE|CHAR|CHARACTER|CHARSET|CHARSETFORM|CHARSETID|CHAR_BASE|CHECK|CLOB_BASE|CLONE|CLOSE|CLUSTER|CLUSTERS|COLAUTH|COLLECT|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPILED|COMPRESS|CONNECT|CONSTANT|CONSTRUCTOR|CONTEXT|CONTINUE|CONVERT|COUNT|CRASH|CREATE|CREDENTIAL|CURRENT|CURSOR|CUSTOMDATUM|DANGLING|DATA|DATE|DATE_BASE|DAY|DECLARE|DEFAULT|DEFINE|DELETE|DESC|DETERMINISTIC|DIRECTORY|DISTINCT|DOUBLE|DROP|DURATION|ELEMENT|ELSE|ELSIF|EMPTY|END|ESCAPE|EXCEPT|EXCEPTION|EXCEPTIONS|EXCLUSIVE|EXECUTE|EXISTS|EXIT|EXTERNAL|FETCH|FINAL|FIRST|FIXED|FLOAT|FOR|FORALL|FORCE|FROM|FUNCTION|GENERAL|GOTO|GRANT|GROUP|HASH|HAVING|HEAP|HIDDEN|HOUR|IDENTIFIED|IF|IMMEDIATE|IMMUTABLE|IN|INCLUDING|INDEX|INDEXES|INDICATOR|INDICES|INFINITE|INSERT|INSTANTIABLE|INT|INTERFACE|INTERSECT|INTERVAL|INTO|INVALIDATE|IS|ISOLATION|JAVA|LANGUAGE|LARGE|LEADING|LENGTH|LEVEL|LIBRARY|LIKE|LIKE2|LIKE4|LIKEC|LIMIT|LIMITED|LOCAL|LOCK|LONG|LOOP|MAP|MAX|MAXLEN|MEMBER|MERGE|MIN|MINUS|MINUTE|MOD|MODE|MODIFY|MONTH|MULTISET|MUTABLE|NAME|NAN|NATIONAL|NATIVE|NCHAR|NEW|NOCOMPRESS|NOCOPY|NOT|NOWAIT|NULL|NUMBER_BASE|OBJECT|OCICOLL|OCIDATE|OCIDATETIME|OCIDURATION|OCIINTERVAL|OCILOBLOCATOR|OCINUMBER|OCIRAW|OCIREF|OCIREFCURSOR|OCIROWID|OCISTRING|OCITYPE|OF|OLD|ON|ONLY|OPAQUE|OPEN|OPERATOR|OPTION|OR|ORACLE|ORADATA|ORDER|ORGANIZATION|ORLANY|ORLVARY|OTHERS|OUT|OVERLAPS|OVERRIDING|PACKAGE|PARALLEL_ENABLE|PARAMETER|PARAMETERS|PARENT|PARTITION|PASCAL|PERSISTABLE|PIPE|PIPELINED|PLUGGABLE|POLYMORPHIC|PRAGMA|PRECISION|PRIOR|PRIVATE|PROCEDURE|PUBLIC|RAISE|RANGE|RAW|READ|RECORD|REF|REFERENCE|RELIES_ON|REM|REMAINDER|RENAME|RESOURCE|RESULT|RESULT_CACHE|RETURN|RETURNING|REVERSE|REVOKE|ROLLBACK|ROW|SAMPLE|SAVE|SAVEPOINT|SB1|SB2|SB4|SECOND|SEGMENT|SELECT|SELF|SEPARATE|SEQUENCE|SERIALIZABLE|SET|SHARE|SHORT|SIZE|SIZE_T|SOME|SPARSE|SQL|SQLCODE|SQLDATA|SQLNAME|SQLSTATE|STANDARD|START|STATIC|STDDEV|STORED|STRING|STRUCT|STYLE|SUBMULTISET|SUBPARTITION|SUBSTITUTABLE|SUBTYPE|SUM|SYNONYM|TABAUTH|TABLE|TDO|THE|THEN|TIME|TIMESTAMP|TIMEZONE_ABBR|TIMEZONE_HOUR|TIMEZONE_MINUTE|TIMEZONE_REGION|TO|TRAILING|TRANSACTION|TRANSACTIONAL|TRUSTED|TYPE|UB1|UB2|UB4|UNDER|UNION|UNIQUE|UNPLUG|UNSIGNED|UNTRUSTED|UPDATE|USE|USING|VALIST|VALUE|VALUES|VARIABLE|VARIANCE|VARRAY|VARYING|VIEW|VIEWS|VOID|WHEN|WHERE|WHILE|WITH|WORK|WRAPPED|WRITE|YEAR|ZONE)\b/i,operator:/:=?|=>|[<>^~!]=|\.\.|\|\||\*\*|[-+*/%<>=@]/}),Prism.languages.insertBefore("plsql","operator",{label:{pattern:/<<\s*\w+\s*>>/,alias:"symbol"}});
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-powershell.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-powershell.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var i=e.languages.powershell={comment:[{pattern:/(^|[^`])<#[\s\S]*?#>/,lookbehind:!0},{pattern:/(^|[^`])#.*/,lookbehind:!0}],string:[{pattern:/"(?:`[\s\S]|[^`"])*"/,greedy:!0,inside:null},{pattern:/'(?:[^']|'')*'/,greedy:!0}],namespace:/\[[a-z](?:\[(?:\[[^\]]*\]|[^\[\]])*\]|[^\[\]])*\]/i,boolean:/\$(?:false|true)\b/i,variable:/\$\w+\b/,function:[/\b(?:Add|Approve|Assert|Backup|Block|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|ForEach|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Sort|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Tee|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Where|Write)-[a-z]+\b/i,/\b(?:ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i],keyword:/\b(?:Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,operator:{pattern:/(^|\W)(?:!|-(?:b?(?:and|x?or)|as|(?:Not)?(?:Contains|In|Like|Match)|eq|ge|gt|is(?:Not)?|Join|le|lt|ne|not|Replace|sh[lr])\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,lookbehind:!0},punctuation:/[|{}[\];(),.]/};i.string[0].inside={function:{pattern:/(^|[^`])\$\((?:\$\([^\r\n()]*\)|(?!\$\()[^\r\n)])*\)/,lookbehind:!0,inside:i},boolean:i.boolean,variable:i.variable}}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-properties.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-properties.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.properties={comment:/^[ \t]*[#!].*$/m,value:{pattern:/(^[ \t]*(?:\\(?:\r\n|[\s\S])|[^\\\s:=])+(?: *[=:] *(?! )| ))(?:\\(?:\r\n|[\s\S])|[^\\\r\n])+/m,lookbehind:!0,alias:"attr-value"},key:{pattern:/^[ \t]*(?:\\(?:\r\n|[\s\S])|[^\\\s:=])+(?= *[=:]| )/m,alias:"attr-name"},punctuation:/[=:]/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-protobuf.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-protobuf.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var s=/\b(?:bool|bytes|double|s?fixed(?:32|64)|float|[su]?int(?:32|64)|string)\b/;e.languages.protobuf=e.languages.extend("clike",{"class-name":[{pattern:/(\b(?:enum|extend|message|service)\s+)[A-Za-z_]\w*(?=\s*\{)/,lookbehind:!0},{pattern:/(\b(?:rpc\s+\w+|returns)\s*\(\s*(?:stream\s+)?)\.?[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*(?=\s*\))/,lookbehind:!0}],keyword:/\b(?:enum|extend|extensions|import|message|oneof|option|optional|package|public|repeated|required|reserved|returns|rpc(?=\s+\w)|service|stream|syntax|to)\b(?!\s*=\s*\d)/,function:/\b[a-z_]\w*(?=\s*\()/i}),e.languages.insertBefore("protobuf","operator",{map:{pattern:/\bmap<\s*[\w.]+\s*,\s*[\w.]+\s*>(?=\s+[a-z_]\w*\s*[=;])/i,alias:"class-name",inside:{punctuation:/[<>.,]/,builtin:s}},builtin:s,"positional-class-name":{pattern:/(?:\b|\B\.)[a-z_]\w*(?:\.[a-z_]\w*)*(?=\s+[a-z_]\w*\s*[=;])/i,alias:"class-name",inside:{punctuation:/\./}},annotation:{pattern:/(\[\s*)[a-z_]\w*(?=\s*=)/i,lookbehind:!0}})}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-python.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-python.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern://,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-r.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-r.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.r={comment:/#.*/,string:{pattern:/(['"])(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},"percent-operator":{pattern:/%[^%\s]*%/,alias:"operator"},boolean:/\b(?:FALSE|TRUE)\b/,ellipsis:/\.\.(?:\.|\d+)/,number:[/\b(?:Inf|NaN)\b/,/(?:\b0x[\dA-Fa-f]+(?:\.\d*)?|\b\d+(?:\.\d*)?|\B\.\d+)(?:[EePp][+-]?\d+)?[iL]?/],keyword:/\b(?:NA|NA_character_|NA_complex_|NA_integer_|NA_real_|NULL|break|else|for|function|if|in|next|repeat|while)\b/,operator:/->?>?|<(?:=|<?-)?|[>=!]=?|::?|&&?|\|\|?|[+*\/^$@~]/,punctuation:/[(){}\[\],;]/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-regex.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-regex.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(a){var e={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},n=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/,t="(?:[^\\\\-]|"+n.source+")",s=RegExp(t+"-"+t),i={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"};a.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:s,inside:{escape:n,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":e,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:n}},"special-escape":e,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":i}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:n,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":i}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}}}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-ruby.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-ruby.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var n={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var t="(?:"+["([^a-zA-Z0-9\\s{(\\[<=])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^]|\\((?:[^()\\\\]|\\\\[^])*\\))*\\)","\\{(?:[^{}\\\\]|\\\\[^]|\\{(?:[^{}\\\\]|\\\\[^])*\\})*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^]|\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\])*\\]","<(?:[^<>\\\\]|\\\\[^]|<(?:[^<>\\\\]|\\\\[^])*>)*>"].join("|")+")",i='(?:"(?:\\\\.|[^"\\\\\r\n])*"|(?:\\b[a-zA-Z_]\\w*|[^\\s\0-\\x7F]+)[?!]?|\\$.)';e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp("%r"+t+"[egimnosux]{0,6}"),greedy:!0,inside:{interpolation:n,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp("(^|[^:]):"+i),lookbehind:!0,greedy:!0},{pattern:RegExp("([\r\n{(,][ \t]*)"+i+"(?=:(?!:))"),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp("%[qQiIwWs]?"+t),greedy:!0,inside:{interpolation:n,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:n,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp("%x"+t),greedy:!0,inside:{interpolation:n,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:n,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-rust.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-rust.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){for(var a="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|<self>)*\\*/",t=0;t<2;t++)a=a.replace(/<self>/g,(function(){return a}));a=a.replace(/<self>/g,(function(){return"[^\\s\\S]"})),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+a),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-sass.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-sass.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var r=/\$[-\w]+|#\{\$[-\w]+\}/,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:r,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:r,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-scala.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-scala.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.scala=Prism.languages.extend("java",{"triple-quoted-string":{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},keyword:/<-|=>|\b(?:abstract|case|catch|class|def|derives|do|else|enum|extends|extension|final|finally|for|forSome|given|if|implicit|import|infix|inline|lazy|match|new|null|object|opaque|open|override|package|private|protected|return|sealed|self|super|this|throw|trait|transparent|try|type|using|val|var|while|with|yield)\b/,number:/\b0x(?:[\da-f]*\.)?[\da-f]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e\d+)?[dfl]?/i,builtin:/\b(?:Any|AnyRef|AnyVal|Boolean|Byte|Char|Double|Float|Int|Long|Nothing|Short|String|Unit)\b/,symbol:/'[^\d\s\\]\w*/}),Prism.languages.insertBefore("scala","triple-quoted-string",{"string-interpolation":{pattern:/\b[a-z]\w*(?:"""(?:[^$]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*?"""|"(?:[^$"\r\n]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*")/i,greedy:!0,inside:{id:{pattern:/^\w+/,greedy:!0,alias:"function"},escape:{pattern:/\\\$"|\$[$"]/,greedy:!0,alias:"symbol"},interpolation:{pattern:/\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,greedy:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:Prism.languages.scala}}},string:/[\s\S]+/}}}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala.function,delete Prism.languages.scala.constant;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-scss.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-scss.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss;
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-shell-session.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-shell-session.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(s){var n=['"(?:\\\\[^]|\\$\\([^)]+\\)|\\$(?!\\()|`[^`]+`|[^"\\\\`$])*"',"'[^']*'","\\$'(?:[^'\\\\]|\\\\[^])*'","<<-?\\s*([\"']?)(\\w+)\\1\\s[^]*?[\r\n]\\2"].join("|");s.languages["shell-session"]={command:{pattern:RegExp('^(?:[^\\s@:$#%*!/\\\\]+@[^\r\n@:$#%*!/\\\\]+(?::[^\0-\\x1F$#%*?"<>:;|]+)?|[/~.][^\0-\\x1F$#%*?"<>@:;|]*)?[$#%](?=\\s)'+"(?:[^\\\\\r\n \t'\"<$]|[ \t](?:(?!#)|#.*$)|\\\\(?:[^\r]|\r\n?)|\\$(?!')|<(?!<)|<<str>>)+".replace(/<<str>>/g,(function(){return n})),"m"),greedy:!0,inside:{info:{pattern:/^[^#$%]+/,alias:"punctuation",inside:{user:/^[^\s@:$#%*!/\\]+@[^\r\n@:$#%*!/\\]+/,punctuation:/:/,path:/[\s\S]+/}},bash:{pattern:/(^[$#%]\s*)\S[\s\S]*/,lookbehind:!0,alias:"language-bash",inside:s.languages.bash},"shell-symbol":{pattern:/^[$#%]/,alias:"important"}}},output:/.(?:.*(?:[\r\n]|.$))*/},s.languages["sh-session"]=s.languages.shellsession=s.languages["shell-session"]}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-sql.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-sql.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/};
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-swift.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-swift.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp('(^|[^"#])(?:"(?:\\\\(?:\\((?:[^()]|\\([^()]*\\))*\\)|\r\n|[^(])|[^\\\\\r\n"])*"|"""(?:\\\\(?:\\((?:[^()]|\\([^()]*\\))*\\)|[^(])|[^\\\\"]|"(?!""))*""")(?!["#])'),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp('(^|[^"#])(#+)(?:"(?:\\\\(?:#+\\((?:[^()]|\\([^()]*\\))*\\)|\r\n|[^#])|[^\\\\\r\n])*?"|"""(?:\\\\(?:#+\\((?:[^()]|\\([^()]*\\))*\\)|[^#])|[^\\\\])*?""")\\2'),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp("#(?:(?:elseif|if)\\b(?:[ \t]*(?:![ \t]*)?(?:\\b\\w+\\b(?:[ \t]*\\((?:[^()]|\\([^()]*\\))*\\))?|\\((?:[^()]|\\([^()]*\\))*\\))(?:[ \t]*(?:&&|\\|\\|))?)+|(?:else|endif)\\b)"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},Prism.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=Prism.languages.swift}));
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-toml.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-toml.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){function n(e){return e.replace(/__/g,(function(){return"(?:[\\w-]+|'[^'\n\r]*'|\"(?:\\\\.|[^\\\\\"\r\n])*\")"}))}e.languages.toml={comment:{pattern:/#.*/,greedy:!0},table:{pattern:RegExp(n("(^[\t ]*\\[\\s*(?:\\[\\s*)?)__(?:\\s*\\.\\s*__)*(?=\\s*\\])"),"m"),lookbehind:!0,greedy:!0,alias:"class-name"},key:{pattern:RegExp(n("(^[\t ]*|[{,]\\s*)__(?:\\s*\\.\\s*__)*(?=\\s*=)"),"m"),lookbehind:!0,greedy:!0,alias:"property"},string:{pattern:/"""(?:\\[\s\S]|[^\\])*?"""|'''[\s\S]*?'''|'[^'\n\r]*'|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},date:[{pattern:/\b\d{4}-\d{2}-\d{2}(?:[T\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?\b/i,alias:"number"},{pattern:/\b\d{2}:\d{2}:\d{2}(?:\.\d+)?\b/,alias:"number"}],number:/(?:\b0(?:x[\da-zA-Z]+(?:_[\da-zA-Z]+)*|o[0-7]+(?:_[0-7]+)*|b[10]+(?:_[10]+)*))\b|[-+]?\b\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?\b|[-+]?\b(?:inf|nan)\b/,boolean:/\b(?:false|true)\b/,punctuation:/[.,=[\]{}]/}}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-tsx.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-tsx.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var a=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",a),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var t=e.languages.tsx.tag;t.pattern=RegExp("(^|[^\\w$]|(?=</))(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-typescript.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-typescript.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var s=e.languages.extend("typescript",{});delete s["class-name"],e.languages.typescript["class-name"].inside=s,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:s}}}}),e.languages.ts=e.languages.typescript}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-vbnet.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-vbnet.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages.vbnet=Prism.languages.extend("basic",{comment:[{pattern:/(?:!|REM\b).+/i,inside:{keyword:/^REM/i}},{pattern:/(^|[^\\:])'.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(^|[^"])"(?:""|[^"])*"(?!")/,lookbehind:!0,greedy:!0},keyword:/(?:\b(?:ADDHANDLER|ADDRESSOF|ALIAS|AND|ANDALSO|AS|BEEP|BLOAD|BOOLEAN|BSAVE|BYREF|BYTE|BYVAL|CALL(?: ABSOLUTE)?|CASE|CATCH|CBOOL|CBYTE|CCHAR|CDATE|CDBL|CDEC|CHAIN|CHAR|CHDIR|CINT|CLASS|CLEAR|CLNG|CLOSE|CLS|COBJ|COM|COMMON|CONST|CONTINUE|CSBYTE|CSHORT|CSNG|CSTR|CTYPE|CUINT|CULNG|CUSHORT|DATA|DATE|DECIMAL|DECLARE|DEF(?: FN| SEG|DBL|INT|LNG|SNG|STR)|DEFAULT|DELEGATE|DIM|DIRECTCAST|DO|DOUBLE|ELSE|ELSEIF|END|ENUM|ENVIRON|ERASE|ERROR|EVENT|EXIT|FALSE|FIELD|FILES|FINALLY|FOR(?: EACH)?|FRIEND|FUNCTION|GET|GETTYPE|GETXMLNAMESPACE|GLOBAL|GOSUB|GOTO|HANDLES|IF|IMPLEMENTS|IMPORTS|IN|INHERITS|INPUT|INTEGER|INTERFACE|IOCTL|IS|ISNOT|KEY|KILL|LET|LIB|LIKE|LINE INPUT|LOCATE|LOCK|LONG|LOOP|LSET|ME|MKDIR|MOD|MODULE|MUSTINHERIT|MUSTOVERRIDE|MYBASE|MYCLASS|NAME|NAMESPACE|NARROWING|NEW|NEXT|NOT|NOTHING|NOTINHERITABLE|NOTOVERRIDABLE|OBJECT|OF|OFF|ON(?: COM| ERROR| KEY| TIMER)?|OPEN|OPERATOR|OPTION(?: BASE)?|OPTIONAL|OR|ORELSE|OUT|OVERLOADS|OVERRIDABLE|OVERRIDES|PARAMARRAY|PARTIAL|POKE|PRIVATE|PROPERTY|PROTECTED|PUBLIC|PUT|RAISEEVENT|READ|READONLY|REDIM|REM|REMOVEHANDLER|RESTORE|RESUME|RETURN|RMDIR|RSET|RUN|SBYTE|SELECT(?: CASE)?|SET|SHADOWS|SHARED|SHELL|SHORT|SINGLE|SLEEP|STATIC|STEP|STOP|STRING|STRUCTURE|SUB|SWAP|SYNCLOCK|SYSTEM|THEN|THROW|TIMER|TO|TROFF|TRON|TRUE|TRY|TRYCAST|TYPE|TYPEOF|UINTEGER|ULONG|UNLOCK|UNTIL|USHORT|USING|VIEW PRINT|WAIT|WEND|WHEN|WHILE|WIDENING|WITH|WITHEVENTS|WRITE|WRITEONLY|XOR)|\B(?:#CONST|#ELSE|#ELSEIF|#END|#IF))(?:\$|\b)/i,punctuation:/[,;:(){}]/});
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-visual-basic.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-visual-basic.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Prism.languages["visual-basic"]={comment:{pattern:/(?:['‘’]|REM\b)(?:[^\r\n_]|_(?:\r\n?|\n)?)*/i,inside:{keyword:/^REM/i}},directive:{pattern:/#(?:Const|Else|ElseIf|End|ExternalChecksum|ExternalSource|If|Region)(?:\b_[ \t]*(?:\r\n?|\n)|.)+/i,alias:"property",greedy:!0},string:{pattern:/\$?["“”](?:["“”]{2}|[^"“”])*["“”]C?/i,greedy:!0},date:{pattern:/#[ \t]*(?:\d+([/-])\d+\1\d+(?:[ \t]+(?:\d+[ \t]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[ \t]*(?:AM|PM))?))?|\d+[ \t]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[ \t]*(?:AM|PM))?)[ \t]*#/i,alias:"number"},number:/(?:(?:\b\d+(?:\.\d+)?|\.\d+)(?:E[+-]?\d+)?|&[HO][\dA-F]+)(?:[FRD]|U?[ILS])?/i,boolean:/\b(?:False|Nothing|True)\b/i,keyword:/\b(?:AddHandler|AddressOf|Alias|And(?:Also)?|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|C(?:Bool|Byte|Char|Date|Dbl|Dec|Int|Lng|Obj|SByte|Short|Sng|Str|Type|UInt|ULng|UShort)|Char|Class|Const|Continue|Currency|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else(?:If)?|End(?:If)?|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get(?:Type|XMLNamespace)?|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|Must(?:Inherit|Override)|My(?:Base|Class)|Namespace|Narrowing|New|Next|Not(?:Inheritable|Overridable)?|Object|Of|On|Operator|Option(?:al)?|Or(?:Else)?|Out|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TryCast|Type|TypeOf|U(?:Integer|Long|Short)|Until|Using|Variant|Wend|When|While|Widening|With(?:Events)?|WriteOnly|Xor)\b/i,operator:/[+\-*/\\^<=>&#@$%!]|\b_(?=[ \t]*[\r\n])/,punctuation:/[{}().,:?]/},Prism.languages.vb=Prism.languages["visual-basic"],Prism.languages.vba=Prism.languages["visual-basic"];
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-xml-doc.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-xml-doc.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(a){function e(e,n){a.languages[e]&&a.languages.insertBefore(e,"comment",{"doc-comment":n})}var n=a.languages.markup.tag,t={pattern:/\/\/\/.*/,greedy:!0,alias:"comment",inside:{tag:n}},g={pattern:/'''.*/,greedy:!0,alias:"comment",inside:{tag:n}};e("csharp",t),e("fsharp",t),e("vbnet",g)}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/components/prism-yaml.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/components/prism-yaml.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var n=/[*&][^\s[\]{},]+/,r=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,t="(?:"+r.source+"(?:[ \t]+"+n.source+")?|"+n.source+"(?:[ \t]+"+r.source+")?)",a="(?:[^\\s\\x00-\\x08\\x0e-\\x1f!\"#%&'*,\\-:>?@[\\]`{|}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*".replace(/<PLAIN>/g,(function(){return"[^\\s\\x00-\\x08\\x0e-\\x1f,[\\]{}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]"})),d="\"(?:[^\"\\\\\r\n]|\\\\.)*\"|'(?:[^'\\\\\r\n]|\\\\.)*'";function o(e,n){n=(n||"").replace(/m/g,"")+"m";var r="([:\\-,[{]\\s*(?:\\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\\]|\\}|(?:[\r\n]\\s*)?#))".replace(/<<prop>>/g,(function(){return t})).replace(/<<value>>/g,(function(){return e}));return RegExp(r,n)}e.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\\S[^\r\n]*(?:\\2[^\r\n]+)*)".replace(/<<prop>>/g,(function(){return t}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\\s*:\\s)".replace(/<<prop>>/g,(function(){return t})).replace(/<<key>>/g,(function(){return"(?:"+a+"|"+d+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:o("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?(?:[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?))?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:o("false|true","i"),lookbehind:!0,alias:"important"},null:{pattern:o("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:o(d),lookbehind:!0,greedy:!0},number:{pattern:o("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:r,important:n,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism);
|
||||
1
assets/foliate-js/src/vendor/prism/prism-autoloader.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/prism-autoloader.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/prism-core.min.js
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/prism-core.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/themes/prism-atom-dark.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-atom-dark.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#c5c8c6;text-shadow:0 1px rgba(0,0,0,.3);font-family:Inconsolata,Monaco,Consolas,'Courier New',Courier,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#1d1f21}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#7c7c7c}.token.punctuation{color:#c5c8c6}.namespace{opacity:.7}.token.keyword,.token.property,.token.tag{color:#96cbfe}.token.class-name{color:#ffffb6;text-decoration:underline}.token.boolean,.token.constant{color:#9c9}.token.deleted,.token.symbol{color:#f92672}.token.number{color:#ff73fd}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a8ff60}.token.variable{color:#c6c5fe}.token.operator{color:#ededed}.token.entity{color:#ffffb6;cursor:help}.token.url{color:#96cbfe}.language-css .token.string,.style .token.string{color:#87c38a}.token.atrule,.token.attr-value{color:#f9ee98}.token.function{color:#dad085}.token.regex{color:#e9c062}.token.important{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-default.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-default.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-dracula.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-dracula.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#282a36}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#6272a4}.token.punctuation{color:#f8f8f2}.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#ff79c6}.token.boolean,.token.number{color:#bd93f9}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#50fa7b}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#f1fa8c}.token.keyword{color:#8be9fd}.token.important,.token.regex{color:#ffb86c}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-github.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-github.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#393a34;font-family:Consolas,"Bitstream Vera Sans Mono","Courier New",Courier,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;font-size:.9em;line-height:1.2em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre>code[class*=language-]{font-size:1em}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{background:#b3d4fc}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border:1px solid #ddd;background-color:#fff}:not(pre)>code[class*=language-]{padding:.2em;padding-top:1px;padding-bottom:1px;background:#f8f8f8;border:1px solid #ddd}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#998;font-style:italic}.token.namespace{opacity:.7}.token.attr-value,.token.string{color:#e3116c}.token.operator,.token.punctuation{color:#393a34}.token.boolean,.token.constant,.token.entity,.token.inserted,.token.number,.token.property,.token.regex,.token.symbol,.token.url,.token.variable{color:#36acaa}.language-autohotkey .token.selector,.token.atrule,.token.attr-name,.token.keyword{color:#00a4db}.language-autohotkey .token.tag,.token.deleted,.token.function{color:#9a050f}.language-autohotkey .token.keyword,.token.selector,.token.tag{color:#00009f}.token.bold,.token.function,.token.important{font-weight:700}.token.italic{font-style:italic}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-material-dark.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-material-dark.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;color:#eee;background:#2f2f2f;font-family:Roboto Mono,monospace;font-size:1em;line-height:1.5em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{background:#363636}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{background:#363636}:not(pre)>code[class*=language-]{white-space:normal;border-radius:.2em;padding:.1em}pre[class*=language-]{overflow:auto;position:relative;margin:.5em 0;padding:1.25em 1em}.language-css>code,.language-sass>code,.language-scss>code{color:#fd9170}[class*=language-] .namespace{opacity:.7}.token.atrule{color:#c792ea}.token.attr-name{color:#ffcb6b}.token.attr-value{color:#a5e844}.token.attribute{color:#a5e844}.token.boolean{color:#c792ea}.token.builtin{color:#ffcb6b}.token.cdata{color:#80cbc4}.token.char{color:#80cbc4}.token.class{color:#ffcb6b}.token.class-name{color:#f2ff00}.token.comment{color:#616161}.token.constant{color:#c792ea}.token.deleted{color:#f66}.token.doctype{color:#616161}.token.entity{color:#f66}.token.function{color:#c792ea}.token.hexcode{color:#f2ff00}.token.id{color:#c792ea;font-weight:700}.token.important{color:#c792ea;font-weight:700}.token.inserted{color:#80cbc4}.token.keyword{color:#c792ea}.token.number{color:#fd9170}.token.operator{color:#89ddff}.token.prolog{color:#616161}.token.property{color:#80cbc4}.token.pseudo-class{color:#a5e844}.token.pseudo-element{color:#a5e844}.token.punctuation{color:#89ddff}.token.regex{color:#f2ff00}.token.selector{color:#f66}.token.string{color:#a5e844}.token.symbol{color:#c792ea}.token.tag{color:#f66}.token.unit{color:#fd9170}.token.url{color:#f66}.token.variable{color:#f66}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-material-light.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-material-light.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;color:#90a4ae;background:#fafafa;font-family:Roboto Mono,monospace;font-size:1em;line-height:1.5em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{background:#cceae7;color:#263238}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{background:#cceae7;color:#263238}:not(pre)>code[class*=language-]{white-space:normal;border-radius:.2em;padding:.1em}pre[class*=language-]{overflow:auto;position:relative;margin:.5em 0;padding:1.25em 1em}.language-css>code,.language-sass>code,.language-scss>code{color:#f76d47}[class*=language-] .namespace{opacity:.7}.token.atrule{color:#7c4dff}.token.attr-name{color:#39adb5}.token.attr-value{color:#f6a434}.token.attribute{color:#f6a434}.token.boolean{color:#7c4dff}.token.builtin{color:#39adb5}.token.cdata{color:#39adb5}.token.char{color:#39adb5}.token.class{color:#39adb5}.token.class-name{color:#6182b8}.token.comment{color:#aabfc9}.token.constant{color:#7c4dff}.token.deleted{color:#e53935}.token.doctype{color:#aabfc9}.token.entity{color:#e53935}.token.function{color:#7c4dff}.token.hexcode{color:#f76d47}.token.id{color:#7c4dff;font-weight:700}.token.important{color:#7c4dff;font-weight:700}.token.inserted{color:#39adb5}.token.keyword{color:#7c4dff}.token.number{color:#f76d47}.token.operator{color:#39adb5}.token.prolog{color:#aabfc9}.token.property{color:#39adb5}.token.pseudo-class{color:#f6a434}.token.pseudo-element{color:#f6a434}.token.punctuation{color:#39adb5}.token.regex{color:#6182b8}.token.selector{color:#e53935}.token.string{color:#f6a434}.token.symbol{color:#7c4dff}.token.tag{color:#e53935}.token.unit{color:#f76d47}.token.url{color:#e53935}.token.variable{color:#e53935}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-night-owl.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-night-owl.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#d6deeb;font-family:Consolas,Monaco,"Andale Mono","Ubuntu Mono",monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:rgba(29,59,83,.99)}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:rgba(29,59,83,.99)}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{color:#fff;background:#011627}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.prolog{color:#637777;font-style:italic}.token.punctuation{color:#c792ea}.namespace{color:#b2ccd6}.token.deleted{color:rgba(239,83,80,.56);font-style:italic}.token.property,.token.symbol{color:#80cbc4}.token.keyword,.token.operator,.token.tag{color:#7fdbca}.token.boolean{color:#ff5874}.token.number{color:#f78c6c}.token.builtin,.token.char,.token.constant,.token.function{color:#82aaff}.token.doctype,.token.selector{color:#c792ea;font-style:italic}.token.attr-name,.token.inserted{color:#addb67;font-style:italic}.language-css .token.string,.style .token.string,.token.entity,.token.string,.token.url{color:#addb67}.token.atrule,.token.attr-value,.token.class-name{color:#ffcb8b}.token.important,.token.regex,.token.variable{color:#d6deeb}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-nord.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-nord.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;font-family:"Fira Code",Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2e3440}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#636f88}.token.punctuation{color:#81a1c1}.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#81a1c1}.token.number{color:#b48ead}.token.boolean{color:#81a1c1}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a3be8c}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#81a1c1}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#88c0d0}.token.keyword{color:#81a1c1}.token.important,.token.regex{color:#ebcb8b}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-one-dark.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-one-dark.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/themes/prism-one-light.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-one-light.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/foliate-js/src/vendor/prism/themes/prism-solarized-dark.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-solarized-dark.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#839496;text-shadow:0 1px rgba(0,0,0,.3);font-family:Inconsolata,Monaco,Consolas,'Courier New',Courier,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#002b36}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#586e75}.token.punctuation{color:#93a1a1}.namespace{opacity:.7}.token.keyword,.token.property,.token.tag{color:#268bd2}.token.class-name{color:#ffffb6;text-decoration:underline}.token.boolean,.token.constant{color:#b58900}.token.deleted,.token.symbol{color:#dc322f}.token.number{color:#859900}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#859900}.token.variable{color:#268bd2}.token.operator{color:#ededed}.token.function{color:#268bd2}.token.regex{color:#e9c062}.token.important{color:#fd971f}.token.entity{color:#ffffb6;cursor:help}.token.url{color:#96cbfe}.language-css .token.string,.style .token.string{color:#87c38a}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.atrule,.token.attr-value{color:#f9ee98}
|
||||
1
assets/foliate-js/src/vendor/prism/themes/prism-vs-dark.min.css
vendored
Normal file
1
assets/foliate-js/src/vendor/prism/themes/prism-vs-dark.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
code[class*=language-],pre[class*=language-]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,"Andale Mono","Ubuntu Mono","Courier New",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#264f78}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;background:#1e1e1e}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#db4c69;background:#1e1e1e}.namespace{opacity:.7}.token.doctype .token.doctype-tag{color:#569cd6}.token.doctype .token.name{color:#9cdcfe}.token.comment,.token.prolog{color:#6a9955}.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation,.token.punctuation{color:#d4d4d4}.token.boolean,.token.constant,.token.inserted,.token.number,.token.property,.token.symbol,.token.tag,.token.unit{color:#b5cea8}.token.attr-name,.token.builtin,.token.char,.token.deleted,.token.selector,.token.string{color:#ce9178}.language-css .token.string.url{text-decoration:underline}.token.entity,.token.operator{color:#d4d4d4}.token.operator.arrow{color:#569cd6}.token.atrule{color:#ce9178}.token.atrule .token.rule{color:#c586c0}.token.atrule .token.url{color:#9cdcfe}.token.atrule .token.url .token.function{color:#dcdcaa}.token.atrule .token.url .token.punctuation{color:#d4d4d4}.token.keyword{color:#569cd6}.token.keyword.control-flow,.token.keyword.module{color:#c586c0}.token.function,.token.function .token.maybe-class-name{color:#dcdcaa}.token.regex{color:#d16969}.token.important{color:#569cd6}.token.italic{font-style:italic}.token.constant{color:#9cdcfe}.token.class-name,.token.maybe-class-name{color:#4ec9b0}.token.console{color:#9cdcfe}.token.parameter{color:#9cdcfe}.token.interpolation{color:#9cdcfe}.token.punctuation.interpolation-punctuation{color:#569cd6}.token.boolean{color:#569cd6}.token.exports .token.maybe-class-name,.token.imports .token.maybe-class-name,.token.property,.token.variable{color:#9cdcfe}.token.selector{color:#d7ba7d}.token.escape{color:#d7ba7d}.token.tag{color:#569cd6}.token.tag .token.punctuation{color:grey}.token.cdata{color:grey}.token.attr-name{color:#9cdcfe}.token.attr-value,.token.attr-value .token.punctuation{color:#ce9178}.token.attr-value .token.punctuation.attr-equals{color:#d4d4d4}.token.entity{color:#569cd6}.token.namespace{color:#4ec9b0}code[class*=language-javascript],code[class*=language-jsx],code[class*=language-tsx],code[class*=language-typescript],pre[class*=language-javascript],pre[class*=language-jsx],pre[class*=language-tsx],pre[class*=language-typescript]{color:#9cdcfe}code[class*=language-css],pre[class*=language-css]{color:#ce9178}code[class*=language-html],pre[class*=language-html]{color:#d4d4d4}.language-regex .token.anchor{color:#dcdcaa}.language-html .token.punctuation{color:grey}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight.line-highlight{background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0}
|
||||
1
assets/foliate-js/src/vendor/zip.js
vendored
Normal file
1
assets/foliate-js/src/vendor/zip.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user