================
The script searches the document for elements with the `tengwar` class.
-The body of a `tengwar` class must be rendered with the included Tengar
-Annatar variant webfont, using the included `tengwar-annatar.css`.
+The class must also include either `parmaite` or `annatar` to select the
+rendering font. This is not merely for the purpose of applying the
+appropriate web font, but also instructs the script on which bindings to
+use for kerning tehtar. The body of a `tengwar` class must be rendered
+with the included Tengar Annatar variant webfont or Tengwar Parmaitë
+using the included `tengwar-annatar.css` or `tengwar-parmaite.css`.
If the element has a `data-tengwar` property, that property is expected
to contain phonetic letters from the latin alphabet and gets transcribed
inner HTML with the font bindings, rendering the desired tengwar text
visible.
-If the element has a `data-mode=classical` property, the latin letters
-are instead transcribed into Tengwar Annatar key bindings through the
-Classical mode, popular for Quenya.
+ class="tengwar annatar"
+
+If the element has a `data-mode` property, the latin letters
+are instead transcribed into key bindings through the
+Classical mode, popular for Quenya, or the mode of Beleriand. Various
+options can also be applied.
+
+ data-mode="general-use no-ach-laut reverse-curls"
+ data-mode="classical reverse-curls"
+ data-mode="beleriand"
If the element has a `data-encoded` property, the value is expected to
be a description of the tengwar and tehtar to display like
`romen:a;ungwe:a;romen:o;numen` for "Aragorn" in the General Use mode.
+ data-encoded="romen:a;ungwe:a;romen:o;numen"
+
Of course, a page can bypass the whole automated transcription process
by statically populating the element with the desired key bindings and
using neither of these data properties.
- `tengwar/general-use` transcribes phonetic latin letters, as Tolkien
wrote it, into Tengwar Notation in the General Use mode, suitable
for Sindarin and many other languages.
- - `transcribe(text, options)` to Tengwar Annatar key bindings
+ - `transcribe(text, options)` to key bindings for the font.
+ Tengwar Annatar by default.
- `encode(text, options)` to Tengwar Notation
- `parse(text, options)` to Tengwar Object Notation
- `makeOptions(options)`
- `font` defaults to the TengwarAnnatar module.
+ - `block` whether to include HTML tags for paragraphs and line
+ breaks.
+ - `plain` whether to exclude all HTML from the output,
+ making it suitable for plain text..
- `doubleNasalsWithTildeBelow`: Many tengwa can be doubled in
General Use mode by placing a tilde above the tengwa, and
many tengwa can be prefixed with the sound of the
their value.
- `false`: by default, a tilde above doubles a nasal
- `true`: a tilde below doubles a nasal
+ - `reverseCurls`: In the Black Speech of the ring inscription,
+ among other samples, the "o" and "u" tehtar are reversed.
+ - `false`: by default, the "o" tehta curls forward, and
+ "u" backward.
+ - `true`: "o" curls backward, "u" forward.
- `noAchLaut`
- `false`: by default, "ch" is transcribed as ach-laut,
the "ch" as in "Bach". "cc" is transcribed as "ch" as
tehta.
- `true`: "is" is a short carrier with an I tehta and S
hook.
+
- `tengwar/classical` transcribes phonetic latin letters into Tengwar
Notation in the Classical mode, most commonly used for Quenya.
- - `transcribe(text, options)` to Tengwar Annatar key bindings
+ - `transcribe(text, options)` to key bindings for the font.
+ Tengwar Annatar by default.
- `encode(text, options)` to Tengwar Notation
- `parse(text, options)` to Tengwar Object Notation
- `makeOptions(options)`
- `font` defaults to the TengwarAnnatar module.
+ - `block` whether to include HTML tags for paragraphs and line
+ breaks.
+ - `plain` whether to exclude all HTML from the output,
+ making it suitable for plain text..
- `viyla`: In the earlier forms of the mode, the tengwa
"vilya" represented the sound of the letter V. The tengwa
"vala" eventually replaced its role and "vilya" was renamed
V.
- `true`: "vilya" serves for V, and W is interpreted as
the vowel U.
+ - `reverseCurls`: In the Black Speech of the ring inscription,
+ among other samples, the "o" and "u" tehtar are reversed.
+ - `false`: by default, the "o" tehta curls forward, and
+ "u" backward.
+ - `true`: "o" curls backward, "u" forward.
- `iuRising`: In the Third Age, IU is a rising diphthong,
meaning that the stress is on the second sound. Whether to
represent a rising diphthong in the same fashion as other
- HY is interpreted as "hyarmen"
- HT still implies CHT so treated as "harma" as above.
- CH, HL, HR, and HW (and WH) are not affected.
+
+- `tengwar/beleriand`: transcribes phonetic latin letters into Tengwar
+ Notation in the mode of Beleriand, which is suitable for Sindarin
+ and uses full tengwar for most vowels, instead of tehtar.
+ - `transcribe(text, options)` to key bindings for the font.
+ Tengwar Annatar by default.
+ - `encode(text, options)` to Tengwar Notation
+ - `parse(text, options)` to Tengwar Object Notation
+ - `makeOptions(options)`
+ - `font` defaults to the TengwarAnnatar module.
+ - `block` whether to include HTML tags for paragraphs and line
+ breaks.
+ - `plain` whether to exclude all HTML from the output,
+ making it suitable for plain text..
+
- `tengwar/tengwar-annatar`: Translates Tengwar Object Notation into
key bindings for Johan Winge’s Tengwar Annatar font. Provides the
`makeColumn` primitive which is aware of how a column of tengwar and
exports.aliases = {
"vilya": "wilya",
- "aha": "harma"
+ "aha": "harma",
+ "gasdil": "halla"
};
--- /dev/null
+
+var TengwarParmaite = require("./tengwar-parmaite");
+var Parser = require("./parser");
+var makeDocumentParser = require("./document-parser");
+var normalize = require("./normalize");
+var punctuation = require("./punctuation");
+
+exports.name = "Mode of Beleriand";
+
+var defaults = {};
+exports.makeOptions = makeOptions;
+function makeOptions(options) {
+ options = options || defaults;
+ return {
+ font: options.font || TengwarParmaite,
+ block: options.block,
+ plain: options.plain
+ };
+}
+
+exports.transcribe = transcribe;
+function transcribe(text, options) {
+ options = makeOptions(options);
+ var font = options.font;
+ return font.transcribe(parse(text, options), options);
+}
+
+exports.encode = encode;
+function encode(text, options) {
+ options = makeOptions(options);
+ return Notation.encode(parse(text, options), options);
+}
+
+var parse = exports.parse = makeDocumentParser(parseNormalWord, makeOptions);
+
+function parseNormalWord(callback, options) {
+ return normalize(parseWord(callback, options));
+}
+
+function parseWord(callback, options, columns) {
+ columns = columns || [];
+ return parseColumn(function (column) {
+ if (column) {
+ return parseWord(
+ callback,
+ options,
+ columns.concat([column])
+ );
+ } else {
+ return callback(columns);
+ }
+ }, options);
+}
+
+function parseColumn(callback, options) {
+ return parseTengwa(function (column) {
+ if (column) {
+ return parseFollowingS(callback, column);
+ } else {
+ return callback();
+ }
+ }, options);
+}
+
+function parseTengwa(callback, options) {
+ var font = options.font;
+ var makeColumn = font.makeColumn;
+ return function (character) {
+ if (character === "n") { // n
+ return function (character) {
+ if (character === "t" || character === "d") { // n{t,d}
+ return parseTengwa(function (column) {
+ return callback(column.addTildeAbove());
+ }, options)(character);
+ } else if (character === "c" || character === "g") { // n{c,g}
+ return parseTengwa(callback, options)("ñ")(character);
+ } else if (character === "n") { // nn
+ return callback(makeColumn("numen"));
+ } else { // n.
+ return callback(makeColumn("ore"))(character);
+ }
+ };
+ } else if (character === "t") { // t
+ return function (character) {
+ if (character === "h") { // th
+ return callback(makeColumn("thule"));
+ } else { // t.
+ return callback(makeColumn("tinco"))(character);
+ }
+ };
+ } else if (character === "d") { // d
+ return function (character) {
+ if (character === "h") { // dh
+ return callback(makeColumn("anto"));
+ } else { // d.
+ return callback(makeColumn("ando"))(character);
+ }
+ };
+ } else if (character === "m") { // m
+ return function (character) {
+ if (
+ character === "p" || character === "b" ||
+ character === "f" || character === "v"
+ ) {
+ return parseTengwa(function (column) {
+ return callback(column.addTildeAbove());
+ }, options)(character);
+ } else if (character === "m") { // mm
+ return callback(makeColumn("malta"));
+ } else { // m.
+ return callback(makeColumn("vala"))(character);
+ }
+ };
+ } else if (character === "p") { // p
+ return callback(makeColumn("parma"));
+ } else if (character === "b") { // b
+ return callback(makeColumn("umbar"));
+ } else if (character === "f") { // f
+ return function (character) {
+ if (Parser.isFinal(character)) { // f final
+ return callback(makeColumn("ampa"))(character);
+ } else {
+ return callback(makeColumn("formen"))(character);
+ }
+ };
+ } else if (character === "v") { // v
+ return callback(makeColumn("ampa"));
+ } else if (character === "ñ") { // ñ
+ return function (character) {
+ if (character === "c" || character === "g") {
+ return parseTengwa(function (column) {
+ if (column.tengwa === "halla") {
+ column.addError("Lenited G (halla) should not be nasalized with prefix N");
+ }
+ return callback(column.addTildeAbove());
+ }, options)(character);
+ } else { // ñ.
+ return callback(makeColumn("noldo"))(character);
+ }
+ };
+ } else if (character === "c") { // c
+ return function (character) {
+ if (character === "h") { // ch
+ return function (character) {
+ if (character === "w") { // chw
+ return callback(makeColumn("hwesta"));
+ } else { // ch.
+ return callback(makeColumn("harma"))(character);
+ }
+ };
+ } else if (character === "w") { // cw
+ return callback(makeColumn("quesse"));
+ } else { // c.
+ return callback(makeColumn("calma"))(character);
+ }
+ };
+ } else if (character === "g") {
+ return function (character) {
+ if (character === "h") { // gh
+ return function (character) {
+ if (character === "w") { // ghw
+ return callback(makeColumn("unque"));
+ } else { // gh.
+ return callback(makeColumn("anca"))(character);
+ }
+ };
+ } else if (character === "w") { // gw
+ return callback(makeColumn("ungwe"));
+ } else if (character === "'") { // g'
+ return callback(makeColumn("halla")); // gasdil
+ } else { // g.
+ return callback(makeColumn("anga"))(character);
+ }
+ };
+ } else if (character === "r") { // r
+ return function (character) {
+ if (character === "h") { // rh
+ return callback(makeColumn("arda"));
+ } else {
+ return callback(makeColumn("romen"))(character);
+ }
+ };
+ } else if (character === "l") { // l
+ return function (character) {
+ if (character === "h") { // lh
+ return callback(makeColumn("alda"));
+ } else {
+ return callback(makeColumn("lambe"))(character);
+ }
+ };
+ } else if (character === "s") { // s
+ return callback(makeColumn("silme"));
+ } else if (character === "a") { // a
+ return function (character) {
+ if (character === "i") { // ai
+ return callback(makeColumn("round-carrier").addAbove("í"));
+ } else if (character === "u") { // au
+ return callback(makeColumn("round-carrier").addAbove("w"));
+ } else if (character === "'") { // a'
+ return callback(makeColumn("round-carrier").addAbove("i"));
+ } else if (character === "a") { // aa
+ return callback(makeColumn("round-carrier").addAbove("e"));
+ } else { // a.
+ return callback(makeColumn("round-carrier"))(character);
+ }
+ };
+ } else if (character === "e") { // e
+ return function (character) {
+ if (character === "i") { // ei
+ return callback(makeColumn("yanta").addAbove("í"));
+ } else if (character === "e") {
+ return callback(makeColumn("yanta").addAbove("e"));
+ } else { // e.
+ return callback(makeColumn("yanta"))(character);
+ }
+ };
+ } else if (character === "i") { // i
+ return function (character) {
+ if (character === "i") { // ii -> í
+ return parseColumn(callback, options)("í");
+ } else {
+ return Parser.countPrimes(function (primes) {
+ if (primes === 0) {
+ return callback(makeColumn("short-carrier"));
+ } else if (primes === 1) {
+ return callback(makeColumn("short-carrier").addAbove("i"));
+ } else if (primes === 3) {
+ return callback(makeColumn("long-carrier"));
+ } else if (primes === 4) {
+ return callback(makeColumn("long-carrier").addAbove("i"));
+ } else {
+ return callback(makeColumn("long-carrier").addAbove("i").addError("I only has four variants between short or long and dotted or not."));
+ }
+ })(character);
+ }
+ };
+ } else if (character === "o") {
+ return function (character) {
+ if (character === "o") { // oo
+ return callback(makeColumn("anna").addAbove("e"));
+ } else {
+ return callback(makeColumn("anna"))(character);
+ }
+ };
+ } else if (character === "u") {
+ return function (character) {
+ if (character === "i") {
+ return callback(makeColumn("ure").addAbove("í"));
+ } else if (character === "u") {
+ return callback(makeColumn("ure").addAbove("e"));
+ } else {
+ return callback(makeColumn("ure"))(character);
+ }
+ };
+ } else if (character === "w") { // w
+ return function (character) {
+ if (character === "w") { // ww
+ return callback(makeColumn("wilya").addAbove("e"));
+ } else { // w.
+ return callback(makeColumn("wilya"))(character);
+ }
+ };
+ } else if (character === "y") {
+ return function (character) {
+ if (character === "y") { // yy
+ return callback(makeColumn("silme-nuquerna").addAbove("e"));
+ } else { // y.
+ return callback(makeColumn("silme-nuquerna"))(character);
+ }
+ };
+ } else if (character === "á") {
+ return callback(makeColumn("round-carrier").addAbove("e"));
+ } else if (character === "é") {
+ return callback(makeColumn("yanta").addAbove("e"));
+ } else if (character === "í") {
+ return Parser.countPrimes(function (primes) {
+ if (primes === 0) {
+ return callback(makeColumn("short-carrier").addAbove("e"));
+ } else if (primes === 1) {
+ return callback(makeColumn("long-carrier").addAbove("e"));
+ } else {
+ return callback(makeColumn("long-carrier").addAbove("e").addError("Í only has one variant."));
+ }
+ });
+ } else if (character === "ó") {
+ return callback(makeColumn("anna").addAbove("e"));
+ } else if (character === "ú") {
+ return callback(makeColumn("ure").addAbove("e"));
+ } else if (character === "h") {
+ return function (character) {
+ //if (character === "m") {
+ // return callback(makeColumn("ore-nasalized"));
+ if (character === "w") {
+ return callback(makeColumn("hwesta-sindarinwa"));
+ } else {
+ return callback(makeColumn("hyarmen"))(character);
+ }
+ };
+ } else if (character === "z") {
+ return callback(makeColumn("silme").addError("Z does not appear in the mode of Beleriand"));
+ } else if (punctuation[character]) {
+ return callback(makeColumn(punctuation[character]));
+ } else if (Parser.isBreak(character)) {
+ return callback()(character);
+ } else {
+ return callback(makeColumn("anna").addError("Unexpected character: " + JSON.stringify(character)));
+ }
+ };
+}
+
+function parseFollowingS(callback, column) {
+ return function (character) {
+ if (character === "s") {
+ if (column.canAddBelow("s")) {
+ return callback(column.addBelow("s"));
+ } else {
+ return Parser.countPrimes(function (primes) {
+ return function (character) {
+ if (Parser.isFinal(character)) { // end of word
+ if (column.canAddFollowing("s-final") && primes-- === 0) {
+ column.addFollowing("s-final");
+ } else if (column.canAddFollowing("s-inverse") && primes -- === 0) {
+ column.addFollowing("s-inverse");
+ } else if (column.canAddFollowing("s-extended") && primes-- === 0) {
+ column.addFollowing("s-extended");
+ } else if (column.canAddFollowing("s-flourish")) {
+ column.addFollowing("s-flourish");
+ if (primes > 0) {
+ column.addError(
+ "Following S only has 3 alternate " +
+ "flourishes."
+ );
+ }
+ } else {
+ return callback(column)("s")(character);
+ }
+ return callback(column)(character);
+ } else {
+ return callback(column)("s")(character);
+ }
+ };
+ });
+ }
+ } else {
+ return callback(column)(character);
+ }
+ };
+}
+
--- /dev/null
+
+n -> ore
+nn -> numen
+nt -> tinco tilde-above
+nth -> thule tilde-above
+nc -> calma tilde-above
+nch -> harma tilde-above
+nchw -> unque tilde-above
+ncw -> quesse tilde-above
+ng ->
+ngh ->
+nghw ->
+ngw ->
+nd -> ando tilde-above
+ndh -> anto tilde-above
+ng -> anga tilde-above
+ng (final) -> noldo
+
+t -> tinco
+th -> thule
+d -> ando
+dh -> anto
+
+m -> vala
+mm -> malta
+mp -> parma tilde-above
+mb -> umbar tilde-above
+mf -> formen tilde-above
+mf (final) -> ampa tilde-above
+mv -> ampa tilde-above
+
+p -> parma
+b -> umbar
+f (final) -> ampa
+f -> formen
+v -> ampa
+
+ñ -> noldo
+ñc -> calma tilde-above
+ñch -> harma tilde-above
+ñcw -> quesse tilde-above
+ñg -> anga tilde-above
+ñgh -> anca tilde-above
+ñghw -> unque tilde-above
+ñgw -> ungwe tilde-above
+ñw -> nwalme tilde-above
+
+c -> calma
+cw -> quesse
+ch -> harma
+chw -> hwesta
+g -> anga
+gw -> ungwe
+gh -> anca
+ghw -> unque
+g' -> halla (indicating lenition)
+
+r -> romen
+rh -> arda
+l -> lambe
+lh -> alda
+
+s -> silme
+
+a -> round-carrier
+a' -> round-carrier i-above
+ai -> round-carrier y-above
+au -> round-carrier w
+e -> yanta
+ei -> yanta y-above
+i -> short-carrier
+i' -> short-carrier i-above
+i'' -> long-carrier
+ii -> short-carrier e-above
+ii' -> long-carrier e-above
+o -> anna
+u -> ure
+ui -> ure y-above
+w -> wilya
+y -> silme-nuquerna
+yy -> silme-nuquerna e-tehta
+
+á -> round-carrier e-tehta
+é -> yanta e-tehta
+í -> short or long carrier e-tehta
+ó -> anna e-tehta
+ú -> ure e-tehta
+
+h -> hyarmen
+hm -> XXX nasalized ore
+hw -> hwesta-sindarinwa
+hl -> use lh
+hr -> use rh
+
+z -> do not use
+
var TengwarAnnatar = require("./tengwar-annatar");
var Notation = require("./notation");
-var makeParser = require("./parser");
+var Parser = require("./parser");
+var makeDocumentParser = require("./document-parser");
var normalize = require("./normalize");
var punctuation = require("./punctuation");
+exports.name = "Classical Mode";
+
var defaults = {};
+exports.makeOptions = makeOptions;
function makeOptions(options) {
options = options || defaults;
return {
// in the third age, through the namarie poem, "r" is only "ore" before
// consontants and at the end of words.
// TODO figure out "h"
+ reverseCurls: options.reverseCurls,
+ // false: by default, o is forward, u is backward
+ // true: o is backward, u is forward
iuRising: options.isRising,
// iuRising thirdAge: anna:y,u
// otherwise: ure:i
return Notation.encode(parse(text, options), options);
}
-// TODO convert to parse tree
-exports.parse = parse;
-function parse(text, options) {
- options = makeOptions(options);
- var font = options.font;
- var makeColumn = font.makeColumn;
- return text.split(/\n\n\n+/).map(function (section) {
- return section.split(/\n\n/).map(function (paragraph) {
- return paragraph.split(/\n/).map(function (line) {
- var words = [];
- var word = [];
- line.toLowerCase().replace(
- /([\wáéíóúëâêîôûñ']+)|(.)/g,
- function ($, contiguous, other) {
- if (contiguous) {
- try {
- word.push.apply(word, parseWord(normalize(contiguous), options));
- } catch (exception) {
- word.push(makeColumn().addError("Cannot transcribe " + JSON.stringify(contiguous) + " because " + exception.message));
- }
- } else if (punctuation[other]) {
- word.push(makeColumn(punctuation[other]));
- } else if (other === " ") {
- words.push(word);
- word = [];
- } else {
- word.push(makeColumn().addError("Cannot transcribe " + JSON.stringify(other)));
- }
- }
- );
- if (word.length) {
- words.push(word);
- }
- return words;
- });
- });
- });
-}
-
-// original mode: (classical)
-// interim: (classical + wilya? + aha? + longHalla?)
-// third age: (iuRising?) default
+var parse = exports.parse = makeDocumentParser(parseNormalWord, makeOptions);
-var parseWord = makeParser(function (callback, options) {
- return parseWordTail(callback, options, []);
-});
-
-// state machine
+function parseNormalWord(callback, options) {
+ return normalize(parseWord(callback, options));
+}
-function parseWordTail(callback, options, columns, previous) {
+function parseWord(callback, options, columns, previous) {
+ columns = columns || [];
return parseColumn(function (moreColumns) {
if (!moreColumns.length) {
return callback(columns);
} else {
- return parseWordTail(
+ return parseWord(
callback,
options,
columns.concat(moreColumns),
}
function parseColumn(callback, options, previous) {
+ var font = options.font;
+ var makeColumn = font.makeColumn;
return parseTengwa(function (columns) {
var previous = columns.pop();
return parseTehta(function (next) {
- return callback(columns.concat(next).filter(Boolean));
+ var next = columns.concat(next).filter(Boolean)
+ if (next.length) {
+ return callback(next);
+ } else {
+ return function (character) {
+ if (Parser.isBreak(character)) {
+ return callback([])(character);
+ } else if (punctuation[character]) {
+ return callback([makeColumn(punctuation[character])]);
+ } else {
+ return callback([makeColumn("anna").addError(
+ "Cannot transcribe " + JSON.stringify(character) +
+ " in Classical Mode"
+ )]);
+ }
+ };
+ }
}, options, previous);
}, options, previous);
}
} else if (character === "s") {
return function (character) {
// TODO s-inverse, s-extended, s-flourish
- if (character === "") { // ts final
+ if (Parser.isFinal(character)) { // ts final
return callback([makeColumn("tinco").addFollowing("s")])(character);
} else { // ts medial
return callback([
return callback([makeColumn("parma").addBelow("y")]);
} else if (character === "s") { // ps
return function (character) {
- if (character === "") { // ps final
+ if (Parser.isFinal(character)) { // ps final
return callback([makeColumn("parma").addFollowing("s")])(character);
} else { // ps medial
return callback([
}
} else {
// pre-consonant and word-final
- if (character === "" || vowels.indexOf(character) === -1) { // ore
+ if (Parser.isFinal(character) || vowels.indexOf(character) === -1) { // ore
return callback([makeColumn("ore")])(character);
} else { // romen
return callback([makeColumn("romen")])(character);
} else if (character === "u") {
return callback([previous, makeColumn("ure", "a")]);
} else if (previous && previous.canAddAbove("a")) {
- previous.addAbove("a");
- return callback([previous])(character);
+ return callback([previous.addAbove("a")])(character);
} else {
return callback([previous, makeColumn("short-carrier", "a")])(character);
}
return function (character) {
if (character === "u") {
if (options.iuRising) {
- return callback([previous, makeColumn("anna", "u").addBelow("y")]);
+ return callback([previous, makeColumn("anna").addAbove(reverseCurls("u", options)).addBelow("y")]);
} else {
return callback([previous, makeColumn("ure", "i")]);
}
} else if (character === "o") {
return function (character) {
if (character === "i") {
- return callback([previous, makeColumn("yanta", "o")]);
+ return callback([previous, makeColumn("yanta").addAbove(reverseCurls("o", options))]);
} else if (previous && previous.canAddAbove("o")) {
- return callback([previous.addAbove("o")])(character);
+ return callback([previous.addAbove(reverseCurls("o", options))])(character);
} else {
- return callback([previous, makeColumn("short-carrier", "o")])(character);
+ return callback([previous, makeColumn("short-carrier").addAbove(reverseCurls("o", options))])(character);
}
};
} else if (character === "u") {
if (character === "i") {
return callback([previous, makeColumn("yanta", "u")]);
} else if (previous && previous.canAddAbove("u")) {
- return callback([previous.addAbove("u")])(character);
+ return callback([previous.addAbove(reverseCurls("u", options))])(character);
} else {
- return callback([previous, makeColumn("short-carrier", "u")])(character);
+ return callback([previous, makeColumn("short-carrier").addAbove(reverseCurls("u", options))])(character);
}
};
} else if (character === "y") {
return callback([previous, makeColumn("long-carrier", "i")]);
} else if (character === "ó") {
if (previous && previous.canAddAbove("ó")) {
- return callback([previous.addAbove("ó")]);
+ return callback([previous.addAbove(reverseCurls("ó", options))]);
} else {
- return callback([previous, makeColumn("long-carrier", "o")]);
+ return callback([previous, makeColumn("long-carrier").addAbove(reverseCurls("o", options))]);
}
} else if (character === "ú") {
if (previous && previous.canAddAbove("ú")) {
- return callback([previous.addAbove("ú")]);
+ return callback([previous.addAbove(reverseCurls("ú", options))]);
} else {
- return callback([previous, makeColumn("long-carrier", "u")]);
+ return callback([previous, makeColumn("long-carrier").addAbove(reverseCurls("u", options))]);
}
} else {
return callback([previous])(character);
};
}
+var curlReversals = {"o": "u", "u": "o", "ó": "ú", "ú": "ó"};
+function reverseCurls(tehta, options) {
+ if (options.reverseCurls) {
+ tehta = curlReversals[tehta] || tehta;
+ }
+ return tehta;
+}
+
// Notes regarding "h":
//
// http://at.mansbjorkman.net/teng_quenya.htm#note_harma
--- /dev/null
+
+var Parser = require("./parser");
+
+// produces a document parser from a word parser in an arbitrary mode
+module.exports = makeDocumentParser;
+function makeDocumentParser(parseWord, makeOptions) {
+ var parseLine = Parser.makeDelimitedParser(parseWord, parseSomeSpaces);
+ var parseParagraph = Parser.makeDelimitedParser(parseLine, parseNewlineSpace);
+ var parseSection = Parser.makeDelimitedParser(parseParagraph, parseNewlineSpace);
+ var parseDocument = Parser.makeDelimitedParser(parseSection, parseNewlineSpaces);
+ return Parser.makeParser(function (callback, options) {
+ options = makeOptions(options);
+ var state = parseDocument(callback, options);
+ return state;
+ });
+}
+
+var parseAnySpaces = Parser.makeParseAny(" ");
+var parseSomeSpaces = Parser.makeParseSome(" ");
+var parseNewline = Parser.makeExpect("\n");
+var parseNewlines = Parser.makeParseSome("\n");
+
+function parseNewlineSpace(callback) {
+ return parseAnySpaces(function () {
+ return parseNewline(function () {
+ return parseAnySpaces(callback);
+ });
+ });
+}
+
+function parseNewlineSpaces(callback) {
+ return parseAnySpaces(function () {
+ return parseNewlines(function () {
+ return parseAnySpaces(callback);
+ });
+ });
+}
<div id="divider"></div>
<div id="input-box">
<div id="form-box">
+
<input type="radio" name="mode" id="input-general-use" value="general-use" checked>
<label for="input-general-use">General Use</label><br>
<input type="radio" name="mode" id="input-classical" value="classical">
<label for="input-classical">Classical</label><br>
+ <input type="radio" name="mode" id="input-beleriand" value="beleriand">
+ <label for="input-beleriand">Beleriand</label><br>
+
<input type="radio" name="font" id="input-tengwar-annatar" value="annatar" checked>
<label for="input-tengwar-annatar">Tengwar Annatar</label><br>
<input type="radio" name="font" id="input-tengwar-parmaite" value="parmaite">
<label for="input-tengwar-parmaite">Tengwar Parmaitë</label><br>
+
<!--
<input type="checkbox" name="transliteration" id="input-transliteration">
<label for="input-transliteration">Show transliteration</label>
-->
+
</div>
<div id="content-box" style="">
<textarea id="input" spellcheck="false"></textarea>
var QS = require("qs");
-var GeneralUse = require("../general-use");
-var Classical = require("../classical");
-var TengwarAnnatar = require("../tengwar-annatar");
-var TengwarParmaite = require("../tengwar-parmaite");
+var modes = require("../modes");
+var fonts = require("../fonts");
var body = document.body;
var input = document.querySelector("#input");
var generalUse = document.querySelector("#input-general-use");
var classical = document.querySelector("#input-classical");
+var beleriand = document.querySelector("#input-beleriand");
var annatar = document.querySelector("#input-tengwar-annatar");
var parmaite = document.querySelector("#input-tengwar-parmaite");
var output = document.querySelector("#output");
input.value = query.q || "";
generalUse.checked = query.mode === "general-use";
classical.checked = query.mode === "classical";
+ beleriand.checked = query.mode === "beleriand";
parmaite.checked = query.font === "parmaite";
annatar.checked = query.font === "annatar";
} else {
input.value = value;
}
history.replaceState(query, value, "?" + QS.stringify(query));
- var mode = query.mode === "classical" ? Classical : GeneralUse;
- var font = query.font === "annatar" ? TengwarAnnatar : TengwarParmaite;
+ var mode = modes[query.mode] || TengwarParmaite;
+ var font = fonts[query.font] || TengwarAnnatar;
output.classList.remove(query.font !== "parmaite" ? "parmaite" : "annatar");
output.classList.add(query.font === "parmaite" ? "parmaite" : "annatar");
output.innerHTML = mode.transcribe(value, {font: font, block: true});
var change;
if (query.q !== input.value) change = true;
query.q = input.value;
- var newMode = generalUse.checked ? "general-use" : "classical";
+ var newMode = generalUse.checked ? "general-use" : classical.checked ? "classical" : "beleriand";
if (query.mode !== newMode) change = true;
query.mode = newMode;
var newFont = annatar.checked ? "annatar" : "parmaite";
input.addEventListener("keydown", onupdate);
input.select();
-/*
-input.focus();
-var range = document.createRange();
-var node;
-if (!input.lastChild) {
- input.appendChild(document.createTextNode(""));
-}
-node = input.lastChild;
-range.selectNode(node);
-range.collapse();
-var selection = window.getSelection();
-selection.removeAllRanges();
-selection.addRange(range);
-*/
generalUse.addEventListener("change", onupdate);
classical.addEventListener("change", onupdate);
+beleriand.addEventListener("change", onupdate);
parmaite.addEventListener("change", onupdate);
annatar.addEventListener("change", onupdate);
--- /dev/null
+module.exports = {
+ "parmaite": require("./tengwar-parmaite"),
+ "annatar": require("./tengwar-annatar")
+};
var TengwarAnnatar = require("./tengwar-annatar");
var Notation = require("./notation");
-var makeParser = require("./parser");
+var Parser = require("./parser");
+var makeDocumentParser = require("./document-parser");
var normalize = require("./normalize");
var punctuation = require("./punctuation");
var parseNumber = require("./numerals");
+exports.name = "General Use Mode";
+
var defaults = {};
+exports.makeOptions = makeOptions;
function makeOptions(options) {
options = options || defaults;
return {
// or below.
// false: by default, place a tilde above doubled nasals.
// true: place the tilde below doubled nasals.
+ reverseCurls: options.reverseCurls,
+ // false: by default, o is forward, u is backward
+ // true: o is backward, u is forward
noAchLaut: options.noAchLaut,
// false: "ch" is interpreted as ach-laut, "cc" as "ch" as in "chew"
// true: "ch" is interpreted as "ch" as in chew
return Notation.encode(parse(text, options), options);
}
-// TODO convert to parse tree
-exports.parse = parse;
-function parse(text, options) {
- options = makeOptions(options);
+var parse = exports.parse = makeDocumentParser(parseNormalWord, makeOptions);
+
+function parseNormalWord(callback, options) {
+ return normalize(parseWord(callback, options));
+}
+
+function parseWord(callback, options) {
var font = options.font;
var makeColumn = font.makeColumn;
- return text.split(/\n\n\n+/).map(function (section) {
- return section.split(/\n\n/).map(function (paragraph) {
- return paragraph.split(/\n/).map(function (line) {
- var words = [];
- var word = [];
- line.toLowerCase().replace(
- /(0[\dab]+)|(\d+)|([\wáéíóúëâêîôûñ']+)|(.)/g,
- function ($, dudecimal, decimal, contiguous, other) {
- if (contiguous) {
- contiguous = normalize(contiguous);
- try {
- if (book[contiguous]) {
- word.push.apply(word, Notation.decodeWord(book[contiguous], makeColumn));
- } else {
- word.push.apply(word, parseWord(contiguous, options));
- }
- } catch (exception) {
- word.push(makeColumn().addError("Cannot transcribe " + JSON.stringify(word) + " because " + exception.message));
- }
- } else if (dudecimal) {
- word.push.apply(word, parseNumber(dudecimal, 12, options));
- } else if (decimal) {
- word.push.apply(word, parseNumber(decimal, 10, options));
- } else if (punctuation[other]) {
- word.push(makeColumn(punctuation[other]));
- } else if (other === " ") {
- words.push(word);
- word = [];
- } else {
- word.push(makeColumn().addError("Cannot transcribe " + JSON.stringify(other)));
- }
- }
- );
- if (word.length) {
- words.push(word);
- }
- return words;
- });
- });
- });
+ return scanWord(function (word) {
+ if (book[word]) {
+ return callback(Notation.decodeWord(book[word], makeColumn));
+ } else {
+ return callback(parseWordPiecewise(word, options));
+ }
+ }, options);
}
var book = {
"is": "short-carrier:i,s"
};
-var parseWord = makeParser(function (callback, options) {
+function scanWord(callback, options, word) {
+ word = word || "";
+ return function (character) {
+ if (Parser.isBreak(character)) {
+ return callback(word)(character);
+ } else {
+ return scanWord(callback, options, word + character);
+ }
+ };
+}
+
+var parseWordPiecewise = Parser.makeParser(function (callback, options) {
return parseWordTail(callback, options, []);
});
.addBelow("s")
]);
} else if (canAddAboveTengwa(tehta) && tengwa.canAddAbove(tehta)) {
+ if (options.reverseCurls) {
+ tehta = reverseCurls[tehta] || tehta;
+ }
tengwa.addAbove(tehta);
return parseTengwaAnnotations(function (tengwa) {
return callback([tengwa]);
return callback([carrier]);
}, makeCarrier(tehta));
} else {
- return callback([]);
+ return function (character) {
+ if (Parser.isBreak(character)) {
+ return callback([]);
+ } else if (punctuation[character]) {
+ return callback([makeColumn(punctuation[character])]);
+ } else {
+ return callback([makeColumn("anna").addError("Unexpected character: " + JSON.stringify(character))]);
+ }
+ };
}
}, options, tehta);
});
var tengwaTehtar = "aeiouóú";
var vowels = "aeiouáéíóú";
var shorterVowels = {"á": "a", "é": "e", "í": "i", "ó": "o", "ú": "u"};
+var reverseCurls = {"o": "u", "u": "o", "ó": "ú", "ú": "ó"};
function canAddAboveTengwa(tehta) {
return tengwaTehtar.indexOf(tehta) !== -1;
} else { // nw.
return callback(makeColumn("numen").addAbove("w"))(character);
}
- return callback(makeColumn("nwalme").addAbove("w"));
};
} else { // n.
return callback(makeColumn("numen"))(character);
};
} else if (character === "ñ") { // ñ
return function (character) {
- // ññ does not really exist
+ // ññ does not exist to the best of my knowledge
// ñw is handled naturally by following w
if (character === "c") { // ñc
return callback(makeColumn("quesse").addTildeAbove());
return callback(makeColumn("tinco").addTildeBelow());
} else if (character === "h") { // th
return callback(makeColumn("thule"));
+ } else if (character === "c") { // tc
+ return function (character) {
+ if (character === "h") { // tch -> tinco calma
+ return callback(makeColumn("tinco"))("c")("h")("'");
+ } else {
+ return callback(makeColumn("tinco"))("c")(character);
+ }
+ };
} else { // t.
return callback(makeColumn("tinco"))(character);
}
return function (character) {
if (character === "d") { // dd
return callback(makeColumn("ando").addTildeBelow());
+ } else if (character === "j") { // dj
+ return callback(makeColumn("anga"));
} else if (character === "h") { // dh
return callback(makeColumn("anto"));
} else { // d.
return callback(makeColumn("esse"))(character);
}
};
- } else if (character === "h") { //
+ } else if (character === "h") { // h
return function (character) {
if (character === "w") { // hw
return callback(makeColumn("hwesta-sindarinwa"));
if (column.canAddBelow("s")) {
return callback(column.addBelow("s"));
} else {
- return countPrimes(function (primes) {
+ return Parser.countPrimes(function (primes) {
return function (character) {
if (character === "") { // end of word
if (column.canAddFollowing("s-final") && primes-- === 0) {
};
}
-function countPrimes(callback, primes) {
- primes = primes || 0;
- return function (character) {
- if (character === "'") {
- return countPrimes(callback, primes + 1);
- } else {
- return callback(primes)(character);
- }
- };
-}
-
--- /dev/null
+module.exports = {
+ "general-use": require("./general-use"),
+ "classical": require("./classical"),
+ "beleriand": require("./beleriand")
+};
-module.exports = function normalize(text) {
- // normalize
- return text.replace(normalFormsRe, function ($, key) {
- return normalForms[key];
- });
+var Parser = require("./parser");
+var makeTrie = require("./trie");
+var makeParserFromTrie = require("./trie-parser");
+var array_ = Array.prototype;
+
+module.exports = normalize;
+function normalize(callback) {
+ return toLowerCase(simplify(callback));
};
-var normalForms = {
+function toLowerCase(callback) {
+ return function passthrough(character) {
+ callback = callback(character.toLowerCase());
+ return passthrough;
+ };
+}
+
+var table = {
"k": "c",
"x": "cs",
- "qu": "cw",
"q": "cw",
+ "qu": "cw",
+ "p": "p",
"ph": "f",
+ "b": "b",
"bh": "v",
"ë": "e",
"â": "á",
"û": "ú"
};
-var normalFormsRe = new RegExp("(" +
- Object.keys(normalForms).join("|") +
-")", "ig");
+var trie = makeTrie(table);
+var simplify = makeParserFromTrie(
+ trie,
+ function makeProducer(string) {
+ return function (callback) {
+ return Array.prototype.reduce.call(string, function (callback, character) {
+ return callback(character);
+ }, callback);
+ };
+ },
+ function callback(callback) {
+ return simplify(callback);
+ },
+ function fallback(callback) {
+ return function (character) {
+ return simplify(callback(character));
+ };
+ }
+);
-module.exports = function makeParser(production, errorHandler) {
- var errorHandler = errorHandler || function (error) {
- throw new Error(error);
+var punctuation = require("./punctuation");
+
+// builds a string parser from a streaming character parser
+exports.makeParser = makeParser;
+function makeParser(production, errorHandler) {
+ var errorHandler = errorHandler || function (error, text) {
+ throw new Error(error + " while parsing " + JSON.stringify(text));
};
return function (text /*, ...args*/) {
-
// the parser is a monadic state machine.
// each state is represented by a function that accepts
// a character. parse functions accept a callback (for forwarding the
var result;
var state = production.apply(null, [function (_result) {
result = _result;
- return expectEof(errorHandler);
+ return expectEof(function (error) {
+ return errorHandler(error, text);
+ });
}].concat(Array.prototype.slice.call(arguments, 1)));
// drive the state machine
Array.prototype.forEach.call(text, function (letter, i) {
state = state(""); // EOF
}
return result;
-
};
}
};
}
+exports.makeExpect = makeExpect;
+function makeExpect(expected) {
+ return function (callback) {
+ return function (character) {
+ if (character === expected) {
+ return callback(character);
+ } else {
+ return callback()(character);
+ }
+ };
+ };
+}
+
+exports.makeParseSome = makeParseSome;
+function makeParseSome(expected) {
+ var parseSome = function (callback) {
+ return function (character) {
+ if (character === expected) {
+ return parseRemaining(callback);
+ } else {
+ return callback()(character);
+ }
+ };
+ };
+ var parseRemaining = makeParseAny(expected);
+ return parseSome;
+}
+
+exports.makeParseAny = makeParseAny;
+function makeParseAny(expected) {
+ return function parseRemaining(callback) {
+ return function (character) {
+ if (character === expected) {
+ return parseRemaining(callback);
+ } else {
+ return callback(expected)(character);
+ }
+ };
+ };
+}
+
+exports.makeDelimitedParser = makeDelimitedParser;
+function makeDelimitedParser(parsePrevious, parseDelimiter) {
+ return function parseSelf(callback, options, terms) {
+ terms = terms || [];
+ return parsePrevious(function (term) {
+ if (!term.length) {
+ return callback(terms);
+ } else {
+ terms = terms.concat([term]);
+ return parseDelimiter(function (delimiter) {
+ if (delimiter) {
+ return parseSelf(callback, options, terms);
+ } else {
+ return callback(terms);
+ }
+ });
+ }
+ }, options);
+ }
+}
+
+// used by parsers to determine whether the cursor is on a word break
+exports.isBreak = isBreak;
+function isBreak(character) {
+ return character === " " || character === "\n" || character === "";
+}
+
+exports.isFinal = isFinal;
+function isFinal(character) {
+ return isBreak(character) || punctuation[character];
+}
+
+// used by multiple modes
+exports.countPrimes = countPrimes;
+function countPrimes(callback, primes) {
+ primes = primes || 0;
+ return function (character) {
+ if (character === "'") {
+ return countPrimes(callback, primes + 1);
+ } else {
+ return callback(primes)(character);
+ }
+ };
+}
+
<div class="tengwar annatar"
data-tengwar=">Ash nazg durbatulûk, ash nazg gimbatul,<
Ash nazg thrakatulûk agh burzum-ishi krimpatul."
- data-mode="general-use"></div>
+ data-mode="general-use reverse-curls"></div>
<p>Compare to the mode on the actual ring inscription.</p>
<img src="ring-inscription.jpg">
module.exports = {
"ainaldo": "yanta:a;numen:a;alda:o",
+ "ainaldo i-luin:\nheru aldost.": "yanta:a;numen:a;alda:o short-carrier:i;comma;lambe;yanta:u;numen;comma\nhyarmen:e;romen:u short-carrier:a;alda:o;silme;tinco;full-stop",
"aldost": "short-carrier:a;alda:o;silme;tinco",
"hlóce": "halla;lambe:ó;calma:e", // attested
"hríve": "halla;romen;long-carrier:i;vala:e", // attested
"aldost": "lambe:a;ando;silme-nuquerna:o;tinco",
"amon sûl": "malta:a;numen:o silme;lambe:ú",
"aragorn": "romen:a;ungwe:a;romen:o;numen",
+ "Aragorn Arathorn:\nTelcontar, Elessar": "romen:a;ungwe:a;romen:o;numen romen:a;thule:a;romen:o;numen;comma\ntinco;lambe:e;quesse;tinco:o,tilde-above;romen:a;comma lambe:e;silme-nuquerna:e,tilde-below;ore:a",
"atto": "tinco:a,tilde-below;short-carrier:o",
"baranduiniant": "umbar;romen:a;ando:a,tilde-above;anna:u;yanta;anto:a,tilde-above",
"dagor bragolach": "ando;ungwe:a;ore:o umbar;romen;ungwe:a;lambe:o;hwesta:a",
"formen": {
"a": 3,
"w": 3,
+ "í": 3,
"others": 2
},
"harma": {
"o": 1,
"u": 1,
"w": 0,
+ "í": 0,
"others": 1
},
"hwesta": {
"o": 2,
"w": 1,
"y": 1,
+ "í": 2,
"others": 3
},
"anna": {
"others": 2
},
"wilya": {
- "a": 1,
- "e": 1,
"i": 2,
- "o": 1,
- "u": 1,
+ "í": 2,
"others": 1
},
"o": 1,
"u": 1,
"w": 1,
+ "í": 2,
"y": null,
"o-under": null,
"others": 0
"a": 3,
"w": 3,
"y": 3,
+ "í": 3,
"others": 2
},
"parma-extended": {
"a": 3,
"w": 3,
"y": 3,
+ "í": 3,
"others": 2
},
"calma-extended": {
"i": 1,
"w": 1,
"y": 0,
+ "í": 0,
"others": 0
},
"quesse-extended": {
"i": 1,
"w": 1,
"y": 0,
+ "í": 0,
"others": 0
}
);
}
-var longVowels = "áéÃóú";
+var longVowels = "áéóú";
function tehtaKeyForTengwa(tengwa, tehta) {
if (!tehtar[tehta])
return null;
+++ /dev/null
-
-var GeneralUse = require("./general-use");
-var Classical = require("./classical");
-
-var tests = {
- classical: {
-
- "ainaldo": "yanta:a;numen:a;alda:o",
- "aldost": "short-carrier:a;alda:o;silme;tinco",
- "hlóce": "halla;lambe:ó;calma:e", // attested
- "hríve": "halla;romen;long-carrier:i;vala:e", // attested
- "hyarmen": "hyarmen:y,a;romen;malta:e;numen",
- "hyarmen(classical)": "hyarmen:a;romen;malta:e;numen",
- "hyarmen(classical,aha)": "hyarmen:y,a;romen;malta:e;numen",
- "lambe": "lambe:a;umbar:e",
- "moria": "malta:o;romen:i;short-carrier:a"
- "silme": "silme-nuquerna:i;lambe;malta:e",
- "syi": "silme:y;short-carrier:i", //*
- "thúlë": "thule:ú;lambe:e",
- "tyelpe": "tinco:y,e;lambe;parma:e",
- "vanwa": "vala:a;numen;wilya:a",
- "yuldar": "anna:y,u;alda:a;ore",
-
- },
- generalUse: {
-
- // sindarin (sorted)
- "ainur": "anna:a;numen;ore:u",
- "aldost": "lambe:a;ando;silme-nuquerna:o;tinco",
- "amon sûl": "malta:a;numen:o silme;lambe:ú",
- "aragorn": "romen:a;ungwe:a;romen:o;numen",
- "atto": "tinco:a,tilde-below;short-carrier:o",
- "baranduiniant": "umbar;romen:a;ando:a,tilde-above;anna:u;yanta;anto:a,tilde-above",
- "dagor bragolach": "ando;ungwe:a;ore:o umbar;romen;ungwe:a;lambe:o;hwesta:a"
- "galadhrim": "ungwe;lambe:a;anto:a;romen;malta:i",
- "galadriel": "ungwe;lambe:a;ando:a;romen;short-carrier:i;lambe:e",
- "gandalf": "ungwe;ando:a,tilde-above;lambe:a;formen",
- "glorfindel": "ungwe;lambe;romen:o;formen;ando:i,tilde-above;lambe:e",
- "gwaith iaur arnor": "ungwe:w;anna:a;thule yanta;vala:a;ore romen:a;numen;ore:o",
- "gwathló": "ungwe:w;thule:a;lambe;long-carrier:o",
- "hwesta sindarinwa": "hwesta-sindarinwa;silme-nuquerna:e;tinco;short-carrier:a silme;ando:i,tilde-above;romen:a;numen:i;vala;short-carrier:a",
- "iant": "yanta;tinco:a,tilde-above",
- "iaur": "yanta;vala:a;ore",
- "isildur": "silme-nuquerna:i;lambe:i;ando;ore:u",
- "lhûn": "alda;numen:ú",
- "lothlórien": "lambe;thule;lambe;romen:ó;short-carrier:i;numen:e",
- "mae govannen": "malta;yanta:a ungwe;ampa:o;numen:a,tilde-above;numen:e",
- "mellon": "malta;lambe:e,tilde-below;numen:o",
- "mordor": "malta;romen:o;ando:ore:o",
- "moria": "malta;romen:o;short-carrier:i;short-carrier:a"
- "noldor": "nwalme;lambe:o;ando;ore:o",
- "periannath": "parma;romen:e;short-carrier:i;numen:a,tilde-above;thule:a"
- "rhûn": "arda;numen:ú",
- "tyelpe": "tinco:y;lambe:e;parma;short-carrier:e",
- "varda": "ampa;romen:a;ando;short-carrier:a",
- "á": "wilya:a",
- "ñoldor": "nwalme;lambe:o;ando;ore:o",
-
- // quenya (improper mode) (sorted)
- "ardalambion": "romen:a;ando;lambe:a;umbar:a,tilde-above;short-carrier:i;numen:o",
- "helcaraxë": "hyarmen;lambe:e;quesse;romen:a;quesse:a,s;short-carrier:e",
- "hyarmen": "hyarmen:y;romen:a;malta;numen:e",
- "istari": "silme-nuqeurna:i;tinco;romen:a;short-carrier:i",
- "sinome maruvan": "silme;numen:i;malta:o;short-carrier:e malta;romen:a;ampa:u;numen:a",
- "telperion": "tinco;lambe:e;parma;romen:e;short-carrier:i;numen:o",
- "yuldar": "short-carrier:í;lambe:u;ando;ore:a",
-
- // english (appropriate mode) (sorted)
- "hobbits": "hyarmen;umbar:o,tilde-below;tinco:i,s",
- "hobbits'": "hyarmen;umbar:o,tilde-below;tinco:i,s-inverse",
- "hobbits''": "hyarmen;umbar:o,tilde-below;tinco:i,s-extended",
-
- // old english
- "írensaga": "long-carrier:i;romen;numen:e;silme;ungwe:a;short-carrier:a",
-
- // interesting clusters
- "xx": "quesse/s;quesse:s",
- "tsts": "tinco;silme;tinco:s",
- "iqs": "quesse:i;vala;silme",
- "aty": "tinco:a,y",
- "is": "short-carrier:i,s",
- "allys": "lambe:a,tilde-below,y:s",
- "alyssa": "lambe:a,y;silme:tilde-below;short-carrier:a"
-
- }
-};
-
--- /dev/null
+
+var Parser = require("./parser");
+
+module.exports = makeParserFromTrie;
+function makeParserFromTrie(trie, makeProducer, callback, fallback) {
+ var children = {};
+ var characters = Object.keys(trie.children);
+ characters.forEach(function (character) {
+ children[character] = makeParserFromTrie(
+ trie.children[character],
+ makeProducer,
+ callback,
+ fallback
+ );
+ });
+ var producer;
+ if (trie.value) {
+ producer = makeProducer(trie.value);
+ }
+ return characters.reduceRight(function (next, expected) {
+ return function (state) {
+ return function (character) {
+ if (character === expected) {
+ return callback(children[character](state));
+ } else {
+ return next(state)(character);
+ }
+ };
+ };
+ }, function (state) {
+ if (producer) {
+ return callback(producer(state));
+ } else {
+ return fallback(state);
+ }
+ });
+}
+
--- /dev/null
+
+module.exports = makeTrie;
+function makeTrie(table) {
+ var strings = Object.keys(table);
+ var trie = {value: void 0, children: {}};
+ var tables = {};
+ strings.forEach(function (string) {
+ if (string.length === 0) {
+ trie.value = table[string];
+ } else {
+ var character = string[0];
+ if (!tables[character]) {
+ tables[character] = {};
+ }
+ var tail = string.slice(1);
+ tables[character][tail] = table[string];
+ }
+ });
+ var characters = Object.keys(tables);
+ characters.forEach(function (character) {
+ trie.children[character] = makeTrie(tables[character]);
+ });
+ return trie;
+}
+
--common_js_entry_module vanilla-tengwar.js \
--js \
vanilla-tengwar.js \
+ modes.js \
general-use.js \
classical.js \
+ beleriand.js \
+ fonts.js \
tengwar-annatar.js \
tengwar-parmaite.js \
- parser.js \
- normalize.js \
- punctuation.js \
- notation.js \
+ dan-smith.js \
alphabet.js \
+ punctuation.js \
numerals.js \
- dan-smith.js
+ notation.js \
+ normalize.js \
+ parser.js \
+ document-parser.js \
+ trie.js \
+ trie-parser.js
+
echo '})();'
) | closure > vanilla-tengwar.min.js
var GeneralUse = require("./general-use");
var Classical = require("./classical");
+var Beleriand = require("./beleriand");
var TengwarAnnatar = require("./tengwar-annatar");
var TengwarParmaite = require("./tengwar-parmaite");
+var modes = require("./modes");
var array_ = Array.prototype;
if (encoding) {
element.innerText = TengwarAnnatar.transcribe(encoding, {block: block});
} else if (tengwar) {
- mode = mode || 'general-use';
font = element.classList.contains("parmaite") ? TengwarParmaite : TengwarAnnatar;
- var Mode = mode === 'general-use' ? GeneralUse : Classical;
- element.innerHTML = Mode.transcribe(tengwar, {
- block: block,
- font: font
+ var flags = mode.split(/\s+/);
+ var mode = flags.shift();
+ var Mode = modes[mode] || GeneralUse;
+ var options = Mode.makeOptions();
+ flags.forEach(function (flag) {
+ flag = flag.replace(/\-(\w)/g, function ($, $1) {
+ return $1.toUpperCase();
+ });
+ options[flag] = true;
});
+ options.block = block;
+ options.font = font;
+ element.innerHTML = Mode.transcribe(tengwar, options);
}
});
}
-(function(){function F(a,e){return a.split(";").map(function(a){var a=a.split(":"),f=a.shift(),a=a.length?a.shift().split(","):[],d=e(f);a.forEach(function(a){"tilde-above"===a?d.addTildeAbove():"tilde-below"===a?d.addBarBelow():"y"===a?d.addBelow("y"):"s"===a||"s-inverse"===a||"s-extended"===a||"s-flourish"===a?"s"===a&&("calma"===f||"quesse"===f)?d.addBelow(a):d.addFollowing(a):d.addAbove(a)});return d})}function q(a,e){var c=!s[e]?null:s[e].special?s[e][a]||null:-1!==X.barsAndTildes.indexOf(e)?
-"lambe"===a||"alda"===a&&2<=s[e].length?2:m[a].wide?0:1:null==m[a]||null===m[a][e]?null:null!=m[a][e]?m[a][e]:null!=m[a].others?m[a].others:m[a];return null==c?null:s[e][a]||s[e][c]||""}function z(a){a=a||Y;return{font:a.font||Z,block:a.block,plain:a.plain,doubleNasalsWithTildeBelow:a.doubleNasalsWithTildeBelow,noAchLaut:a.noAchLaut}}function A(a,e){var e=z(e),c=e.font.makeColumn;return a.split(/\n\n\n+/).map(function(a){return a.split(/\n\n/).map(function(a){return a.split(/\n/).map(function(a){var d=
-[],g=[];a.toLowerCase().replace(/(0[\dab]+)|(\d+)|([\w\u00e1\u00e9\u00ed\u00f3\u00fa\u00eb\u00e2\u00ea\u00ee\u00f4\u00fb\u00f1']+)|(.)/g,function(a,b,f,n,h){if(n){n=aa(n);try{H[n]?g.push.apply(g,I.decodeWord(H[n],c)):g.push.apply(g,ba(n,e))}catch(ca){g.push(c().addError("Cannot transcribe "+JSON.stringify(g)+" because "+ca.message))}}else b?g.push.apply(g,J(b,12,e)):f?g.push.apply(g,J(f,10,e)):K[h]?g.push(c(K[h])):" "===h?(d.push(g),g=[]):g.push(c().addError("Cannot transcribe "+JSON.stringify(h)))});
-g.length&&d.push(g);return d})})})}function L(a,e,c){var f=function(b){return b.length?L(a,e,c.concat(b),b[b.length-1]):a(c)},d=function(a){return y[a]?b("long-carrier").addAbove(y[a]):b("short-carrier").addAbove(a)},b=e.font.makeColumn,G=function(a){var b=function(b){return b?a?-1!==B.indexOf(a)&&b.canAddAbove(a)?(b.addAbove(a),u(function(b){return f([b])},b)):u(function(b){return f([d(a),b])},b):u(function(b){return f([b])},b):a?u(function(b){return f([b])},d(a)):f([])},c=e.font.makeColumn;return function(d){return"n"===
-d?function(a){return"n"===a?e.doubleNasalsWithTildeBelow?b(c("numen").addTildeBelow()):b(c("numen").addTildeAbove()):"t"===a?function(a){return"h"===a?b(c("thule").addTildeAbove()):b(c("tinco").addTildeAbove())(a)}:"d"===a?b(c("ando").addTildeAbove()):"c"===a?b(c("quesse").addTildeAbove()):"g"===a?b(c("ungwe").addTildeAbove()):"j"===a?b(c("anca").addTildeAbove()):"w"===a?b(c("nwalme").addAbove("w")):b(c("numen"))(a)}:"m"===d?function(a){return"m"===a?e.doubleNasalsWithTildeBelow?b(c("malta").addTildeBelow()):
-b(c("malta").addTildeAbove()):"p"===a?b(c("parma").addTildeAbove()):"b"===a?b(c("umbar").addTildeAbove()):"f"===a?b(c("formen").addTildeAbove()):"v"===a?b(c("ampa").addTildeAbove()):b(c("malta"))(a)}:"\u00f1"===d?function(a){return"c"===a?b(c("quesse").addTildeAbove()):"g"===a?b(c("ungwe").addTildeAbove()):b(c("nwalme"))(a)}:"t"===d?function(a){return"t"===a?b(c("tinco").addTildeBelow()):"h"===a?b(c("thule")):b(c("tinco"))(a)}:"p"===d?function(a){return"p"===a?b(c("parma").addTildeBelow()):b(c("parma"))(a)}:
-"c"===d?function(a){return"c"===a?b(c("calma")):"h"===a?e.noAchLaut?b(c("calma")):b(c("hwesta")):b(c("quesse"))(a)}:"d"===d?function(a){return"d"===a?b(c("ando").addTildeBelow()):"h"===a?b(c("anto")):b(c("ando"))(a)}:"b"===d?function(a){return"b"===a?b(c("umbar").addTildeBelow()):b(c("umbar"))(a)}:"g"===d?function(a){return"g"===a?b(c("ungwe").addTildeBelow()):"h"===a?b(c("unque")):b(c("ungwe"))(a)}:"f"===d?function(a){return"f"===a?b(c("formen").addTildeBelow()):b(c("formen"))(a)}:"v"===d?b(c("ampa")):
-"j"===d?b(c("anca")):"s"===d?function(a){return"s"===a?b(c("silme").addTildeBelow()):"h"===a?b(c("harma")):b(c("silme"))(a)}:"z"===d?function(a){return"z"===a?b(c("esse").addTildeBelow()):b(c("esse"))(a)}:"h"===d?function(a){return"w"===a?b(c("hwesta-sindarinwa")):b(c("hyarmen"))(a)}:"r"===d?function(a){return"r"===a?b(c("romen").addTildeBelow()):"h"===a?b(c("arda")):""===a?b(c("ore"))(a):b(c("romen"))(a)}:"l"===d?function(a){return"l"===a?b(c("lambe").addTildeBelow()):"h"===a?b(c("alda")):b(c("lambe"))(a)}:
-"i"===d?b(c("anna")):"u"===d?b(c("vala")):"w"===d?function(a){return"h"===a?b(c("hwesta-sindarinwa")):b(c("vala"))(a)}:"e"===d&&(!a||"a"===a)?b(c("yanta")):"y"===d?b(c("wilya").addBelow("y")):"\u00e1"===d?b(c("wilya").addAbove("a")):y[d]&&-1==B.indexOf(d)?b(c("long-carrier").addAbove(y[d])):b()(d)}};return function(a){return-1!==B.indexOf(a)?G(a):G()(a)}}function u(a,e){var c=function(c){var d=function(b){return function(c){return"s"===c?b.canAddBelow("s")?a(b.addBelow("s")):M(function(c){return function(d){if(""===
-d){if(b.canAddFollowing("s-final")&&0===c--)b.addFollowing("s-final");else if(b.canAddFollowing("s-inverse")&&0===c--)b.addFollowing("s-inverse");else if(b.canAddFollowing("s-extended")&&0===c--)b.addFollowing("s-extended");else if(b.canAddFollowing("s-flourish"))b.addFollowing("s-flourish"),0<c&&b.addError("Following S only has 3 alternate flourishes.");else return a(b)("s")(d);return a(b)(d)}return a(b)("s")(d)}}):a(b)(c)}};return function(a){return"y"===a&&c.canAddBelow("y")?d(c.addBelow("y")):
-d(c)(a)}};return e.canAddAbove("w")?function(a){return"w"===a?c(e.addAbove("w")):c(e)(a)}:c(e)}function M(a,e){e=e||0;return function(c){return"'"===c?M(a,e+1):a(e)(c)}}function C(a){a=a||da;return{font:a.font||ea,block:a.block,plain:a.plain,vilya:a.vilya,harma:a.harma,classical:a.classical,iuRising:a.isRising,longHalla:a.longHalla}}function D(a,e){var e=C(e),c=e.font.makeColumn;return a.split(/\n\n\n+/).map(function(a){return a.split(/\n\n/).map(function(a){return a.split(/\n/).map(function(a){var d=
-[],g=[];a.toLowerCase().replace(/([\w\u00e1\u00e9\u00ed\u00f3\u00fa\u00eb\u00e2\u00ea\u00ee\u00f4\u00fb\u00f1']+)|(.)/g,function(a,b,f){if(b)try{g.push.apply(g,fa(ga(b),e))}catch(n){g.push(c().addError("Cannot transcribe "+JSON.stringify(b)+" because "+n.message))}else N[f]?g.push(c(N[f])):" "===f?(d.push(g),g=[]):g.push(c().addError("Cannot transcribe "+JSON.stringify(f)))});g.length&&d.push(g);return d})})})}function O(a,e,c,f){var d=function(b){var d=b.pop();return P(function(d){d=b.concat(d).filter(Boolean);
-return d.length?O(a,e,c.concat(d),d[d.length-1]):a(c)},e,d)},b=e.font.makeColumn;return function(a){return"n"===a?function(a){return"n"===a?d([b("numen").addTildeBelow()]):"t"===a?d([b("anto")]):"d"===a?d([b("ando")]):"g"===a?function(a){return"w"===a?d([b("ungwe")]):d([b("anga")])(a)}:"c"===a?function(a){return"w"===a?d([b("unque")]):d([b("anca")])(a)}:d([b("numen")])(a)}:"m"===a?function(a){return"m"===a?d([b("malta").addTildeBelow()]):"p"===a?d([b("ampa")]):"b"===a?d([b("umbar")]):d([b("malta")])(a)}:
-"\u00f1"===a?function(a){return"g"===a?function(a){return"w"===a?d([b("ungwe")]):d([b("anga")])(a)}:"c"===a?function(a){return"w"===a?d([b("unque")]):d([b("anca")])}:d([b("noldo")])(a)}:"t"===a?function(a){return"t"===a?function(a){return"y"===a?d([b("tinco").addBelow("y").addTildeBelow()]):d([b("tinco").addTildeBelow()])(a)}:"y"===a?d([b("tinco").addBelow("y")]):"h"===a?d([b("thule")]):"s"===a?function(a){return""===a?d([b("tinco").addFollowing("s")])(a):d([b("tinco"),b("silme")])(a)}:d([b("tinco")])(a)}:
-"p"===a?function(a){return"p"===a?function(a){return"y"===a?d([b("parma").addBelow("y").addTildeBelow()]):d([b("parma").addTildeBelow()])(a)}:"y"===a?d([b("parma").addBelow("y")]):"s"===a?function(a){return""===a?d([b("parma").addFollowing("s")])(a):d([b("parma"),b("silme")])(a)}:d([b("parma")])(a)}:"c"===a?function(a){return"c"===a?d([b("calma").addTildeBelow()]):"s"===a?d([b("calma").addBelow("s")]):"h"===a?d([b("harma")]):"w"===a?d([b("quesse")]):d([b("calma")])(a)}:"f"===a?d([b("formen")]):"v"===
-a?e.vilya?d([b("wilya")]):d([b("vala")]):"w"===a?e.vilya?d([])("u"):d([b("wilya")]):"r"===a?function(a){return"d"===a?d([b("arda")]):"h"===a?d([b("halla").addError("R should preceed H in the HR diagraph in Classical mode."),b("romen").addError("R should preceed H in the HR diagraph in Classical mode.")]):e.classical?f&&f.above&&""!==a&&-1!==Q.indexOf(a)?d([b("ore")])(a):d([b("romen")])(a):""===a||-1===Q.indexOf(a)?d([b("ore")])(a):d([b("romen")])(a)}:"l"===a?function(a){return"l"===a?function(a){return"y"===
-a?d([b("lambe").addBelow("y").addTildeBelow()]):d([b("lambe").addTildeBelow()])(a)}:"y"===a?d([b("lambe").addBelow("y")]):"h"===a?d([b("halla").addError("L should preceed H in the HL diagraph in Classical mode."),b("lambe").addError("L should preceed H in the HL diagraph in Classical mode.")]):"d"===a?d([b("alda")]):"b"===a?d([b("lambe"),b("umbar")]):d([b("lambe")])(a)}:"s"===a?function(a){return"s"===a?d([b("esse")]):d([b("silme")])(a)}:"h"===a?function(a){return"l"===a?d([b("halla"),b("lambe")]):
-"r"===a?d([b("halla"),b("romen")]):"w"===a?d([b("hwesta")]):"t"===a?d([b("harma")]):"y"===a?e.classical&&e.harma?d([b("hyarmen")]):d([b("hyarmen").addBelow("y")]):e.classical?e.harma?d([b("harma")])(a):f?d([b("hyarmen")])(a):d([b("harma")])(a):d([b("hyarmen")])(a)}:"d"===a?d([b("ando").addError("D cannot appear except after N, L, or R")]):"b"===a?d([b("umbar").addError("B cannot appear except after M or L")]):"g"===a?d([b("anga").addError("G cannot appear except after N or \u00d1")]):"j"===a?d([b().addError("J cannot be transcribed in Classical Mode")]):
-d([])(a)}}function P(a,e,c){var f=e.font.makeColumn;return function(d){if("a"===d)return function(b){return"i"===b?a([c,f("yanta","a")]):"u"===b?a([c,f("ure","a")]):c&&c.canAddAbove("a")?(c.addAbove("a"),a([c])(b)):a([c,f("short-carrier","a")])(b)};if("e"===d)return function(b){return"u"===b?a([c,f("ure","e")]):c&&c.canAddAbove("e")?a([c.addAbove("e")])(b):a([c,f("short-carrier","e")])(b)};if("i"===d)return function(b){return"u"===b?e.iuRising?a([c,f("anna","u").addBelow("y")]):a([c,f("ure","i")]):
-c&&c.canAddAbove("i")?a([c.addAbove("i")])(b):a([c,f("short-carrier","i")])(b)};if("o"===d)return function(b){return"i"===b?a([c,f("yanta","o")]):c&&c.canAddAbove("o")?a([c.addAbove("o")])(b):a([c,f("short-carrier","o")])(b)};if("u"===d)return function(b){return"i"===b?a([c,f("yanta","u")]):c&&c.canAddAbove("u")?a([c.addAbove("u")])(b):a([c,f("short-carrier","u")])(b)};if("y"===d){if(c&&c.canAddBelow("y"))return a([c.addBelow("y")]);d=f("anna").addBelow("y");return P(function(b){return a([c].concat(b))},
-e,d)}return"\u00e1"===d?a([c,f("long-carrier","a")]):"\u00e9"===d?a([c,f("long-carrier","e")]):"\u00ed"===d?a([c,f("long-carrier","i")]):"\u00f3"===d?c&&c.canAddAbove("\u00f3")?a([c.addAbove("\u00f3")]):a([c,f("long-carrier","o")]):"\u00fa"===d?c&&c.canAddAbove("\u00fa")?a([c.addAbove("\u00fa")]):a([c,f("long-carrier","u")]):a([c])(d)}}function r(a,e){var c=!t[e]||-1!==ha.indexOf(e)?null:t[e].special?t[e][a]||null:-1!==ia.barsAndTildes.indexOf(e)?"lambe"===a||"alda"===a&&2<=t[e].length?2:o[a].wide?
-0:1:null==o[a]||null===o[a][e]?null:null!=o[a][e]?o[a][e]:null!=o[a].others?o[a].others:o[a];return null==c?null:t[e][a]||t[e][c]||null}function R(){if(document.body.classList&&document.querySelectorAll&&S.forEach){var a=document.querySelectorAll(".tengwar");S.forEach.call(a,function(a){var c=a.dataset,f,d,b;b="div"===a.tagName.toLowerCase();c?(f=c.tengwar,d=c.mode,c=c.encoding):(f=a.getAttribute("data-tengwar"),d=a.getAttribute("data-mode"),c=a.getAttribute("data-encoding"));c?a.innerText=T.transcribe(c,
-{block:b}):f&&(d=d||"general-use",c=a.classList.contains("parmaite")?ja:T,a.innerHTML=("general-use"===d?ka:la).transcribe(f,{block:b,font:c}))})}}var h={module$exports:function(a,e){e=e||function(a){throw Error(a);};return function(c){var f,d=a.apply(null,[function(a){f=a;var c=e;return function(a){""!==a&&c("Unexpected "+JSON.stringify(a));return function $(){return $}}}].concat(Array.prototype.slice.call(arguments,1)));for(Array.prototype.forEach.call(c,function(a){d=d(a)});!f;)d=d("");return f}}};
-h.module$exports&&(h=h.module$exports);var v={module$exports:function(a){return a.replace(ma,function(a,c){return U[c]})}},U={k:"c",x:"cs",qu:"cw",q:"cw",ph:"f",bh:"v","\u00eb":"e","\u00e2":"\u00e1","\u00ea":"\u00e9","\u00ee":"\u00ed","\u00f4":"\u00f3","\u00fb":"\u00fa"},ma=RegExp("("+Object.keys(U).join("|")+")","ig");v.module$exports&&(v=v.module$exports);var w={module$exports:{"-":"comma",",":"comma",":":"comma",";":"full-stop",".":"full-stop","!":"exclamation-point","?":"question-mark","(":"open-paren",
-")":"close-paren",">":"flourish-left","<":"flourish-right"}};w.module$exports&&(w=w.module$exports);var E={encode:function(a){return a.map(function(a){return a.map(function(a){return a.map(function(a){return a.map(function(a){return a.map(function(a){var c=[];a.above&&c.push(a.above);a.below&&c.push(a.below);a.following&&c.push(a.following);a.tildeAbove&&c.push("tilde-above");a.tildeBelow&&c.push("tilde-below");return c.length?a.tengwa+":"+c.join(","):a.tengwa}).join(";")}).join(" ")}).join("\n")}).join("\n\n")}).join("\n\n\n")},
-decode:function(a,e){return a.split("\n\n\n").map(function(a){return a.split("\n\n").map(function(a){return a.split("\n").map(function(a){return a.split(" ").map(function(a){return F(a,e)})})})})}};E.decodeWord=F;var p={tengwar:[["tinco","parma","calma","quesse"],["ando","umbar","anga","ungwe"],["thule","formen","harma","hwesta"],["anto","ampa","anca","unque"],["numen","malta","noldo","nwalme"],["ore","vala","anna","wilya"],["romen","arda","lambe","alda"],["silme","silme-nuquerna","esse","esse-nuquerna"],
-["hyarmen","hwesta-sindarinwa","yanta","ure"],["halla","short-carrier","long-carrier","round-carrier"],["tinco-extended","parma-extended","calma-extended","quesse-extended"]],tehtarAbove:"aeiou\u00e1\u00e9\u00ed\u00f3\u00faw".split(""),tehtarBelow:["y","s","o-under"],tehtarFollowing:["s-final","s-inverse","s-extended","s-flourish"],barsAndTildes:"tilde-above tilde-below tilde-high-above tilde-far-below bar-above bar-below bar-high-above bar-far-below".split(" ")};p.tehtar=[].concat(p.tehtarAbove,
-p.tehtarBelow,p.tehtarFollowing,p.barsAndTildes);p.aliases={vilya:"wilya",aha:"harma"};var i={},na=Array.prototype;i.module$exports=function(a,e,c){var f=c.font.makeColumn;return na.map.call(parseInt(a,e).toString(e),function(a){return f("#"+a)})};i.module$exports&&(i=i.module$exports);var V={tinco:"1",parma:"q",calma:"a",quesse:"z",ando:"2",umbar:"w",anga:"s",ungwe:"x",thule:"3",formen:"e",harma:"d",hwesta:"c",anto:"4",ampa:"r",anca:"f",unque:"v",numen:"5",malta:"t",noldo:"g",nwalme:"b",ore:"6",
-vala:"y",anna:"h",wilya:"n",romen:"7",arda:"u",lambe:"j",alda:"m",silme:"8","silme-nuquerna":"i",esse:"k","esse-nuquerna":",",hyarmen:"9","hwesta-sindarinwa":"o",yanta:"l",ure:".",halla:"\u00bd","short-carrier":"`","long-carrier":"~","round-carrier":"]","tinco-extended":"!","parma-extended":"Q","calma-extended":"A","quesse-extended":"Z",comma:"=","full-stop":"-","exclamation-point":"\u00c1","question-mark":"\u00c0","open-paren":"Œ","close-paren":"œ","flourish-left":"Ğ","flourish-right":"ğ",
-"#0":"\uf8ff","#1":"\u00d2","#2":"\u00da","#3":"\u00db","#4":"\u00d9","#5":"\u0131","#6":"\u02c6","#7":"\u02dc","#8":"\u00af","#9":"\u02d8","#10":"\u02d9","#11":"\u02da"},W={a:"#EDC",e:"$RFV",i:"%TGB",o:"^YHN",u:"& U J M Ā ā Ă ă".split(" "),"\u00f3":["Ą","ą","Ć","ć"],"\u00fa":["Ĉ","ĉ","Ċ","ċ"],"\u00ed":["Ô","Õ","Ö","×"],w:"\u00e8\u00e9\u00ea\u00eb",y:"\u00cc\u00cd\u00ce\u00cf\u00b4","o-under":["\u00e4","å","\u00e6",
-"\u00e7","|"],s:{special:!0,calma:"|",quesse:"|","short-carrier":"}"},"s-final":{special:!0,tinco:"+",ando:"+",numen:"+",lambe:"_"},"s-inverse":{special:!0,tinco:"\u00a1"},"s-extended":{special:!0,tinco:"Ç"},"s-flourish":{special:!0,tinco:"£",lambe:"¥"},"tilde-above":"Pp","tilde-below":[":",";","°"],"tilde-high-above":")0","tilde-far-below":"?/","bar-above":"{[","bar-below":['"',"'","¸"],"bar-high-above":"\u00ec\u00ee","bar-far-below":"\u00ed\u00ef"},l={},X=p,oa=l.tengwar=
-V,s=l.tehtar=W,m=l.positions={tinco:{o:3,w:3,others:2},parma:{o:3,w:3,others:2},calma:{o:3,w:3,u:3,"o-under":1,others:2},quesse:{o:3,w:3,"o-under":1,others:2},ando:{wide:!0,e:1,o:2,"\u00f3":1,"\u00fa":1,others:0},umbar:{wide:!0,e:1,o:2,"\u00f3":1,"\u00fa":1,others:0},anga:{wide:!0,e:1,"\u00f3":1,"\u00fa":1,others:0},ungwe:{wide:!0,e:1,o:1,"\u00f3":1,"\u00fa":1,others:0},thule:{others:3},formen:3,harma:{e:0,o:3,u:7,"\u00f3":2,"\u00fa":2,w:0,others:1},hwesta:{e:0,o:3,u:7,w:0,others:1},anto:{wide:!0,
-"\u00f3":1,"\u00fa":1,others:0},ampa:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},anca:{wide:!0,u:7,"\u00f3":1,"\u00fa":1,others:0},unque:{wide:!0,u:7,others:0},numen:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},malta:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},noldo:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},nwalme:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},ore:{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},vala:{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},anna:{e:3,o:3,u:3,"\u00f3":2,"\u00fa":2,others:1},wilya:{e:3,
-o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},romen:{e:3,o:3,u:3,"\u00f3":2,"\u00fa":2,y:null,"o-under":null,others:1},arda:{a:1,e:3,i:1,o:3,u:3,"\u00ed":1,"\u00f3":2,"\u00fa":2,y:null,"o-under":null,others:0},lambe:{wide:!0,e:1,y:4,"\u00f3":1,"\u00fa":1,"o-under":null,others:0},alda:{wide:!0,"o-under":null,others:1},silme:{y:3,"o-under":2,others:null},"silme-nuquerna":{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,y:null,"o-under":null,others:1},esse:{y:null,others:null},"esse-nuquerna":{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,
-others:1},hyarmen:3,"hwesta-sindarinwa":{o:2,u:2,"\u00f3":1,"\u00fa":2,others:0},yanta:{e:3,o:3,u:3,"\u00f3":2,"\u00fa":2,others:1},ure:{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},halla:{others:null},"short-carrier":3,"long-carrier":{y:null,"o-under":null,others:3},"round-carrier":3,"tinco-extended":3,"parma-extended":3,"calma-extended":{o:3,u:7,"\u00f3":2,"\u00fa":2,others:1},"quesse-extended":{o:0,u:7,others:1}};l.transcribe=function(a,e){var e=e||{},c=e.plain||!1,f=e.block||!1,d=f?"<p>":"",b=
-f?"<br>":"",h=f?"</p>":"";return a.map(function(a){return a.map(function(a){return d+a.map(function(a){return a.map(function(a){return a.map(function(a){var b=a.tengwa||"anna",d=[];a.above&&d.push(a.above);a.below&&d.push(a.below);a.tildeBelow&&d.push("tilde-below");a.tildeAbove&&d.push("tilde-above");a.following&&d.push(a.following);d=oa[b]+d.map(function(a){return q(b,a)}).join("");a.errors&&!c&&(d='<abbr class="error" title="'+a.errors.join("\n").replace(/"/g,""")+'">'+d+"</abbr>");return d}).join("")}).join(" ")}).join(b+
-"\n")+h}).join("\n\n")}).join("\n\n\n")};l.tehtaForTengwa=q;l.makeColumn=function(a,e,c){return new j(a,e,c)};var j=function(a,e,c){this.above=e;this.tildeAbove=void 0;this.tengwa=a;this.tildeBelow=void 0;this.below=c;this.error=this.following=void 0};j.prototype.canAddAbove=function(a){return!this.above&&!!q(this.tengwa,a)||!this.below&&("silme"===this.tengwa&&q("silme-nuquerna",a)||"esse"===this.tengwa&&q("esse-nuquerna",a))};j.prototype.addAbove=function(a){"silme"===this.tengwa&&(this.tengwa=
-"silme-nuquerna");"esse"===this.tengwa&&(this.tengwa="esse-nuquerna");this.above=a;return this};j.prototype.canAddBelow=function(a){return!this.below&&!!q(this.tengwa,a)};j.prototype.addBelow=function(a){this.below=a;return this};j.prototype.addTildeAbove=function(){this.tildeAbove=!0;return this};j.prototype.addTildeBelow=function(){this.tildeBelow=!0;return this};j.prototype.canAddFollowing=function(a){return!this.following&&!!q(this.tengwa,a)};j.prototype.addFollowing=function(a){this.following=
-a;return this};j.prototype.addError=function(a){this.errors=this.errors||[];this.errors.push(a);return this};var x={},Z=l,I=E,aa=v,K=w,J=i,Y={};x.transcribe=function(a,e){e=z(e);return e.font.transcribe(A(a,e),e)};x.encode=function(a,e){e=z(e);return I.encode(A(a,e),e)};x.parse=A;var H={iant:"yanta;tinco:a,tilde-above",iaur:"yanta;vala:a;ore",baranduiniant:"umbar;romen:a;ando:a,tilde-above;anna:u;yanta;anto:a,tilde-above",ioreth:"yanta;romen:o;thule:e",noldo:"nwalme;lambe:o;ando;short-carrier:o",
-noldor:"nwalme;lambe:o;ando;ore:o",is:"short-carrier:i,s"},ba=h(function(a,e){return L(a,e,[])}),B="aeiou\u00f3\u00fa",y={"\u00e1":"a","\u00e9":"e","\u00ed":"i","\u00f3":"o","\u00fa":"u"};x.parseTengwaAnnotations=u;var i={},ea=l,ga=v,N=w,da={};i.transcribe=function(a,e){e=C(e);return e.font.transcribe(D(a,e),e)};i.encode=function(a,e){e=C(e);return E.encode(D(a,e),e)};i.parse=D;var fa=h(function(a,e){return O(a,e,[])}),Q="aeiouy\u00e1\u00e9\u00ed\u00f3\u00fa",h={},ia=p,pa=h.tengwar=V,t=h.tehtar=W,
-o=h.positions={tinco:2,parma:2,calma:{y:1,"o-under":1,others:2},quesse:{y:1,"o-under":1,others:2},ando:{wide:!0,others:0},umbar:{wide:!0,others:0},anga:{wide:!0,others:0},ungwe:{wide:!0,others:0},thule:{a:3,w:3,others:2},formen:{a:3,w:3,others:2},harma:{a:0,e:0,i:1,o:1,u:1,w:0,others:1},hwesta:{a:0,e:0,i:1,o:1,u:1,w:0,others:1},anto:{wide:!0,others:0},ampa:{wide:!0,others:0},anca:{wide:!0,others:0},unque:{wide:!0,others:0},numen:{wide:!0,others:0},malta:{wide:!0,others:0},noldo:{wide:!0,others:0},
-nwalme:{wide:!0,others:0},ore:{a:1,e:2,i:1,o:2,u:3,others:1},vala:{a:1,e:2,i:2,o:2,w:1,y:1,others:3},anna:{a:1,e:2,i:2,o:2,u:3,w:3,others:1},wilya:{a:1,e:1,i:2,o:1,u:1,others:1},romen:{a:1,e:1,i:2,o:1,u:1,y:null,"o-under":null,others:1},arda:{a:1,e:1,i:2,o:1,u:1,w:1,y:null,"o-under":null,others:0},lambe:{wide:!0,e:1,y:4,w:0,"o-under":null,others:0},alda:{wide:!0,w:0,y:null,"o-under":null,others:1},silme:{y:2,"o-under":2,others:null},"silme-nuquerna":{e:2,y:null,"o-under":null,others:1},esse:{others:null},
-"esse-nuquerna":{e:2,y:null,"o-under":null,others:1},hyarmen:{y:1,others:3},"hwesta-sindarinwa":{w:1,y:1,others:0},yanta:{a:1,others:2},ure:{a:1,others:2},halla:{others:null},"short-carrier":{y:null,others:3},"long-carrier":{y:null,"o-under":null,others:3},"round-carrier":2,"tinco-extended":{a:3,w:3,y:3,others:2},"parma-extended":{a:3,w:3,y:3,others:2},"calma-extended":{i:1,w:1,y:0,others:0},"quesse-extended":{i:1,w:1,y:0,others:0}};h.transcribe=function(a,e){var e=e||{},c=e.plain||!1,f=e.block||
-!1,d=f?"<p>":"",b=f?"<br>":"",h=f?"</p>":"";return a.map(function(a){return a.map(function(a){return d+a.map(function(a){return a.map(function(a){return a.map(function(a){var b=a.tengwa||"anna",d=[];a.above&&d.push(a.above);a.below&&d.push(a.below);a.tildeBelow&&d.push("tilde-below");a.tildeAbove&&d.push("tilde-above");a.following&&d.push(a.following);d=pa[b]+d.map(function(a){return r(b,a)}).join("");a.errors&&!c&&(d='<abbr class="error" title="'+a.errors.join("\n").replace(/"/g,""")+'">'+d+
-"</abbr>");return d}).join("")}).join(" ")}).join(b+"\n")+h}).join("\n\n")}).join("\n\n\n")};h.tehtaForTengwa=r;var ha="\u00e1\u00e9\u00ed\u00f3\u00fa";h.makeColumn=function(a,e,c){return new k(a,e,c)};var k=function(a,e,c){this.above=e;this.tildeAbove=void 0;this.tengwa=a;this.tildeBelow=void 0;this.below=c;this.error=this.following=void 0};k.prototype.canAddAbove=function(a){return!this.above&&!!r(this.tengwa,a)||!this.below&&("silme"===this.tengwa&&r("silme-nuquerna",a)||"esse"===this.tengwa&&
-r("esse-nuquerna",a))};k.prototype.addAbove=function(a){"silme"===this.tengwa&&(this.tengwa="silme-nuquerna");"esse"===this.tengwa&&(this.tengwa="esse-nuquerna");this.above=a;return this};k.prototype.canAddBelow=function(a){return!this.below&&!!r(this.tengwa,a)};k.prototype.addBelow=function(a){this.below=a;return this};k.prototype.addTildeAbove=function(){this.tildeAbove=!0;return this};k.prototype.addTildeBelow=function(){this.tildeBelow=!0;return this};k.prototype.canAddFollowing=function(a){return!this.following&&
-!!r(this.tengwa,a)};k.prototype.addFollowing=function(a){this.following=a;return this};k.prototype.addError=function(a){this.errors=this.errors||[];this.errors.push(a);return this};var ka=x,la=i,T=l,ja=h,S=Array.prototype;"complete"===document.readyState?R():document.addEventListener("DOMContentLoaded",R,!0)})();
+(function(){function w(a,c){var b=!y[c]?null:y[c].special?y[c][a]||null:-1!==la.barsAndTildes.indexOf(c)?"lambe"===a||"alda"===a&&2<=y[c].length?2:t[a].wide?0:1:null==t[a]||null===t[a][c]?null:null!=t[a][c]?t[a][c]:null!=t[a].others?t[a].others:t[a];return null==b?null:y[c][a]||y[c][b]||""}function x(a,c){var b=!z[c]||-1!==ma.indexOf(c)?null:z[c].special?z[c][a]||null:-1!==na.barsAndTildes.indexOf(c)?"lambe"===a||"alda"===a&&2<=z[c].length?2:u[a].wide?0:1:null==u[a]||null===u[a][c]?null:null!=u[a][c]?
+u[a][c]:null!=u[a].others?u[a].others:u[a];return null==b?null:z[c][a]||z[c][b]||null}function O(a,c){return a.split(";").map(function(a){var a=a.split(":"),d=a.shift(),a=a.length?a.shift().split(","):[],e=c(d);a.forEach(function(a){"tilde-above"===a?e.addTildeAbove():"tilde-below"===a?e.addBarBelow():"y"===a?e.addBelow("y"):"s"===a||"s-inverse"===a||"s-extended"===a||"s-flourish"===a?"s"===a&&("calma"===d||"quesse"===d)?e.addBelow(a):e.addFollowing(a):e.addAbove(a)});return e})}function P(a){return function b(d){return function(e){return e===
+a?b(d):d(a)(e)}}}function Q(a){return" "===a||"\n"===a||""===a}function R(a,c){c=c||0;return function(b){return"'"===b?R(a,c+1):a(c)(b)}}function S(a){return E(function(){return oa(function(){return E(a)})})}function pa(a){return E(function(){return qa(function(){return E(a)})})}function T(a){var c={value:void 0,children:{}},b={};Object.keys(a).forEach(function(d){if(0===d.length)c.value=a[d];else{var e=d[0];b[e]||(b[e]={});var i=d.slice(1);b[e][i]=a[d]}});Object.keys(b).forEach(function(a){c.children[a]=
+T(b[a])});return c}function U(a,c,b,d){var e={},i=Object.keys(a.children);i.forEach(function(g){e[g]=U(a.children[g],c,b,d)});var f;a.value&&(f=c(a.value));return i.reduceRight(function(a,c){return function(d){return function(h){return h===c?b(e[h](d)):a(d)(h)}}},function(a){return f?b(f(a)):d(a)})}function F(a){a=a||sa;return{font:a.font||ta,block:a.block,plain:a.plain,doubleNasalsWithTildeBelow:a.doubleNasalsWithTildeBelow,reverseCurls:a.reverseCurls,noAchLaut:a.noAchLaut,isHook:a.isHook}}function V(a,
+c,b){b=b||"";return function(d){return G.isBreak(d)?a(b)(d):V(a,c,b+d)}}function W(a,c,b){var d=function(e){return e.length?W(a,c,b.concat(e),e[e.length-1]):a(b)},e=function(a){return H[a]?i("long-carrier").addAbove(H[a]):i("short-carrier").addAbove(a)},i=c.font.makeColumn,f=function(a){var b=function(b){return b?a?"silme"===b.tengwa&&"i"===a&&c.isHook?d([i("short-carrier").addAbove("i").addBelow("s")]):-1!==M.indexOf(a)&&b.canAddAbove(a)?(c.reverseCurls&&(a=ua[a]||a),b.addAbove(a),C(function(a){return d([a])},
+b)):C(function(b){return d([e(a),b])},b):C(function(a){return d([a])},b):a?C(function(a){return d([a])},e(a)):function(a){return G.isBreak(a)?d([]):X[a]?d([i(X[a])]):d([i("anna").addError("Unexpected character: "+JSON.stringify(a))])}},f=a,h=c.font.makeColumn;return function(a){return"n"===a?function(a){return"n"===a?c.doubleNasalsWithTildeBelow?b(h("numen").addTildeBelow()):b(h("numen").addTildeAbove()):"t"===a?function(a){return"h"===a?b(h("thule").addTildeAbove()):b(h("tinco").addTildeAbove())(a)}:
+"d"===a?b(h("ando").addTildeAbove()):"c"===a?b(h("quesse").addTildeAbove()):"g"===a?b(h("ungwe").addTildeAbove()):"j"===a?b(h("anca").addTildeAbove()):"w"===a?function(a){return"a"===a?function(a){return"l"===a?b(h("nwalme").addAbove("w"))("a")(a):b(h("numen").addAbove("w"))("a")(a)}:"nw'"===a?b(h("nwalme").addAbove("w")):b(h("numen").addAbove("w"))(a)}:b(h("numen"))(a)}:"m"===a?function(a){return"m"===a?c.doubleNasalsWithTildeBelow?b(h("malta").addTildeBelow()):b(h("malta").addTildeAbove()):"p"===
+a?b(h("parma").addTildeAbove()):"b"===a?b(h("umbar").addTildeAbove()):"f"===a?b(h("formen").addTildeAbove()):"v"===a?b(h("ampa").addTildeAbove()):b(h("malta"))(a)}:"\u00f1"===a?function(a){return"c"===a?b(h("quesse").addTildeAbove()):"g"===a?b(h("ungwe").addTildeAbove()):b(h("nwalme"))(a)}:"t"===a?function(a){return"t"===a?b(h("tinco").addTildeBelow()):"h"===a?b(h("thule")):"c"===a?function(a){return"h"===a?b(h("tinco"))("c")("h")("'"):b(h("tinco"))("c")(a)}:b(h("tinco"))(a)}:"p"===a?function(a){return"p"===
+a?b(h("parma").addTildeBelow()):b(h("parma"))(a)}:"c"===a?function(a){return"c"===a?b(h("calma")):"h"===a?c.noAchLaut?b(h("calma")):b(h("hwesta")):b(h("quesse"))(a)}:"d"===a?function(a){return"d"===a?b(h("ando").addTildeBelow()):"j"===a?b(h("anga")):"h"===a?b(h("anto")):b(h("ando"))(a)}:"b"===a?function(a){return"b"===a?b(h("umbar").addTildeBelow()):b(h("umbar"))(a)}:"g"===a?function(a){return"g"===a?b(h("ungwe").addTildeBelow()):"h"===a?b(h("unque")):b(h("ungwe"))(a)}:"f"===a?function(a){return"f"===
+a?b(h("formen").addTildeBelow()):b(h("formen"))(a)}:"v"===a?b(h("ampa")):"j"===a?b(h("anca")):"s"===a?function(a){return"s"===a?b(h("silme").addTildeBelow()):"h"===a?b(h("harma")):b(h("silme"))(a)}:"z"===a?function(a){return"z"===a?b(h("esse").addTildeBelow()):b(h("esse"))(a)}:"h"===a?function(a){return"w"===a?b(h("hwesta-sindarinwa")):b(h("hyarmen"))(a)}:"r"===a?function(a){return"r"===a?b(h("romen").addTildeBelow()):"h"===a?b(h("arda")):""===a?b(h("ore"))(a):b(h("romen"))(a)}:"l"===a?function(a){return"l"===
+a?b(h("lambe").addTildeBelow()):"h"===a?b(h("alda")):b(h("lambe"))(a)}:"i"===a?b(h("anna")):"u"===a?b(h("vala")):"w"===a?function(a){return"h"===a?b(h("hwesta-sindarinwa")):b(h("vala"))(a)}:"e"===a&&(!f||"a"===f)?b(h("yanta")):"y"===a?b(h("wilya").addBelow("y")):"\u00e1"===a?b(h("wilya").addAbove("a")):H[a]&&-1==M.indexOf(a)?b(h("long-carrier").addAbove(H[a])):b()(a)}};return function(a){return-1!==M.indexOf(a)?f(a):f()(a)}}function C(a,c){var b=function(b){var c=function(b){return function(c){return"s"===
+c?b.canAddBelow("s")?a(b.addBelow("s")):G.countPrimes(function(c){return function(e){if(""===e){if(b.canAddFollowing("s-final")&&0===c--)b.addFollowing("s-final");else if(b.canAddFollowing("s-inverse")&&0===c--)b.addFollowing("s-inverse");else if(b.canAddFollowing("s-extended")&&0===c--)b.addFollowing("s-extended");else if(b.canAddFollowing("s-flourish"))b.addFollowing("s-flourish"),0<c&&b.addError("Following S only has 3 alternate flourishes.");else return a(b)("s")(e);return a(b)(e)}return a(b)("s")(e)}}):
+a(b)(c)}};return function(a){return"y"===a&&b.canAddBelow("y")?c(b.addBelow("y")):c(b)(a)}};return c.canAddAbove("w")?function(a){return"w"===a?b(c.addAbove("w")):b(c)(a)}:b(c)}function I(a){a=a||va;return{font:a.font||wa,block:a.block,plain:a.plain,vilya:a.vilya,harma:a.harma,classical:a.classical,reverseCurls:a.reverseCurls,iuRising:a.isRising,longHalla:a.longHalla}}function Y(a,c,b,d){var b=b||[],e=function(e){return e.length?Y(a,c,b.concat(e),e[e.length-1]):a(b)},i=c.font.makeColumn,f=function(a){var b=
+a.pop();return Z(function(b){b=a.concat(b).filter(Boolean);return b.length?e(b):function(a){return J.isBreak(a)?e([])(a):$[a]?e([i($[a])]):e([i("anna").addError("Cannot transcribe "+JSON.stringify(a)+" in Classical Mode")])}},c,b)},g=c.font.makeColumn;return function(a){return"n"===a?function(a){return"n"===a?f([g("numen").addTildeBelow()]):"t"===a?f([g("anto")]):"d"===a?f([g("ando")]):"g"===a?function(a){return"w"===a?f([g("ungwe")]):f([g("anga")])(a)}:"c"===a?function(a){return"w"===a?f([g("unque")]):
+f([g("anca")])(a)}:f([g("numen")])(a)}:"m"===a?function(a){return"m"===a?f([g("malta").addTildeBelow()]):"p"===a?f([g("ampa")]):"b"===a?f([g("umbar")]):f([g("malta")])(a)}:"\u00f1"===a?function(a){return"g"===a?function(a){return"w"===a?f([g("ungwe")]):f([g("anga")])(a)}:"c"===a?function(a){return"w"===a?f([g("unque")]):f([g("anca")])}:f([g("noldo")])(a)}:"t"===a?function(a){return"t"===a?function(a){return"y"===a?f([g("tinco").addBelow("y").addTildeBelow()]):f([g("tinco").addTildeBelow()])(a)}:"y"===
+a?f([g("tinco").addBelow("y")]):"h"===a?f([g("thule")]):"s"===a?function(a){return J.isFinal(a)?f([g("tinco").addFollowing("s")])(a):f([g("tinco"),g("silme")])(a)}:f([g("tinco")])(a)}:"p"===a?function(a){return"p"===a?function(a){return"y"===a?f([g("parma").addBelow("y").addTildeBelow()]):f([g("parma").addTildeBelow()])(a)}:"y"===a?f([g("parma").addBelow("y")]):"s"===a?function(a){return J.isFinal(a)?f([g("parma").addFollowing("s")])(a):f([g("parma"),g("silme")])(a)}:f([g("parma")])(a)}:"c"===a?function(a){return"c"===
+a?f([g("calma").addTildeBelow()]):"s"===a?f([g("calma").addBelow("s")]):"h"===a?f([g("harma")]):"w"===a?f([g("quesse")]):f([g("calma")])(a)}:"f"===a?f([g("formen")]):"v"===a?c.vilya?f([g("wilya")]):f([g("vala")]):"w"===a?c.vilya?f([])("u"):f([g("wilya")]):"r"===a?function(a){return"d"===a?f([g("arda")]):"h"===a?f([g("halla").addError("R should preceed H in the HR diagraph in Classical mode."),g("romen").addError("R should preceed H in the HR diagraph in Classical mode.")]):c.classical?d&&d.above&&
+""!==a&&-1!==aa.indexOf(a)?f([g("ore")])(a):f([g("romen")])(a):J.isFinal(a)||-1===aa.indexOf(a)?f([g("ore")])(a):f([g("romen")])(a)}:"l"===a?function(a){return"l"===a?function(a){return"y"===a?f([g("lambe").addBelow("y").addTildeBelow()]):f([g("lambe").addTildeBelow()])(a)}:"y"===a?f([g("lambe").addBelow("y")]):"h"===a?f([g("halla").addError("L should preceed H in the HL diagraph in Classical mode."),g("lambe").addError("L should preceed H in the HL diagraph in Classical mode.")]):"d"===a?f([g("alda")]):
+"b"===a?f([g("lambe"),g("umbar")]):f([g("lambe")])(a)}:"s"===a?function(a){return"s"===a?f([g("esse")]):f([g("silme")])(a)}:"h"===a?function(a){return"l"===a?f([g("halla"),g("lambe")]):"r"===a?f([g("halla"),g("romen")]):"w"===a?f([g("hwesta")]):"t"===a?f([g("harma")]):"y"===a?c.classical&&c.harma?f([g("hyarmen")]):f([g("hyarmen").addBelow("y")]):c.classical?c.harma?f([g("harma")])(a):d?f([g("hyarmen")])(a):f([g("harma")])(a):f([g("hyarmen")])(a)}:"d"===a?f([g("ando").addError("D cannot appear except after N, L, or R")]):
+"b"===a?f([g("umbar").addError("B cannot appear except after M or L")]):"g"===a?f([g("anga").addError("G cannot appear except after N or \u00d1")]):"j"===a?f([g().addError("J cannot be transcribed in Classical Mode")]):f([])(a)}}function Z(a,c,b){var d=c.font.makeColumn;return function(e){if("a"===e)return function(c){return"i"===c?a([b,d("yanta","a")]):"u"===c?a([b,d("ure","a")]):b&&b.canAddAbove("a")?a([b.addAbove("a")])(c):a([b,d("short-carrier","a")])(c)};if("e"===e)return function(c){return"u"===
+c?a([b,d("ure","e")]):b&&b.canAddAbove("e")?a([b.addAbove("e")])(c):a([b,d("short-carrier","e")])(c)};if("i"===e)return function(e){return"u"===e?c.iuRising?a([b,d("anna").addAbove(p("u",c)).addBelow("y")]):a([b,d("ure","i")]):b&&b.canAddAbove("i")?a([b.addAbove("i")])(e):a([b,d("short-carrier","i")])(e)};if("o"===e)return function(e){return"i"===e?a([b,d("yanta").addAbove(p("o",c))]):b&&b.canAddAbove("o")?a([b.addAbove(p("o",c))])(e):a([b,d("short-carrier").addAbove(p("o",c))])(e)};if("u"===e)return function(e){return"i"===
+e?a([b,d("yanta","u")]):b&&b.canAddAbove("u")?a([b.addAbove(p("u",c))])(e):a([b,d("short-carrier").addAbove(p("u",c))])(e)};if("y"===e){if(b&&b.canAddBelow("y"))return a([b.addBelow("y")]);e=d("anna").addBelow("y");return Z(function(c){return a([b].concat(c))},c,e)}return"\u00e1"===e?a([b,d("long-carrier","a")]):"\u00e9"===e?a([b,d("long-carrier","e")]):"\u00ed"===e?a([b,d("long-carrier","i")]):"\u00f3"===e?b&&b.canAddAbove("\u00f3")?a([b.addAbove(p("\u00f3",c))]):a([b,d("long-carrier").addAbove(p("o",
+c))]):"\u00fa"===e?b&&b.canAddAbove("\u00fa")?a([b.addAbove(p("\u00fa",c))]):a([b,d("long-carrier").addAbove(p("u",c))]):a([b])(e)}}function p(a,c){c.reverseCurls&&(a=xa[a]||a);return a}function K(a){a=a||ya;return{font:a.font||za,block:a.block,plain:a.plain}}function ba(a,c,b){b=b||[];return ca(function(d){return d?ba(a,c,b.concat([d])):a(b)},c)}function ca(a,c){return D(function(b){return b?function(c){return"s"===c?b.canAddBelow("s")?a(b.addBelow("s")):A.countPrimes(function(c){return function(d){if(A.isFinal(d)){if(b.canAddFollowing("s-final")&&
+0===c--)b.addFollowing("s-final");else if(b.canAddFollowing("s-inverse")&&0===c--)b.addFollowing("s-inverse");else if(b.canAddFollowing("s-extended")&&0===c--)b.addFollowing("s-extended");else if(b.canAddFollowing("s-flourish"))b.addFollowing("s-flourish"),0<c&&b.addError("Following S only has 3 alternate flourishes.");else return a(b)("s")(d);return a(b)(d)}return a(b)("s")(d)}}):a(b)(c)}:a()},c)}function D(a,c){var b=c.font.makeColumn;return function(d){return"n"===d?function(e){return"t"===e||
+"d"===e?D(function(b){return a(b.addTildeAbove())},c)(e):"c"===e||"g"===e?D(a,c)("\u00f1")(e):"n"===e?a(b("numen")):a(b("ore"))(e)}:"t"===d?function(c){return"h"===c?a(b("thule")):a(b("tinco"))(c)}:"d"===d?function(c){return"h"===c?a(b("anto")):a(b("ando"))(c)}:"m"===d?function(e){return"p"===e||"b"===e||"f"===e||"v"===e?D(function(b){return a(b.addTildeAbove())},c)(e):"m"===e?a(b("malta")):a(b("vala"))(e)}:"p"===d?a(b("parma")):"b"===d?a(b("umbar")):"f"===d?function(c){return A.isFinal(c)?a(b("ampa"))(c):
+a(b("formen"))(c)}:"v"===d?a(b("ampa")):"\u00f1"===d?function(e){return"c"===e||"g"===e?D(function(b){"halla"===b.tengwa&&b.addError("Lenited G (halla) should not be nasalized with prefix N");return a(b.addTildeAbove())},c)(e):a(b("noldo"))(e)}:"c"===d?function(c){return"h"===c?function(c){return"w"===c?a(b("hwesta")):a(b("harma"))(c)}:"w"===c?a(b("quesse")):a(b("calma"))(c)}:"g"===d?function(c){return"h"===c?function(c){return"w"===c?a(b("unque")):a(b("anca"))(c)}:"w"===c?a(b("ungwe")):"'"===c?a(b("halla")):
+a(b("anga"))(c)}:"r"===d?function(c){return"h"===c?a(b("arda")):a(b("romen"))(c)}:"l"===d?function(c){return"h"===c?a(b("alda")):a(b("lambe"))(c)}:"s"===d?a(b("silme")):"a"===d?function(c){return"i"===c?a(b("round-carrier").addAbove("\u00ed")):"u"===c?a(b("round-carrier").addAbove("w")):"'"===c?a(b("round-carrier").addAbove("i")):"a"===c?a(b("round-carrier").addAbove("e")):a(b("round-carrier"))(c)}:"e"===d?function(c){return"i"===c?a(b("yanta").addAbove("\u00ed")):"e"===c?a(b("yanta").addAbove("e")):
+a(b("yanta"))(c)}:"i"===d?function(e){return"i"===e?ca(a,c)("\u00ed"):A.countPrimes(function(c){return 0===c?a(b("short-carrier")):1===c?a(b("short-carrier").addAbove("i")):3===c?a(b("long-carrier")):4===c?a(b("long-carrier").addAbove("i")):a(b("long-carrier").addAbove("i").addError("I only has four variants between short or long and dotted or not."))})(e)}:"o"===d?function(c){return"o"===c?a(b("anna").addAbove("e")):a(b("anna"))(c)}:"u"===d?function(c){return"i"===c?a(b("ure").addAbove("\u00ed")):
+"u"===c?a(b("ure").addAbove("e")):a(b("ure"))(c)}:"w"===d?function(c){return"w"===c?a(b("wilya").addAbove("e")):a(b("wilya"))(c)}:"y"===d?function(c){return"y"===c?a(b("silme-nuquerna").addAbove("e")):a(b("silme-nuquerna"))(c)}:"\u00e1"===d?a(b("round-carrier").addAbove("e")):"\u00e9"===d?a(b("yanta").addAbove("e")):"\u00ed"===d?A.countPrimes(function(c){return 0===c?a(b("short-carrier").addAbove("e")):1===c?a(b("long-carrier").addAbove("e")):a(b("long-carrier").addAbove("e").addError("\u00cd only has one variant."))}):
+"\u00f3"===d?a(b("anna").addAbove("e")):"\u00fa"===d?a(b("ure").addAbove("e")):"h"===d?function(c){return"w"===c?a(b("hwesta-sindarinwa")):a(b("hyarmen"))(c)}:"z"===d?a(b("silme").addError("Z does not appear in the mode of Beleriand")):da[d]?a(b(da[d])):A.isBreak(d)?a()(d):a(b("anna").addError("Unexpected character: "+JSON.stringify(d)))}}function ea(){if(document.body.classList&&document.querySelectorAll&&fa.forEach){var a=document.querySelectorAll(".tengwar");fa.forEach.call(a,function(a){var b=
+a.dataset,d,e,i;i="div"===a.tagName.toLowerCase();b?(d=b.tengwar,e=b.mode,b=b.encoding):(d=a.getAttribute("data-tengwar"),e=a.getAttribute("data-mode"),b=a.getAttribute("data-encoding"));if(b)a.innerText=ga.transcribe(b,{block:i});else if(d){var b=a.classList.contains("parmaite")?Aa:ga,f=e.split(/\s+/);e=f.shift();e=Ba[e]||Ca;var g=e.makeOptions();f.forEach(function(a){a=a.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()});g[a]=!0});g.block=i;g.font=b;a.innerHTML=e.transcribe(d,g)}})}}var k=
+{tinco:"1",parma:"q",calma:"a",quesse:"z",ando:"2",umbar:"w",anga:"s",ungwe:"x",thule:"3",formen:"e",harma:"d",hwesta:"c",anto:"4",ampa:"r",anca:"f",unque:"v",numen:"5",malta:"t",noldo:"g",nwalme:"b",ore:"6",vala:"y",anna:"h",wilya:"n",romen:"7",arda:"u",lambe:"j",alda:"m",silme:"8","silme-nuquerna":"i",esse:"k","esse-nuquerna":",",hyarmen:"9","hwesta-sindarinwa":"o",yanta:"l",ure:".",halla:"\u00bd","short-carrier":"`","long-carrier":"~","round-carrier":"]","tinco-extended":"!","parma-extended":"Q",
+"calma-extended":"A","quesse-extended":"Z",comma:"=","full-stop":"-","exclamation-point":"\u00c1","question-mark":"\u00c0","open-paren":"Œ","close-paren":"œ","flourish-left":"Ğ","flourish-right":"ğ","#0":"\uf8ff","#1":"\u00d2","#2":"\u00da","#3":"\u00db","#4":"\u00d9","#5":"\u0131","#6":"\u02c6","#7":"\u02dc","#8":"\u00af","#9":"\u02d8","#10":"\u02d9","#11":"\u02da"},n={a:"#EDC",e:"$RFV",i:"%TGB",o:"^YHN",u:"& U J M Ā ā Ă ă".split(" "),"\u00f3":["Ą","ą",
+"Ć","ć"],"\u00fa":["Ĉ","ĉ","Ċ","ċ"],"\u00ed":["Ô","Õ","Ö","×"],w:"\u00e8\u00e9\u00ea\u00eb",y:"\u00cc\u00cd\u00ce\u00cf\u00b4","o-under":["\u00e4","å","\u00e6","\u00e7","|"],s:{special:!0,calma:"|",quesse:"|","short-carrier":"}"},"s-final":{special:!0,tinco:"+",ando:"+",numen:"+",lambe:"_"},"s-inverse":{special:!0,tinco:"\u00a1"},"s-extended":{special:!0,tinco:"Ç"},"s-flourish":{special:!0,tinco:"£",lambe:"¥"},"tilde-above":"Pp",
+"tilde-below":[":",";","°"],"tilde-high-above":")0","tilde-far-below":"?/","bar-above":"{[","bar-below":['"',"'","¸"],"bar-high-above":"\u00ec\u00ee","bar-far-below":"\u00ed\u00ef"},m={tengwar:[["tinco","parma","calma","quesse"],["ando","umbar","anga","ungwe"],["thule","formen","harma","hwesta"],["anto","ampa","anca","unque"],["numen","malta","noldo","nwalme"],["ore","vala","anna","wilya"],["romen","arda","lambe","alda"],["silme","silme-nuquerna","esse","esse-nuquerna"],["hyarmen","hwesta-sindarinwa",
+"yanta","ure"],["halla","short-carrier","long-carrier","round-carrier"],["tinco-extended","parma-extended","calma-extended","quesse-extended"]],tehtarAbove:"aeiou\u00e1\u00e9\u00ed\u00f3\u00faw".split(""),tehtarBelow:["y","s","o-under"],tehtarFollowing:["s-final","s-inverse","s-extended","s-flourish"],barsAndTildes:"tilde-above tilde-below tilde-high-above tilde-far-below bar-above bar-below bar-high-above bar-far-below".split(" ")};m.tehtar=[].concat(m.tehtarAbove,m.tehtarBelow,m.tehtarFollowing,
+m.barsAndTildes);m.aliases={vilya:"wilya",aha:"harma",gasdil:"halla"};var s={},la=m,Da=s.tengwar=k,y=s.tehtar=n,t=s.positions={tinco:{o:3,w:3,others:2},parma:{o:3,w:3,others:2},calma:{o:3,w:3,u:3,"o-under":1,others:2},quesse:{o:3,w:3,"o-under":1,others:2},ando:{wide:!0,e:1,o:2,"\u00f3":1,"\u00fa":1,others:0},umbar:{wide:!0,e:1,o:2,"\u00f3":1,"\u00fa":1,others:0},anga:{wide:!0,e:1,"\u00f3":1,"\u00fa":1,others:0},ungwe:{wide:!0,e:1,o:1,"\u00f3":1,"\u00fa":1,others:0},thule:{others:3},formen:3,harma:{e:0,
+o:3,u:7,"\u00f3":2,"\u00fa":2,w:0,others:1},hwesta:{e:0,o:3,u:7,w:0,others:1},anto:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},ampa:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},anca:{wide:!0,u:7,"\u00f3":1,"\u00fa":1,others:0},unque:{wide:!0,u:7,others:0},numen:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},malta:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},noldo:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},nwalme:{wide:!0,"\u00f3":1,"\u00fa":1,others:0},ore:{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},vala:{e:3,o:3,
+u:3,"\u00f3":3,"\u00fa":3,others:1},anna:{e:3,o:3,u:3,"\u00f3":2,"\u00fa":2,others:1},wilya:{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},romen:{e:3,o:3,u:3,"\u00f3":2,"\u00fa":2,y:null,"o-under":null,others:1},arda:{a:1,e:3,i:1,o:3,u:3,"\u00ed":1,"\u00f3":2,"\u00fa":2,y:null,"o-under":null,others:0},lambe:{wide:!0,e:1,y:4,"\u00f3":1,"\u00fa":1,"o-under":null,others:0},alda:{wide:!0,"o-under":null,others:1},silme:{y:3,"o-under":2,others:null},"silme-nuquerna":{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,y:null,
+"o-under":null,others:1},esse:{y:null,others:null},"esse-nuquerna":{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},hyarmen:3,"hwesta-sindarinwa":{o:2,u:2,"\u00f3":1,"\u00fa":2,others:0},yanta:{e:3,o:3,u:3,"\u00f3":2,"\u00fa":2,others:1},ure:{e:3,o:3,u:3,"\u00f3":3,"\u00fa":3,others:1},halla:{others:null},"short-carrier":3,"long-carrier":{y:null,"o-under":null,others:3},"round-carrier":3,"tinco-extended":3,"parma-extended":3,"calma-extended":{o:3,u:7,"\u00f3":2,"\u00fa":2,others:1},"quesse-extended":{o:0,
+u:7,others:1}};s.transcribe=function(a,c){var c=c||{},b=c.plain||!1,d=c.block||!1,e=d?"<p>":"",i=d?"<br>":"",f=d?"</p>":"";return a.map(function(a){return a.map(function(a){return e+a.map(function(a){return a.map(function(a){return a.map(function(a){var c=a.tengwa||"anna",d=[];a.above&&d.push(a.above);a.below&&d.push(a.below);a.tildeBelow&&d.push("tilde-below");a.tildeAbove&&d.push("tilde-above");a.following&&d.push(a.following);d=Da[c]+d.map(function(a){return w(c,a)}).join("");a.errors&&!b&&(d=
+'<abbr class="error" title="'+a.errors.join("\n").replace(/"/g,""")+'">'+d+"</abbr>");return d}).join("")}).join(" ")}).join(i+"\n")+f}).join("\n\n")}).join("\n\n\n")};s.tehtaForTengwa=w;s.makeColumn=function(a,c,b){return new q(a,c,b)};var q=function(a,c,b){this.above=c;this.tildeAbove=void 0;this.tengwa=a;this.tildeBelow=void 0;this.below=b;this.error=this.following=void 0};q.prototype.canAddAbove=function(a){return!this.above&&!!w(this.tengwa,a)||!this.below&&("silme"===this.tengwa&&w("silme-nuquerna",
+a)||"esse"===this.tengwa&&w("esse-nuquerna",a))};q.prototype.addAbove=function(a){"silme"===this.tengwa&&(this.tengwa="silme-nuquerna");"esse"===this.tengwa&&(this.tengwa="esse-nuquerna");this.above=a;return this};q.prototype.canAddBelow=function(a){return!this.below&&!!w(this.tengwa,a)};q.prototype.addBelow=function(a){this.below=a;return this};q.prototype.addTildeAbove=function(){this.tildeAbove=!0;return this};q.prototype.addTildeBelow=function(){this.tildeBelow=!0;return this};q.prototype.canAddFollowing=
+function(a){return!this.following&&!!w(this.tengwa,a)};q.prototype.addFollowing=function(a){this.following=a;return this};q.prototype.addError=function(a){this.errors=this.errors||[];this.errors.push(a);return this};var v={},na=m,Ea=v.tengwar=k,z=v.tehtar=n,u=v.positions={tinco:2,parma:2,calma:{y:1,"o-under":1,others:2},quesse:{y:1,"o-under":1,others:2},ando:{wide:!0,others:0},umbar:{wide:!0,others:0},anga:{wide:!0,others:0},ungwe:{wide:!0,others:0},thule:{a:3,w:3,others:2},formen:{a:3,w:3,"\u00ed":3,
+others:2},harma:{a:0,e:0,i:1,o:1,u:1,w:0,"\u00ed":0,others:1},hwesta:{a:0,e:0,i:1,o:1,u:1,w:0,others:1},anto:{wide:!0,others:0},ampa:{wide:!0,others:0},anca:{wide:!0,others:0},unque:{wide:!0,others:0},numen:{wide:!0,others:0},malta:{wide:!0,others:0},noldo:{wide:!0,others:0},nwalme:{wide:!0,others:0},ore:{a:1,e:2,i:1,o:2,u:3,others:1},vala:{a:1,e:2,i:2,o:2,w:1,y:1,"\u00ed":2,others:3},anna:{a:1,w:3,others:2},wilya:{i:2,"\u00ed":2,others:1},romen:{a:1,e:1,i:2,o:1,u:1,y:3,"o-under":null,others:1},arda:{a:1,
+e:1,i:2,o:1,u:1,w:1,"\u00ed":2,y:null,"o-under":null,others:0},lambe:{wide:!0,e:1,y:4,w:0,"o-under":null,others:0},alda:{wide:!0,w:0,y:null,"o-under":null,others:1},silme:{y:2,"o-under":2,others:null},"silme-nuquerna":{e:2,y:null,"o-under":null,others:1},esse:{others:null},"esse-nuquerna":{e:2,y:null,"o-under":null,others:1},hyarmen:{y:1,others:3},"hwesta-sindarinwa":{w:1,y:1,others:0},yanta:{a:1,others:2},ure:{a:1,others:2},halla:{others:null},"short-carrier":{y:null,others:3},"long-carrier":{y:null,
+"o-under":null,others:3},"round-carrier":2,"tinco-extended":{a:3,w:3,y:3,"\u00ed":3,others:2},"parma-extended":{a:3,w:3,y:3,"\u00ed":3,others:2},"calma-extended":{i:1,w:1,y:0,"\u00ed":0,others:0},"quesse-extended":{i:1,w:1,y:0,"\u00ed":0,others:0}};v.transcribe=function(a,c){var c=c||{},b=c.plain||!1,d=c.block||!1,e=d?"<p>":"",i=d?"<br>":"",f=d?"</p>":"";return a.map(function(a){return a.map(function(a){return e+a.map(function(a){return a.map(function(a){return a.map(function(a){var c=a.tengwa||"anna",
+d=[];a.above&&d.push(a.above);a.below&&d.push(a.below);a.tildeBelow&&d.push("tilde-below");a.tildeAbove&&d.push("tilde-above");a.following&&d.push(a.following);d=Ea[c]+d.map(function(a){return x(c,a)}).join("");a.errors&&!b&&(d='<abbr class="error" title="'+a.errors.join("\n").replace(/"/g,""")+'">'+d+"</abbr>");return d}).join("")}).join(" ")}).join(i+"\n")+f}).join("\n\n")}).join("\n\n\n")};v.tehtaForTengwa=x;var ma="\u00e1\u00e9\u00f3\u00fa";v.makeColumn=function(a,c,b){return new r(a,c,b)};
+var r=function(a,c,b){this.above=c;this.tildeAbove=void 0;this.tengwa=a;this.tildeBelow=void 0;this.below=b;this.error=this.following=void 0};r.prototype.canAddAbove=function(a){return!this.above&&!!x(this.tengwa,a)||!this.below&&("silme"===this.tengwa&&x("silme-nuquerna",a)||"esse"===this.tengwa&&x("esse-nuquerna",a))};r.prototype.addAbove=function(a){"silme"===this.tengwa&&(this.tengwa="silme-nuquerna");"esse"===this.tengwa&&(this.tengwa="esse-nuquerna");this.above=a;return this};r.prototype.canAddBelow=
+function(a){return!this.below&&!!x(this.tengwa,a)};r.prototype.addBelow=function(a){this.below=a;return this};r.prototype.addTildeAbove=function(){this.tildeAbove=!0;return this};r.prototype.addTildeBelow=function(){this.tildeBelow=!0;return this};r.prototype.canAddFollowing=function(a){return!this.following&&!!x(this.tengwa,a)};r.prototype.addFollowing=function(a){this.following=a;return this};r.prototype.addError=function(a){this.errors=this.errors||[];this.errors.push(a);return this};k={module$exports:{"-":"comma",
+",":"comma",":":"comma",";":"full-stop",".":"full-stop","!":"exclamation-point","?":"question-mark","(":"open-paren",")":"close-paren",">":"flourish-left","<":"flourish-right"}};k.module$exports&&(k=k.module$exports);var n={},Fa=Array.prototype;n.module$exports=function(a,c,b){var d=b.font.makeColumn;return Fa.map.call(parseInt(a,c).toString(c),function(a){return d("#"+a)})};n.module$exports&&(n=n.module$exports);var L={encode:function(a){return a.map(function(a){return a.map(function(a){return a.map(function(a){return a.map(function(a){return a.map(function(a){var b=
+[];a.above&&b.push(a.above);a.below&&b.push(a.below);a.following&&b.push(a.following);a.tildeAbove&&b.push("tilde-above");a.tildeBelow&&b.push("tilde-below");return b.length?a.tengwa+":"+b.join(","):a.tengwa}).join(";")}).join(" ")}).join("\n")}).join("\n\n")}).join("\n\n\n")},decode:function(a,c){return a.split("\n\n\n").map(function(a){return a.split("\n\n").map(function(a){return a.split("\n").map(function(a){return a.split(" ").map(function(a){return O(a,c)})})})})}};L.decodeWord=O;var j={},Ga=
+k;j.makeParser=function(a,c){c=c||function(a,c){throw Error(a+" while parsing "+JSON.stringify(c));};return function(b){var d,e=a.apply(null,[function(a){d=a;return function(a){""!==a&&(a="Unexpected "+JSON.stringify(a),c(a,b));return function ra(){return ra}}}].concat(Array.prototype.slice.call(arguments,1)));for(Array.prototype.forEach.call(b,function(a){e=e(a)});!d;)e=e("");return d}};j.makeExpect=function(a){return function(c){return function(b){return b===a?c(b):c()(b)}}};j.makeParseSome=function(a){var c=
+P(a);return function(b){return function(d){return d===a?c(b):b()(d)}}};j.makeParseAny=P;j.makeDelimitedParser=function(a,c){return function d(e,i,f){f=f||[];return a(function(a){return a.length?(f=f.concat([a]),c(function(a){return a?d(e,i,f):e(f)})):e(f)},i)}};j.isBreak=Q;j.isFinal=function(a){return Q(a)||Ga[a]};j.countPrimes=R;var n={module$exports:function(a,c){var b=j.makeDelimitedParser(a,Ha),b=j.makeDelimitedParser(b,S),b=j.makeDelimitedParser(b,S),d=j.makeDelimitedParser(b,pa);return j.makeParser(function(a,
+b){b=c(b);return d(a,b)})}},E=j.makeParseAny(" "),Ha=j.makeParseSome(" "),oa=j.makeExpect("\n"),qa=j.makeParseSome("\n");n.module$exports&&(n=n.module$exports);var l={};l.module$exports=T;l.module$exports&&(l=l.module$exports);var o={};o.module$exports=U;o.module$exports&&(o=o.module$exports);var m={module$exports:function(a){var c=N(a);return function d(a){c=c(a.toLowerCase());return d}}},l=l({k:"c",x:"cs",q:"cw",qu:"cw",p:"p",ph:"f",b:"b",bh:"v","\u00eb":"e","\u00e2":"\u00e1","\u00ea":"\u00e9",
+"\u00ee":"\u00ed","\u00f4":"\u00f3","\u00fb":"\u00fa"}),N=o(l,function(a){return function(c){return Array.prototype.reduce.call(a,function(a,c){return a(c)},c)}},function(a){return N(a)},function(a){return function(c){return N(a(c))}});m.module$exports&&(m=m.module$exports);var l={},ta=s,G=j,Ia=m,X=k;l.name="General Use Mode";var sa={};l.makeOptions=F;l.transcribe=function(a,c){c=F(c);return c.font.transcribe(ha(a,c),c)};l.encode=function(a,c){c=F(c);return L.encode(ha(a,c),c)};var ha=l.parse=n(function(a,
+c){var b,d=c.font.makeColumn;b=V(function(b){return ia[b]?a(L.decodeWord(ia[b],d)):a(Ja(b,c))},c);return Ia(b)},F),ia={iant:"yanta;tinco:a,tilde-above",iaur:"yanta;vala:a;ore",baranduiniant:"umbar;romen:a;ando:a,tilde-above;anna:u;yanta;anto:a,tilde-above",ioreth:"yanta;romen:o;thule:e",noldo:"nwalme;lambe:o;ando;short-carrier:o",noldor:"nwalme;lambe:o;ando;ore:o",is:"short-carrier:i,s"},Ja=G.makeParser(function(a,c){return W(a,c,[])}),M="aeiou\u00f3\u00fa",H={"\u00e1":"a","\u00e9":"e","\u00ed":"i",
+"\u00f3":"o","\u00fa":"u"},ua={o:"u",u:"o","\u00f3":"\u00fa","\u00fa":"\u00f3"};l.parseTengwaAnnotations=C;var o={},wa=s,J=j,Ka=m,$=k;o.name="Classical Mode";var va={};o.makeOptions=I;o.transcribe=function(a,c){c=I(c);return c.font.transcribe(ja(a,c),c)};o.encode=function(a,c){c=I(c);return L.encode(ja(a,c),c)};var ja=o.parse=n(function(a,c){return Ka(Y(a,c))},I),aa="aeiouy\u00e1\u00e9\u00ed\u00f3\u00fa",xa={o:"u",u:"o","\u00f3":"\u00fa","\u00fa":"\u00f3"},B={},za=v,A=j,La=m,da=k;B.name="Mode of Beleriand";
+var ya={};B.makeOptions=K;B.transcribe=function(a,c){c=K(c);return c.font.transcribe(ka(a,c),c)};B.encode=function(a,c){c=K(c);return Notation.encode(ka(a,c),c)};var ka=B.parse=n(function(a,c){return La(ba(a,c))},K),k={};k.module$exports={"general-use":l,classical:o,beleriand:B};k.module$exports&&(k=k.module$exports);var Ca=l,ga=s,Aa=v,Ba=k,fa=Array.prototype;"complete"===document.readyState?ea():document.addEventListener("DOMContentLoaded",ea,!0)})();