From 8d8d87b9cecef81e2b2813137bb3f71e13418b11 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 11 Apr 2016 18:20:42 +0200 Subject: [PATCH 001/100] Add project and impl for initial barebones dottydoc --- .gitignore | 1 + dottydoc/js/src/DottyDoc.scala | 44 + dottydoc/js/src/html/CustomTags.scala | 13 + dottydoc/js/src/html/Layout.scala | 71 ++ dottydoc/js/static/github.css | 124 +++ dottydoc/js/static/highlight.pack.js | 2 + dottydoc/js/static/index.css | 9 + dottydoc/js/static/material.min.css | 9 + dottydoc/js/static/material.min.js | 10 + .../src/dotty/tools/dottydoc/DottyDoc.scala | 40 + .../dotty/tools/dottydoc/core/Phases.scala | 104 +++ .../tools/dottydoc/model/CommentParsers.scala | 16 + .../src/dotty/tools/dottydoc/model/Html.scala | 37 + .../dottydoc/model/comment/BodyEntities.scala | 88 ++ .../dottydoc/model/comment/BodyParsers.scala | 57 ++ .../model/comment/CommentCleaner.scala | 25 + .../model/comment/CommentCooker.scala | 8 + .../model/comment/CommentParser.scala | 779 ++++++++++++++++++ .../dottydoc/model/comment/CommentRegex.scala | 84 ++ .../tools/dottydoc/util/IndexWriters.scala | 43 + .../dotty/tools/dottydoc/model/Entity.scala | 126 +++ .../dottydoc/model/EntityFactories.scala | 37 + .../dottydoc/model/comment/Comment.scala | 6 + project/Build.scala | 57 ++ 24 files changed, 1790 insertions(+) create mode 100644 dottydoc/js/src/DottyDoc.scala create mode 100644 dottydoc/js/src/html/CustomTags.scala create mode 100644 dottydoc/js/src/html/Layout.scala create mode 100644 dottydoc/js/static/github.css create mode 100644 dottydoc/js/static/highlight.pack.js create mode 100644 dottydoc/js/static/index.css create mode 100644 dottydoc/js/static/material.min.css create mode 100644 dottydoc/js/static/material.min.js create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala create mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala create mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala create mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala diff --git a/.gitignore b/.gitignore index c9f12e98668f..05f8019612f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.DS_Store *.class *.log +*.swp *~ *.swp diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala new file mode 100644 index 000000000000..33adc0aca1dd --- /dev/null +++ b/dottydoc/js/src/DottyDoc.scala @@ -0,0 +1,44 @@ +package dotty.tools.dottydoc +package js + +import scala.scalajs.js +import js.Dynamic.global +import js.JSApp +import js.annotation.{ JSExport, JSName } +import org.scalajs.dom +import model.Entities._ + +@JSExport object DottyDocJS { + @JSExport def main(target: dom.html.Div) = { + global.document.title = "Dotty " + ParsedIndex.currentEntity.path.mkString(".") + target.appendChild(html.Index.layout(ParsedIndex.currentEntity).render) + hljs.initHighlightingOnLoad() + } +} + +object ParsedIndex { + import prickle._ + import model.Entities._ + + val packages: Map[String, Package] = Unpickle[Map[String, Package]] + .fromString(js.JSON.stringify(Index.packages)) + .toOption + .getOrElse(Map.empty) + + val currentEntity: Entity = Unpickle[Entity] + .fromString(js.JSON.stringify(Index.currentEntity)) + .toOption + .getOrElse(NonEntity) +} + +@js.native +object Index extends js.Object { + def packages: js.Any = js.native + + def currentEntity: js.Any = js.native +} + +@js.native +object hljs extends js.Object { + def initHighlightingOnLoad(): js.Any = js.native +} diff --git a/dottydoc/js/src/html/CustomTags.scala b/dottydoc/js/src/html/CustomTags.scala new file mode 100644 index 000000000000..af1016f20639 --- /dev/null +++ b/dottydoc/js/src/html/CustomTags.scala @@ -0,0 +1,13 @@ +package dotty.tools.dottydoc +package js +package html + +import scalatags.JsDom.all._ +import scalatags.generic +import scalatags.generic.Util +import org.scalajs.dom + +object CustomTags { + lazy val main = "main".tag[dom.html.Element] + lazy val nav = "nav".tag[dom.html.Element] +} diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala new file mode 100644 index 000000000000..59d27a15d550 --- /dev/null +++ b/dottydoc/js/src/html/Layout.scala @@ -0,0 +1,71 @@ +package dotty.tools.dottydoc +package js +package html + +import scalatags.JsDom.all._ + +object Index { + import model.Entities._ + import CustomTags._ + + def layout(ent: Entity) = ent match { + case x: Entity with Members with Modifiers => packageMember(x) + } + + def packageMember(m: Entity with Members with Modifiers) = + div( + cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", + div( + cls := "mdl-layout__drawer", + span( + cls := "mdl-layout-title subtitle", + m.path.dropRight(1).mkString(".") + ), + span( + cls := "mdl-layout-title", + m.name + ), + nav( + cls := "mdl-navigation", + a(cls := "mdl-navigation__link", href := companionHref(m).map(_.path.last + ".html").getOrElse(""), "Companion " + m.name), + a(cls := "mdl-navigation__link", href := m.sourceUrl, "Source") + ), + span( + cls := "mdl-layout-title", + "Packages" + ) + ), + main( + cls := "mdl-layout__content", + div( + cls := "page-content", + div(raw(m.comment.fold("")(_.body))), + div( + cls := "mld-grid", + m.members + .collect { case x: Entity with Modifiers if !x.isPrivate => x} + .flatMap(member) + ) + ) + ) + ) + + def companionHref(m: Entity): Option[PackageMember] = { + val pack = m.path.dropRight(1).mkString(".") + println(pack) + ParsedIndex.packages.get(pack) + .flatMap(_.children.find(e => e.name == m.name && e.path.last != m.path.last)) + } + + def member(m: Entity) = m match { + case m: Entity with Modifiers => Seq( + div( + cls := "mdl-cell mdl-cell--12-col", + h6(m.modifiers.mkString(" ") + " " + m.kind + " " + m.name) + ), + div( + cls := "mdl-cell mdl-cell--12-col", + raw(m.comment.fold("")(_.body))) + ) + } +} diff --git a/dottydoc/js/static/github.css b/dottydoc/js/static/github.css new file mode 100644 index 000000000000..9b4f3aa17fbd --- /dev/null +++ b/dottydoc/js/static/github.css @@ -0,0 +1,124 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; + -webkit-text-size-adjust: none; +} + +.hljs-comment, +.diff .hljs-header, +.hljs-javadoc { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.css .rule .hljs-keyword, +.hljs-winutils, +.nginx .hljs-title, +.hljs-subst, +.hljs-request, +.hljs-status { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-hexcolor, +.ruby .hljs-constant { + color: #008080; +} + +.hljs-string, +.hljs-tag .hljs-value, +.hljs-phpdoc, +.hljs-dartdoc, +.tex .hljs-formula { + color: #d14; +} + +.hljs-title, +.hljs-id, +.scss .hljs-preprocessor { + color: #900; + font-weight: bold; +} + +.hljs-list .hljs-keyword, +.hljs-subst { + font-weight: normal; +} + +.hljs-class .hljs-title, +.hljs-type, +.vhdl .hljs-literal, +.tex .hljs-command { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-tag .hljs-title, +.hljs-rules .hljs-property, +.django .hljs-tag .hljs-keyword { + color: #000080; + font-weight: normal; +} + +.hljs-attribute, +.hljs-variable, +.lisp .hljs-body { + color: #008080; +} + +.hljs-regexp { + color: #009926; +} + +.hljs-symbol, +.ruby .hljs-symbol .hljs-string, +.lisp .hljs-keyword, +.clojure .hljs-keyword, +.scheme .hljs-keyword, +.tex .hljs-special, +.hljs-prompt { + color: #990073; +} + +.hljs-built_in { + color: #0086b3; +} + +.hljs-preprocessor, +.hljs-pragma, +.hljs-pi, +.hljs-doctype, +.hljs-shebang, +.hljs-cdata { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.diff .hljs-change { + background: #0086b3; +} + +.hljs-chunk { + color: #aaa; +} diff --git a/dottydoc/js/static/highlight.pack.js b/dottydoc/js/static/highlight.pack.js new file mode 100644 index 000000000000..60dbdab66c78 --- /dev/null +++ b/dottydoc/js/static/highlight.pack.js @@ -0,0 +1,2 @@ +!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){var n=(e.className+" "+(e.parentNode?e.parentNode.className:"")).split(/\s+/);return n=n.map(function(e){return e.replace(/^lang(uage)?-/,"")}),n.filter(function(e){return N(e)||/no(-?)highlight/.test(e)})[0]}function o(e,n){var t={};for(var r in e)t[r]=e[r];if(n)for(var r in n)t[r]=n[r];return t}function i(e){var n=[];return function r(e,a){for(var o=e.firstChild;o;o=o.nextSibling)3==o.nodeType?a+=o.nodeValue.length:1==o.nodeType&&(n.push({event:"start",offset:a,node:o}),a=r(o,a),t(o).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:o}));return a}(e,0),n}function c(e,r,a){function o(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"==e.event?i:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=o();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=o();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(i)}else"start"==g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function u(e){function n(e){return e&&e.source||e}function t(t,r){return RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var c={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");c[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):Object.keys(a.k).forEach(function(e){u(e,a.k[e])}),a.k=c}a.lR=t(a.l||/\b[A-Za-z0-9_]+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function s(e,t,a,o){function i(e,n){for(var t=0;t";return o+=e+'">',o+n+i}function d(){if(!w.k)return n(y);var e="",t=0;w.lR.lastIndex=0;for(var r=w.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(w,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=w.lR.lastIndex,r=w.lR.exec(y)}return e+n(y.substr(t))}function h(){if(w.sL&&!R[w.sL])return n(y);var e=w.sL?s(w.sL,y,!0,L[w.sL]):l(y);return w.r>0&&(B+=e.r),"continuous"==w.subLanguageMode&&(L[w.sL]=e.top),p(e.language,e.value,!1,!0)}function v(){return void 0!==w.sL?h():d()}function b(e,t){var r=e.cN?p(e.cN,"",!0):"";e.rB?(M+=r,y=""):e.eB?(M+=n(t)+r,y=""):(M+=r,y=t),w=Object.create(e,{parent:{value:w}})}function m(e,t){if(y+=e,void 0===t)return M+=v(),0;var r=i(t,w);if(r)return M+=v(),b(r,t),r.rB?0:t.length;var a=c(w,t);if(a){var o=w;o.rE||o.eE||(y+=t),M+=v();do w.cN&&(M+=""),B+=w.r,w=w.parent;while(w!=a.parent);return o.eE&&(M+=n(t)),y="",a.starts&&b(a.starts,""),o.rE?0:t.length}if(f(t,w))throw new Error('Illegal lexeme "'+t+'" for mode "'+(w.cN||"")+'"');return y+=t,t.length||1}var x=N(e);if(!x)throw new Error('Unknown language: "'+e+'"');u(x);for(var w=o||x,L={},M="",k=w;k!=x;k=k.parent)k.cN&&(M=p(k.cN,"",!0)+M);var y="",B=0;try{for(var C,j,I=0;;){if(w.t.lastIndex=I,C=w.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}m(t.substr(I));for(var k=w;k.parent;k=k.parent)k.cN&&(M+="");return{r:B,value:M,language:e,top:w}}catch(A){if(-1!=A.message.indexOf("Illegal"))return{r:0,value:n(t)};throw A}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(N(n)){var t=s(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function f(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
")),e}function g(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/(\s|^)hljs(\s|$)/)||a.push("hljs"),r&&a.push(r),a.join(" ").trim()}function p(e){var n=a(e);if(!/no(-?)highlight/.test(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?s(n,r,!0):l(r),u=i(t);if(u.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(u,i(p),r)}o.value=f(o.value),e.innerHTML=o.value,e.className=g(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",h,!1),addEventListener("load",h,!1)}function b(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function m(){return Object.keys(R)}function N(e){return R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=s,e.highlightAuto=l,e.fixMarkup=f,e.highlightBlock=p,e.configure=d,e.initHighlighting=h,e.initHighlightingOnLoad=v,e.registerLanguage=b,e.listLanguages=m,e.getLanguage=N,e.inherit=o,e.IR="[a-zA-Z][a-zA-Z0-9_]*",e.UIR="[a-zA-Z_][a-zA-Z0-9_]*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.CLCM={cN:"comment",b:"//",e:"$",c:[e.PWM]},e.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM]},e.HCM={cN:"comment",b:"#",e:"$",c:[e.PWM]},e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("asciidoc",function(){return{c:[{cN:"comment",b:"^/{4,}\\n",e:"\\n/{4,}$",r:10},{cN:"comment",b:"^//",e:"$",r:0},{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"smartquote",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("cpp",function(t){var i={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex _Complex _Imaginaryintmax_t uintmax_t int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_tint_least8_t uint_least8_t int_least16_t uint_least16_t int_least32_t uint_least32_tint_least64_t uint_least64_t int_fast8_t uint_fast8_t int_fast16_t uint_fast16_t int_fast32_tuint_fast32_t int_fast64_t uint_fast64_t intptr_t uintptr_t atomic_bool atomic_char atomic_scharatomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llongatomic_ullong atomic_wchar_t atomic_char16_t atomic_char32_t atomic_intmax_t atomic_uintmax_tatomic_intptr_t atomic_uintptr_t atomic_size_t atomic_ptrdiff_t atomic_int_least8_t atomic_int_least16_tatomic_int_least32_t atomic_int_least64_t atomic_uint_least8_t atomic_uint_least16_t atomic_uint_least32_tatomic_uint_least64_t atomic_int_fast8_t atomic_int_fast16_t atomic_int_fast32_t atomic_int_fast64_tatomic_uint_fast8_t atomic_uint_fast16_t atomic_uint_fast32_t atomic_uint_fast64_t",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf"};return{aliases:["c","h","c++","h++"],k:i,i:""]',k:"include",i:"\\n"},t.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:i,c:["self"]},{b:t.IR+"::"},{bK:"new throw return",r:0},{cN:"function",b:"("+t.IR+"\\s+)+"+t.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:t.IR+"\\s*\\(",rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:i,r:0,c:[t.CBCM]},t.CLCM,t.CBCM]}]}});hljs.registerLanguage("haskell",function(e){var i={cN:"comment",v:[{b:"--",e:"$"},{b:"{-",e:"-}",c:["self"]}]},c={cN:"pragma",b:"{-#",e:"#-}"},a={cN:"preprocessor",b:"^#",e:"$"},n={cN:"type",b:"\\b[A-Z][\\w']*",r:0},l={cN:"container",b:"\\(",e:"\\)",i:'"',c:[c,i,a,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"})]},t={cN:"container",b:"{",e:"}",c:l.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{cN:"module",b:"\\bmodule\\b",e:"where",k:"module where",c:[l,i],i:"\\W\\.|;"},{cN:"import",b:"\\bimport\\b",e:"$",k:"import|0 qualified as hiding",c:[l,i],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[n,l,i]},{cN:"typedef",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[c,i,n,l,t]},{cN:"default",bK:"default",e:"$",c:[n,l,i]},{cN:"infix",bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{cN:"foreign",b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[n,e.QSM,i]},{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},c,i,a,e.QSM,e.CNM,n,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),{b:"->|<-"}]}});hljs.registerLanguage("rsl",function(e){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:""},{b:"<=",r:0},{b:"=>",r:0},{b:"/\\\\"},{b:"\\\\/"}]},c={cN:"built_in",v:[{b:":-\\|-->"},{b:"=",r:0}]};return{aliases:["m","moo"],k:i,c:[s,c,t,_,n,e.NM,a,o,{b:/:-/}]}});hljs.registerLanguage("axapta",function(e){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bK:"class interface",e:"{",eE:!0,i:":",c:[{bK:"extends implements"},e.UTM]}]}});hljs.registerLanguage("verilog",function(e){return{aliases:["v"],cI:!0,k:{keyword:"always and assign begin buf bufif0 bufif1 case casex casez cmos deassign default defparam disable edge else end endcase endfunction endmodule endprimitive endspecify endtable endtask event for force forever fork function if ifnone initial inout input join macromodule module nand negedge nmos nor not notif0 notif1 or output parameter pmos posedge primitive pulldown pullup rcmos release repeat rnmos rpmos rtran rtranif0 rtranif1 specify specparam table task timescale tran tranif0 tranif1 wait while xnor xor",typename:"highz0 highz1 integer large medium pull0 pull1 real realtime reg scalared signed small strong0 strong1 supply0 supply0 supply1 supply1 time tri tri0 tri1 triand trior trireg vectored wand weak0 weak1 wire wor"},c:[e.CBCM,e.CLCM,e.QSM,{cN:"number",b:"\\b(\\d+'(b|h|o|d|B|H|O|D))?[0-9xzXZ]+",c:[e.BE],r:0},{cN:"typename",b:"\\.\\w+",r:0},{cN:"value",b:"#\\((?!parameter).+\\)"},{cN:"keyword",b:"\\+|-|\\*|/|%|<|>|=|#|`|\\!|&|\\||@|:|\\^|~|\\{|\\}",r:0}]}});hljs.registerLanguage("matlab",function(e){var a=[e.CNM,{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]}],s={r:0,c:[{cN:"operator",b:/'['\.]*/}]};return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{b:/[a-zA-Z_][a-zA-Z_0-9]*'['\.]*/,rB:!0,r:0,c:[{b:/[a-zA-Z_][a-zA-Z_0-9]*/,r:0},s.c[0]]},{cN:"matrix",b:"\\[",e:"\\]",c:a,r:0,starts:s},{cN:"cell",b:"\\{",e:/\}/,c:a,r:0,i:/:/,starts:s},{b:/\)/,r:0,starts:s},{cN:"comment",b:"\\%",e:"$"}].concat(a)}});hljs.registerLanguage("handlebars",function(){var e="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z- .]+",k:e},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z- .]+",k:e},{cN:"variable",b:"[a-zA-Z-.]+",k:e}]}]}});hljs.registerLanguage("php",function(e){var c={cN:"variable",b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},i={cN:"preprocessor",b:/<\?(php)?|\?>/},a={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.CLCM,e.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"},i]},{cN:"comment",b:"__halt_compiler.+?;",eW:!0,k:"__halt_compiler",l:e.UIR},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},i,c,{b:/->+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,a,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},a,n]}});hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",n="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:n},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},s={eW:!0,rE:!0,l:r,k:n,r:0},i={cN:"function",bK:"def defmacro",e:/\bdo\b/,c:[e.inherit(e.TM,{b:b,starts:s})]},l=e.inherit(i,{cN:"class",bK:"defmodule defrecord",e:/\bdo\b|$|;/}),t=[a,e.HCM,l,i,{cN:"constant",b:"(\\b[A-Z_]\\w*(.)?)+",r:0},{cN:"symbol",b:":",c:[a,{b:b}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=t,s.c=t,{l:r,k:n,c:t}});hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch|10 stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...|10",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]}]}});hljs.registerLanguage("xl",function(e){var t="ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts",o={keyword:"if then else do while until for loop import with is as where when by data constant",literal:"true false nil",type:"integer real text name boolean symbol infix prefix postfix block tree",built_in:"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at",module:t,id:"text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons"},a={cN:"constant",b:"[A-Z][A-Z_0-9]+",r:0},r={cN:"variable",b:"([A-Z][a-z_0-9]+)+",r:0},i={cN:"id",b:"[a-z][a-z_0-9]+",r:0},l={cN:"string",b:'"',e:'"',i:"\\n"},n={cN:"string",b:"'",e:"'",i:"\\n"},s={cN:"string",b:"<<",e:">>"},c={cN:"number",b:"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?",r:10},_={cN:"import",bK:"import",e:"$",k:{keyword:"import",module:t},r:0,c:[l]},d={cN:"function",b:"[a-z].*->"};return{aliases:["tao"],l:/[a-zA-Z][a-zA-Z0-9_?]*/,k:o,c:[e.CLCM,e.CBCM,l,n,s,d,_,a,r,i,c,e.NM]}});hljs.registerLanguage("sql",function(e){var t={cN:"comment",b:"--",e:"$"};return{cI:!0,i:/[<>]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate savepoint release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup",e:/;/,eW:!0,k:{keyword:"abs absolute acos action add adddate addtime aes_decrypt aes_encrypt after aggregate all allocate alter analyze and any are as asc ascii asin assertion at atan atan2 atn2 authorization authors avg backup before begin benchmark between bin binlog bit_and bit_count bit_length bit_or bit_xor both by cache call cascade cascaded case cast catalog ceil ceiling chain change changed char_length character_length charindex charset check checksum checksum_agg choose close coalesce coercibility collate collation collationproperty column columns columns_updated commit compress concat concat_ws concurrent connect connection connection_id consistent constraint constraints continue contributors conv convert convert_tz corresponding cos cot count count_big crc32 create cross cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime data database databases datalength date_add date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts datetimeoffsetfromparts day dayname dayofmonth dayofweek dayofyear deallocate declare decode default deferrable deferred degrees delayed delete des_decrypt des_encrypt des_key_file desc describe descriptor diagnostics difference disconnect distinct distinctrow div do domain double drop dumpfile each else elt enclosed encode encrypt end end-exec engine engines eomonth errors escape escaped event eventdata events except exception exec execute exists exp explain export_set extended external extract fast fetch field fields find_in_set first first_value floor flush for force foreign format found found_rows from from_base64 from_days from_unixtime full function get get_format get_lock getdate getutcdate global go goto grant grants greatest group group_concat grouping grouping_id gtid_subset gtid_subtract handler having help hex high_priority hosts hour ident_current ident_incr ident_seed identified identity if ifnull ignore iif ilike immediate in index indicator inet6_aton inet6_ntoa inet_aton inet_ntoa infile initially inner innodb input insert install instr intersect into is is_free_lock is_ipv4 is_ipv4_compat is_ipv4_mapped is_not is_not_null is_used_lock isdate isnull isolation join key kill language last last_day last_insert_id last_value lcase lead leading least leaves left len lenght level like limit lines ln load load_file local localtime localtimestamp locate lock log log10 log2 logfile logs low_priority lower lpad ltrim make_set makedate maketime master master_pos_wait match matched max md5 medium merge microsecond mid min minute mod mode module month monthname mutex name_const names national natural nchar next no no_write_to_binlog not now nullif nvarchar oct octet_length of old_password on only open optimize option optionally or ord order outer outfile output pad parse partial partition password patindex percent_rank percentile_cont percentile_disc period_add period_diff pi plugin position pow power pragma precision prepare preserve primary prior privileges procedure procedure_analyze processlist profile profiles public publishingservername purge quarter query quick quote quotename radians rand read references regexp relative relaylog release release_lock rename repair repeat replace replicate reset restore restrict return returns reverse revoke right rlike rollback rollup round row row_count rows rpad rtrim savepoint schema scroll sec_to_time second section select serializable server session session_user set sha sha1 sha2 share show sign sin size slave sleep smalldatetimefromparts snapshot some soname soundex sounds_like space sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sql_variant_property sqlstate sqrt square start starting status std stddev stddev_pop stddev_samp stdev stdevp stop str str_to_date straight_join strcmp string stuff subdate substr substring subtime subtring_index sum switchoffset sysdate sysdatetime sysdatetimeoffset system_user sysutcdatetime table tables tablespace tan temporary terminated tertiary_weights then time time_format time_to_sec timediff timefromparts timestamp timestampadd timestampdiff timezone_hour timezone_minute to to_base64 to_days to_seconds todatetimeoffset trailing transaction translation trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse ucase uncompress uncompressed_length unhex unicode uninstall union unique unix_timestamp unknown unlock update upgrade upped upper usage use user user_resources using utc_date utc_time utc_timestamp uuid uuid_short validate_password_strength value values var var_pop var_samp variables variance varp version view warnings week weekday weekofyear weight_string when whenever where with work write xml xor year yearweek zon",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int integer interval number numeric real serial smallint varchar varying int8 serial8 text"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",a={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},n={cN:"comment",b:"%",e:"$"},b={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},i={b:"fun\\s+"+r+"/\\d+"},o={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{cN:"function_name",b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},d={cN:"tuple",b:"{",e:"}",r:0},t={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},l={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0},f={b:"#"+e.UIR,r:0,rB:!0,c:[{cN:"record_name",b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:a};s.c=[n,i,e.inherit(e.ASM,{cN:""}),s,o,e.QSM,b,d,t,l,f];var u=[n,i,s,o,e.QSM,b,d,t,l,f];o.c[1].c=u,d.c=u,f.c[1].c=u;var v={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:a,i:"(",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[v,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:a,c:u}},n,{cN:"pp",b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[v]},b,e.QSM,f,t,l,d,{b:/\.$/}]}});hljs.registerLanguage("makefile",function(e){var a={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{cN:"constant",e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:"title",b:/^[\w]+:\s*$/},{cN:"phony",b:/^\.PHONY:/,e:/$/,k:".PHONY",l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,a]}]}});hljs.registerLanguage("nsis",function(e){var t={cN:"symbol",b:"\\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)"},n={cN:"constant",b:"\\$+{[a-zA-Z0-9_]+}"},i={cN:"variable",b:"\\$+[a-zA-Z0-9_]+",i:"\\(\\){}"},r={cN:"constant",b:"\\$+\\([a-zA-Z0-9_]+\\)"},o={cN:"params",b:"(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)"},l={cN:"constant",b:"\\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)"};return{cI:!1,k:{keyword:"Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetPluginUnload SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption SubSectionEnd Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle",literal:"admin all auto both colored current false force hide highest lastused leave listonly none normal notset off on open print show silent silentlog smooth textonly true user "},c:[e.HCM,e.CBCM,{cN:"string",b:'"',e:'"',i:"\\n",c:[{cN:"symbol",b:"\\$(\\\\(n|r|t)|\\$)"},t,n,i,r]},{cN:"comment",b:";",e:"$",r:0},{cN:"function",bK:"Function PageEx Section SectionGroup SubSection",e:"$"},l,n,i,r,o,e.NM,{cN:"literal",b:e.IR+"::"+e.IR}]}});hljs.registerLanguage("stata",function(e){return{aliases:["do","ado"],cI:!0,k:"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5",c:[{cN:"label",v:[{b:"\\$\\{?[a-zA-Z_]+\\}?"},{b:"`[a-zA-Z_]+'"}]},{cN:"string",v:[{b:'`".*"\''},{b:'".*"'}]},{cN:"literal",v:[{b:"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},{cN:"comment",v:[{b:"^\\*.*$"},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("nimrod",function(t){return{k:{keyword:"addr and as asm bind block break|0 case|0 cast const|0 continue|0 converter discard distinct|10 div do elif else|0 end|0 enum|0 except export finally for from generic if|0 import|0 in include|0 interface is isnot|10 iterator|10 let|0 macro method|10 mixin mod nil not notin|10 object|0 of or out proc|10 ptr raise ref|10 return shl shr static template|10 try|0 tuple type|0 using|0 var|0 when while|0 with without xor yield",literal:"shared guarded stdin stdout stderr result|10 true false"},c:[{cN:"decorator",b:/{\./,e:/\.}/,r:10},{cN:"string",b:/[a-zA-Z]\w*"/,e:/"/,c:[{b:/""/}]},{cN:"string",b:/([a-zA-Z]\w*)?"""/,e:/"""/},{cN:"string",b:/"/,e:/"/,i:/\n/,c:[{b:/\\./}]},{cN:"type",b:/\b[A-Z]\w+\b/,r:0},{cN:"type",b:/\b(int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|float|float32|float64|bool|char|string|cstring|pointer|expr|stmt|void|auto|any|range|array|openarray|varargs|seq|set|clong|culong|cchar|cschar|cshort|cint|csize|clonglong|cfloat|cdouble|clongdouble|cuchar|cushort|cuint|culonglong|cstringarray|semistatic)\b/},{cN:"number",b:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/,r:0},{cN:"number",b:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/,r:0},{cN:"number",b:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/,r:0},{cN:"number",b:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/,r:0},t.HCM]}});hljs.registerLanguage("haxe",function(e){var r="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";return{aliases:["hx"],k:{keyword:"break callback case cast catch class continue default do dynamic else enum extends extern for function here if implements import in inline interface never new override package private public return static super switch this throw trace try typedef untyped using var while",literal:"true false null"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end error"},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM]},{cN:"type",b:":",e:r,r:10}]}]}});hljs.registerLanguage("clojure",function(e){var t={built_in:"def cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},c=e.inherit(e.QSM,{i:null}),i={cN:"comment",b:";",e:"$",r:0},d={cN:"literal",b:/\b(true|false|nil)\b/},l={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p={cN:"comment",b:"\\^\\{",e:"\\}"},u={cN:"attribute",b:"[:]"+n},f={cN:"list",b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"keyword",b:n,starts:h},b=[f,c,m,p,i,u,l,s,d,o];return f.c=[{cN:"comment",b:"comment"},y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,c,m,p,i,u,l,s,d]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"title",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("step21",function(e){var r="[A-Z_][A-Z0-9_.]*",c="END-ISO-10303-21;",i={literal:"",built_in:"",keyword:"HEADER ENDSEC DATA"},t={cN:"preprocessor",b:"ISO-10303-21;",r:10},l=[e.CLCM,{cN:"comment",b:"/\\*\\*!",e:"\\*/",c:[e.PWM]},e.CBCM,e.CNM,e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"'",e:"'"},{cN:"label",v:[{b:"#",e:"\\d+",i:"\\W"}]}];return{aliases:["p21","step","stp"],cI:!0,l:r,k:i,c:[{cN:"preprocessor",b:c,r:10},t].concat(l)}});hljs.registerLanguage("applescript",function(e){var t=e.inherit(e.QSM,{i:""}),r={cN:"params",b:"\\(",e:"\\)",c:["self",e.CNM,t]},o=[{cN:"comment",b:"--",e:"$"},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",{b:"--",e:"$"}]},e.HCM];return{aliases:["osascript"],k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[t,e.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bK:"on",i:"[${=;\\n]",c:[e.UTM,r]}].concat(o),i:"//|->|=>"}});hljs.registerLanguage("thrift",function(e){var t="bool byte i16 i32 i64 double string binary";return{k:{keyword:"namespace const typedef struct enum service exception void oneway set list map required optional",built_in:t,literal:"true false"},c:[e.QSM,e.NM,e.CLCM,e.CBCM,{cN:"class",bK:"struct enum service exception",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"stl_container",b:"\\b(set|list|map)\\s*<",e:">",k:t,c:["self"]}]}});hljs.registerLanguage("xml",function(){var t="[A-Za-z0-9\\._:-]+",e={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"},c={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[c],starts:{e:"",rE:!0,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[c],starts:{e:"",rE:!0,sL:"javascript"}},e,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},c]}]}});hljs.registerLanguage("clojure-repl",function(){return{c:[{cN:"prompt",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure",subLanguageMode:"continuous"}}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,e.NM,s,a,t]}});hljs.registerLanguage("delphi",function(e){var r="exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure",t={cN:"comment",v:[{b:/\{/,e:/\}/,r:0},{b:/\(\*/,e:/\*\)/,r:10}]},i={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},c={cN:"string",b:/(#\d+)+/},o={b:e.IR+"\\s*=\\s*class\\s*\\(",rB:!0,c:[e.TM]},n={cN:"function",bK:"function constructor destructor procedure",e:/[:;]/,k:"function constructor|10 destructor|10 procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[i,c]},t]};return{cI:!0,k:r,i:/"|\$[G-Zg-z]|\/\*|<\/|\|/,c:[t,e.CLCM,i,c,e.NM,o,n]}});hljs.registerLanguage("profile",function(e){return{c:[e.CNM,{cN:"built_in",b:"{",e:"}$",eB:!0,eE:!0,c:[e.ASM,e.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:!0},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[e.CNM],r:10},e.ASM,e.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[e.UTM],r:0}]}});hljs.registerLanguage("ini",function(e){return{cI:!0,i:/\S/,c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:!0,k:"on off true false yes no",c:[e.QSM,e.NM],r:0}]}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",t={cN:"subst",b:/#\{/,e:/}/,k:c},r=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,t]},{b:/"/,e:/"/,c:[e.BE,t]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[t,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];t.c=r;var i=e.inherit(e.TM,{b:n}),s="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(r)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:r.concat([{cN:"comment",b:"###",e:"###",c:[e.PWM]},e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+s,e:"[-=]>",rB:!0,c:[i,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:s,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("aspectj",function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence",i="get set args call";return{k:t,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"aspect",bK:"aspect",e:/[{;=]/,eE:!0,i:/[:;"\[\]]/,c:[{bK:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UTM,{b:/\([^\)]*/,e:/[)]+/,k:t+" "+i,eE:!1}]},{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,r:0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"pointcut after before around throwing returning",e:/[)]/,eE:!1,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",rB:!0,c:[e.UTM]}]},{b:/[:]/,rB:!0,e:/[{;]/,r:0,eE:!1,k:t,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",k:t+" "+i},e.QSM]},{bK:"new throw",r:0},{cN:"function",b:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s\,]+)?[\{\;]/,rB:!0,e:/[{;=]/,k:t,eE:!0,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,r:0,k:t,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},e.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("actionscript",function(e){var a="[a-zA-Z_$][a-zA-Z0-9_$]*",c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)",t={cN:"rest_arg",b:"[.]{3}",e:a,r:10};return{aliases:["as"],k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"package",bK:"package",e:"{",c:[e.TM]},{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"preprocessor",bK:"import include",e:";"},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM,t]},{cN:"type",b:":",e:c,r:10}]}]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"{",e:"}"},n={cN:"variable",v:[{b:/\$\d/},{b:/[\$\%\@](\^\w\b|#\w+(\:\:\w+)*|{\w+}|\w+(\:\:\w*)*)/},{b:/[\$\%\@][^\s\w{]/,r:0}]},o={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5},i=[e.BE,r,n],c=[n,e.HCM,o,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:!0},s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,o,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",r:5},{cN:"operator",b:"-\\w\\b",r:0}];return r.c=c,s.c=c,{aliases:["pl"],k:t,c:c}});hljs.registerLanguage("vbscript-html",function(){return{sL:"xml",subLanguageMode:"continuous",c:[{b:"<%",e:"%>",sL:"vbscript"}]}});hljs.registerLanguage("powershell",function(e){var t={b:"`[\\s\\S]",r:0},r={cN:"variable",v:[{b:/\$[\w\d][\w\d_:]*/}]},o={cN:"string",b:/"/,e:/"/,c:[t,r,{cN:"variable",b:/\$[A-z]/,e:/[^A-z]/}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["ps"],l:/-?[A-z\.\-]+/,cI:!0,k:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",literal:"$null $true $false",built_in:"Add-Content Add-History Add-Member Add-PSSnapin Clear-Content Clear-Item Clear-Item Property Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ConvertTo-Html ConvertTo-SecureString Copy-Item Copy-ItemProperty Export-Alias Export-Clixml Export-Console Export-Csv ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item Join-Path Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug Set-Service Set-TraceSource Set-Variable Sort-Object Split-Path Start-Service Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where-Object Write-Debug Write-Error Write-Host Write-Output Write-Progress Write-Verbose Write-Warning",operator:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},c:[e.HCM,e.NM,o,a,r]}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"tag",b:""},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("twig",function(){var e={cN:"params",b:"\\(",e:"\\)"},t="attribute block constant cycle date dump include max min parent random range source template_from_string",a={cN:"function",bK:t,r:0,c:[e]},r={cN:"filter",b:/\|[A-Za-z]+\:?/,k:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",c:[a]},c="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return c=c+" "+c.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"comment",b:/\{#/,e:/#}/},{cN:"template_tag",b:/\{%/,e:/%}/,k:c,c:[r,a]},{cN:"variable",b:/\{\{/,e:/}}/,c:[r,a]}]}});hljs.registerLanguage("autohotkey",function(e){var r={cN:"escape",b:"`[\\s\\S]"},c={cN:"comment",b:";",e:"$",r:0},n=[{cN:"built_in",b:"A_[a-zA-Z0-9]+"},{cN:"built_in",bK:"ComSpec Clipboard ClipboardAll ErrorLevel"}];return{cI:!0,k:{keyword:"Break Continue Else Gosub If Loop Return While",literal:"A true false NOT AND OR"},c:n.concat([r,e.inherit(e.QSM,{c:[r]}),c,{cN:"number",b:e.NR,r:0},{cN:"var_expand",b:"%",e:"%",i:"\\n",c:[r]},{cN:"label",c:[r],v:[{b:'^[^\\n";]+::(?!=)'},{b:'^[^\\n";]+:(?!=)',r:0}]},{b:",\\s*,",r:10}])}});hljs.registerLanguage("smalltalk",function(a){var c="[a-z][a-zA-Z0-9_]*",e={cN:"char",b:"\\$.{1}"},r={cN:"symbol",b:"#"+a.UIR};return{aliases:["st"],k:"self super nil true false thisContext",c:[{cN:"comment",b:'"',e:'"'},a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:c+":",r:0},a.CNM,r,e,{cN:"localvars",b:"\\|[ ]*"+c+"([ ]+"+c+")*[ ]*\\|",rB:!0,e:/\|/,i:/\S/,c:[{b:"(\\|[ ]*)?"+c}]},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,e,a.CNM,r]}]}});hljs.registerLanguage("cs",function(e){var r="abstract as base bool break byte case catch char checked const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",t=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:r,i:/::/,c:[{cN:"comment",b:"///",e:"$",rB:!0,c:[{cN:"xmlDocTag",v:[{b:"///",r:0},{b:""},{b:""}]}]},e.CLCM,e.CBCM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class namespace interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("diff",function(){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});hljs.registerLanguage("livescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger case default function var with then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super case default function var void const let enum export import native __hasProp __extends __slice __bind __indexOf",literal:"true false null undefined yes no on off it that void",built_in:"npm require console print module global window document"},s="[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*",i=e.inherit(e.TM,{b:s}),n={cN:"subst",b:/#\{/,e:/\}/,k:t},c={cN:"subst",b:/#[A-Za-z$_]/,e:/(?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*/,k:t},r=[e.BNM,{cN:"number",b:"(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)",r:0,starts:{e:"(\\s*/)?",r:0}},{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,n,c]},{b:/"/,e:/"/,c:[e.BE,n,c]},{b:/\\/,e:/(\s|$)/,eE:!0}]},{cN:"pi",v:[{b:"//",e:"//[gim]*",c:[n,e.HCM]},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+s},{b:"``",e:"``",eB:!0,eE:!0,sL:"javascript"}];n.c=r;var a={cN:"params",b:"\\(",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(r)}]};return{aliases:["ls"],k:t,i:/\/\*/,c:r.concat([{cN:"comment",b:"\\/\\*",e:"\\*\\/"},e.HCM,{cN:"function",c:[i,a],rB:!0,v:[{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?",e:"\\->\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?",e:"[-~]{1,2}>\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?",e:"!?[-~]{1,2}>\\*?"}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:s+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("typescript",function(e){return{aliases:["ts"],k:{keyword:"in if for while finally var new function|0 do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private get set super interface extendsstatic constructor implements enum export import declare",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:0},e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/,r:0},{cN:"constructor",bK:"constructor",e:/\{/,eE:!0,r:10},{cN:"module",bK:"module",e:/\{/,eE:!0},{cN:"interface",bK:"interface",e:/\{/,eE:!0},{b:/\$[(.]/},{b:"\\."+e.IR,r:0}]}});hljs.registerLanguage("tcl",function(e){return{aliases:["tk"],k:"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while",c:[{cN:"comment",v:[{b:";[ \\t]*#",e:"$"},{b:"^[ \\t]*#",e:"$"}]},{bK:"proc",e:"[\\{]",eE:!0,c:[{cN:"symbol",b:"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"[ \\t\\n\\r]",eW:!0,eE:!0}]},{cN:"variable",eE:!0,v:[{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)",e:"[^a-zA-Z0-9_\\}\\$]"},{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{cN:"string",c:[e.BE],v:[e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},{cN:"number",v:[e.BNM,e.CNM]}]}});hljs.registerLanguage("vala",function(e){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bK:"class interface delegate namespace",e:"{",eE:!0,i:"[^,:\\n\\s\\.]",c:[e.UTM]},e.CLCM,e.CBCM,{cN:"string",b:'"""',e:'"""',r:5},e.ASM,e.QSM,e.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}});hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)"},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self"]},{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"tag",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"char",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("haml",function(){return{cI:!0,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(!=#|=#|-#|/).*$",r:0},{b:"^\\s*(-|=|!=)(?!#)",starts:{e:"\\n",sL:"ruby"}},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+"},{cN:"value",b:"[#\\.]\\w+"},{b:"{\\s*",e:"\\s*}",eE:!0,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:!0,eW:!0,c:[{cN:"symbol",b:":\\w+"},{cN:"string",b:'"',e:'"'},{cN:"string",b:"'",e:"'"},{b:"\\w+",r:0}]}]},{b:"\\(\\s*",e:"\\s*\\)",eE:!0,c:[{b:"\\w+\\s*=",e:"\\s+",rB:!0,eW:!0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"'},{cN:"string",b:"'",e:"'"},{b:"\\w+",r:0}]}]}]},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"}}]}});hljs.registerLanguage("erlang-repl",function(e){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},e.ASM,e.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}});hljs.registerLanguage("stylus",function(t){var e={cN:"variable",b:"\\$"+t.IR},o={cN:"hexcolor",b:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})",r:10},i=["charset","css","debug","extend","font-face","for","import","include","media","mixin","page","warn","while"],r=["after","before","first-letter","first-line","active","first-child","focus","hover","lang","link","visited"],n=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],a="[\\.\\s\\n\\[\\:,]",l=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-variant-ligatures","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"],d=["\\{","\\}","\\?","(\\bReturn\\b)","(\\bEnd\\b)","(\\bend\\b)",";","#\\s","\\*\\s","===\\s","\\|"];return{aliases:["styl"],cI:!1,i:"("+d.join("|")+")",k:"if else for in",c:[t.QSM,t.ASM,t.CLCM,t.CBCM,o,{b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"class",b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"id",b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\b("+n.join("|")+")"+a,rB:!0,c:[{cN:"tag",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{cN:"pseudo",b:"&?:?:\\b("+r.join("|")+")"+a},{cN:"at_rule",b:"@("+i.join("|")+")\\b"},e,t.CSSNM,t.NM,{cN:"function",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)",i:"[\\n]",rB:!0,c:[{cN:"title",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{cN:"params",b:/\(/,e:/\)/,c:[o,e,t.ASM,t.CSSNM,t.NM,t.QSM]}]},{cN:"attribute",b:"\\b("+l.reverse().join("|")+")\\b"}]}});hljs.registerLanguage("gherkin",function(e){return{aliases:["feature"],k:"Feature Background Ability Business Need Scenario Scenarios Scenario Outline Scenario Template Examples Given And Then But When",c:[{cN:"keyword",b:"\\*"},{cN:"comment",b:"@[^@\r\n ]+",e:"$"},{cN:"string",b:"\\|",e:"\\$"},{cN:"variable",b:"<",e:">"},e.HCM,{cN:"string",b:'"""',e:'"""'},e.QSM]}});hljs.registerLanguage("scala",function(e){var t={cN:"annotation",b:"@[A-Za-z]+"},a={cN:"string",b:'u?r?"""',e:'"""',r:10},r={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},c={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},i={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},l={cN:"class",bK:"class object trait type",e:/[:={\[(\n;]/,c:[{cN:"keyword",bK:"extends with",r:10},i]},n={cN:"function",bK:"def val",e:/[:={\[(\n;]/,c:[i]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,a,e.QSM,r,c,n,l,e.CNM,t]}});hljs.registerLanguage("java",function(e){var a=e.UIR+"(<"+e.UIR+">)?",t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",c="(\\b(0b[01_]+)|\\b0[xX][a-fA-F0-9_]+|(\\b[\\d_]+(\\.[\\d_]*)?|\\.[\\d_]+)([eE][-+]?\\d+)?)[lLfF]?",r={cN:"number",b:c,r:0};return{aliases:["jsp"],k:t,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return",r:0},{cN:"function",b:"("+a+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},r,{cN:"annotation",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("lasso",function(e){var r="[a-zA-Z_][a-zA-Z0-9_.]*",a="<\\?(lasso(script)?|=)",t="\\]|\\?>",s={literal:"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft",built_in:"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome"},n={cN:"comment",b:"",r:0},o={cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:!0,c:[n]}},i={cN:"preprocessor",b:"\\[/noprocess|"+a},l={cN:"variable",b:"'"+r+"'"},c=[e.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/",c:[e.PWM]},e.CBCM,e.inherit(e.CNM,{b:e.CNR+"|(-?infinity|nan)\\b"}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",v:[{b:"[#$]"+r},{b:"#",e:"\\d+",i:"\\W"}]},{cN:"tag",b:"::\\s*",e:r,i:"\\W"},{cN:"attribute",v:[{b:"-"+e.UIR,r:0},{b:"(\\.\\.\\.)"}]},{cN:"subst",v:[{b:"->\\s*",c:[l]},{b:":=|/(?!\\w)=?|[-+*%=<>&|!?\\\\]+",r:0}]},{cN:"built_in",b:"\\.\\.?\\s*",r:0,c:[l]},{cN:"class",bK:"define",rE:!0,e:"\\(|=>",c:[e.inherit(e.TM,{b:e.UIR+"(=(?!>))?"})]}];return{aliases:["ls","lassoscript"],cI:!0,l:r+"|&[lg]t;",k:s,c:[{cN:"preprocessor",b:t,r:0,starts:{cN:"markup",e:"\\[|"+a,rE:!0,r:0,c:[n]}},o,i,{cN:"preprocessor",b:"\\[no_square_brackets",starts:{e:"\\[/no_square_brackets\\]",l:r+"|&[lg]t;",k:s,c:[{cN:"preprocessor",b:t,r:0,starts:{cN:"markup",e:"\\[noprocess\\]|"+a,rE:!0,c:[n]}},o,i].concat(c)}},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10}].concat(c)}});hljs.registerLanguage("objectivec",function(e){var t={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSData NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView NSView NSViewController NSWindow NSWindowController NSSet NSUUID NSIndexSet UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection NSURLSession NSURLSessionDataTask NSURLSessionDownloadTask NSURLSessionUploadTask NSURLResponseUIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},o=/[a-zA-Z@][a-zA-Z0-9_]*/,a="@interface @class @protocol @implementation";return{aliases:["m","mm","objc","obj-c"],k:t,l:o,i:""}]}]},{cN:"class",b:"("+a.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:a,l:o,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("smali",function(){var r=["add","and","cmp","cmpg","cmpl","const","div","double","float","goto","if","int","long","move","mul","neg","new","nop","not","or","rem","return","shl","shr","sput","sub","throw","ushr","xor"],t=["aget","aput","array","check","execute","fill","filled","goto/16","goto/32","iget","instance","invoke","iput","monitor","packed","sget","sparse"],n=["transient","constructor","abstract","final","synthetic","public","private","protected","static","bridge","system"];return{aliases:["smali"],c:[{cN:"string",b:'"',e:'"',r:0},{cN:"comment",b:"#",e:"$",r:0},{cN:"keyword",b:"\\s*\\.end\\s[a-zA-Z0-9]*",r:1},{cN:"keyword",b:"^[ ]*\\.[a-zA-Z]*",r:0},{cN:"keyword",b:"\\s:[a-zA-Z_0-9]*",r:0},{cN:"keyword",b:"\\s("+n.join("|")+")",r:1},{cN:"keyword",b:"\\[",r:0},{cN:"instruction",b:"\\s("+r.join("|")+")\\s",r:1},{cN:"instruction",b:"\\s("+r.join("|")+")((\\-|/)[a-zA-Z0-9]+)+\\s",r:10},{cN:"instruction",b:"\\s("+t.join("|")+")((\\-|/)[a-zA-Z0-9]+)*\\s",r:10},{cN:"class",b:"L[^(;:\n]*;",r:0},{cN:"function",b:'( |->)[^(\n ;"]*\\(',r:0},{cN:"function",b:"\\)",r:0},{cN:"variable",b:"[vp][0-9]+",r:0}]}});hljs.registerLanguage("nix",function(e){var t={keyword:"rec with let in inherit assert if else then",constant:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},i={cN:"subst",b:/\$\{/,e:/\}/,k:t},r={cN:"variable",b:/[a-zA-Z0-9-_]+(\s*=)/},n={cN:"string",b:"''",e:"''",c:[i]},s={cN:"string",b:'"',e:'"',c:[i]},a=[e.NM,e.HCM,e.CBCM,n,s,r];return i.c=a,{aliases:["nixos"],k:t,c:a}});hljs.registerLanguage("parser3",function(e){return{sL:"xml",r:0,c:[{cN:"comment",b:"^#",e:"$"},{cN:"comment",b:"\\^rem{",e:"}",r:10,c:[{b:"{",e:"}",c:["self"]}]},{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},e.CNM]}});hljs.registerLanguage("x86asm",function(s){return{cI:!0,l:"\\.?"+s.IR,k:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",literal:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l",pseudo:"db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times",preprocessor:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public ",built_in:"bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},c:[{cN:"comment",b:";",e:"$",r:0},{cN:"number",b:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",r:0},{cN:"number",b:"\\$[0-9][0-9A-Fa-f]*",r:0},{cN:"number",b:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[HhXx]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{cN:"number",b:"\\b(?:0[HhXx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"},s.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"[^\\\\]`",r:0},{cN:"string",b:"\\.[A-Za-z0-9]+",r:0},{cN:"label",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0},{cN:"label",b:"^\\s*%%[A-Za-z0-9_$#@~.?]*:",r:0},{cN:"argument",b:"%[0-9]+",r:0},{cN:"built_in",b:"%!S+",r:0}]}});hljs.registerLanguage("dos",function(e){var r={cN:"comment",b:/@?rem\b/,e:/$/,r:10},t={cN:"label",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0};return{aliases:["bat","cmd"],cI:!0,k:{flow:"if else goto for in do call exit not exist errorlevel defined",operator:"equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del",built_in:"append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol"},c:[{cN:"envvar",b:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{cN:"function",b:t.b,e:"goto:eof",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),r]},{cN:"number",b:"\\b\\d+",r:0},r]}});hljs.registerLanguage("brainfuck",function(){var r={cN:"literal",b:"[\\+\\-]",r:0};return{aliases:["bf"],c:[{cN:"comment",b:"[^\\[\\]\\.,\\+\\-<> \r\n]",rE:!0,e:"[\\[\\]\\.,\\+\\-<> \r\n]",r:0},{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]",r:0},{b:/\+\+|\-\-/,rB:!0,c:[r]},r]}});hljs.registerLanguage("lisp",function(e){var b="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*",c="\\|[^]*?\\|",r="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?",t={cN:"shebang",b:"^#!",e:"$"},a={cN:"literal",b:"\\b(t{1}|nil)\\b"},i={cN:"number",v:[{b:r,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"},{b:"#c\\("+r+" +"+r,e:"\\)"}]},l=e.inherit(e.QSM,{i:null}),n={cN:"comment",b:";",e:"$",r:0},N={cN:"variable",b:"\\*",e:"\\*"},d={cN:"keyword",b:"[:&]"+b},o={b:c},u={b:"\\(",e:"\\)",c:["self",a,l,i]},s={cN:"quoted",c:[i,l,N,d,u],v:[{b:"['`]\\(",e:"\\)"},{b:"\\(quote ",e:"\\)",k:"quote"},{b:"'"+c}]},f={cN:"quoted",b:"'"+b},v={cN:"list",b:"\\(",e:"\\)"},g={eW:!0,r:0};return v.c=[{cN:"keyword",v:[{b:b},{b:c}]},g],g.c=[s,f,v,a,i,l,n,N,d,o],{i:/\S/,c:[i,t,a,l,n,s,f,v]}});hljs.registerLanguage("d",function(e){var r={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},t="(0|[1-9][\\d_]*)",a="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",i="0[bB][01_]+",n="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",c="0[xX]"+n,_="([eE][+-]?"+a+")",d="("+a+"(\\.\\d*|"+_+")|\\d+\\."+a+a+"|\\."+t+_+"?)",o="(0[xX]("+n+"\\."+n+"|\\.?"+n+")[pP][+-]?"+a+")",s="("+t+"|"+i+"|"+c+")",l="("+o+"|"+d+")",u="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",b={cN:"number",b:"\\b"+s+"(L|u|U|Lu|LU|uL|UL)?",r:0},f={cN:"number",b:"\\b("+l+"([fF]|L|i|[fF]i|Li)?|"+s+"(i|[fF]i|Li))",r:0},g={cN:"string",b:"'("+u+"|.)",e:"'",i:"."},h={b:u,r:0},p={cN:"string",b:'"',c:[h],e:'"[cwd]?'},N={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5},m={cN:"string",b:"`",e:"`[cwd]?"},w={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10},A={cN:"string",b:'q"\\{',e:'\\}"'},F={cN:"shebang",b:"^#!",e:"$",r:5},y={cN:"preprocessor",b:"#(line)",e:"$",r:5},L={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"},v={cN:"comment",b:"\\/\\+",c:["self"],e:"\\+\\/",r:10};return{l:e.UIR,k:r,c:[e.CLCM,e.CBCM,v,w,p,N,m,A,f,b,g,F,y,L]}});hljs.registerLanguage("mel",function(e){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:">|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",c={cN:"yardoctag",b:"@[A-Za-z]+"},a={cN:"value",b:"#<",e:">"},s={cN:"comment",v:[{b:"#",e:"$",c:[c]},{b:"^\\=begin",e:"^\\=end",c:[c],r:10},{b:"^__END__",e:"\\n$"}]},n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},i={cN:"params",b:"\\(",e:"\\)",k:r},d=[t,a,s,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]},s]},{cN:"function",bK:"def",e:" |$|;",r:0,c:[e.inherit(e.TM,{b:b}),i,s]},{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,s,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];n.c=d,i.c=d;var l="[>?]>",u="[\\w#]+\\(\\w+\\):\\d+:\\d+>",N="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",o=[{b:/^\s*=>/,cN:"status",starts:{e:"$",c:d}},{cN:"prompt",b:"^("+l+"|"+u+"|"+N+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,c:[s].concat(o).concat(d)}});hljs.registerLanguage("roboconf",function(e){var n="[a-zA-Z-_][^\n{\r\n]+\\{";return{aliases:["graph","instances"],cI:!0,k:"import",c:[{cN:"facet",b:"^facet "+n,e:"}",k:"facet installer exports children extends",c:[e.HCM]},{cN:"instance-of",b:"^instance of "+n,e:"}",k:"name count channels instance-data instance-state instance of",c:[{cN:"keyword",b:"[a-zA-Z-_]+( | )*:"},e.HCM]},{cN:"component",b:"^"+n,e:"}",l:"\\(?[a-zA-Z]+\\)?",k:"installer exports children extends imports facets alias (optional)",c:[{cN:"string",b:"\\.[a-zA-Z-_]+",e:"\\s|,|;",eE:!0},e.HCM]},e.HCM]}});hljs.registerLanguage("erb",function(){return{sL:"xml",subLanguageMode:"continuous",c:[{cN:"comment",b:"<%#",e:"%>"},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0}]}});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage("dust",function(){var e="if eq ne lt lte gt gte select default math sep";return{aliases:["dst"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"expression",b:"{",e:"}",r:0,c:[{cN:"begin-block",b:"#[a-zA-Z- .]+",k:e},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z- .]+",k:e},{cN:"variable",b:"[a-zA-Z-.]+",k:e,r:0}]}]}});hljs.registerLanguage("markdown",function(){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link_url",e:"$"}}]}]}});hljs.registerLanguage("1c",function(c){var e="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*",r="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт",t="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон",i={cN:"dquote",b:'""'},n={cN:"string",b:'"',e:'"|$',c:[i]},a={cN:"string",b:"\\|",e:'"|$',c:[i]};return{cI:!0,l:e,k:{keyword:r,built_in:t},c:[c.CLCM,c.NM,n,a,{cN:"function",b:"(процедура|функция)",e:"$",l:e,k:"процедура функция",c:[c.inherit(c.TM,{b:e}),{cN:"tail",eW:!0,c:[{cN:"params",b:"\\(",e:"\\)",l:e,k:"знач",c:[n,a]},{cN:"export",b:"экспорт",eW:!0,l:e,k:"экспорт",c:[c.CLCM]}]},c.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}});hljs.registerLanguage("glsl",function(e){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[e.CLCM,e.CBCM,e.CNM,{cN:"preprocessor",b:"#",e:"$"}]}});hljs.registerLanguage("sml",function(e){return{aliases:["ml"],k:{keyword:"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while",built_in:"array bool char exn int list option order real ref string substring vector unit word",literal:"true false NONE SOME LESS EQUAL GREATER nil"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)"},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",e.PWM]},{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"tag",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"char",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("livecodeserver",function(e){var r={cN:"variable",b:"\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+",r:0},t={cN:"comment",e:"$",v:[e.CBCM,e.HCM,{b:"--"},{b:"[^:]//"}]},a=e.inherit(e.TM,{v:[{b:"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{b:"\\b_[a-z0-9\\-]+"}]}),o=e.inherit(e.TM,{b:"\\b([A-Za-z0-9_\\-]+)\\b"});return{cI:!1,k:{keyword:"after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if",constant:"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK",operator:"div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys",built_in:"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg base64Decode base64Encode baseConvert binaryDecode binaryEncode byteToNum cachedURL cachedURLs charToNum cipherNames commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames global globals hasMemory hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames num number numToByte numToChar offset open openfiles openProcesses openProcessIDs openSockets paramCount param params peerAddress pendingMessages platform processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_Execute revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sec secs seconds sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName tick ticks time to toLower toUpper transpose trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus value variableNames version waitDepth weekdayNames wordOffset add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket process post seek rel relative read from process rename replace require resetAll revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split subtract union unload wait write"},c:[r,{cN:"keyword",b:"\\bend\\sif\\b"},{cN:"function",bK:"function",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"function",bK:"end",e:"$",c:[o,a]},{cN:"command",bK:"command on",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"command",bK:"end",e:"$",c:[o,a]},{cN:"preprocessor",b:"<\\?rev|<\\?lc|<\\?livecode",r:10},{cN:"preprocessor",b:"<\\?"},{cN:"preprocessor",b:"\\?>"},t,e.ASM,e.QSM,e.BNM,e.CNM,a],i:";$|^\\[|^="}});hljs.registerLanguage("scheme",function(e){var t="[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+",r="(\\-|\\+)?\\d+([./]\\d+)?",i=r+"[+\\-]"+r+"i",a={built_in:"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"},n={cN:"shebang",b:"^#!",e:"$"},c={cN:"literal",b:"(#t|#f|#\\\\"+t+"|#\\\\.)"},l={cN:"number",v:[{b:r,r:0},{b:i,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"}]},s=e.QSM,o={cN:"comment",v:[{b:";",e:"$",r:0},{b:"#\\|",e:"\\|#"}]},u={b:t,r:0},p={cN:"variable",b:"'"+t},d={eW:!0,r:0},g={cN:"list",v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}],c:[{cN:"keyword",b:t,l:t,k:a},d]};return d.c=[c,l,s,o,u,p,g],{i:/\S/,c:[n,l,s,o,p,g]}});hljs.registerLanguage("monkey",function(e){var n={cN:"number",r:0,v:[{b:"[$][a-fA-F0-9]+"},e.NM]};return{cI:!0,k:{keyword:"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw",built_in:"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI",literal:"true false null and or shl shr mod"},c:[{cN:"comment",b:"#rem",e:"#end"},{cN:"comment",b:"'",e:"$",r:0},{cN:"function",bK:"function method",e:"[(=:]|$",i:/\n/,c:[e.UTM]},{cN:"class",bK:"class interface",e:"$",c:[{bK:"extends implements"},e.UTM]},{cN:"variable",b:"\\b(self|super)\\b"},{cN:"preprocessor",bK:"import",e:"$"},{cN:"preprocessor",b:"\\s*#",e:"$",k:"if else elseif endif end then"},{cN:"pi",b:"^\\s*strict\\b"},{bK:"alias",e:"=",c:[e.UTM]},e.QSM,n]}});hljs.registerLanguage("vbnet",function(e){return{aliases:["vb"],cI:!0,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"//|{|}|endif|gosub|variant|wend",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$",rB:!0,c:[{cN:"xmlDocTag",b:"'''|"},{cN:"xmlDocTag",b:""}]},e.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"}]}});hljs.registerLanguage("avrasm",function(r){return{cI:!0,l:"\\.?"+r.IR,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf",preprocessor:".byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list .listmac .macro .nolist .org .set"},c:[r.CBCM,{cN:"comment",b:";",e:"$",r:0},r.CNM,r.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},r.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"localvars",b:"@[0-9]+"}]}});hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})+",a=[],c=[],n=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},i=function(e,r,t){return{cN:e,b:r,r:t}},s=function(r,t,a){return e.inherit({cN:r,b:t+"\\(",e:"\\(",rB:!0,eE:!0,r:0},a)},b={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,n("'"),n('"'),e.CSSNM,i("hexcolor","#[0-9A-Fa-f]+\\b"),s("function","(url|data-uri)",{starts:{cN:"string",e:"[\\)\\n]",eE:!0}}),s("function",r),b,i("variable","@@?"+r,10),i("variable","@{"+r+"}"),i("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0});var o=c.concat({b:"{",e:"}",c:a}),u={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},C={cN:"attribute",b:t,e:":",eE:!0,c:[e.CLCM,e.CBCM],i:/\S/,starts:{e:"[;}]",rE:!0,c:c,i:"[<=$]"}},l={cN:"at_rule",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},d={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:o}},p={v:[{b:"[\\.#:&\\[]",e:"[;{}]"},{b:t+"[^;]*{",e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",c:[e.CLCM,e.CBCM,u,i("keyword","all\\b"),i("variable","@{"+r+"}"),i("tag",t+"%?",0),i("id","#"+t),i("class","\\."+t,0),i("keyword","&",0),s("pseudo",":not"),s("keyword",":extend"),i("pseudo","::?"+t),{cN:"attr_selector",b:"\\[",e:"\\]"},{b:"\\(",e:"\\)",c:o},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,l,d,p,C),{cI:!0,i:"[=>'/<($\"]",c:a}});hljs.registerLanguage("capnproto",function(t){return{aliases:["capnp"],k:{keyword:"struct enum interface union group import using const annotation extends in of on as with from fixed",built_in:"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List",literal:"true false"},c:[t.QSM,t.NM,t.HCM,{cN:"shebang",b:/@0x[\w\d]{16};/,i:/\n/},{cN:"number",b:/@\d+\b/},{cN:"class",bK:"struct enum",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]},{cN:"class",bK:"interface",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]}]}});hljs.registerLanguage("mathematica",function(e){return{aliases:["mma"],l:"(\\$|\\b)"+e.IR+"\\b",k:"AbelianGroup Abort AbortKernels AbortProtect Above Abs Absolute AbsoluteCorrelation AbsoluteCorrelationFunction AbsoluteCurrentValue AbsoluteDashing AbsoluteFileName AbsoluteOptions AbsolutePointSize AbsoluteThickness AbsoluteTime AbsoluteTiming AccountingForm Accumulate Accuracy AccuracyGoal ActionDelay ActionMenu ActionMenuBox ActionMenuBoxOptions Active ActiveItem ActiveStyle AcyclicGraphQ AddOnHelpPath AddTo AdjacencyGraph AdjacencyList AdjacencyMatrix AdjustmentBox AdjustmentBoxOptions AdjustTimeSeriesForecast AffineTransform After AiryAi AiryAiPrime AiryAiZero AiryBi AiryBiPrime AiryBiZero AlgebraicIntegerQ AlgebraicNumber AlgebraicNumberDenominator AlgebraicNumberNorm AlgebraicNumberPolynomial AlgebraicNumberTrace AlgebraicRules AlgebraicRulesData Algebraics AlgebraicUnitQ Alignment AlignmentMarker AlignmentPoint All AllowedDimensions AllowGroupClose AllowInlineCells AllowKernelInitialization AllowReverseGroupClose AllowScriptLevelChange AlphaChannel AlternatingGroup AlternativeHypothesis Alternatives AmbientLight Analytic AnchoredSearch And AndersonDarlingTest AngerJ AngleBracket AngularGauge Animate AnimationCycleOffset AnimationCycleRepetitions AnimationDirection AnimationDisplayTime AnimationRate AnimationRepetitions AnimationRunning Animator AnimatorBox AnimatorBoxOptions AnimatorElements Annotation Annuity AnnuityDue Antialiasing Antisymmetric Apart ApartSquareFree Appearance AppearanceElements AppellF1 Append AppendTo Apply ArcCos ArcCosh ArcCot ArcCoth ArcCsc ArcCsch ArcSec ArcSech ArcSin ArcSinDistribution ArcSinh ArcTan ArcTanh Arg ArgMax ArgMin ArgumentCountQ ARIMAProcess ArithmeticGeometricMean ARMAProcess ARProcess Array ArrayComponents ArrayDepth ArrayFlatten ArrayPad ArrayPlot ArrayQ ArrayReshape ArrayRules Arrays Arrow Arrow3DBox ArrowBox Arrowheads AspectRatio AspectRatioFixed Assert Assuming Assumptions AstronomicalData Asynchronous AsynchronousTaskObject AsynchronousTasks AtomQ Attributes AugmentedSymmetricPolynomial AutoAction AutoDelete AutoEvaluateEvents AutoGeneratedPackage AutoIndent AutoIndentSpacings AutoItalicWords AutoloadPath AutoMatch Automatic AutomaticImageSize AutoMultiplicationSymbol AutoNumberFormatting AutoOpenNotebooks AutoOpenPalettes AutorunSequencing AutoScaling AutoScroll AutoSpacing AutoStyleOptions AutoStyleWords Axes AxesEdge AxesLabel AxesOrigin AxesStyle Axis BabyMonsterGroupB Back Background BackgroundTasksSettings Backslash Backsubstitution Backward Band BandpassFilter BandstopFilter BarabasiAlbertGraphDistribution BarChart BarChart3D BarLegend BarlowProschanImportance BarnesG BarOrigin BarSpacing BartlettHannWindow BartlettWindow BaseForm Baseline BaselinePosition BaseStyle BatesDistribution BattleLemarieWavelet Because BeckmannDistribution Beep Before Begin BeginDialogPacket BeginFrontEndInteractionPacket BeginPackage BellB BellY Below BenfordDistribution BeniniDistribution BenktanderGibratDistribution BenktanderWeibullDistribution BernoulliB BernoulliDistribution BernoulliGraphDistribution BernoulliProcess BernsteinBasis BesselFilterModel BesselI BesselJ BesselJZero BesselK BesselY BesselYZero Beta BetaBinomialDistribution BetaDistribution BetaNegativeBinomialDistribution BetaPrimeDistribution BetaRegularized BetweennessCentrality BezierCurve BezierCurve3DBox BezierCurve3DBoxOptions BezierCurveBox BezierCurveBoxOptions BezierFunction BilateralFilter Binarize BinaryFormat BinaryImageQ BinaryRead BinaryReadList BinaryWrite BinCounts BinLists Binomial BinomialDistribution BinomialProcess BinormalDistribution BiorthogonalSplineWavelet BipartiteGraphQ BirnbaumImportance BirnbaumSaundersDistribution BitAnd BitClear BitGet BitLength BitNot BitOr BitSet BitShiftLeft BitShiftRight BitXor Black BlackmanHarrisWindow BlackmanNuttallWindow BlackmanWindow Blank BlankForm BlankNullSequence BlankSequence Blend Block BlockRandom BlomqvistBeta BlomqvistBetaTest Blue Blur BodePlot BohmanWindow Bold Bookmarks Boole BooleanConsecutiveFunction BooleanConvert BooleanCountingFunction BooleanFunction BooleanGraph BooleanMaxterms BooleanMinimize BooleanMinterms Booleans BooleanTable BooleanVariables BorderDimensions BorelTannerDistribution Bottom BottomHatTransform BoundaryStyle Bounds Box BoxBaselineShift BoxData BoxDimensions Boxed Boxes BoxForm BoxFormFormatTypes BoxFrame BoxID BoxMargins BoxMatrix BoxRatios BoxRotation BoxRotationPoint BoxStyle BoxWhiskerChart Bra BracketingBar BraKet BrayCurtisDistance BreadthFirstScan Break Brown BrownForsytheTest BrownianBridgeProcess BrowserCategory BSplineBasis BSplineCurve BSplineCurve3DBox BSplineCurveBox BSplineCurveBoxOptions BSplineFunction BSplineSurface BSplineSurface3DBox BubbleChart BubbleChart3D BubbleScale BubbleSizes BulletGauge BusinessDayQ ButterflyGraph ButterworthFilterModel Button ButtonBar ButtonBox ButtonBoxOptions ButtonCell ButtonContents ButtonData ButtonEvaluator ButtonExpandable ButtonFrame ButtonFunction ButtonMargins ButtonMinHeight ButtonNote ButtonNotebook ButtonSource ButtonStyle ButtonStyleMenuListing Byte ByteCount ByteOrdering C CachedValue CacheGraphics CalendarData CalendarType CallPacket CanberraDistance Cancel CancelButton CandlestickChart Cap CapForm CapitalDifferentialD CardinalBSplineBasis CarmichaelLambda Cases Cashflow Casoratian Catalan CatalanNumber Catch CauchyDistribution CauchyWindow CayleyGraph CDF CDFDeploy CDFInformation CDFWavelet Ceiling Cell CellAutoOverwrite CellBaseline CellBoundingBox CellBracketOptions CellChangeTimes CellContents CellContext CellDingbat CellDynamicExpression CellEditDuplicate CellElementsBoundingBox CellElementSpacings CellEpilog CellEvaluationDuplicate CellEvaluationFunction CellEventActions CellFrame CellFrameColor CellFrameLabelMargins CellFrameLabels CellFrameMargins CellGroup CellGroupData CellGrouping CellGroupingRules CellHorizontalScrolling CellID CellLabel CellLabelAutoDelete CellLabelMargins CellLabelPositioning CellMargins CellObject CellOpen CellPrint CellProlog Cells CellSize CellStyle CellTags CellularAutomaton CensoredDistribution Censoring Center CenterDot CentralMoment CentralMomentGeneratingFunction CForm ChampernowneNumber ChanVeseBinarize Character CharacterEncoding CharacterEncodingsPath CharacteristicFunction CharacteristicPolynomial CharacterRange Characters ChartBaseStyle ChartElementData ChartElementDataFunction ChartElementFunction ChartElements ChartLabels ChartLayout ChartLegends ChartStyle Chebyshev1FilterModel Chebyshev2FilterModel ChebyshevDistance ChebyshevT ChebyshevU Check CheckAbort CheckAll Checkbox CheckboxBar CheckboxBox CheckboxBoxOptions ChemicalData ChessboardDistance ChiDistribution ChineseRemainder ChiSquareDistribution ChoiceButtons ChoiceDialog CholeskyDecomposition Chop Circle CircleBox CircleDot CircleMinus CirclePlus CircleTimes CirculantGraph CityData Clear ClearAll ClearAttributes ClearSystemCache ClebschGordan ClickPane Clip ClipboardNotebook ClipFill ClippingStyle ClipPlanes ClipRange Clock ClockGauge ClockwiseContourIntegral Close Closed CloseKernels ClosenessCentrality Closing ClosingAutoSave ClosingEvent ClusteringComponents CMYKColor Coarse Coefficient CoefficientArrays CoefficientDomain CoefficientList CoefficientRules CoifletWavelet Collect Colon ColonForm ColorCombine ColorConvert ColorData ColorDataFunction ColorFunction ColorFunctionScaling Colorize ColorNegate ColorOutput ColorProfileData ColorQuantize ColorReplace ColorRules ColorSelectorSettings ColorSeparate ColorSetter ColorSetterBox ColorSetterBoxOptions ColorSlider ColorSpace Column ColumnAlignments ColumnBackgrounds ColumnForm ColumnLines ColumnsEqual ColumnSpacings ColumnWidths CommonDefaultFormatTypes Commonest CommonestFilter CommonUnits CommunityBoundaryStyle CommunityGraphPlot CommunityLabels CommunityRegionStyle CompatibleUnitQ CompilationOptions CompilationTarget Compile Compiled CompiledFunction Complement CompleteGraph CompleteGraphQ CompleteKaryTree CompletionsListPacket Complex Complexes ComplexExpand ComplexInfinity ComplexityFunction ComponentMeasurements ComponentwiseContextMenu Compose ComposeList ComposeSeries Composition CompoundExpression CompoundPoissonDistribution CompoundPoissonProcess CompoundRenewalProcess Compress CompressedData Condition ConditionalExpression Conditioned Cone ConeBox ConfidenceLevel ConfidenceRange ConfidenceTransform ConfigurationPath Congruent Conjugate ConjugateTranspose Conjunction Connect ConnectedComponents ConnectedGraphQ ConnesWindow ConoverTest ConsoleMessage ConsoleMessagePacket ConsolePrint Constant ConstantArray Constants ConstrainedMax ConstrainedMin ContentPadding ContentsBoundingBox ContentSelectable ContentSize Context ContextMenu Contexts ContextToFilename ContextToFileName Continuation Continue ContinuedFraction ContinuedFractionK ContinuousAction ContinuousMarkovProcess ContinuousTimeModelQ ContinuousWaveletData ContinuousWaveletTransform ContourDetect ContourGraphics ContourIntegral ContourLabels ContourLines ContourPlot ContourPlot3D Contours ContourShading ContourSmoothing ContourStyle ContraharmonicMean Control ControlActive ControlAlignment ControllabilityGramian ControllabilityMatrix ControllableDecomposition ControllableModelQ ControllerDuration ControllerInformation ControllerInformationData ControllerLinking ControllerManipulate ControllerMethod ControllerPath ControllerState ControlPlacement ControlsRendering ControlType Convergents ConversionOptions ConversionRules ConvertToBitmapPacket ConvertToPostScript ConvertToPostScriptPacket Convolve ConwayGroupCo1 ConwayGroupCo2 ConwayGroupCo3 CoordinateChartData CoordinatesToolOptions CoordinateTransform CoordinateTransformData CoprimeQ Coproduct CopulaDistribution Copyable CopyDirectory CopyFile CopyTag CopyToClipboard CornerFilter CornerNeighbors Correlation CorrelationDistance CorrelationFunction CorrelationTest Cos Cosh CoshIntegral CosineDistance CosineWindow CosIntegral Cot Coth Count CounterAssignments CounterBox CounterBoxOptions CounterClockwiseContourIntegral CounterEvaluator CounterFunction CounterIncrements CounterStyle CounterStyleMenuListing CountRoots CountryData Covariance CovarianceEstimatorFunction CovarianceFunction CoxianDistribution CoxIngersollRossProcess CoxModel CoxModelFit CramerVonMisesTest CreateArchive CreateDialog CreateDirectory CreateDocument CreateIntermediateDirectories CreatePalette CreatePalettePacket CreateScheduledTask CreateTemporary CreateWindow CriticalityFailureImportance CriticalitySuccessImportance CriticalSection Cross CrossingDetect CrossMatrix Csc Csch CubeRoot Cubics Cuboid CuboidBox Cumulant CumulantGeneratingFunction Cup CupCap Curl CurlyDoubleQuote CurlyQuote CurrentImage CurrentlySpeakingPacket CurrentValue CurvatureFlowFilter CurveClosed Cyan CycleGraph CycleIndexPolynomial Cycles CyclicGroup Cyclotomic Cylinder CylinderBox CylindricalDecomposition D DagumDistribution DamerauLevenshteinDistance DampingFactor Darker Dashed Dashing DataCompression DataDistribution DataRange DataReversed Date DateDelimiters DateDifference DateFunction DateList DateListLogPlot DateListPlot DatePattern DatePlus DateRange DateString DateTicksFormat DaubechiesWavelet DavisDistribution DawsonF DayCount DayCountConvention DayMatchQ DayName DayPlus DayRange DayRound DeBruijnGraph Debug DebugTag Decimal DeclareKnownSymbols DeclarePackage Decompose Decrement DedekindEta Default DefaultAxesStyle DefaultBaseStyle DefaultBoxStyle DefaultButton DefaultColor DefaultControlPlacement DefaultDuplicateCellStyle DefaultDuration DefaultElement DefaultFaceGridsStyle DefaultFieldHintStyle DefaultFont DefaultFontProperties DefaultFormatType DefaultFormatTypeForStyle DefaultFrameStyle DefaultFrameTicksStyle DefaultGridLinesStyle DefaultInlineFormatType DefaultInputFormatType DefaultLabelStyle DefaultMenuStyle DefaultNaturalLanguage DefaultNewCellStyle DefaultNewInlineCellStyle DefaultNotebook DefaultOptions DefaultOutputFormatType DefaultStyle DefaultStyleDefinitions DefaultTextFormatType DefaultTextInlineFormatType DefaultTicksStyle DefaultTooltipStyle DefaultValues Defer DefineExternal DefineInputStreamMethod DefineOutputStreamMethod Definition Degree DegreeCentrality DegreeGraphDistribution DegreeLexicographic DegreeReverseLexicographic Deinitialization Del Deletable Delete DeleteBorderComponents DeleteCases DeleteContents DeleteDirectory DeleteDuplicates DeleteFile DeleteSmallComponents DeleteWithContents DeletionWarning Delimiter DelimiterFlashTime DelimiterMatching Delimiters Denominator DensityGraphics DensityHistogram DensityPlot DependentVariables Deploy Deployed Depth DepthFirstScan Derivative DerivativeFilter DescriptorStateSpace DesignMatrix Det DGaussianWavelet DiacriticalPositioning Diagonal DiagonalMatrix Dialog DialogIndent DialogInput DialogLevel DialogNotebook DialogProlog DialogReturn DialogSymbols Diamond DiamondMatrix DiceDissimilarity DictionaryLookup DifferenceDelta DifferenceOrder DifferenceRoot DifferenceRootReduce Differences DifferentialD DifferentialRoot DifferentialRootReduce DifferentiatorFilter DigitBlock DigitBlockMinimum DigitCharacter DigitCount DigitQ DihedralGroup Dilation Dimensions DiracComb DiracDelta DirectedEdge DirectedEdges DirectedGraph DirectedGraphQ DirectedInfinity Direction Directive Directory DirectoryName DirectoryQ DirectoryStack DirichletCharacter DirichletConvolve DirichletDistribution DirichletL DirichletTransform DirichletWindow DisableConsolePrintPacket DiscreteChirpZTransform DiscreteConvolve DiscreteDelta DiscreteHadamardTransform DiscreteIndicator DiscreteLQEstimatorGains DiscreteLQRegulatorGains DiscreteLyapunovSolve DiscreteMarkovProcess DiscretePlot DiscretePlot3D DiscreteRatio DiscreteRiccatiSolve DiscreteShift DiscreteTimeModelQ DiscreteUniformDistribution DiscreteVariables DiscreteWaveletData DiscreteWaveletPacketTransform DiscreteWaveletTransform Discriminant Disjunction Disk DiskBox DiskMatrix Dispatch DispersionEstimatorFunction Display DisplayAllSteps DisplayEndPacket DisplayFlushImagePacket DisplayForm DisplayFunction DisplayPacket DisplayRules DisplaySetSizePacket DisplayString DisplayTemporary DisplayWith DisplayWithRef DisplayWithVariable DistanceFunction DistanceTransform Distribute Distributed DistributedContexts DistributeDefinitions DistributionChart DistributionDomain DistributionFitTest DistributionParameterAssumptions DistributionParameterQ Dithering Div Divergence Divide DivideBy Dividers Divisible Divisors DivisorSigma DivisorSum DMSList DMSString Do DockedCells DocumentNotebook DominantColors DOSTextFormat Dot DotDashed DotEqual Dotted DoubleBracketingBar DoubleContourIntegral DoubleDownArrow DoubleLeftArrow DoubleLeftRightArrow DoubleLeftTee DoubleLongLeftArrow DoubleLongLeftRightArrow DoubleLongRightArrow DoubleRightArrow DoubleRightTee DoubleUpArrow DoubleUpDownArrow DoubleVerticalBar DoublyInfinite Down DownArrow DownArrowBar DownArrowUpArrow DownLeftRightVector DownLeftTeeVector DownLeftVector DownLeftVectorBar DownRightTeeVector DownRightVector DownRightVectorBar Downsample DownTee DownTeeArrow DownValues DragAndDrop DrawEdges DrawFrontFaces DrawHighlighted Drop DSolve Dt DualLinearProgramming DualSystemsModel DumpGet DumpSave DuplicateFreeQ Dynamic DynamicBox DynamicBoxOptions DynamicEvaluationTimeout DynamicLocation DynamicModule DynamicModuleBox DynamicModuleBoxOptions DynamicModuleParent DynamicModuleValues DynamicName DynamicNamespace DynamicReference DynamicSetting DynamicUpdating DynamicWrapper DynamicWrapperBox DynamicWrapperBoxOptions E EccentricityCentrality EdgeAdd EdgeBetweennessCentrality EdgeCapacity EdgeCapForm EdgeColor EdgeConnectivity EdgeCost EdgeCount EdgeCoverQ EdgeDashing EdgeDelete EdgeDetect EdgeForm EdgeIndex EdgeJoinForm EdgeLabeling EdgeLabels EdgeLabelStyle EdgeList EdgeOpacity EdgeQ EdgeRenderingFunction EdgeRules EdgeShapeFunction EdgeStyle EdgeThickness EdgeWeight Editable EditButtonSettings EditCellTagsSettings EditDistance EffectiveInterest Eigensystem Eigenvalues EigenvectorCentrality Eigenvectors Element ElementData Eliminate EliminationOrder EllipticE EllipticExp EllipticExpPrime EllipticF EllipticFilterModel EllipticK EllipticLog EllipticNomeQ EllipticPi EllipticReducedHalfPeriods EllipticTheta EllipticThetaPrime EmitSound EmphasizeSyntaxErrors EmpiricalDistribution Empty EmptyGraphQ EnableConsolePrintPacket Enabled Encode End EndAdd EndDialogPacket EndFrontEndInteractionPacket EndOfFile EndOfLine EndOfString EndPackage EngineeringForm Enter EnterExpressionPacket EnterTextPacket Entropy EntropyFilter Environment Epilog Equal EqualColumns EqualRows EqualTilde EquatedTo Equilibrium EquirippleFilterKernel Equivalent Erf Erfc Erfi ErlangB ErlangC ErlangDistribution Erosion ErrorBox ErrorBoxOptions ErrorNorm ErrorPacket ErrorsDialogSettings EstimatedDistribution EstimatedProcess EstimatorGains EstimatorRegulator EuclideanDistance EulerE EulerGamma EulerianGraphQ EulerPhi Evaluatable Evaluate Evaluated EvaluatePacket EvaluationCell EvaluationCompletionAction EvaluationElements EvaluationMode EvaluationMonitor EvaluationNotebook EvaluationObject EvaluationOrder Evaluator EvaluatorNames EvenQ EventData EventEvaluator EventHandler EventHandlerTag EventLabels ExactBlackmanWindow ExactNumberQ ExactRootIsolation ExampleData Except ExcludedForms ExcludePods Exclusions ExclusionsStyle Exists Exit ExitDialog Exp Expand ExpandAll ExpandDenominator ExpandFileName ExpandNumerator Expectation ExpectationE ExpectedValue ExpGammaDistribution ExpIntegralE ExpIntegralEi Exponent ExponentFunction ExponentialDistribution ExponentialFamily ExponentialGeneratingFunction ExponentialMovingAverage ExponentialPowerDistribution ExponentPosition ExponentStep Export ExportAutoReplacements ExportPacket ExportString Expression ExpressionCell ExpressionPacket ExpToTrig ExtendedGCD Extension ExtentElementFunction ExtentMarkers ExtentSize ExternalCall ExternalDataCharacterEncoding Extract ExtractArchive ExtremeValueDistribution FaceForm FaceGrids FaceGridsStyle Factor FactorComplete Factorial Factorial2 FactorialMoment FactorialMomentGeneratingFunction FactorialPower FactorInteger FactorList FactorSquareFree FactorSquareFreeList FactorTerms FactorTermsList Fail FailureDistribution False FARIMAProcess FEDisableConsolePrintPacket FeedbackSector FeedbackSectorStyle FeedbackType FEEnableConsolePrintPacket Fibonacci FieldHint FieldHintStyle FieldMasked FieldSize File FileBaseName FileByteCount FileDate FileExistsQ FileExtension FileFormat FileHash FileInformation FileName FileNameDepth FileNameDialogSettings FileNameDrop FileNameJoin FileNames FileNameSetter FileNameSplit FileNameTake FilePrint FileType FilledCurve FilledCurveBox Filling FillingStyle FillingTransform FilterRules FinancialBond FinancialData FinancialDerivative FinancialIndicator Find FindArgMax FindArgMin FindClique FindClusters FindCurvePath FindDistributionParameters FindDivisions FindEdgeCover FindEdgeCut FindEulerianCycle FindFaces FindFile FindFit FindGeneratingFunction FindGeoLocation FindGeometricTransform FindGraphCommunities FindGraphIsomorphism FindGraphPartition FindHamiltonianCycle FindIndependentEdgeSet FindIndependentVertexSet FindInstance FindIntegerNullVector FindKClan FindKClique FindKClub FindKPlex FindLibrary FindLinearRecurrence FindList FindMaximum FindMaximumFlow FindMaxValue FindMinimum FindMinimumCostFlow FindMinimumCut FindMinValue FindPermutation FindPostmanTour FindProcessParameters FindRoot FindSequenceFunction FindSettings FindShortestPath FindShortestTour FindThreshold FindVertexCover FindVertexCut Fine FinishDynamic FiniteAbelianGroupCount FiniteGroupCount FiniteGroupData First FirstPassageTimeDistribution FischerGroupFi22 FischerGroupFi23 FischerGroupFi24Prime FisherHypergeometricDistribution FisherRatioTest FisherZDistribution Fit FitAll FittedModel FixedPoint FixedPointList FlashSelection Flat Flatten FlattenAt FlatTopWindow FlipView Floor FlushPrintOutputPacket Fold FoldList Font FontColor FontFamily FontForm FontName FontOpacity FontPostScriptName FontProperties FontReencoding FontSize FontSlant FontSubstitutions FontTracking FontVariations FontWeight For ForAll Format FormatRules FormatType FormatTypeAutoConvert FormatValues FormBox FormBoxOptions FortranForm Forward ForwardBackward Fourier FourierCoefficient FourierCosCoefficient FourierCosSeries FourierCosTransform FourierDCT FourierDCTFilter FourierDCTMatrix FourierDST FourierDSTMatrix FourierMatrix FourierParameters FourierSequenceTransform FourierSeries FourierSinCoefficient FourierSinSeries FourierSinTransform FourierTransform FourierTrigSeries FractionalBrownianMotionProcess FractionalPart FractionBox FractionBoxOptions FractionLine Frame FrameBox FrameBoxOptions Framed FrameInset FrameLabel Frameless FrameMargins FrameStyle FrameTicks FrameTicksStyle FRatioDistribution FrechetDistribution FreeQ FrequencySamplingFilterKernel FresnelC FresnelS Friday FrobeniusNumber FrobeniusSolve FromCharacterCode FromCoefficientRules FromContinuedFraction FromDate FromDigits FromDMS Front FrontEndDynamicExpression FrontEndEventActions FrontEndExecute FrontEndObject FrontEndResource FrontEndResourceString FrontEndStackSize FrontEndToken FrontEndTokenExecute FrontEndValueCache FrontEndVersion FrontFaceColor FrontFaceOpacity Full FullAxes FullDefinition FullForm FullGraphics FullOptions FullSimplify Function FunctionExpand FunctionInterpolation FunctionSpace FussellVeselyImportance GaborFilter GaborMatrix GaborWavelet GainMargins GainPhaseMargins Gamma GammaDistribution GammaRegularized GapPenalty Gather GatherBy GaugeFaceElementFunction GaugeFaceStyle GaugeFrameElementFunction GaugeFrameSize GaugeFrameStyle GaugeLabels GaugeMarkers GaugeStyle GaussianFilter GaussianIntegers GaussianMatrix GaussianWindow GCD GegenbauerC General GeneralizedLinearModelFit GenerateConditions GeneratedCell GeneratedParameters GeneratingFunction Generic GenericCylindricalDecomposition GenomeData GenomeLookup GeodesicClosing GeodesicDilation GeodesicErosion GeodesicOpening GeoDestination GeodesyData GeoDirection GeoDistance GeoGridPosition GeometricBrownianMotionProcess GeometricDistribution GeometricMean GeometricMeanFilter GeometricTransformation GeometricTransformation3DBox GeometricTransformation3DBoxOptions GeometricTransformationBox GeometricTransformationBoxOptions GeoPosition GeoPositionENU GeoPositionXYZ GeoProjectionData GestureHandler GestureHandlerTag Get GetBoundingBoxSizePacket GetContext GetEnvironment GetFileName GetFrontEndOptionsDataPacket GetLinebreakInformationPacket GetMenusPacket GetPageBreakInformationPacket Glaisher GlobalClusteringCoefficient GlobalPreferences GlobalSession Glow GoldenRatio GompertzMakehamDistribution GoodmanKruskalGamma GoodmanKruskalGammaTest Goto Grad Gradient GradientFilter GradientOrientationFilter Graph GraphAssortativity GraphCenter GraphComplement GraphData GraphDensity GraphDiameter GraphDifference GraphDisjointUnion GraphDistance GraphDistanceMatrix GraphElementData GraphEmbedding GraphHighlight GraphHighlightStyle GraphHub Graphics Graphics3D Graphics3DBox Graphics3DBoxOptions GraphicsArray GraphicsBaseline GraphicsBox GraphicsBoxOptions GraphicsColor GraphicsColumn GraphicsComplex GraphicsComplex3DBox GraphicsComplex3DBoxOptions GraphicsComplexBox GraphicsComplexBoxOptions GraphicsContents GraphicsData GraphicsGrid GraphicsGridBox GraphicsGroup GraphicsGroup3DBox GraphicsGroup3DBoxOptions GraphicsGroupBox GraphicsGroupBoxOptions GraphicsGrouping GraphicsHighlightColor GraphicsRow GraphicsSpacing GraphicsStyle GraphIntersection GraphLayout GraphLinkEfficiency GraphPeriphery GraphPlot GraphPlot3D GraphPower GraphPropertyDistribution GraphQ GraphRadius GraphReciprocity GraphRoot GraphStyle GraphUnion Gray GrayLevel GreatCircleDistance Greater GreaterEqual GreaterEqualLess GreaterFullEqual GreaterGreater GreaterLess GreaterSlantEqual GreaterTilde Green Grid GridBaseline GridBox GridBoxAlignment GridBoxBackground GridBoxDividers GridBoxFrame GridBoxItemSize GridBoxItemStyle GridBoxOptions GridBoxSpacings GridCreationSettings GridDefaultElement GridElementStyleOptions GridFrame GridFrameMargins GridGraph GridLines GridLinesStyle GroebnerBasis GroupActionBase GroupCentralizer GroupElementFromWord GroupElementPosition GroupElementQ GroupElements GroupElementToWord GroupGenerators GroupMultiplicationTable GroupOrbits GroupOrder GroupPageBreakWithin GroupSetwiseStabilizer GroupStabilizer GroupStabilizerChain Gudermannian GumbelDistribution HaarWavelet HadamardMatrix HalfNormalDistribution HamiltonianGraphQ HammingDistance HammingWindow HankelH1 HankelH2 HankelMatrix HannPoissonWindow HannWindow HaradaNortonGroupHN HararyGraph HarmonicMean HarmonicMeanFilter HarmonicNumber Hash HashTable Haversine HazardFunction Head HeadCompose Heads HeavisideLambda HeavisidePi HeavisideTheta HeldGroupHe HeldPart HelpBrowserLookup HelpBrowserNotebook HelpBrowserSettings HermiteDecomposition HermiteH HermitianMatrixQ HessenbergDecomposition Hessian HexadecimalCharacter Hexahedron HexahedronBox HexahedronBoxOptions HiddenSurface HighlightGraph HighlightImage HighpassFilter HigmanSimsGroupHS HilbertFilter HilbertMatrix Histogram Histogram3D HistogramDistribution HistogramList HistogramTransform HistogramTransformInterpolation HitMissTransform HITSCentrality HodgeDual HoeffdingD HoeffdingDTest Hold HoldAll HoldAllComplete HoldComplete HoldFirst HoldForm HoldPattern HoldRest HolidayCalendar HomeDirectory HomePage Horizontal HorizontalForm HorizontalGauge HorizontalScrollPosition HornerForm HotellingTSquareDistribution HoytDistribution HTMLSave Hue HumpDownHump HumpEqual HurwitzLerchPhi HurwitzZeta HyperbolicDistribution HypercubeGraph HyperexponentialDistribution Hyperfactorial Hypergeometric0F1 Hypergeometric0F1Regularized Hypergeometric1F1 Hypergeometric1F1Regularized Hypergeometric2F1 Hypergeometric2F1Regularized HypergeometricDistribution HypergeometricPFQ HypergeometricPFQRegularized HypergeometricU Hyperlink HyperlinkCreationSettings Hyphenation HyphenationOptions HypoexponentialDistribution HypothesisTestData I Identity IdentityMatrix If IgnoreCase Im Image Image3D Image3DSlices ImageAccumulate ImageAdd ImageAdjust ImageAlign ImageApply ImageAspectRatio ImageAssemble ImageCache ImageCacheValid ImageCapture ImageChannels ImageClip ImageColorSpace ImageCompose ImageConvolve ImageCooccurrence ImageCorners ImageCorrelate ImageCorrespondingPoints ImageCrop ImageData ImageDataPacket ImageDeconvolve ImageDemosaic ImageDifference ImageDimensions ImageDistance ImageEffect ImageFeatureTrack ImageFileApply ImageFileFilter ImageFileScan ImageFilter ImageForestingComponents ImageForwardTransformation ImageHistogram ImageKeypoints ImageLevels ImageLines ImageMargins ImageMarkers ImageMeasurements ImageMultiply ImageOffset ImagePad ImagePadding ImagePartition ImagePeriodogram ImagePerspectiveTransformation ImageQ ImageRangeCache ImageReflect ImageRegion ImageResize ImageResolution ImageRotate ImageRotated ImageScaled ImageScan ImageSize ImageSizeAction ImageSizeCache ImageSizeMultipliers ImageSizeRaw ImageSubtract ImageTake ImageTransformation ImageTrim ImageType ImageValue ImageValuePositions Implies Import ImportAutoReplacements ImportString ImprovementImportance In IncidenceGraph IncidenceList IncidenceMatrix IncludeConstantBasis IncludeFileExtension IncludePods IncludeSingularTerm Increment Indent IndentingNewlineSpacings IndentMaxFraction IndependenceTest IndependentEdgeSetQ IndependentUnit IndependentVertexSetQ Indeterminate IndexCreationOptions Indexed IndexGraph IndexTag Inequality InexactNumberQ InexactNumbers Infinity Infix Information Inherited InheritScope Initialization InitializationCell InitializationCellEvaluation InitializationCellWarning InlineCounterAssignments InlineCounterIncrements InlineRules Inner Inpaint Input InputAliases InputAssumptions InputAutoReplacements InputField InputFieldBox InputFieldBoxOptions InputForm InputGrouping InputNamePacket InputNotebook InputPacket InputSettings InputStream InputString InputStringPacket InputToBoxFormPacket Insert InsertionPointObject InsertResults Inset Inset3DBox Inset3DBoxOptions InsetBox InsetBoxOptions Install InstallService InString Integer IntegerDigits IntegerExponent IntegerLength IntegerPart IntegerPartitions IntegerQ Integers IntegerString Integral Integrate Interactive InteractiveTradingChart Interlaced Interleaving InternallyBalancedDecomposition InterpolatingFunction InterpolatingPolynomial Interpolation InterpolationOrder InterpolationPoints InterpolationPrecision Interpretation InterpretationBox InterpretationBoxOptions InterpretationFunction InterpretTemplate InterquartileRange Interrupt InterruptSettings Intersection Interval IntervalIntersection IntervalMemberQ IntervalUnion Inverse InverseBetaRegularized InverseCDF InverseChiSquareDistribution InverseContinuousWaveletTransform InverseDistanceTransform InverseEllipticNomeQ InverseErf InverseErfc InverseFourier InverseFourierCosTransform InverseFourierSequenceTransform InverseFourierSinTransform InverseFourierTransform InverseFunction InverseFunctions InverseGammaDistribution InverseGammaRegularized InverseGaussianDistribution InverseGudermannian InverseHaversine InverseJacobiCD InverseJacobiCN InverseJacobiCS InverseJacobiDC InverseJacobiDN InverseJacobiDS InverseJacobiNC InverseJacobiND InverseJacobiNS InverseJacobiSC InverseJacobiSD InverseJacobiSN InverseLaplaceTransform InversePermutation InverseRadon InverseSeries InverseSurvivalFunction InverseWaveletTransform InverseWeierstrassP InverseZTransform Invisible InvisibleApplication InvisibleTimes IrreduciblePolynomialQ IsolatingInterval IsomorphicGraphQ IsotopeData Italic Item ItemBox ItemBoxOptions ItemSize ItemStyle ItoProcess JaccardDissimilarity JacobiAmplitude Jacobian JacobiCD JacobiCN JacobiCS JacobiDC JacobiDN JacobiDS JacobiNC JacobiND JacobiNS JacobiP JacobiSC JacobiSD JacobiSN JacobiSymbol JacobiZeta JankoGroupJ1 JankoGroupJ2 JankoGroupJ3 JankoGroupJ4 JarqueBeraALMTest JohnsonDistribution Join Joined JoinedCurve JoinedCurveBox JoinForm JordanDecomposition JordanModelDecomposition K KagiChart KaiserBesselWindow KaiserWindow KalmanEstimator KalmanFilter KarhunenLoeveDecomposition KaryTree KatzCentrality KCoreComponents KDistribution KelvinBei KelvinBer KelvinKei KelvinKer KendallTau KendallTauTest KernelExecute KernelMixtureDistribution KernelObject Kernels Ket Khinchin KirchhoffGraph KirchhoffMatrix KleinInvariantJ KnightTourGraph KnotData KnownUnitQ KolmogorovSmirnovTest KroneckerDelta KroneckerModelDecomposition KroneckerProduct KroneckerSymbol KuiperTest KumaraswamyDistribution Kurtosis KuwaharaFilter Label Labeled LabeledSlider LabelingFunction LabelStyle LaguerreL LambdaComponents LambertW LanczosWindow LandauDistribution Language LanguageCategory LaplaceDistribution LaplaceTransform Laplacian LaplacianFilter LaplacianGaussianFilter Large Larger Last Latitude LatitudeLongitude LatticeData LatticeReduce Launch LaunchKernels LayeredGraphPlot LayerSizeFunction LayoutInformation LCM LeafCount LeapYearQ LeastSquares LeastSquaresFilterKernel Left LeftArrow LeftArrowBar LeftArrowRightArrow LeftDownTeeVector LeftDownVector LeftDownVectorBar LeftRightArrow LeftRightVector LeftTee LeftTeeArrow LeftTeeVector LeftTriangle LeftTriangleBar LeftTriangleEqual LeftUpDownVector LeftUpTeeVector LeftUpVector LeftUpVectorBar LeftVector LeftVectorBar LegendAppearance Legended LegendFunction LegendLabel LegendLayout LegendMargins LegendMarkers LegendMarkerSize LegendreP LegendreQ LegendreType Length LengthWhile LerchPhi Less LessEqual LessEqualGreater LessFullEqual LessGreater LessLess LessSlantEqual LessTilde LetterCharacter LetterQ Level LeveneTest LeviCivitaTensor LevyDistribution Lexicographic LibraryFunction LibraryFunctionError LibraryFunctionInformation LibraryFunctionLoad LibraryFunctionUnload LibraryLoad LibraryUnload LicenseID LiftingFilterData LiftingWaveletTransform LightBlue LightBrown LightCyan Lighter LightGray LightGreen Lighting LightingAngle LightMagenta LightOrange LightPink LightPurple LightRed LightSources LightYellow Likelihood Limit LimitsPositioning LimitsPositioningTokens LindleyDistribution Line Line3DBox LinearFilter LinearFractionalTransform LinearModelFit LinearOffsetFunction LinearProgramming LinearRecurrence LinearSolve LinearSolveFunction LineBox LineBreak LinebreakAdjustments LineBreakChart LineBreakWithin LineColor LineForm LineGraph LineIndent LineIndentMaxFraction LineIntegralConvolutionPlot LineIntegralConvolutionScale LineLegend LineOpacity LineSpacing LineWrapParts LinkActivate LinkClose LinkConnect LinkConnectedQ LinkCreate LinkError LinkFlush LinkFunction LinkHost LinkInterrupt LinkLaunch LinkMode LinkObject LinkOpen LinkOptions LinkPatterns LinkProtocol LinkRead LinkReadHeld LinkReadyQ Links LinkWrite LinkWriteHeld LiouvilleLambda List Listable ListAnimate ListContourPlot ListContourPlot3D ListConvolve ListCorrelate ListCurvePathPlot ListDeconvolve ListDensityPlot Listen ListFourierSequenceTransform ListInterpolation ListLineIntegralConvolutionPlot ListLinePlot ListLogLinearPlot ListLogLogPlot ListLogPlot ListPicker ListPickerBox ListPickerBoxBackground ListPickerBoxOptions ListPlay ListPlot ListPlot3D ListPointPlot3D ListPolarPlot ListQ ListStreamDensityPlot ListStreamPlot ListSurfacePlot3D ListVectorDensityPlot ListVectorPlot ListVectorPlot3D ListZTransform Literal LiteralSearch LocalClusteringCoefficient LocalizeVariables LocationEquivalenceTest LocationTest Locator LocatorAutoCreate LocatorBox LocatorBoxOptions LocatorCentering LocatorPane LocatorPaneBox LocatorPaneBoxOptions LocatorRegion Locked Log Log10 Log2 LogBarnesG LogGamma LogGammaDistribution LogicalExpand LogIntegral LogisticDistribution LogitModelFit LogLikelihood LogLinearPlot LogLogisticDistribution LogLogPlot LogMultinormalDistribution LogNormalDistribution LogPlot LogRankTest LogSeriesDistribution LongEqual Longest LongestAscendingSequence LongestCommonSequence LongestCommonSequencePositions LongestCommonSubsequence LongestCommonSubsequencePositions LongestMatch LongForm Longitude LongLeftArrow LongLeftRightArrow LongRightArrow Loopback LoopFreeGraphQ LowerCaseQ LowerLeftArrow LowerRightArrow LowerTriangularize LowpassFilter LQEstimatorGains LQGRegulator LQOutputRegulatorGains LQRegulatorGains LUBackSubstitution LucasL LuccioSamiComponents LUDecomposition LyapunovSolve LyonsGroupLy MachineID MachineName MachineNumberQ MachinePrecision MacintoshSystemPageSetup Magenta Magnification Magnify MainSolve MaintainDynamicCaches Majority MakeBoxes MakeExpression MakeRules MangoldtLambda ManhattanDistance Manipulate Manipulator MannWhitneyTest MantissaExponent Manual Map MapAll MapAt MapIndexed MAProcess MapThread MarcumQ MardiaCombinedTest MardiaKurtosisTest MardiaSkewnessTest MarginalDistribution MarkovProcessProperties Masking MatchingDissimilarity MatchLocalNameQ MatchLocalNames MatchQ Material MathematicaNotation MathieuC MathieuCharacteristicA MathieuCharacteristicB MathieuCharacteristicExponent MathieuCPrime MathieuGroupM11 MathieuGroupM12 MathieuGroupM22 MathieuGroupM23 MathieuGroupM24 MathieuS MathieuSPrime MathMLForm MathMLText Matrices MatrixExp MatrixForm MatrixFunction MatrixLog MatrixPlot MatrixPower MatrixQ MatrixRank Max MaxBend MaxDetect MaxExtraBandwidths MaxExtraConditions MaxFeatures MaxFilter Maximize MaxIterations MaxMemoryUsed MaxMixtureKernels MaxPlotPoints MaxPoints MaxRecursion MaxStableDistribution MaxStepFraction MaxSteps MaxStepSize MaxValue MaxwellDistribution McLaughlinGroupMcL Mean MeanClusteringCoefficient MeanDegreeConnectivity MeanDeviation MeanFilter MeanGraphDistance MeanNeighborDegree MeanShift MeanShiftFilter Median MedianDeviation MedianFilter Medium MeijerG MeixnerDistribution MemberQ MemoryConstrained MemoryInUse Menu MenuAppearance MenuCommandKey MenuEvaluator MenuItem MenuPacket MenuSortingValue MenuStyle MenuView MergeDifferences Mesh MeshFunctions MeshRange MeshShading MeshStyle Message MessageDialog MessageList MessageName MessageOptions MessagePacket Messages MessagesNotebook MetaCharacters MetaInformation Method MethodOptions MexicanHatWavelet MeyerWavelet Min MinDetect MinFilter MinimalPolynomial MinimalStateSpaceModel Minimize Minors MinRecursion MinSize MinStableDistribution Minus MinusPlus MinValue Missing MissingDataMethod MittagLefflerE MixedRadix MixedRadixQuantity MixtureDistribution Mod Modal Mode Modular ModularLambda Module Modulus MoebiusMu Moment Momentary MomentConvert MomentEvaluate MomentGeneratingFunction Monday Monitor MonomialList MonomialOrder MonsterGroupM MorletWavelet MorphologicalBinarize MorphologicalBranchPoints MorphologicalComponents MorphologicalEulerNumber MorphologicalGraph MorphologicalPerimeter MorphologicalTransform Most MouseAnnotation MouseAppearance MouseAppearanceTag MouseButtons Mouseover MousePointerNote MousePosition MovingAverage MovingMedian MoyalDistribution MultiedgeStyle MultilaunchWarning MultiLetterItalics MultiLetterStyle MultilineFunction Multinomial MultinomialDistribution MultinormalDistribution MultiplicativeOrder Multiplicity Multiselection MultivariateHypergeometricDistribution MultivariatePoissonDistribution MultivariateTDistribution N NakagamiDistribution NameQ Names NamespaceBox Nand NArgMax NArgMin NBernoulliB NCache NDSolve NDSolveValue Nearest NearestFunction NeedCurrentFrontEndPackagePacket NeedCurrentFrontEndSymbolsPacket NeedlemanWunschSimilarity Needs Negative NegativeBinomialDistribution NegativeMultinomialDistribution NeighborhoodGraph Nest NestedGreaterGreater NestedLessLess NestedScriptRules NestList NestWhile NestWhileList NevilleThetaC NevilleThetaD NevilleThetaN NevilleThetaS NewPrimitiveStyle NExpectation Next NextPrime NHoldAll NHoldFirst NHoldRest NicholsGridLines NicholsPlot NIntegrate NMaximize NMaxValue NMinimize NMinValue NominalVariables NonAssociative NoncentralBetaDistribution NoncentralChiSquareDistribution NoncentralFRatioDistribution NoncentralStudentTDistribution NonCommutativeMultiply NonConstants None NonlinearModelFit NonlocalMeansFilter NonNegative NonPositive Nor NorlundB Norm Normal NormalDistribution NormalGrouping Normalize NormalizedSquaredEuclideanDistance NormalsFunction NormFunction Not NotCongruent NotCupCap NotDoubleVerticalBar Notebook NotebookApply NotebookAutoSave NotebookClose NotebookConvertSettings NotebookCreate NotebookCreateReturnObject NotebookDefault NotebookDelete NotebookDirectory NotebookDynamicExpression NotebookEvaluate NotebookEventActions NotebookFileName NotebookFind NotebookFindReturnObject NotebookGet NotebookGetLayoutInformationPacket NotebookGetMisspellingsPacket NotebookInformation NotebookInterfaceObject NotebookLocate NotebookObject NotebookOpen NotebookOpenReturnObject NotebookPath NotebookPrint NotebookPut NotebookPutReturnObject NotebookRead NotebookResetGeneratedCells Notebooks NotebookSave NotebookSaveAs NotebookSelection NotebookSetupLayoutInformationPacket NotebooksMenu NotebookWrite NotElement NotEqualTilde NotExists NotGreater NotGreaterEqual NotGreaterFullEqual NotGreaterGreater NotGreaterLess NotGreaterSlantEqual NotGreaterTilde NotHumpDownHump NotHumpEqual NotLeftTriangle NotLeftTriangleBar NotLeftTriangleEqual NotLess NotLessEqual NotLessFullEqual NotLessGreater NotLessLess NotLessSlantEqual NotLessTilde NotNestedGreaterGreater NotNestedLessLess NotPrecedes NotPrecedesEqual NotPrecedesSlantEqual NotPrecedesTilde NotReverseElement NotRightTriangle NotRightTriangleBar NotRightTriangleEqual NotSquareSubset NotSquareSubsetEqual NotSquareSuperset NotSquareSupersetEqual NotSubset NotSubsetEqual NotSucceeds NotSucceedsEqual NotSucceedsSlantEqual NotSucceedsTilde NotSuperset NotSupersetEqual NotTilde NotTildeEqual NotTildeFullEqual NotTildeTilde NotVerticalBar NProbability NProduct NProductFactors NRoots NSolve NSum NSumTerms Null NullRecords NullSpace NullWords Number NumberFieldClassNumber NumberFieldDiscriminant NumberFieldFundamentalUnits NumberFieldIntegralBasis NumberFieldNormRepresentatives NumberFieldRegulator NumberFieldRootsOfUnity NumberFieldSignature NumberForm NumberFormat NumberMarks NumberMultiplier NumberPadding NumberPoint NumberQ NumberSeparator NumberSigns NumberString Numerator NumericFunction NumericQ NuttallWindow NValues NyquistGridLines NyquistPlot O ObservabilityGramian ObservabilityMatrix ObservableDecomposition ObservableModelQ OddQ Off Offset OLEData On ONanGroupON OneIdentity Opacity Open OpenAppend Opener OpenerBox OpenerBoxOptions OpenerView OpenFunctionInspectorPacket Opening OpenRead OpenSpecialOptions OpenTemporary OpenWrite Operate OperatingSystem OptimumFlowData Optional OptionInspectorSettings OptionQ Options OptionsPacket OptionsPattern OptionValue OptionValueBox OptionValueBoxOptions Or Orange Order OrderDistribution OrderedQ Ordering Orderless OrnsteinUhlenbeckProcess Orthogonalize Out Outer OutputAutoOverwrite OutputControllabilityMatrix OutputControllableModelQ OutputForm OutputFormData OutputGrouping OutputMathEditExpression OutputNamePacket OutputResponse OutputSizeLimit OutputStream Over OverBar OverDot Overflow OverHat Overlaps Overlay OverlayBox OverlayBoxOptions Overscript OverscriptBox OverscriptBoxOptions OverTilde OverVector OwenT OwnValues PackingMethod PaddedForm Padding PadeApproximant PadLeft PadRight PageBreakAbove PageBreakBelow PageBreakWithin PageFooterLines PageFooters PageHeaderLines PageHeaders PageHeight PageRankCentrality PageWidth PairedBarChart PairedHistogram PairedSmoothHistogram PairedTTest PairedZTest PaletteNotebook PalettePath Pane PaneBox PaneBoxOptions Panel PanelBox PanelBoxOptions Paneled PaneSelector PaneSelectorBox PaneSelectorBoxOptions PaperWidth ParabolicCylinderD ParagraphIndent ParagraphSpacing ParallelArray ParallelCombine ParallelDo ParallelEvaluate Parallelization Parallelize ParallelMap ParallelNeeds ParallelProduct ParallelSubmit ParallelSum ParallelTable ParallelTry Parameter ParameterEstimator ParameterMixtureDistribution ParameterVariables ParametricFunction ParametricNDSolve ParametricNDSolveValue ParametricPlot ParametricPlot3D ParentConnect ParentDirectory ParentForm Parenthesize ParentList ParetoDistribution Part PartialCorrelationFunction PartialD ParticleData Partition PartitionsP PartitionsQ ParzenWindow PascalDistribution PassEventsDown PassEventsUp Paste PasteBoxFormInlineCells PasteButton Path PathGraph PathGraphQ Pattern PatternSequence PatternTest PauliMatrix PaulWavelet Pause PausedTime PDF PearsonChiSquareTest PearsonCorrelationTest PearsonDistribution PerformanceGoal PeriodicInterpolation Periodogram PeriodogramArray PermutationCycles PermutationCyclesQ PermutationGroup PermutationLength PermutationList PermutationListQ PermutationMax PermutationMin PermutationOrder PermutationPower PermutationProduct PermutationReplace Permutations PermutationSupport Permute PeronaMalikFilter Perpendicular PERTDistribution PetersenGraph PhaseMargins Pi Pick PIDData PIDDerivativeFilter PIDFeedforward PIDTune Piecewise PiecewiseExpand PieChart PieChart3D PillaiTrace PillaiTraceTest Pink Pivoting PixelConstrained PixelValue PixelValuePositions Placed Placeholder PlaceholderReplace Plain PlanarGraphQ Play PlayRange Plot Plot3D Plot3Matrix PlotDivision PlotJoined PlotLabel PlotLayout PlotLegends PlotMarkers PlotPoints PlotRange PlotRangeClipping PlotRangePadding PlotRegion PlotStyle Plus PlusMinus Pochhammer PodStates PodWidth Point Point3DBox PointBox PointFigureChart PointForm PointLegend PointSize PoissonConsulDistribution PoissonDistribution PoissonProcess PoissonWindow PolarAxes PolarAxesOrigin PolarGridLines PolarPlot PolarTicks PoleZeroMarkers PolyaAeppliDistribution PolyGamma Polygon Polygon3DBox Polygon3DBoxOptions PolygonBox PolygonBoxOptions PolygonHoleScale PolygonIntersections PolygonScale PolyhedronData PolyLog PolynomialExtendedGCD PolynomialForm PolynomialGCD PolynomialLCM PolynomialMod PolynomialQ PolynomialQuotient PolynomialQuotientRemainder PolynomialReduce PolynomialRemainder Polynomials PopupMenu PopupMenuBox PopupMenuBoxOptions PopupView PopupWindow Position Positive PositiveDefiniteMatrixQ PossibleZeroQ Postfix PostScript Power PowerDistribution PowerExpand PowerMod PowerModList PowerSpectralDensity PowersRepresentations PowerSymmetricPolynomial Precedence PrecedenceForm Precedes PrecedesEqual PrecedesSlantEqual PrecedesTilde Precision PrecisionGoal PreDecrement PredictionRoot PreemptProtect PreferencesPath Prefix PreIncrement Prepend PrependTo PreserveImageOptions Previous PriceGraphDistribution PrimaryPlaceholder Prime PrimeNu PrimeOmega PrimePi PrimePowerQ PrimeQ Primes PrimeZetaP PrimitiveRoot PrincipalComponents PrincipalValue Print PrintAction PrintForm PrintingCopies PrintingOptions PrintingPageRange PrintingStartingPageNumber PrintingStyleEnvironment PrintPrecision PrintTemporary Prism PrismBox PrismBoxOptions PrivateCellOptions PrivateEvaluationOptions PrivateFontOptions PrivateFrontEndOptions PrivateNotebookOptions PrivatePaths Probability ProbabilityDistribution ProbabilityPlot ProbabilityPr ProbabilityScalePlot ProbitModelFit ProcessEstimator ProcessParameterAssumptions ProcessParameterQ ProcessStateDomain ProcessTimeDomain Product ProductDistribution ProductLog ProgressIndicator ProgressIndicatorBox ProgressIndicatorBoxOptions Projection Prolog PromptForm Properties Property PropertyList PropertyValue Proportion Proportional Protect Protected ProteinData Pruning PseudoInverse Purple Put PutAppend Pyramid PyramidBox PyramidBoxOptions QBinomial QFactorial QGamma QHypergeometricPFQ QPochhammer QPolyGamma QRDecomposition QuadraticIrrationalQ Quantile QuantilePlot Quantity QuantityForm QuantityMagnitude QuantityQ QuantityUnit Quartics QuartileDeviation Quartiles QuartileSkewness QueueingNetworkProcess QueueingProcess QueueProperties Quiet Quit Quotient QuotientRemainder RadialityCentrality RadicalBox RadicalBoxOptions RadioButton RadioButtonBar RadioButtonBox RadioButtonBoxOptions Radon RamanujanTau RamanujanTauL RamanujanTauTheta RamanujanTauZ Random RandomChoice RandomComplex RandomFunction RandomGraph RandomImage RandomInteger RandomPermutation RandomPrime RandomReal RandomSample RandomSeed RandomVariate RandomWalkProcess Range RangeFilter RangeSpecification RankedMax RankedMin Raster Raster3D Raster3DBox Raster3DBoxOptions RasterArray RasterBox RasterBoxOptions Rasterize RasterSize Rational RationalFunctions Rationalize Rationals Ratios Raw RawArray RawBoxes RawData RawMedium RayleighDistribution Re Read ReadList ReadProtected Real RealBlockDiagonalForm RealDigits RealExponent Reals Reap Record RecordLists RecordSeparators Rectangle RectangleBox RectangleBoxOptions RectangleChart RectangleChart3D RecurrenceFilter RecurrenceTable RecurringDigitsForm Red Reduce RefBox ReferenceLineStyle ReferenceMarkers ReferenceMarkerStyle Refine ReflectionMatrix ReflectionTransform Refresh RefreshRate RegionBinarize RegionFunction RegionPlot RegionPlot3D RegularExpression Regularization Reinstall Release ReleaseHold ReliabilityDistribution ReliefImage ReliefPlot Remove RemoveAlphaChannel RemoveAsynchronousTask Removed RemoveInputStreamMethod RemoveOutputStreamMethod RemoveProperty RemoveScheduledTask RenameDirectory RenameFile RenderAll RenderingOptions RenewalProcess RenkoChart Repeated RepeatedNull RepeatedString Replace ReplaceAll ReplaceHeldPart ReplaceImageValue ReplaceList ReplacePart ReplacePixelValue ReplaceRepeated Resampling Rescale RescalingTransform ResetDirectory ResetMenusPacket ResetScheduledTask Residue Resolve Rest Resultant ResumePacket Return ReturnExpressionPacket ReturnInputFormPacket ReturnPacket ReturnTextPacket Reverse ReverseBiorthogonalSplineWavelet ReverseElement ReverseEquilibrium ReverseGraph ReverseUpEquilibrium RevolutionAxis RevolutionPlot3D RGBColor RiccatiSolve RiceDistribution RidgeFilter RiemannR RiemannSiegelTheta RiemannSiegelZ Riffle Right RightArrow RightArrowBar RightArrowLeftArrow RightCosetRepresentative RightDownTeeVector RightDownVector RightDownVectorBar RightTee RightTeeArrow RightTeeVector RightTriangle RightTriangleBar RightTriangleEqual RightUpDownVector RightUpTeeVector RightUpVector RightUpVectorBar RightVector RightVectorBar RiskAchievementImportance RiskReductionImportance RogersTanimotoDissimilarity Root RootApproximant RootIntervals RootLocusPlot RootMeanSquare RootOfUnityQ RootReduce Roots RootSum Rotate RotateLabel RotateLeft RotateRight RotationAction RotationBox RotationBoxOptions RotationMatrix RotationTransform Round RoundImplies RoundingRadius Row RowAlignments RowBackgrounds RowBox RowHeights RowLines RowMinHeight RowReduce RowsEqual RowSpacings RSolve RudvalisGroupRu Rule RuleCondition RuleDelayed RuleForm RulerUnits Run RunScheduledTask RunThrough RuntimeAttributes RuntimeOptions RussellRaoDissimilarity SameQ SameTest SampleDepth SampledSoundFunction SampledSoundList SampleRate SamplingPeriod SARIMAProcess SARMAProcess SatisfiabilityCount SatisfiabilityInstances SatisfiableQ Saturday Save Saveable SaveAutoDelete SaveDefinitions SawtoothWave Scale Scaled ScaleDivisions ScaledMousePosition ScaleOrigin ScalePadding ScaleRanges ScaleRangeStyle ScalingFunctions ScalingMatrix ScalingTransform Scan ScheduledTaskActiveQ ScheduledTaskData ScheduledTaskObject ScheduledTasks SchurDecomposition ScientificForm ScreenRectangle ScreenStyleEnvironment ScriptBaselineShifts ScriptLevel ScriptMinSize ScriptRules ScriptSizeMultipliers Scrollbars ScrollingOptions ScrollPosition Sec Sech SechDistribution SectionGrouping SectorChart SectorChart3D SectorOrigin SectorSpacing SeedRandom Select Selectable SelectComponents SelectedCells SelectedNotebook Selection SelectionAnimate SelectionCell SelectionCellCreateCell SelectionCellDefaultStyle SelectionCellParentStyle SelectionCreateCell SelectionDebuggerTag SelectionDuplicateCell SelectionEvaluate SelectionEvaluateCreateCell SelectionMove SelectionPlaceholder SelectionSetStyle SelectWithContents SelfLoops SelfLoopStyle SemialgebraicComponentInstances SendMail Sequence SequenceAlignment SequenceForm SequenceHold SequenceLimit Series SeriesCoefficient SeriesData SessionTime Set SetAccuracy SetAlphaChannel SetAttributes Setbacks SetBoxFormNamesPacket SetDelayed SetDirectory SetEnvironment SetEvaluationNotebook SetFileDate SetFileLoadingContext SetNotebookStatusLine SetOptions SetOptionsPacket SetPrecision SetProperty SetSelectedNotebook SetSharedFunction SetSharedVariable SetSpeechParametersPacket SetStreamPosition SetSystemOptions Setter SetterBar SetterBox SetterBoxOptions Setting SetValue Shading Shallow ShannonWavelet ShapiroWilkTest Share Sharpen ShearingMatrix ShearingTransform ShenCastanMatrix Short ShortDownArrow Shortest ShortestMatch ShortestPathFunction ShortLeftArrow ShortRightArrow ShortUpArrow Show ShowAutoStyles ShowCellBracket ShowCellLabel ShowCellTags ShowClosedCellArea ShowContents ShowControls ShowCursorTracker ShowGroupOpenCloseIcon ShowGroupOpener ShowInvisibleCharacters ShowPageBreaks ShowPredictiveInterface ShowSelection ShowShortBoxForm ShowSpecialCharacters ShowStringCharacters ShowSyntaxStyles ShrinkingDelay ShrinkWrapBoundingBox SiegelTheta SiegelTukeyTest Sign Signature SignedRankTest SignificanceLevel SignPadding SignTest SimilarityRules SimpleGraph SimpleGraphQ Simplify Sin Sinc SinghMaddalaDistribution SingleEvaluation SingleLetterItalics SingleLetterStyle SingularValueDecomposition SingularValueList SingularValuePlot SingularValues Sinh SinhIntegral SinIntegral SixJSymbol Skeleton SkeletonTransform SkellamDistribution Skewness SkewNormalDistribution Skip SliceDistribution Slider Slider2D Slider2DBox Slider2DBoxOptions SliderBox SliderBoxOptions SlideView Slot SlotSequence Small SmallCircle Smaller SmithDelayCompensator SmithWatermanSimilarity SmoothDensityHistogram SmoothHistogram SmoothHistogram3D SmoothKernelDistribution SocialMediaData Socket SokalSneathDissimilarity Solve SolveAlways SolveDelayed Sort SortBy Sound SoundAndGraphics SoundNote SoundVolume Sow Space SpaceForm Spacer Spacings Span SpanAdjustments SpanCharacterRounding SpanFromAbove SpanFromBoth SpanFromLeft SpanLineThickness SpanMaxSize SpanMinSize SpanningCharacters SpanSymmetric SparseArray SpatialGraphDistribution Speak SpeakTextPacket SpearmanRankTest SpearmanRho Spectrogram SpectrogramArray Specularity SpellingCorrection SpellingDictionaries SpellingDictionariesPath SpellingOptions SpellingSuggestionsPacket Sphere SphereBox SphericalBesselJ SphericalBesselY SphericalHankelH1 SphericalHankelH2 SphericalHarmonicY SphericalPlot3D SphericalRegion SpheroidalEigenvalue SpheroidalJoiningFactor SpheroidalPS SpheroidalPSPrime SpheroidalQS SpheroidalQSPrime SpheroidalRadialFactor SpheroidalS1 SpheroidalS1Prime SpheroidalS2 SpheroidalS2Prime Splice SplicedDistribution SplineClosed SplineDegree SplineKnots SplineWeights Split SplitBy SpokenString Sqrt SqrtBox SqrtBoxOptions Square SquaredEuclideanDistance SquareFreeQ SquareIntersection SquaresR SquareSubset SquareSubsetEqual SquareSuperset SquareSupersetEqual SquareUnion SquareWave StabilityMargins StabilityMarginsStyle StableDistribution Stack StackBegin StackComplete StackInhibit StandardDeviation StandardDeviationFilter StandardForm Standardize StandbyDistribution Star StarGraph StartAsynchronousTask StartingStepSize StartOfLine StartOfString StartScheduledTask StartupSound StateDimensions StateFeedbackGains StateOutputEstimator StateResponse StateSpaceModel StateSpaceRealization StateSpaceTransform StationaryDistribution StationaryWaveletPacketTransform StationaryWaveletTransform StatusArea StatusCentrality StepMonitor StieltjesGamma StirlingS1 StirlingS2 StopAsynchronousTask StopScheduledTask StrataVariables StratonovichProcess StreamColorFunction StreamColorFunctionScaling StreamDensityPlot StreamPlot StreamPoints StreamPosition Streams StreamScale StreamStyle String StringBreak StringByteCount StringCases StringCount StringDrop StringExpression StringForm StringFormat StringFreeQ StringInsert StringJoin StringLength StringMatchQ StringPosition StringQ StringReplace StringReplaceList StringReplacePart StringReverse StringRotateLeft StringRotateRight StringSkeleton StringSplit StringTake StringToStream StringTrim StripBoxes StripOnInput StripWrapperBoxes StrokeForm StructuralImportance StructuredArray StructuredSelection StruveH StruveL Stub StudentTDistribution Style StyleBox StyleBoxAutoDelete StyleBoxOptions StyleData StyleDefinitions StyleForm StyleKeyMapping StyleMenuListing StyleNameDialogSettings StyleNames StylePrint StyleSheetPath Subfactorial Subgraph SubMinus SubPlus SubresultantPolynomialRemainders SubresultantPolynomials Subresultants Subscript SubscriptBox SubscriptBoxOptions Subscripted Subset SubsetEqual Subsets SubStar Subsuperscript SubsuperscriptBox SubsuperscriptBoxOptions Subtract SubtractFrom SubValues Succeeds SucceedsEqual SucceedsSlantEqual SucceedsTilde SuchThat Sum SumConvergence Sunday SuperDagger SuperMinus SuperPlus Superscript SuperscriptBox SuperscriptBoxOptions Superset SupersetEqual SuperStar Surd SurdForm SurfaceColor SurfaceGraphics SurvivalDistribution SurvivalFunction SurvivalModel SurvivalModelFit SuspendPacket SuzukiDistribution SuzukiGroupSuz SwatchLegend Switch Symbol SymbolName SymletWavelet Symmetric SymmetricGroup SymmetricMatrixQ SymmetricPolynomial SymmetricReduction Symmetrize SymmetrizedArray SymmetrizedArrayRules SymmetrizedDependentComponents SymmetrizedIndependentComponents SymmetrizedReplacePart SynchronousInitialization SynchronousUpdating Syntax SyntaxForm SyntaxInformation SyntaxLength SyntaxPacket SyntaxQ SystemDialogInput SystemException SystemHelpPath SystemInformation SystemInformationData SystemOpen SystemOptions SystemsModelDelay SystemsModelDelayApproximate SystemsModelDelete SystemsModelDimensions SystemsModelExtract SystemsModelFeedbackConnect SystemsModelLabels SystemsModelOrder SystemsModelParallelConnect SystemsModelSeriesConnect SystemsModelStateFeedbackConnect SystemStub Tab TabFilling Table TableAlignments TableDepth TableDirections TableForm TableHeadings TableSpacing TableView TableViewBox TabSpacings TabView TabViewBox TabViewBoxOptions TagBox TagBoxNote TagBoxOptions TaggingRules TagSet TagSetDelayed TagStyle TagUnset Take TakeWhile Tally Tan Tanh TargetFunctions TargetUnits TautologyQ TelegraphProcess TemplateBox TemplateBoxOptions TemplateSlotSequence TemporalData Temporary TemporaryVariable TensorContract TensorDimensions TensorExpand TensorProduct TensorQ TensorRank TensorReduce TensorSymmetry TensorTranspose TensorWedge Tetrahedron TetrahedronBox TetrahedronBoxOptions TeXForm TeXSave Text Text3DBox Text3DBoxOptions TextAlignment TextBand TextBoundingBox TextBox TextCell TextClipboardType TextData TextForm TextJustification TextLine TextPacket TextParagraph TextRecognize TextRendering TextStyle Texture TextureCoordinateFunction TextureCoordinateScaling Therefore ThermometerGauge Thick Thickness Thin Thinning ThisLink ThompsonGroupTh Thread ThreeJSymbol Threshold Through Throw Thumbnail Thursday Ticks TicksStyle Tilde TildeEqual TildeFullEqual TildeTilde TimeConstrained TimeConstraint Times TimesBy TimeSeriesForecast TimeSeriesInvertibility TimeUsed TimeValue TimeZone Timing Tiny TitleGrouping TitsGroupT ToBoxes ToCharacterCode ToColor ToContinuousTimeModel ToDate ToDiscreteTimeModel ToeplitzMatrix ToExpression ToFileName Together Toggle ToggleFalse Toggler TogglerBar TogglerBox TogglerBoxOptions ToHeldExpression ToInvertibleTimeSeries TokenWords Tolerance ToLowerCase ToNumberField TooBig Tooltip TooltipBox TooltipBoxOptions TooltipDelay TooltipStyle Top TopHatTransform TopologicalSort ToRadicals ToRules ToString Total TotalHeight TotalVariationFilter TotalWidth TouchscreenAutoZoom TouchscreenControlPlacement ToUpperCase Tr Trace TraceAbove TraceAction TraceBackward TraceDepth TraceDialog TraceForward TraceInternal TraceLevel TraceOff TraceOn TraceOriginal TracePrint TraceScan TrackedSymbols TradingChart TraditionalForm TraditionalFunctionNotation TraditionalNotation TraditionalOrder TransferFunctionCancel TransferFunctionExpand TransferFunctionFactor TransferFunctionModel TransferFunctionPoles TransferFunctionTransform TransferFunctionZeros TransformationFunction TransformationFunctions TransformationMatrix TransformedDistribution TransformedField Translate TranslationTransform TransparentColor Transpose TreeForm TreeGraph TreeGraphQ TreePlot TrendStyle TriangleWave TriangularDistribution Trig TrigExpand TrigFactor TrigFactorList Trigger TrigReduce TrigToExp TrimmedMean True TrueQ TruncatedDistribution TsallisQExponentialDistribution TsallisQGaussianDistribution TTest Tube TubeBezierCurveBox TubeBezierCurveBoxOptions TubeBox TubeBSplineCurveBox TubeBSplineCurveBoxOptions Tuesday TukeyLambdaDistribution TukeyWindow Tuples TuranGraph TuringMachine Transparent UnateQ Uncompress Undefined UnderBar Underflow Underlined Underoverscript UnderoverscriptBox UnderoverscriptBoxOptions Underscript UnderscriptBox UnderscriptBoxOptions UndirectedEdge UndirectedGraph UndirectedGraphQ UndocumentedTestFEParserPacket UndocumentedTestGetSelectionPacket Unequal Unevaluated UniformDistribution UniformGraphDistribution UniformSumDistribution Uninstall Union UnionPlus Unique UnitBox UnitConvert UnitDimensions Unitize UnitRootTest UnitSimplify UnitStep UnitTriangle UnitVector Unprotect UnsameQ UnsavedVariables Unset UnsetShared UntrackedVariables Up UpArrow UpArrowBar UpArrowDownArrow Update UpdateDynamicObjects UpdateDynamicObjectsSynchronous UpdateInterval UpDownArrow UpEquilibrium UpperCaseQ UpperLeftArrow UpperRightArrow UpperTriangularize Upsample UpSet UpSetDelayed UpTee UpTeeArrow UpValues URL URLFetch URLFetchAsynchronous URLSave URLSaveAsynchronous UseGraphicsRange Using UsingFrontEnd V2Get ValidationLength Value ValueBox ValueBoxOptions ValueForm ValueQ ValuesData Variables Variance VarianceEquivalenceTest VarianceEstimatorFunction VarianceGammaDistribution VarianceTest VectorAngle VectorColorFunction VectorColorFunctionScaling VectorDensityPlot VectorGlyphData VectorPlot VectorPlot3D VectorPoints VectorQ Vectors VectorScale VectorStyle Vee Verbatim Verbose VerboseConvertToPostScriptPacket VerifyConvergence VerifySolutions VerifyTestAssumptions Version VersionNumber VertexAdd VertexCapacity VertexColors VertexComponent VertexConnectivity VertexCoordinateRules VertexCoordinates VertexCorrelationSimilarity VertexCosineSimilarity VertexCount VertexCoverQ VertexDataCoordinates VertexDegree VertexDelete VertexDiceSimilarity VertexEccentricity VertexInComponent VertexInDegree VertexIndex VertexJaccardSimilarity VertexLabeling VertexLabels VertexLabelStyle VertexList VertexNormals VertexOutComponent VertexOutDegree VertexQ VertexRenderingFunction VertexReplace VertexShape VertexShapeFunction VertexSize VertexStyle VertexTextureCoordinates VertexWeight Vertical VerticalBar VerticalForm VerticalGauge VerticalSeparator VerticalSlider VerticalTilde ViewAngle ViewCenter ViewMatrix ViewPoint ViewPointSelectorSettings ViewPort ViewRange ViewVector ViewVertical VirtualGroupData Visible VisibleCell VoigtDistribution VonMisesDistribution WaitAll WaitAsynchronousTask WaitNext WaitUntil WakebyDistribution WalleniusHypergeometricDistribution WaringYuleDistribution WatershedComponents WatsonUSquareTest WattsStrogatzGraphDistribution WaveletBestBasis WaveletFilterCoefficients WaveletImagePlot WaveletListPlot WaveletMapIndexed WaveletMatrixPlot WaveletPhi WaveletPsi WaveletScale WaveletScalogram WaveletThreshold WeaklyConnectedComponents WeaklyConnectedGraphQ WeakStationarity WeatherData WeberE Wedge Wednesday WeibullDistribution WeierstrassHalfPeriods WeierstrassInvariants WeierstrassP WeierstrassPPrime WeierstrassSigma WeierstrassZeta WeightedAdjacencyGraph WeightedAdjacencyMatrix WeightedData WeightedGraphQ Weights WelchWindow WheelGraph WhenEvent Which While White Whitespace WhitespaceCharacter WhittakerM WhittakerW WienerFilter WienerProcess WignerD WignerSemicircleDistribution WilksW WilksWTest WindowClickSelect WindowElements WindowFloating WindowFrame WindowFrameElements WindowMargins WindowMovable WindowOpacity WindowSelected WindowSize WindowStatusArea WindowTitle WindowToolbars WindowWidth With WolframAlpha WolframAlphaDate WolframAlphaQuantity WolframAlphaResult Word WordBoundary WordCharacter WordData WordSearch WordSeparators WorkingPrecision Write WriteString Wronskian XMLElement XMLObject Xnor Xor Yellow YuleDissimilarity ZernikeR ZeroSymmetric ZeroTest ZeroWidthTimes Zeta ZetaZero ZipfDistribution ZTest ZTransform $Aborted $ActivationGroupID $ActivationKey $ActivationUserRegistered $AddOnsDirectory $AssertFunction $Assumptions $AsynchronousTask $BaseDirectory $BatchInput $BatchOutput $BoxForms $ByteOrdering $Canceled $CharacterEncoding $CharacterEncodings $CommandLine $CompilationTarget $ConditionHold $ConfiguredKernels $Context $ContextPath $ControlActiveSetting $CreationDate $CurrentLink $DateStringFormat $DefaultFont $DefaultFrontEnd $DefaultImagingDevice $DefaultPath $Display $DisplayFunction $DistributedContexts $DynamicEvaluation $Echo $Epilog $ExportFormats $Failed $FinancialDataSource $FormatType $FrontEnd $FrontEndSession $GeoLocation $HistoryLength $HomeDirectory $HTTPCookies $IgnoreEOF $ImagingDevices $ImportFormats $InitialDirectory $Input $InputFileName $InputStreamMethods $Inspector $InstallationDate $InstallationDirectory $InterfaceEnvironment $IterationLimit $KernelCount $KernelID $Language $LaunchDirectory $LibraryPath $LicenseExpirationDate $LicenseID $LicenseProcesses $LicenseServer $LicenseSubprocesses $LicenseType $Line $Linked $LinkSupported $LoadedFiles $MachineAddresses $MachineDomain $MachineDomains $MachineEpsilon $MachineID $MachineName $MachinePrecision $MachineType $MaxExtraPrecision $MaxLicenseProcesses $MaxLicenseSubprocesses $MaxMachineNumber $MaxNumber $MaxPiecewiseCases $MaxPrecision $MaxRootDegree $MessageGroups $MessageList $MessagePrePrint $Messages $MinMachineNumber $MinNumber $MinorReleaseNumber $MinPrecision $ModuleNumber $NetworkLicense $NewMessage $NewSymbol $Notebooks $NumberMarks $Off $OperatingSystem $Output $OutputForms $OutputSizeLimit $OutputStreamMethods $Packages $ParentLink $ParentProcessID $PasswordFile $PatchLevelID $Path $PathnameSeparator $PerformanceGoal $PipeSupported $Post $Pre $PreferencesDirectory $PrePrint $PreRead $PrintForms $PrintLiteral $ProcessID $ProcessorCount $ProcessorType $ProductInformation $ProgramName $RandomState $RecursionLimit $ReleaseNumber $RootDirectory $ScheduledTask $ScriptCommandLine $SessionID $SetParentLink $SharedFunctions $SharedVariables $SoundDisplay $SoundDisplayFunction $SuppressInputFormHeads $SynchronousEvaluation $SyntaxHandler $System $SystemCharacterEncoding $SystemID $SystemWordLength $TemporaryDirectory $TemporaryPrefix $TextStyle $TimedOut $TimeUnit $TimeZone $TopDirectory $TraceOff $TraceOn $TracePattern $TracePostAction $TracePreAction $Urgent $UserAddOnsDirectory $UserBaseDirectory $UserDocumentsDirectory $UserName $Version $VersionNumber",c:[{cN:"comment",b:/\(\*/,e:/\*\)/},e.ASM,e.QSM,e.CNM,{cN:"list",b:/\{/,e:/\}/,i:/:/}]} +});hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},{cN:"comment",b:"\\(\\*",e:"\\*\\)"},{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"attribute",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}});hljs.registerLanguage("dart",function(e){var t={cN:"subst",b:"\\$\\{",e:"}",k:"true false null this is new super"},r={cN:"string",v:[{b:"r'''",e:"'''"},{b:'r"""',e:'"""'},{b:"r'",e:"'",i:"\\n"},{b:'r"',e:'"',i:"\\n"},{b:"'''",e:"'''",c:[e.BE,t]},{b:'"""',e:'"""',c:[e.BE,t]},{b:"'",e:"'",i:"\\n",c:[e.BE,t]},{b:'"',e:'"',i:"\\n",c:[e.BE,t]}]};t.c=[e.CNM,r];var n={keyword:"assert break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch this throw true try var void while with",literal:"abstract as dynamic export external factory get implements import library operator part set static typedef",built_in:"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"};return{k:n,c:[r,{cN:"dartdoc",b:"/\\*\\*",e:"\\*/",sL:"markdown",subLanguageMode:"continuous"},{cN:"dartdoc",b:"///",e:"$",sL:"markdown",subLanguageMode:"continuous"},e.CLCM,e.CBCM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"annotation",b:"@[A-Za-z]+"},{b:"=>"}]}});hljs.registerLanguage("scilab",function(e){var n=[e.CNM,{cN:"string",b:"'|\"",e:"'|\"",c:[e.BE,{b:"''"}]}];return{aliases:["sci"],k:{keyword:"abort break case clear catch continue do elseif else endfunction end for functionglobal if pause return resume select try then while%f %F %t %T %pi %eps %inf %nan %e %i %z %s",built_in:"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp errorexec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isemptyisinfisnan isvector lasterror length load linspace list listfiles log10 log2 logmax min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand realround sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tantype typename warning zeros matrix"},i:'("|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function endfunction",e:"$",k:"function endfunction|10",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:"",r:0},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",r:0,c:n},{cN:"comment",b:"//",e:"$"}].concat(n)}});hljs.registerLanguage("tex",function(){var c={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"},e={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"},m={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:!0,c:[c,e,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:!0}],r:10},c,e,m,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[c,e,m],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[c,e,m],r:0},{cN:"comment",b:"%",e:"$",r:0}]}});hljs.registerLanguage("ruleslanguage",function(T){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[T.CLCM,T.CBCM,T.ASM,T.QSM,T.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}});hljs.registerLanguage("vbscript",function(e){return{aliases:["vbs"],cI:!0,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),{cN:"comment",b:/'/,e:/$/,r:0},e.CNM]}});hljs.registerLanguage("vhdl",function(e){return{cI:!0,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[e.CBCM,{cN:"comment",b:"--",e:"$"},e.QSM,e.CNM,{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[e.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[e.BE]}]}});hljs.registerLanguage("http",function(){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:!0}}]}});hljs.registerLanguage("oxygene",function(e){var r="abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained",t={cN:"comment",b:"{",e:"}",r:0},a={cN:"comment",b:"\\(\\*",e:"\\*\\)",r:10},n={cN:"string",b:"'",e:"'",c:[{b:"''"}]},o={cN:"string",b:"(#\\d+)+"},c={cN:"function",bK:"function constructor destructor procedure method",e:"[:;]",k:"function constructor|10 destructor|10 procedure|10 method|10",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",k:r,c:[n,o]},t,a]};return{cI:!0,k:r,i:'("|\\$[G-Zg-z]|\\/\\*||->)',c:[t,a,e.CLCM,n,o,e.NM,c,{cN:"class",b:"=\\bclass\\b",e:"end;",k:r,c:[n,o,t,a,e.CLCM,c]}]}});hljs.registerLanguage("puppet",function(e){var s="augeas computer cron exec file filebucket host interface k5login macauthorization mailalias maillist mcx mount nagios_command nagios_contact nagios_contactgroup nagios_host nagios_hostdependency nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service firewall nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo nagios_servicegroup nagios_timeperiod notify package resources router schedule scheduled_task selboolean selmodule service ssh_authorized_key sshkey stage tidy user vlan yumrepo zfs zone zpool",r="alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",a={keyword:"and case class default define else elsif false if in import enherits node or true undef unless main settings $string "+s,literal:r,built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},i={cN:"comment",b:"#",e:"$"},o={cN:"string",c:[e.BE],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},n=[o,i,{cN:"keyword",bK:"class",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"(::)?[A-Za-z_]\\w*(::\\w+)*"}),i,o]},{cN:"keyword",b:"([a-zA-Z_(::)]+ *\\{)",c:[o,i],r:0},{cN:"keyword",b:"(\\}|\\{)",r:0},{cN:"function",b:"[a-zA-Z_]+\\s*=>"},{cN:"constant",b:"(::)?(\\b[A-Z][a-z_]*(::)?)+",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0}];return{aliases:["pp"],k:a,c:n}});hljs.registerLanguage("gcode",function(e){var N="[A-Z_][A-Z0-9_.]*",c="\\%",i={literal:"",built_in:"",keyword:"IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR"},r={cN:"preprocessor",b:"([O])([0-9]+)"},t=[e.CLCM,{cN:"comment",b:/\(/,e:/\)/,c:[e.PWM]},e.CBCM,e.inherit(e.CNM,{b:"([-+]?([0-9]*\\.?[0-9]+\\.?))|"+e.CNR}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"keyword",b:"([G])([0-9]+\\.?[0-9]?)"},{cN:"title",b:"([M])([0-9]+\\.?[0-9]?)"},{cN:"title",b:"(VC|VS|#)",e:"(\\d+)"},{cN:"title",b:"(VZOFX|VZOFY|VZOFZ)"},{cN:"built_in",b:"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)",e:"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{cN:"label",v:[{b:"N",e:"\\d+",i:"\\W"}]}];return{aliases:["nc"],cI:!0,l:N,k:i,c:[{cN:"preprocessor",b:c},r].concat(t)}});hljs.registerLanguage("rust",function(e){var t=e.inherit(e.CBCM);return t.c.push("self"),{aliases:["rs"],k:{keyword:"alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self sizeof static struct super trait true type typeof unsafe unsized use virtual while yield int i8 i16 i32 i64 uint u8 u32 u64 float f32 f64 str char bool",built_in:"assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln!"},l:e.IR+"!?",i:""}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",a={cN:"function",b:c+"\\(",rB:!0,eE:!0,e:"\\("};return{cI:!0,i:"[=/|']",c:[e.CBCM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[a,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:c,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[e.CBCM,{cN:"rule",b:"[^\\s]",rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{cN:"value",eW:!0,eE:!0,c:[a,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}});hljs.registerLanguage("protobuf",function(e){return{k:{keyword:"package import option optional required repeated group",built_in:"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes",literal:"true false"},c:[e.QSM,e.NM,e.CLCM,{cN:"class",bK:"message enum service",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"function",bK:"rpc",e:/;/,eE:!0,k:"rpc returns"},{cN:"constant",b:/^\s*[A-Z_]+/,e:/\s*=/,eE:!0}]}});hljs.registerLanguage("swift",function(e){var t={keyword:"class deinit enum extension func import init let protocol static struct subscript typealias var break case continue default do else fallthrough if in for return switch where while as dynamicType is new super self Self Type __COLUMN__ __FILE__ __FUNCTION__ __LINE__ associativity didSet get infix inout left mutating none nonmutating operator override postfix precedence prefix right set unowned unowned safe unsafe weak willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue assert bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal false filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced join lexicographicalCompare map max maxElement min minElement nil numericCast partition posix print println quickSort reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith strideof strideofValue swap swift toString transcode true underestimateCount unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafePointers withVaList"},i={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM,"self"]},r={cN:"subst",b:/\\\(/,e:"\\)",k:t,c:[]},s={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0},o=e.inherit(e.QSM,{c:[r,e.BE]});return r.c=[s],{k:t,c:[o,e.CLCM,n,i,s,{cN:"func",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/,i:/\(/}),{cN:"generics",b:/\/,i:/\>/},{cN:"params",b:/\(/,e:/\)/,k:t,c:["self",s,o,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",k:"struct protocol class extension enum",b:"(struct|protocol|class(?! (func|var))|extension|enum)",e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/})]},{cN:"preprocessor",b:"(@assignment|@class_protocol|@exported|@final|@lazy|@noreturn|@NSCopying|@NSManaged|@objc|@optional|@required|@auto_closure|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix)"}]}});hljs.registerLanguage("vim",function(e){return{l:/[!#@\w]+/,k:{keyword:"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw d|0 delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu g|0 go gr grepa gu gv ha h|0 helpf helpg helpt hi hid his i|0 ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs n|0 new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf q|0 quita qa r|0 rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv s|0 sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync t|0 tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up v|0 ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank",built_in:"abs acos add and append argc argidx argv asin atan atan2 browse browsedir bufexists buflisted bufloaded bufname bufnr bufwinnr byte2line byteidx call ceil changenr char2nr cindent clearmatches col complete complete_add complete_check confirm copy cos cosh count cscope_connection cursor deepcopy delete did_filetype diff_filler diff_hlID empty escape eval eventhandler executable exists exp expand extend feedkeys filereadable filewritable filter finddir findfile float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreground function garbagecollect get getbufline getbufvar getchar getcharmod getcmdline getcmdpos getcmdtype getcwd getfontname getfperm getfsize getftime getftype getline getloclist getmatches getpid getpos getqflist getreg getregtype gettabvar gettabwinvar getwinposx getwinposy getwinvar glob globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlexists hlID hostname iconv indent index input inputdialog inputlist inputrestore inputsave inputsecret insert invert isdirectory islocked items join keys len libcall libcallnr line line2byte lispindent localtime log log10 luaeval map maparg mapcheck match matchadd matcharg matchdelete matchend matchlist matchstr max min mkdir mode mzeval nextnonblank nr2char or pathshorten pow prevnonblank printf pumvisible py3eval pyeval range readfile reltime reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remove rename repeat resolve reverse round screenattr screenchar screencol screenrow search searchdecl searchpair searchpairpos searchpos server2client serverlist setbufvar setcmdpos setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar setwinvar sha256 shellescape shiftwidth simplify sin sinh sort soundfold spellbadword spellsuggest split sqrt str2float str2nr strchars strdisplaywidth strftime stridx string strlen strpart strridx strtrans strwidth submatch substitute synconcealed synID synIDattr synIDtrans synstack system tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname tolower toupper tr trunc type undofile undotree values virtcol visualmode wildmenumode winbufnr wincol winheight winline winnr winrestcmd winrestview winsaveview winwidth writefile xor"},i:/[{:]/,c:[e.NM,e.ASM,{cN:"string",b:/"((\\")|[^"\n])*("|\n)/},{cN:"variable",b:/[bwtglsav]:[\w\d_]*/},{cN:"function",bK:"function function!",e:"$",r:0,c:[e.TM,{cN:"params",b:"\\(",e:"\\)"}]}]}});hljs.registerLanguage("fix",function(){return{c:[{b:/[^\u2401\u0001]+/,e:/[\u2401\u0001]/,eE:!0,rB:!0,rE:!1,c:[{b:/([^\u2401\u0001=]+)/,e:/=([^\u2401\u0001=]+)/,rE:!0,rB:!1,cN:"attribute"},{b:/=/,e:/([\u2401\u0001])/,eE:!0,eB:!0,cN:"string"}]}],cI:!0}});hljs.registerLanguage("javascript",function(r){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",r:10,v:[{b:/^\s*('|")use strict('|")/},{b:/^\s*('|")use asm('|")/}]},r.ASM,r.QSM,r.CLCM,r.CBCM,r.CNM,{b:"("+r.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[r.CLCM,r.CBCM,r.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[r.CLCM,r.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+r.IR,r:0}]}});hljs.registerLanguage("lua",function(e){var t="\\[=*\\[",a="\\]=*\\]",r={b:t,e:a,c:["self"]},n=[{cN:"comment",b:"--(?!"+t+")",e:"$"},{cN:"comment",b:"--"+t,e:a,c:[r],r:10}];return{l:e.UIR,k:{keyword:"and break do else elseif end false for if in local nil not or repeat return then true until while",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},c:n.concat([{cN:"function",bK:"function",e:"\\)",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{cN:"params",b:"\\(",eW:!0,c:n}].concat(n)},e.CNM,e.ASM,e.QSM,{cN:"string",b:t,e:a,c:[r],r:5}])}});hljs.registerLanguage("django",function(){var e={cN:"filter",b:/\|[A-Za-z]+\:?/,k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:/"/,e:/"/},{cN:"argument",b:/'/,e:/'/}]};return{aliases:["jinja"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"comment",b:/\{%\s*comment\s*%}/,e:/\{%\s*endcomment\s*%}/},{cN:"comment",b:/\{#/,e:/#}/},{cN:"template_tag",b:/\{%/,e:/%}/,k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[e]},{cN:"variable",b:/\{\{/,e:/}}/,c:[e]}]}});hljs.registerLanguage("python",function(e){var r={cN:"prompt",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},l={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},c={cN:"params",b:/\(/,e:/\)/,c:["self",r,l,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,l,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n]/,c:[e.UTM,c]},{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("cmake",function(e){return{aliases:["cmake.in"],cI:!0,k:{keyword:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or",operator:"equal less greater strless strgreater strequal matches"},c:[{cN:"envvar",b:"\\${",e:"}"},e.HCM,e.QSM,e.NM]}}); \ No newline at end of file diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css new file mode 100644 index 000000000000..edfde01077d3 --- /dev/null +++ b/dottydoc/js/static/index.css @@ -0,0 +1,9 @@ +main > div.page-content { + padding: 30px 60px; +} + +span.subtitle { + font-size: 12px; + line-height: 0 !important; + padding-top: 32px; +} diff --git a/dottydoc/js/static/material.min.css b/dottydoc/js/static/material.min.css new file mode 100644 index 000000000000..e750f8137205 --- /dev/null +++ b/dottydoc/js/static/material.min.css @@ -0,0 +1,9 @@ +/** + * material-design-lite - Material Design Components in CSS, JS and HTML + * @version v1.1.3 + * @license Apache-2.0 + * @copyright 2015 Google, Inc. + * @link https://github.com/google/material-design-lite + */ +@charset "UTF-8";html{color:rgba(0,0,0,.87)}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.browserupgrade{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.hidden{display:none!important}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}@media print{*,*:before,*:after,*:first-letter{background:transparent!important;color:#000!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}a,.mdl-accordion,.mdl-button,.mdl-card,.mdl-checkbox,.mdl-dropdown-menu,.mdl-icon-toggle,.mdl-item,.mdl-radio,.mdl-slider,.mdl-switch,.mdl-tabs__tab{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:rgba(255,255,255,0)}html{width:100%;height:100%;-ms-touch-action:manipulation;touch-action:manipulation}body{width:100%;min-height:100%;margin:0}main{display:block}*[hidden]{display:none!important}html,body{font-family:"Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:20px}h1,h2,h3,h4,h5,h6,p{padding:0}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400;line-height:1.35;letter-spacing:-.02em;opacity:.54;font-size:.6em}h1{font-size:56px;line-height:1.35;letter-spacing:-.02em;margin:24px 0}h1,h2{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h2{font-size:45px;line-height:48px}h2,h3{margin:24px 0}h3{font-size:34px;line-height:40px}h3,h4{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h4{font-size:24px;line-height:32px;-moz-osx-font-smoothing:grayscale;margin:24px 0 16px}h5{font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}h5,h6{font-family:"Roboto","Helvetica","Arial",sans-serif;margin:24px 0 16px}h6{font-size:16px;letter-spacing:.04em}h6,p{font-weight:400;line-height:24px}p{font-size:14px;letter-spacing:0;margin:0 0 16px}a{color:#ff4081;font-weight:500}blockquote{font-family:"Roboto","Helvetica","Arial",sans-serif;position:relative;font-size:24px;font-weight:300;font-style:italic;line-height:1.35;letter-spacing:.08em}blockquote:before{position:absolute;left:-.5em;content:'“'}blockquote:after{content:'”';margin-left:-.05em}mark{background-color:#f4ff81}dt{font-weight:700}address{font-size:12px;line-height:1;font-style:normal}address,ul,ol{font-weight:400;letter-spacing:0}ul,ol{font-size:14px;line-height:24px}.mdl-typography--display-4,.mdl-typography--display-4-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:112px;font-weight:300;line-height:1;letter-spacing:-.04em}.mdl-typography--display-4-color-contrast{opacity:.54}.mdl-typography--display-3,.mdl-typography--display-3-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:56px;font-weight:400;line-height:1.35;letter-spacing:-.02em}.mdl-typography--display-3-color-contrast{opacity:.54}.mdl-typography--display-2,.mdl-typography--display-2-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:45px;font-weight:400;line-height:48px}.mdl-typography--display-2-color-contrast{opacity:.54}.mdl-typography--display-1,.mdl-typography--display-1-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:34px;font-weight:400;line-height:40px}.mdl-typography--display-1-color-contrast{opacity:.54}.mdl-typography--headline,.mdl-typography--headline-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:24px;font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}.mdl-typography--headline-color-contrast{opacity:.87}.mdl-typography--title,.mdl-typography--title-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}.mdl-typography--title-color-contrast{opacity:.87}.mdl-typography--subhead,.mdl-typography--subhead-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;line-height:24px;letter-spacing:.04em}.mdl-typography--subhead-color-contrast{opacity:.87}.mdl-typography--body-2,.mdl-typography--body-2-color-contrast{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0}.mdl-typography--body-2-color-contrast{opacity:.87}.mdl-typography--body-1,.mdl-typography--body-1-color-contrast{font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-color-contrast{opacity:.87}.mdl-typography--body-2-force-preferred-font,.mdl-typography--body-2-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0}.mdl-typography--body-2-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--body-1-force-preferred-font,.mdl-typography--body-1-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--caption,.mdl-typography--caption-force-preferred-font{font-size:12px;font-weight:400;line-height:1;letter-spacing:0}.mdl-typography--caption-force-preferred-font{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--caption-color-contrast,.mdl-typography--caption-force-preferred-font-color-contrast{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;opacity:.54}.mdl-typography--caption-force-preferred-font-color-contrast,.mdl-typography--menu{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--menu{font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--menu-color-contrast{opacity:.87}.mdl-typography--menu-color-contrast,.mdl-typography--button,.mdl-typography--button-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--button,.mdl-typography--button-color-contrast{text-transform:uppercase}.mdl-typography--button-color-contrast{opacity:.87}.mdl-typography--text-left{text-align:left}.mdl-typography--text-right{text-align:right}.mdl-typography--text-center{text-align:center}.mdl-typography--text-justify{text-align:justify}.mdl-typography--text-nowrap{white-space:nowrap}.mdl-typography--text-lowercase{text-transform:lowercase}.mdl-typography--text-uppercase{text-transform:uppercase}.mdl-typography--text-capitalize{text-transform:capitalize}.mdl-typography--font-thin{font-weight:200!important}.mdl-typography--font-light{font-weight:300!important}.mdl-typography--font-regular{font-weight:400!important}.mdl-typography--font-medium{font-weight:500!important}.mdl-typography--font-bold{font-weight:700!important}.mdl-typography--font-black{font-weight:900!important}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased}.mdl-color-text--red{color:#f44336 !important}.mdl-color--red{background-color:#f44336 !important}.mdl-color-text--red-50{color:#ffebee !important}.mdl-color--red-50{background-color:#ffebee !important}.mdl-color-text--red-100{color:#ffcdd2 !important}.mdl-color--red-100{background-color:#ffcdd2 !important}.mdl-color-text--red-200{color:#ef9a9a !important}.mdl-color--red-200{background-color:#ef9a9a !important}.mdl-color-text--red-300{color:#e57373 !important}.mdl-color--red-300{background-color:#e57373 !important}.mdl-color-text--red-400{color:#ef5350 !important}.mdl-color--red-400{background-color:#ef5350 !important}.mdl-color-text--red-500{color:#f44336 !important}.mdl-color--red-500{background-color:#f44336 !important}.mdl-color-text--red-600{color:#e53935 !important}.mdl-color--red-600{background-color:#e53935 !important}.mdl-color-text--red-700{color:#d32f2f !important}.mdl-color--red-700{background-color:#d32f2f !important}.mdl-color-text--red-800{color:#c62828 !important}.mdl-color--red-800{background-color:#c62828 !important}.mdl-color-text--red-900{color:#b71c1c !important}.mdl-color--red-900{background-color:#b71c1c !important}.mdl-color-text--red-A100{color:#ff8a80 !important}.mdl-color--red-A100{background-color:#ff8a80 !important}.mdl-color-text--red-A200{color:#ff5252 !important}.mdl-color--red-A200{background-color:#ff5252 !important}.mdl-color-text--red-A400{color:#ff1744 !important}.mdl-color--red-A400{background-color:#ff1744 !important}.mdl-color-text--red-A700{color:#d50000 !important}.mdl-color--red-A700{background-color:#d50000 !important}.mdl-color-text--pink{color:#e91e63 !important}.mdl-color--pink{background-color:#e91e63 !important}.mdl-color-text--pink-50{color:#fce4ec !important}.mdl-color--pink-50{background-color:#fce4ec !important}.mdl-color-text--pink-100{color:#f8bbd0 !important}.mdl-color--pink-100{background-color:#f8bbd0 !important}.mdl-color-text--pink-200{color:#f48fb1 !important}.mdl-color--pink-200{background-color:#f48fb1 !important}.mdl-color-text--pink-300{color:#f06292 !important}.mdl-color--pink-300{background-color:#f06292 !important}.mdl-color-text--pink-400{color:#ec407a !important}.mdl-color--pink-400{background-color:#ec407a !important}.mdl-color-text--pink-500{color:#e91e63 !important}.mdl-color--pink-500{background-color:#e91e63 !important}.mdl-color-text--pink-600{color:#d81b60 !important}.mdl-color--pink-600{background-color:#d81b60 !important}.mdl-color-text--pink-700{color:#c2185b !important}.mdl-color--pink-700{background-color:#c2185b !important}.mdl-color-text--pink-800{color:#ad1457 !important}.mdl-color--pink-800{background-color:#ad1457 !important}.mdl-color-text--pink-900{color:#880e4f !important}.mdl-color--pink-900{background-color:#880e4f !important}.mdl-color-text--pink-A100{color:#ff80ab !important}.mdl-color--pink-A100{background-color:#ff80ab !important}.mdl-color-text--pink-A200{color:#ff4081 !important}.mdl-color--pink-A200{background-color:#ff4081 !important}.mdl-color-text--pink-A400{color:#f50057 !important}.mdl-color--pink-A400{background-color:#f50057 !important}.mdl-color-text--pink-A700{color:#c51162 !important}.mdl-color--pink-A700{background-color:#c51162 !important}.mdl-color-text--purple{color:#9c27b0 !important}.mdl-color--purple{background-color:#9c27b0 !important}.mdl-color-text--purple-50{color:#f3e5f5 !important}.mdl-color--purple-50{background-color:#f3e5f5 !important}.mdl-color-text--purple-100{color:#e1bee7 !important}.mdl-color--purple-100{background-color:#e1bee7 !important}.mdl-color-text--purple-200{color:#ce93d8 !important}.mdl-color--purple-200{background-color:#ce93d8 !important}.mdl-color-text--purple-300{color:#ba68c8 !important}.mdl-color--purple-300{background-color:#ba68c8 !important}.mdl-color-text--purple-400{color:#ab47bc !important}.mdl-color--purple-400{background-color:#ab47bc !important}.mdl-color-text--purple-500{color:#9c27b0 !important}.mdl-color--purple-500{background-color:#9c27b0 !important}.mdl-color-text--purple-600{color:#8e24aa !important}.mdl-color--purple-600{background-color:#8e24aa !important}.mdl-color-text--purple-700{color:#7b1fa2 !important}.mdl-color--purple-700{background-color:#7b1fa2 !important}.mdl-color-text--purple-800{color:#6a1b9a !important}.mdl-color--purple-800{background-color:#6a1b9a !important}.mdl-color-text--purple-900{color:#4a148c !important}.mdl-color--purple-900{background-color:#4a148c !important}.mdl-color-text--purple-A100{color:#ea80fc !important}.mdl-color--purple-A100{background-color:#ea80fc !important}.mdl-color-text--purple-A200{color:#e040fb !important}.mdl-color--purple-A200{background-color:#e040fb !important}.mdl-color-text--purple-A400{color:#d500f9 !important}.mdl-color--purple-A400{background-color:#d500f9 !important}.mdl-color-text--purple-A700{color:#a0f !important}.mdl-color--purple-A700{background-color:#a0f !important}.mdl-color-text--deep-purple{color:#673ab7 !important}.mdl-color--deep-purple{background-color:#673ab7 !important}.mdl-color-text--deep-purple-50{color:#ede7f6 !important}.mdl-color--deep-purple-50{background-color:#ede7f6 !important}.mdl-color-text--deep-purple-100{color:#d1c4e9 !important}.mdl-color--deep-purple-100{background-color:#d1c4e9 !important}.mdl-color-text--deep-purple-200{color:#b39ddb !important}.mdl-color--deep-purple-200{background-color:#b39ddb !important}.mdl-color-text--deep-purple-300{color:#9575cd !important}.mdl-color--deep-purple-300{background-color:#9575cd !important}.mdl-color-text--deep-purple-400{color:#7e57c2 !important}.mdl-color--deep-purple-400{background-color:#7e57c2 !important}.mdl-color-text--deep-purple-500{color:#673ab7 !important}.mdl-color--deep-purple-500{background-color:#673ab7 !important}.mdl-color-text--deep-purple-600{color:#5e35b1 !important}.mdl-color--deep-purple-600{background-color:#5e35b1 !important}.mdl-color-text--deep-purple-700{color:#512da8 !important}.mdl-color--deep-purple-700{background-color:#512da8 !important}.mdl-color-text--deep-purple-800{color:#4527a0 !important}.mdl-color--deep-purple-800{background-color:#4527a0 !important}.mdl-color-text--deep-purple-900{color:#311b92 !important}.mdl-color--deep-purple-900{background-color:#311b92 !important}.mdl-color-text--deep-purple-A100{color:#b388ff !important}.mdl-color--deep-purple-A100{background-color:#b388ff !important}.mdl-color-text--deep-purple-A200{color:#7c4dff !important}.mdl-color--deep-purple-A200{background-color:#7c4dff !important}.mdl-color-text--deep-purple-A400{color:#651fff !important}.mdl-color--deep-purple-A400{background-color:#651fff !important}.mdl-color-text--deep-purple-A700{color:#6200ea !important}.mdl-color--deep-purple-A700{background-color:#6200ea !important}.mdl-color-text--indigo{color:#3f51b5 !important}.mdl-color--indigo{background-color:#3f51b5 !important}.mdl-color-text--indigo-50{color:#e8eaf6 !important}.mdl-color--indigo-50{background-color:#e8eaf6 !important}.mdl-color-text--indigo-100{color:#c5cae9 !important}.mdl-color--indigo-100{background-color:#c5cae9 !important}.mdl-color-text--indigo-200{color:#9fa8da !important}.mdl-color--indigo-200{background-color:#9fa8da !important}.mdl-color-text--indigo-300{color:#7986cb !important}.mdl-color--indigo-300{background-color:#7986cb !important}.mdl-color-text--indigo-400{color:#5c6bc0 !important}.mdl-color--indigo-400{background-color:#5c6bc0 !important}.mdl-color-text--indigo-500{color:#3f51b5 !important}.mdl-color--indigo-500{background-color:#3f51b5 !important}.mdl-color-text--indigo-600{color:#3949ab !important}.mdl-color--indigo-600{background-color:#3949ab !important}.mdl-color-text--indigo-700{color:#303f9f !important}.mdl-color--indigo-700{background-color:#303f9f !important}.mdl-color-text--indigo-800{color:#283593 !important}.mdl-color--indigo-800{background-color:#283593 !important}.mdl-color-text--indigo-900{color:#1a237e !important}.mdl-color--indigo-900{background-color:#1a237e !important}.mdl-color-text--indigo-A100{color:#8c9eff !important}.mdl-color--indigo-A100{background-color:#8c9eff !important}.mdl-color-text--indigo-A200{color:#536dfe !important}.mdl-color--indigo-A200{background-color:#536dfe !important}.mdl-color-text--indigo-A400{color:#3d5afe !important}.mdl-color--indigo-A400{background-color:#3d5afe !important}.mdl-color-text--indigo-A700{color:#304ffe !important}.mdl-color--indigo-A700{background-color:#304ffe !important}.mdl-color-text--blue{color:#2196f3 !important}.mdl-color--blue{background-color:#2196f3 !important}.mdl-color-text--blue-50{color:#e3f2fd !important}.mdl-color--blue-50{background-color:#e3f2fd !important}.mdl-color-text--blue-100{color:#bbdefb !important}.mdl-color--blue-100{background-color:#bbdefb !important}.mdl-color-text--blue-200{color:#90caf9 !important}.mdl-color--blue-200{background-color:#90caf9 !important}.mdl-color-text--blue-300{color:#64b5f6 !important}.mdl-color--blue-300{background-color:#64b5f6 !important}.mdl-color-text--blue-400{color:#42a5f5 !important}.mdl-color--blue-400{background-color:#42a5f5 !important}.mdl-color-text--blue-500{color:#2196f3 !important}.mdl-color--blue-500{background-color:#2196f3 !important}.mdl-color-text--blue-600{color:#1e88e5 !important}.mdl-color--blue-600{background-color:#1e88e5 !important}.mdl-color-text--blue-700{color:#1976d2 !important}.mdl-color--blue-700{background-color:#1976d2 !important}.mdl-color-text--blue-800{color:#1565c0 !important}.mdl-color--blue-800{background-color:#1565c0 !important}.mdl-color-text--blue-900{color:#0d47a1 !important}.mdl-color--blue-900{background-color:#0d47a1 !important}.mdl-color-text--blue-A100{color:#82b1ff !important}.mdl-color--blue-A100{background-color:#82b1ff !important}.mdl-color-text--blue-A200{color:#448aff !important}.mdl-color--blue-A200{background-color:#448aff !important}.mdl-color-text--blue-A400{color:#2979ff !important}.mdl-color--blue-A400{background-color:#2979ff !important}.mdl-color-text--blue-A700{color:#2962ff !important}.mdl-color--blue-A700{background-color:#2962ff !important}.mdl-color-text--light-blue{color:#03a9f4 !important}.mdl-color--light-blue{background-color:#03a9f4 !important}.mdl-color-text--light-blue-50{color:#e1f5fe !important}.mdl-color--light-blue-50{background-color:#e1f5fe !important}.mdl-color-text--light-blue-100{color:#b3e5fc !important}.mdl-color--light-blue-100{background-color:#b3e5fc !important}.mdl-color-text--light-blue-200{color:#81d4fa !important}.mdl-color--light-blue-200{background-color:#81d4fa !important}.mdl-color-text--light-blue-300{color:#4fc3f7 !important}.mdl-color--light-blue-300{background-color:#4fc3f7 !important}.mdl-color-text--light-blue-400{color:#29b6f6 !important}.mdl-color--light-blue-400{background-color:#29b6f6 !important}.mdl-color-text--light-blue-500{color:#03a9f4 !important}.mdl-color--light-blue-500{background-color:#03a9f4 !important}.mdl-color-text--light-blue-600{color:#039be5 !important}.mdl-color--light-blue-600{background-color:#039be5 !important}.mdl-color-text--light-blue-700{color:#0288d1 !important}.mdl-color--light-blue-700{background-color:#0288d1 !important}.mdl-color-text--light-blue-800{color:#0277bd !important}.mdl-color--light-blue-800{background-color:#0277bd !important}.mdl-color-text--light-blue-900{color:#01579b !important}.mdl-color--light-blue-900{background-color:#01579b !important}.mdl-color-text--light-blue-A100{color:#80d8ff !important}.mdl-color--light-blue-A100{background-color:#80d8ff !important}.mdl-color-text--light-blue-A200{color:#40c4ff !important}.mdl-color--light-blue-A200{background-color:#40c4ff !important}.mdl-color-text--light-blue-A400{color:#00b0ff !important}.mdl-color--light-blue-A400{background-color:#00b0ff !important}.mdl-color-text--light-blue-A700{color:#0091ea !important}.mdl-color--light-blue-A700{background-color:#0091ea !important}.mdl-color-text--cyan{color:#00bcd4 !important}.mdl-color--cyan{background-color:#00bcd4 !important}.mdl-color-text--cyan-50{color:#e0f7fa !important}.mdl-color--cyan-50{background-color:#e0f7fa !important}.mdl-color-text--cyan-100{color:#b2ebf2 !important}.mdl-color--cyan-100{background-color:#b2ebf2 !important}.mdl-color-text--cyan-200{color:#80deea !important}.mdl-color--cyan-200{background-color:#80deea !important}.mdl-color-text--cyan-300{color:#4dd0e1 !important}.mdl-color--cyan-300{background-color:#4dd0e1 !important}.mdl-color-text--cyan-400{color:#26c6da !important}.mdl-color--cyan-400{background-color:#26c6da !important}.mdl-color-text--cyan-500{color:#00bcd4 !important}.mdl-color--cyan-500{background-color:#00bcd4 !important}.mdl-color-text--cyan-600{color:#00acc1 !important}.mdl-color--cyan-600{background-color:#00acc1 !important}.mdl-color-text--cyan-700{color:#0097a7 !important}.mdl-color--cyan-700{background-color:#0097a7 !important}.mdl-color-text--cyan-800{color:#00838f !important}.mdl-color--cyan-800{background-color:#00838f !important}.mdl-color-text--cyan-900{color:#006064 !important}.mdl-color--cyan-900{background-color:#006064 !important}.mdl-color-text--cyan-A100{color:#84ffff !important}.mdl-color--cyan-A100{background-color:#84ffff !important}.mdl-color-text--cyan-A200{color:#18ffff !important}.mdl-color--cyan-A200{background-color:#18ffff !important}.mdl-color-text--cyan-A400{color:#00e5ff !important}.mdl-color--cyan-A400{background-color:#00e5ff !important}.mdl-color-text--cyan-A700{color:#00b8d4 !important}.mdl-color--cyan-A700{background-color:#00b8d4 !important}.mdl-color-text--teal{color:#009688 !important}.mdl-color--teal{background-color:#009688 !important}.mdl-color-text--teal-50{color:#e0f2f1 !important}.mdl-color--teal-50{background-color:#e0f2f1 !important}.mdl-color-text--teal-100{color:#b2dfdb !important}.mdl-color--teal-100{background-color:#b2dfdb !important}.mdl-color-text--teal-200{color:#80cbc4 !important}.mdl-color--teal-200{background-color:#80cbc4 !important}.mdl-color-text--teal-300{color:#4db6ac !important}.mdl-color--teal-300{background-color:#4db6ac !important}.mdl-color-text--teal-400{color:#26a69a !important}.mdl-color--teal-400{background-color:#26a69a !important}.mdl-color-text--teal-500{color:#009688 !important}.mdl-color--teal-500{background-color:#009688 !important}.mdl-color-text--teal-600{color:#00897b !important}.mdl-color--teal-600{background-color:#00897b !important}.mdl-color-text--teal-700{color:#00796b !important}.mdl-color--teal-700{background-color:#00796b !important}.mdl-color-text--teal-800{color:#00695c !important}.mdl-color--teal-800{background-color:#00695c !important}.mdl-color-text--teal-900{color:#004d40 !important}.mdl-color--teal-900{background-color:#004d40 !important}.mdl-color-text--teal-A100{color:#a7ffeb !important}.mdl-color--teal-A100{background-color:#a7ffeb !important}.mdl-color-text--teal-A200{color:#64ffda !important}.mdl-color--teal-A200{background-color:#64ffda !important}.mdl-color-text--teal-A400{color:#1de9b6 !important}.mdl-color--teal-A400{background-color:#1de9b6 !important}.mdl-color-text--teal-A700{color:#00bfa5 !important}.mdl-color--teal-A700{background-color:#00bfa5 !important}.mdl-color-text--green{color:#4caf50 !important}.mdl-color--green{background-color:#4caf50 !important}.mdl-color-text--green-50{color:#e8f5e9 !important}.mdl-color--green-50{background-color:#e8f5e9 !important}.mdl-color-text--green-100{color:#c8e6c9 !important}.mdl-color--green-100{background-color:#c8e6c9 !important}.mdl-color-text--green-200{color:#a5d6a7 !important}.mdl-color--green-200{background-color:#a5d6a7 !important}.mdl-color-text--green-300{color:#81c784 !important}.mdl-color--green-300{background-color:#81c784 !important}.mdl-color-text--green-400{color:#66bb6a !important}.mdl-color--green-400{background-color:#66bb6a !important}.mdl-color-text--green-500{color:#4caf50 !important}.mdl-color--green-500{background-color:#4caf50 !important}.mdl-color-text--green-600{color:#43a047 !important}.mdl-color--green-600{background-color:#43a047 !important}.mdl-color-text--green-700{color:#388e3c !important}.mdl-color--green-700{background-color:#388e3c !important}.mdl-color-text--green-800{color:#2e7d32 !important}.mdl-color--green-800{background-color:#2e7d32 !important}.mdl-color-text--green-900{color:#1b5e20 !important}.mdl-color--green-900{background-color:#1b5e20 !important}.mdl-color-text--green-A100{color:#b9f6ca !important}.mdl-color--green-A100{background-color:#b9f6ca !important}.mdl-color-text--green-A200{color:#69f0ae !important}.mdl-color--green-A200{background-color:#69f0ae !important}.mdl-color-text--green-A400{color:#00e676 !important}.mdl-color--green-A400{background-color:#00e676 !important}.mdl-color-text--green-A700{color:#00c853 !important}.mdl-color--green-A700{background-color:#00c853 !important}.mdl-color-text--light-green{color:#8bc34a !important}.mdl-color--light-green{background-color:#8bc34a !important}.mdl-color-text--light-green-50{color:#f1f8e9 !important}.mdl-color--light-green-50{background-color:#f1f8e9 !important}.mdl-color-text--light-green-100{color:#dcedc8 !important}.mdl-color--light-green-100{background-color:#dcedc8 !important}.mdl-color-text--light-green-200{color:#c5e1a5 !important}.mdl-color--light-green-200{background-color:#c5e1a5 !important}.mdl-color-text--light-green-300{color:#aed581 !important}.mdl-color--light-green-300{background-color:#aed581 !important}.mdl-color-text--light-green-400{color:#9ccc65 !important}.mdl-color--light-green-400{background-color:#9ccc65 !important}.mdl-color-text--light-green-500{color:#8bc34a !important}.mdl-color--light-green-500{background-color:#8bc34a !important}.mdl-color-text--light-green-600{color:#7cb342 !important}.mdl-color--light-green-600{background-color:#7cb342 !important}.mdl-color-text--light-green-700{color:#689f38 !important}.mdl-color--light-green-700{background-color:#689f38 !important}.mdl-color-text--light-green-800{color:#558b2f !important}.mdl-color--light-green-800{background-color:#558b2f !important}.mdl-color-text--light-green-900{color:#33691e !important}.mdl-color--light-green-900{background-color:#33691e !important}.mdl-color-text--light-green-A100{color:#ccff90 !important}.mdl-color--light-green-A100{background-color:#ccff90 !important}.mdl-color-text--light-green-A200{color:#b2ff59 !important}.mdl-color--light-green-A200{background-color:#b2ff59 !important}.mdl-color-text--light-green-A400{color:#76ff03 !important}.mdl-color--light-green-A400{background-color:#76ff03 !important}.mdl-color-text--light-green-A700{color:#64dd17 !important}.mdl-color--light-green-A700{background-color:#64dd17 !important}.mdl-color-text--lime{color:#cddc39 !important}.mdl-color--lime{background-color:#cddc39 !important}.mdl-color-text--lime-50{color:#f9fbe7 !important}.mdl-color--lime-50{background-color:#f9fbe7 !important}.mdl-color-text--lime-100{color:#f0f4c3 !important}.mdl-color--lime-100{background-color:#f0f4c3 !important}.mdl-color-text--lime-200{color:#e6ee9c !important}.mdl-color--lime-200{background-color:#e6ee9c !important}.mdl-color-text--lime-300{color:#dce775 !important}.mdl-color--lime-300{background-color:#dce775 !important}.mdl-color-text--lime-400{color:#d4e157 !important}.mdl-color--lime-400{background-color:#d4e157 !important}.mdl-color-text--lime-500{color:#cddc39 !important}.mdl-color--lime-500{background-color:#cddc39 !important}.mdl-color-text--lime-600{color:#c0ca33 !important}.mdl-color--lime-600{background-color:#c0ca33 !important}.mdl-color-text--lime-700{color:#afb42b !important}.mdl-color--lime-700{background-color:#afb42b !important}.mdl-color-text--lime-800{color:#9e9d24 !important}.mdl-color--lime-800{background-color:#9e9d24 !important}.mdl-color-text--lime-900{color:#827717 !important}.mdl-color--lime-900{background-color:#827717 !important}.mdl-color-text--lime-A100{color:#f4ff81 !important}.mdl-color--lime-A100{background-color:#f4ff81 !important}.mdl-color-text--lime-A200{color:#eeff41 !important}.mdl-color--lime-A200{background-color:#eeff41 !important}.mdl-color-text--lime-A400{color:#c6ff00 !important}.mdl-color--lime-A400{background-color:#c6ff00 !important}.mdl-color-text--lime-A700{color:#aeea00 !important}.mdl-color--lime-A700{background-color:#aeea00 !important}.mdl-color-text--yellow{color:#ffeb3b !important}.mdl-color--yellow{background-color:#ffeb3b !important}.mdl-color-text--yellow-50{color:#fffde7 !important}.mdl-color--yellow-50{background-color:#fffde7 !important}.mdl-color-text--yellow-100{color:#fff9c4 !important}.mdl-color--yellow-100{background-color:#fff9c4 !important}.mdl-color-text--yellow-200{color:#fff59d !important}.mdl-color--yellow-200{background-color:#fff59d !important}.mdl-color-text--yellow-300{color:#fff176 !important}.mdl-color--yellow-300{background-color:#fff176 !important}.mdl-color-text--yellow-400{color:#ffee58 !important}.mdl-color--yellow-400{background-color:#ffee58 !important}.mdl-color-text--yellow-500{color:#ffeb3b !important}.mdl-color--yellow-500{background-color:#ffeb3b !important}.mdl-color-text--yellow-600{color:#fdd835 !important}.mdl-color--yellow-600{background-color:#fdd835 !important}.mdl-color-text--yellow-700{color:#fbc02d !important}.mdl-color--yellow-700{background-color:#fbc02d !important}.mdl-color-text--yellow-800{color:#f9a825 !important}.mdl-color--yellow-800{background-color:#f9a825 !important}.mdl-color-text--yellow-900{color:#f57f17 !important}.mdl-color--yellow-900{background-color:#f57f17 !important}.mdl-color-text--yellow-A100{color:#ffff8d !important}.mdl-color--yellow-A100{background-color:#ffff8d !important}.mdl-color-text--yellow-A200{color:#ff0 !important}.mdl-color--yellow-A200{background-color:#ff0 !important}.mdl-color-text--yellow-A400{color:#ffea00 !important}.mdl-color--yellow-A400{background-color:#ffea00 !important}.mdl-color-text--yellow-A700{color:#ffd600 !important}.mdl-color--yellow-A700{background-color:#ffd600 !important}.mdl-color-text--amber{color:#ffc107 !important}.mdl-color--amber{background-color:#ffc107 !important}.mdl-color-text--amber-50{color:#fff8e1 !important}.mdl-color--amber-50{background-color:#fff8e1 !important}.mdl-color-text--amber-100{color:#ffecb3 !important}.mdl-color--amber-100{background-color:#ffecb3 !important}.mdl-color-text--amber-200{color:#ffe082 !important}.mdl-color--amber-200{background-color:#ffe082 !important}.mdl-color-text--amber-300{color:#ffd54f !important}.mdl-color--amber-300{background-color:#ffd54f !important}.mdl-color-text--amber-400{color:#ffca28 !important}.mdl-color--amber-400{background-color:#ffca28 !important}.mdl-color-text--amber-500{color:#ffc107 !important}.mdl-color--amber-500{background-color:#ffc107 !important}.mdl-color-text--amber-600{color:#ffb300 !important}.mdl-color--amber-600{background-color:#ffb300 !important}.mdl-color-text--amber-700{color:#ffa000 !important}.mdl-color--amber-700{background-color:#ffa000 !important}.mdl-color-text--amber-800{color:#ff8f00 !important}.mdl-color--amber-800{background-color:#ff8f00 !important}.mdl-color-text--amber-900{color:#ff6f00 !important}.mdl-color--amber-900{background-color:#ff6f00 !important}.mdl-color-text--amber-A100{color:#ffe57f !important}.mdl-color--amber-A100{background-color:#ffe57f !important}.mdl-color-text--amber-A200{color:#ffd740 !important}.mdl-color--amber-A200{background-color:#ffd740 !important}.mdl-color-text--amber-A400{color:#ffc400 !important}.mdl-color--amber-A400{background-color:#ffc400 !important}.mdl-color-text--amber-A700{color:#ffab00 !important}.mdl-color--amber-A700{background-color:#ffab00 !important}.mdl-color-text--orange{color:#ff9800 !important}.mdl-color--orange{background-color:#ff9800 !important}.mdl-color-text--orange-50{color:#fff3e0 !important}.mdl-color--orange-50{background-color:#fff3e0 !important}.mdl-color-text--orange-100{color:#ffe0b2 !important}.mdl-color--orange-100{background-color:#ffe0b2 !important}.mdl-color-text--orange-200{color:#ffcc80 !important}.mdl-color--orange-200{background-color:#ffcc80 !important}.mdl-color-text--orange-300{color:#ffb74d !important}.mdl-color--orange-300{background-color:#ffb74d !important}.mdl-color-text--orange-400{color:#ffa726 !important}.mdl-color--orange-400{background-color:#ffa726 !important}.mdl-color-text--orange-500{color:#ff9800 !important}.mdl-color--orange-500{background-color:#ff9800 !important}.mdl-color-text--orange-600{color:#fb8c00 !important}.mdl-color--orange-600{background-color:#fb8c00 !important}.mdl-color-text--orange-700{color:#f57c00 !important}.mdl-color--orange-700{background-color:#f57c00 !important}.mdl-color-text--orange-800{color:#ef6c00 !important}.mdl-color--orange-800{background-color:#ef6c00 !important}.mdl-color-text--orange-900{color:#e65100 !important}.mdl-color--orange-900{background-color:#e65100 !important}.mdl-color-text--orange-A100{color:#ffd180 !important}.mdl-color--orange-A100{background-color:#ffd180 !important}.mdl-color-text--orange-A200{color:#ffab40 !important}.mdl-color--orange-A200{background-color:#ffab40 !important}.mdl-color-text--orange-A400{color:#ff9100 !important}.mdl-color--orange-A400{background-color:#ff9100 !important}.mdl-color-text--orange-A700{color:#ff6d00 !important}.mdl-color--orange-A700{background-color:#ff6d00 !important}.mdl-color-text--deep-orange{color:#ff5722 !important}.mdl-color--deep-orange{background-color:#ff5722 !important}.mdl-color-text--deep-orange-50{color:#fbe9e7 !important}.mdl-color--deep-orange-50{background-color:#fbe9e7 !important}.mdl-color-text--deep-orange-100{color:#ffccbc !important}.mdl-color--deep-orange-100{background-color:#ffccbc !important}.mdl-color-text--deep-orange-200{color:#ffab91 !important}.mdl-color--deep-orange-200{background-color:#ffab91 !important}.mdl-color-text--deep-orange-300{color:#ff8a65 !important}.mdl-color--deep-orange-300{background-color:#ff8a65 !important}.mdl-color-text--deep-orange-400{color:#ff7043 !important}.mdl-color--deep-orange-400{background-color:#ff7043 !important}.mdl-color-text--deep-orange-500{color:#ff5722 !important}.mdl-color--deep-orange-500{background-color:#ff5722 !important}.mdl-color-text--deep-orange-600{color:#f4511e !important}.mdl-color--deep-orange-600{background-color:#f4511e !important}.mdl-color-text--deep-orange-700{color:#e64a19 !important}.mdl-color--deep-orange-700{background-color:#e64a19 !important}.mdl-color-text--deep-orange-800{color:#d84315 !important}.mdl-color--deep-orange-800{background-color:#d84315 !important}.mdl-color-text--deep-orange-900{color:#bf360c !important}.mdl-color--deep-orange-900{background-color:#bf360c !important}.mdl-color-text--deep-orange-A100{color:#ff9e80 !important}.mdl-color--deep-orange-A100{background-color:#ff9e80 !important}.mdl-color-text--deep-orange-A200{color:#ff6e40 !important}.mdl-color--deep-orange-A200{background-color:#ff6e40 !important}.mdl-color-text--deep-orange-A400{color:#ff3d00 !important}.mdl-color--deep-orange-A400{background-color:#ff3d00 !important}.mdl-color-text--deep-orange-A700{color:#dd2c00 !important}.mdl-color--deep-orange-A700{background-color:#dd2c00 !important}.mdl-color-text--brown{color:#795548 !important}.mdl-color--brown{background-color:#795548 !important}.mdl-color-text--brown-50{color:#efebe9 !important}.mdl-color--brown-50{background-color:#efebe9 !important}.mdl-color-text--brown-100{color:#d7ccc8 !important}.mdl-color--brown-100{background-color:#d7ccc8 !important}.mdl-color-text--brown-200{color:#bcaaa4 !important}.mdl-color--brown-200{background-color:#bcaaa4 !important}.mdl-color-text--brown-300{color:#a1887f !important}.mdl-color--brown-300{background-color:#a1887f !important}.mdl-color-text--brown-400{color:#8d6e63 !important}.mdl-color--brown-400{background-color:#8d6e63 !important}.mdl-color-text--brown-500{color:#795548 !important}.mdl-color--brown-500{background-color:#795548 !important}.mdl-color-text--brown-600{color:#6d4c41 !important}.mdl-color--brown-600{background-color:#6d4c41 !important}.mdl-color-text--brown-700{color:#5d4037 !important}.mdl-color--brown-700{background-color:#5d4037 !important}.mdl-color-text--brown-800{color:#4e342e !important}.mdl-color--brown-800{background-color:#4e342e !important}.mdl-color-text--brown-900{color:#3e2723 !important}.mdl-color--brown-900{background-color:#3e2723 !important}.mdl-color-text--grey{color:#9e9e9e !important}.mdl-color--grey{background-color:#9e9e9e !important}.mdl-color-text--grey-50{color:#fafafa !important}.mdl-color--grey-50{background-color:#fafafa !important}.mdl-color-text--grey-100{color:#f5f5f5 !important}.mdl-color--grey-100{background-color:#f5f5f5 !important}.mdl-color-text--grey-200{color:#eee !important}.mdl-color--grey-200{background-color:#eee !important}.mdl-color-text--grey-300{color:#e0e0e0 !important}.mdl-color--grey-300{background-color:#e0e0e0 !important}.mdl-color-text--grey-400{color:#bdbdbd !important}.mdl-color--grey-400{background-color:#bdbdbd !important}.mdl-color-text--grey-500{color:#9e9e9e !important}.mdl-color--grey-500{background-color:#9e9e9e !important}.mdl-color-text--grey-600{color:#757575 !important}.mdl-color--grey-600{background-color:#757575 !important}.mdl-color-text--grey-700{color:#616161 !important}.mdl-color--grey-700{background-color:#616161 !important}.mdl-color-text--grey-800{color:#424242 !important}.mdl-color--grey-800{background-color:#424242 !important}.mdl-color-text--grey-900{color:#212121 !important}.mdl-color--grey-900{background-color:#212121 !important}.mdl-color-text--blue-grey{color:#607d8b !important}.mdl-color--blue-grey{background-color:#607d8b !important}.mdl-color-text--blue-grey-50{color:#eceff1 !important}.mdl-color--blue-grey-50{background-color:#eceff1 !important}.mdl-color-text--blue-grey-100{color:#cfd8dc !important}.mdl-color--blue-grey-100{background-color:#cfd8dc !important}.mdl-color-text--blue-grey-200{color:#b0bec5 !important}.mdl-color--blue-grey-200{background-color:#b0bec5 !important}.mdl-color-text--blue-grey-300{color:#90a4ae !important}.mdl-color--blue-grey-300{background-color:#90a4ae !important}.mdl-color-text--blue-grey-400{color:#78909c !important}.mdl-color--blue-grey-400{background-color:#78909c !important}.mdl-color-text--blue-grey-500{color:#607d8b !important}.mdl-color--blue-grey-500{background-color:#607d8b !important}.mdl-color-text--blue-grey-600{color:#546e7a !important}.mdl-color--blue-grey-600{background-color:#546e7a !important}.mdl-color-text--blue-grey-700{color:#455a64 !important}.mdl-color--blue-grey-700{background-color:#455a64 !important}.mdl-color-text--blue-grey-800{color:#37474f !important}.mdl-color--blue-grey-800{background-color:#37474f !important}.mdl-color-text--blue-grey-900{color:#263238 !important}.mdl-color--blue-grey-900{background-color:#263238 !important}.mdl-color--black{background-color:#000 !important}.mdl-color-text--black{color:#000 !important}.mdl-color--white{background-color:#fff !important}.mdl-color-text--white{color:#fff !important}.mdl-color--primary{background-color:#3f51b5 !important}.mdl-color--primary-contrast{background-color:#fff !important}.mdl-color--primary-dark{background-color:#303f9f !important}.mdl-color--accent{background-color:#ff4081 !important}.mdl-color--accent-contrast{background-color:#fff !important}.mdl-color-text--primary{color:#3f51b5 !important}.mdl-color-text--primary-contrast{color:#fff !important}.mdl-color-text--primary-dark{color:#303f9f !important}.mdl-color-text--accent{color:#ff4081 !important}.mdl-color-text--accent-contrast{color:#fff !important}.mdl-ripple{background:#000;border-radius:50%;height:50px;left:0;opacity:0;pointer-events:none;position:absolute;top:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:50px;overflow:hidden}.mdl-ripple.is-animating{transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1);transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1),-webkit-transform .3s cubic-bezier(0,0,.2,1)}.mdl-ripple.is-visible{opacity:.3}.mdl-animation--default,.mdl-animation--fast-out-slow-in{transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-animation--linear-out-slow-in{transition-timing-function:cubic-bezier(0,0,.2,1)}.mdl-animation--fast-out-linear-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.mdl-badge{position:relative;white-space:nowrap;margin-right:24px}.mdl-badge:not([data-badge]){margin-right:auto}.mdl-badge[data-badge]:after{content:attr(data-badge);display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:-11px;right:-24px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:600;font-size:12px;width:22px;height:22px;border-radius:50%;background:#ff4081;color:#fff}.mdl-button .mdl-badge[data-badge]:after{top:-10px;right:-5px}.mdl-badge.mdl-badge--no-background[data-badge]:after{color:#ff4081;background:rgba(255,255,255,.2);box-shadow:0 0 1px gray}.mdl-badge.mdl-badge--overlap{margin-right:10px}.mdl-badge.mdl-badge--overlap:after{right:-10px}.mdl-button{background:0 0;border:none;border-radius:2px;color:#000;position:relative;height:36px;margin:0;min-width:64px;padding:0 16px;display:inline-block;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;letter-spacing:0;overflow:hidden;will-change:box-shadow;transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:none;cursor:pointer;text-decoration:none;text-align:center;line-height:36px;vertical-align:middle}.mdl-button::-moz-focus-inner{border:0}.mdl-button:hover{background-color:rgba(158,158,158,.2)}.mdl-button:focus:not(:active){background-color:rgba(0,0,0,.12)}.mdl-button:active{background-color:rgba(158,158,158,.4)}.mdl-button.mdl-button--colored{color:#3f51b5}.mdl-button.mdl-button--colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.mdl-button[type="submit"]{-webkit-appearance:none}.mdl-button--raised{background:rgba(158,158,158,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-button--raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--raised.mdl-button--colored{background:#3f51b5;color:#fff}.mdl-button--raised.mdl-button--colored:hover{background-color:#3f51b5}.mdl-button--raised.mdl-button--colored:active{background-color:#3f51b5}.mdl-button--raised.mdl-button--colored:focus:not(:active){background-color:#3f51b5}.mdl-button--raised.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--fab{border-radius:50%;font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;overflow:hidden;background:rgba(158,158,158,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);position:relative;line-height:normal}.mdl-button--fab .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--fab.mdl-button--mini-fab{height:40px;min-width:40px;width:40px}.mdl-button--fab .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button--fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--fab.mdl-button--colored{background:#ff4081;color:#fff}.mdl-button--fab.mdl-button--colored:hover{background-color:#ff4081}.mdl-button--fab.mdl-button--colored:focus:not(:active){background-color:#ff4081}.mdl-button--fab.mdl-button--colored:active{background-color:#ff4081}.mdl-button--fab.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--icon{border-radius:50%;font-size:24px;height:32px;margin-left:0;margin-right:0;min-width:32px;width:32px;padding:0;overflow:hidden;color:inherit;line-height:normal}.mdl-button--icon .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon{height:24px;min-width:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon .material-icons{top:0;left:0}.mdl-button--icon .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button__ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-button[disabled] .mdl-button__ripple-container .mdl-ripple,.mdl-button.mdl-button--disabled .mdl-button__ripple-container .mdl-ripple{background-color:transparent}.mdl-button--primary.mdl-button--primary{color:#3f51b5}.mdl-button--primary.mdl-button--primary .mdl-ripple{background:#fff}.mdl-button--primary.mdl-button--primary.mdl-button--raised,.mdl-button--primary.mdl-button--primary.mdl-button--fab{color:#fff;background-color:#3f51b5}.mdl-button--accent.mdl-button--accent{color:#ff4081}.mdl-button--accent.mdl-button--accent .mdl-ripple{background:#fff}.mdl-button--accent.mdl-button--accent.mdl-button--raised,.mdl-button--accent.mdl-button--accent.mdl-button--fab{color:#fff;background-color:#ff4081}.mdl-button[disabled][disabled],.mdl-button.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26);cursor:default;background-color:transparent}.mdl-button--fab[disabled][disabled],.mdl-button--fab.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-button--raised[disabled][disabled],.mdl-button--raised.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:none}.mdl-button--colored[disabled][disabled],.mdl-button--colored.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26)}.mdl-button .material-icons{vertical-align:middle}.mdl-card{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;font-size:16px;font-weight:400;min-height:200px;overflow:hidden;width:330px;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.mdl-card__media{background-color:#ff4081;background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.mdl-card__title{-webkit-align-items:center;-ms-flex-align:center;align-items:center;color:#000;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;line-height:normal;padding:16px;-webkit-perspective-origin:165px 56px;perspective-origin:165px 56px;-webkit-transform-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.mdl-card__title.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__title-text{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;color:inherit;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:24px;font-weight:300;line-height:normal;overflow:hidden;-webkit-transform-origin:149px 48px;transform-origin:149px 48px;margin:0}.mdl-card__subtitle-text{font-size:14px;color:rgba(0,0,0,.54);margin:0}.mdl-card__supporting-text{color:rgba(0,0,0,.54);font-size:1rem;line-height:18px;overflow:hidden;padding:16px;width:90%}.mdl-card__actions{font-size:16px;line-height:normal;width:100%;background-color:transparent;padding:8px;box-sizing:border-box}.mdl-card__actions.mdl-card--border{border-top:1px solid rgba(0,0,0,.1)}.mdl-card--expand{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-card__menu{position:absolute;right:16px;top:16px}.mdl-checkbox{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0}.mdl-checkbox.is-upgraded{padding-left:24px}.mdl-checkbox__input{line-height:24px}.mdl-checkbox.is-upgraded .mdl-checkbox__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-checkbox__box-outline{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;overflow:hidden;border:2px solid rgba(0,0,0,.54);border-radius:2px;z-index:2}.mdl-checkbox.is-checked .mdl-checkbox__box-outline{border:2px solid #3f51b5}fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline,.mdl-checkbox.is-disabled .mdl-checkbox__box-outline{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__focus-helper{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;border-radius:50%;background-color:transparent}.mdl-checkbox.is-focused .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.mdl-checkbox__tick-outline{position:absolute;top:0;left:0;height:100%;width:100%;-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");background:0 0;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background}.mdl-checkbox.is-checked .mdl-checkbox__tick-outline{background:#3f51b5 url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}fieldset[disabled] .mdl-checkbox.is-checked .mdl-checkbox__tick-outline,.mdl-checkbox.is-checked.is-disabled .mdl-checkbox__tick-outline{background:rgba(0,0,0,.26)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}.mdl-checkbox__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0}fieldset[disabled] .mdl-checkbox .mdl-checkbox__label,.mdl-checkbox.is-disabled .mdl-checkbox__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__ripple-container{position:absolute;z-index:2;top:-6px;left:-10px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-checkbox__ripple-container .mdl-ripple{background:#3f51b5}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container{cursor:auto}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container .mdl-ripple,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container .mdl-ripple{background:0 0}.mdl-data-table{position:relative;border:1px solid rgba(0,0,0,.12);border-collapse:collapse;white-space:nowrap;font-size:13px;background-color:#fff}.mdl-data-table thead{padding-bottom:3px}.mdl-data-table thead .mdl-data-table__select{margin-top:0}.mdl-data-table tbody tr{position:relative;height:48px;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background-color}.mdl-data-table tbody tr.is-selected{background-color:#e0e0e0}.mdl-data-table tbody tr:hover{background-color:#eee}.mdl-data-table td{text-align:right}.mdl-data-table th{padding:0 18px 12px 18px;text-align:right}.mdl-data-table td:first-of-type,.mdl-data-table th:first-of-type{padding-left:24px}.mdl-data-table td:last-of-type,.mdl-data-table th:last-of-type{padding-right:24px}.mdl-data-table td{position:relative;height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding:12px 18px;box-sizing:border-box}.mdl-data-table td,.mdl-data-table td .mdl-data-table__select{vertical-align:middle}.mdl-data-table th{position:relative;vertical-align:bottom;text-overflow:ellipsis;font-weight:700;line-height:24px;letter-spacing:0;height:48px;font-size:12px;color:rgba(0,0,0,.54);padding-bottom:8px;box-sizing:border-box}.mdl-data-table th.mdl-data-table__header--sorted-ascending,.mdl-data-table th.mdl-data-table__header--sorted-descending{color:rgba(0,0,0,.87)}.mdl-data-table th.mdl-data-table__header--sorted-ascending:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:before{font-family:'Material Icons';font-weight:400;font-style:normal;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-size:16px;content:"\e5d8";margin-right:5px;vertical-align:sub}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover{cursor:pointer}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover:before{color:rgba(0,0,0,.26)}.mdl-data-table th.mdl-data-table__header--sorted-descending:before{content:"\e5db"}.mdl-data-table__select{width:16px}.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric{text-align:left}.mdl-dialog{border:none;box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);width:280px}.mdl-dialog__title{padding:24px 24px 0;margin:0;font-size:2.5rem}.mdl-dialog__actions{padding:8px 8px 8px 24px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.mdl-dialog__actions>*{margin-right:8px;height:36px}.mdl-dialog__actions>*:first-child{margin-right:0}.mdl-dialog__actions--full-width{padding:0 0 8px}.mdl-dialog__actions--full-width>*{height:48px;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;padding-right:16px;margin-right:0;text-align:right}.mdl-dialog__content{padding:20px 24px 24px;color:rgba(0,0,0,.54)}.mdl-mega-footer{padding:16px 40px;color:#9e9e9e;background-color:#424242}.mdl-mega-footer--top-section:after,.mdl-mega-footer--middle-section:after,.mdl-mega-footer--bottom-section:after,.mdl-mega-footer__top-section:after,.mdl-mega-footer__middle-section:after,.mdl-mega-footer__bottom-section:after{content:'';display:block;clear:both}.mdl-mega-footer--left-section,.mdl-mega-footer__left-section,.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{margin-bottom:16px}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:block;margin-bottom:16px;color:inherit;text-decoration:none}@media screen and (min-width:760px){.mdl-mega-footer--left-section,.mdl-mega-footer__left-section{float:left}.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{float:right}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:inline-block;margin-left:16px;line-height:36px;vertical-align:middle}}.mdl-mega-footer--social-btn,.mdl-mega-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{display:block;position:relative}@media screen and (min-width:760px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{width:33%}.mdl-mega-footer--drop-down-section:nth-child(1),.mdl-mega-footer--drop-down-section:nth-child(2),.mdl-mega-footer__drop-down-section:nth-child(1),.mdl-mega-footer__drop-down-section:nth-child(2){float:left}.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(3){float:right}.mdl-mega-footer--drop-down-section:nth-child(3):after,.mdl-mega-footer__drop-down-section:nth-child(3):after{clear:right}.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section:nth-child(4){clear:right;float:right}.mdl-mega-footer--middle-section:after,.mdl-mega-footer__middle-section:after{content:'';display:block;clear:both}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:0}}@media screen and (min-width:1024px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section,.mdl-mega-footer__drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(4){width:24%;float:left}}.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{position:absolute;width:100%;height:55.8px;padding:32px;margin:-16px 0 0;cursor:pointer;z-index:1;opacity:0}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CE'}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list{display:none}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CF'}.mdl-mega-footer--heading,.mdl-mega-footer__heading{position:relative;width:100%;padding-right:39.8px;margin-bottom:16px;box-sizing:border-box;font-size:14px;line-height:23.8px;font-weight:500;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:#e0e0e0}.mdl-mega-footer--heading:after,.mdl-mega-footer__heading:after{content:'';position:absolute;top:0;right:0;display:block;width:23.8px;height:23.8px;background-size:cover}.mdl-mega-footer--link-list,.mdl-mega-footer__link-list{list-style:none;padding:0;margin:0 0 32px}.mdl-mega-footer--link-list:after,.mdl-mega-footer__link-list:after{clear:both;display:block;content:''}.mdl-mega-footer--link-list li,.mdl-mega-footer__link-list li{font-size:14px;font-weight:400;letter-spacing:0;line-height:20px}.mdl-mega-footer--link-list a,.mdl-mega-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}@media screen and (min-width:760px){.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{display:none}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{content:''}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list{display:block}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{content:''}}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:16px;margin-bottom:16px}.mdl-logo{margin-bottom:16px;color:#fff}.mdl-mega-footer--bottom-section .mdl-mega-footer--link-list li,.mdl-mega-footer__bottom-section .mdl-mega-footer__link-list li{float:left;margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-logo{float:left;margin-bottom:0;margin-right:16px}}.mdl-mini-footer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:32px 16px;color:#9e9e9e;background-color:#424242}.mdl-mini-footer:after{content:'';display:block}.mdl-mini-footer .mdl-logo{line-height:36px}.mdl-mini-footer--link-list,.mdl-mini-footer__link-list{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;list-style:none;margin:0;padding:0}.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{line-height:36px}}.mdl-mini-footer--link-list a,.mdl-mini-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}.mdl-mini-footer--left-section,.mdl-mini-footer__left-section{display:inline-block;-webkit-order:0;-ms-flex-order:0;order:0}.mdl-mini-footer--right-section,.mdl-mini-footer__right-section{display:inline-block;-webkit-order:1;-ms-flex-order:1;order:1}.mdl-mini-footer--social-btn,.mdl-mini-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-icon-toggle{position:relative;z-index:1;vertical-align:middle;display:inline-block;height:32px;margin:0;padding:0}.mdl-icon-toggle__input{line-height:32px}.mdl-icon-toggle.is-upgraded .mdl-icon-toggle__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-icon-toggle__label{display:inline-block;position:relative;cursor:pointer;height:32px;width:32px;min-width:32px;color:#616161;border-radius:50%;padding:0;margin-left:0;margin-right:0;text-align:center;background-color:transparent;will-change:background-color;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.mdl-icon-toggle__label.material-icons{line-height:32px;font-size:24px}.mdl-icon-toggle.is-checked .mdl-icon-toggle__label{color:#3f51b5}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__label{color:rgba(0,0,0,.26);cursor:auto;transition:none}.mdl-icon-toggle.is-focused .mdl-icon-toggle__label{background-color:rgba(0,0,0,.12)}.mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label{background-color:rgba(63,81,181,.26)}.mdl-icon-toggle__ripple-container{position:absolute;z-index:2;top:-2px;left:-2px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-icon-toggle__ripple-container .mdl-ripple{background:#616161}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container{cursor:auto}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container .mdl-ripple{background:0 0}.mdl-list{display:block;padding:8px 0;list-style:none}.mdl-list__item{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;letter-spacing:.04em;line-height:1;min-height:48px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;padding:16px;cursor:default;color:rgba(0,0,0,.87);overflow:hidden}.mdl-list__item,.mdl-list__item .mdl-list__item-primary-content{box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.mdl-list__item .mdl-list__item-primary-content{-webkit-order:0;-ms-flex-order:0;order:0;-webkit-flex-grow:2;-ms-flex-positive:2;flex-grow:2;text-decoration:none}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-icon{margin-right:32px}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-avatar{margin-right:16px}.mdl-list__item .mdl-list__item-secondary-content{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:column;-ms-flex-flow:column;flex-flow:column;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end;margin-left:16px}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-action label{display:inline}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-info{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;color:rgba(0,0,0,.54)}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-sub-header{padding:0 0 0 16px}.mdl-list__item-icon,.mdl-list__item-icon.material-icons{height:24px;width:24px;font-size:24px;box-sizing:border-box;color:#757575}.mdl-list__item-avatar,.mdl-list__item-avatar.material-icons{height:40px;width:40px;box-sizing:border-box;border-radius:50%;background-color:#757575;font-size:40px;color:#fff}.mdl-list__item--two-line{height:72px}.mdl-list__item--two-line .mdl-list__item-primary-content{height:36px;line-height:20px;display:block}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-avatar{float:left}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left;margin-top:6px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-secondary-content{height:36px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-sub-title{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-list__item--three-line{height:88px}.mdl-list__item--three-line .mdl-list__item-primary-content{height:52px;line-height:20px;display:block}.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-avatar,.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left}.mdl-list__item--three-line .mdl-list__item-secondary-content{height:52px}.mdl-list__item--three-line .mdl-list__item-text-body{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;height:52px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-menu__container{display:block;margin:0;padding:0;border:none;position:absolute;overflow:visible;height:0;width:0;visibility:hidden;z-index:-1}.mdl-menu__container.is-visible,.mdl-menu__container.is-animating{z-index:999;visibility:visible}.mdl-menu__outline{display:block;background:#fff;margin:0;padding:0;border:none;border-radius:2px;position:absolute;top:0;left:0;overflow:hidden;opacity:0;-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:0 0;transform-origin:0 0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);will-change:transform;transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),-webkit-transform .3s cubic-bezier(.4,0,.2,1);z-index:-1}.mdl-menu__container.is-visible .mdl-menu__outline{opacity:1;-webkit-transform:scale(1);transform:scale(1);z-index:999}.mdl-menu__outline.mdl-menu--bottom-right{-webkit-transform-origin:100% 0;transform-origin:100% 0}.mdl-menu__outline.mdl-menu--top-left{-webkit-transform-origin:0 100%;transform-origin:0 100%}.mdl-menu__outline.mdl-menu--top-right{-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.mdl-menu{position:absolute;list-style:none;top:0;left:0;height:auto;width:auto;min-width:124px;padding:8px 0;margin:0;opacity:0;clip:rect(0 0 0 0);z-index:-1}.mdl-menu__container.is-visible .mdl-menu{opacity:1;z-index:999}.mdl-menu.is-animating{transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1)}.mdl-menu.mdl-menu--bottom-right{left:auto;right:0}.mdl-menu.mdl-menu--top-left{top:auto;bottom:0}.mdl-menu.mdl-menu--top-right{top:auto;left:auto;bottom:0;right:0}.mdl-menu.mdl-menu--unaligned{top:auto;left:auto}.mdl-menu__item{display:block;border:none;color:rgba(0,0,0,.87);background-color:transparent;text-align:left;margin:0;padding:0 16px;outline-color:#bdbdbd;position:relative;overflow:hidden;font-size:14px;font-weight:400;letter-spacing:0;text-decoration:none;cursor:pointer;height:48px;line-height:48px;white-space:nowrap;opacity:0;transition:opacity .2s cubic-bezier(.4,0,.2,1);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-menu__container.is-visible .mdl-menu__item{opacity:1}.mdl-menu__item::-moz-focus-inner{border:0}.mdl-menu__item--full-bleed-divider{border-bottom:1px solid rgba(0,0,0,.12)}.mdl-menu__item[disabled],.mdl-menu__item[data-mdl-disabled]{color:#bdbdbd;background-color:transparent;cursor:auto}.mdl-menu__item[disabled]:hover,.mdl-menu__item[data-mdl-disabled]:hover{background-color:transparent}.mdl-menu__item[disabled]:focus,.mdl-menu__item[data-mdl-disabled]:focus{background-color:transparent}.mdl-menu__item[disabled] .mdl-ripple,.mdl-menu__item[data-mdl-disabled] .mdl-ripple{background:0 0}.mdl-menu__item:hover{background-color:#eee}.mdl-menu__item:focus{outline:none;background-color:#eee}.mdl-menu__item:active{background-color:#e0e0e0}.mdl-menu__item--ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-progress{display:block;position:relative;height:4px;width:500px;max-width:100%}.mdl-progress>.bar{display:block;position:absolute;top:0;bottom:0;width:0%;transition:width .2s cubic-bezier(.4,0,.2,1)}.mdl-progress>.progressbar{background-color:#3f51b5;z-index:1;left:0}.mdl-progress>.bufferbar{background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5 ,#3f51b5);z-index:0;left:0}.mdl-progress>.auxbar{right:0}@supports (-webkit-appearance:none){.mdl-progress:not(.mdl-progress--indeterminate):not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate):not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5 ,#3f51b5);-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=")}}.mdl-progress:not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(255,255,255,.9),rgba(255,255,255,.9)),linear-gradient(to right,#3f51b5 ,#3f51b5)}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1{-webkit-animation-name:indeterminate1;animation-name:indeterminate1}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1,.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-color:#3f51b5;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-image:none;-webkit-animation-name:indeterminate2;animation-name:indeterminate2}@-webkit-keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@-webkit-keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}@keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}.mdl-navigation{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;box-sizing:border-box}.mdl-navigation__link{color:#424242;text-decoration:none;margin:0;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0;opacity:.87}.mdl-navigation__link .material-icons{vertical-align:middle}.mdl-layout{width:100%;height:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-overflow-scrolling:touch}.mdl-layout.is-small-screen .mdl-layout--large-screen-only{display:none}.mdl-layout:not(.is-small-screen) .mdl-layout--small-screen-only{display:none}.mdl-layout__container{position:absolute;width:100%;height:100%}.mdl-layout__title,.mdl-layout-title{display:block;position:relative;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.mdl-layout-spacer{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-layout__drawer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;width:240px;height:100%;max-height:100%;position:absolute;top:0;left:0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);box-sizing:border-box;border-right:1px solid #e0e0e0;background:#fafafa;-webkit-transform:translateX(-250px);transform:translateX(-250px);-webkit-transform-style:preserve-3d;transform-style:preserve-3d;will-change:transform;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;color:#424242;overflow:visible;overflow-y:auto;z-index:5}.mdl-layout__drawer.is-visible{-webkit-transform:translateX(0);transform:translateX(0)}.mdl-layout__drawer.is-visible~.mdl-layout__content.mdl-layout__content{overflow:hidden}.mdl-layout__drawer>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:64px;padding-left:40px}@media screen and (max-width:1024px){.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:56px;padding-left:16px}}.mdl-layout__drawer .mdl-navigation{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:stretch;-ms-flex-align:stretch;-ms-grid-row-align:stretch;align-items:stretch;padding-top:16px}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{display:block;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;padding:16px 40px;margin:0;color:#757575}@media screen and (max-width:1024px){.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{padding:16px}}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover{background-color:#e0e0e0}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link--current{background-color:#000;color:#e0e0e0}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__drawer{-webkit-transform:translateX(0);transform:translateX(0)}}.mdl-layout__drawer-button{display:block;position:absolute;height:48px;width:48px;border:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden;text-align:center;cursor:pointer;font-size:26px;line-height:50px;font-family:Helvetica,Arial,sans-serif;margin:10px 12px;top:0;left:0;color:#fff;z-index:4}.mdl-layout__header .mdl-layout__drawer-button{position:absolute;color:#fff;background-color:inherit}@media screen and (max-width:1024px){.mdl-layout__header .mdl-layout__drawer-button{margin:4px}}@media screen and (max-width:1024px){.mdl-layout__drawer-button{margin:4px;color:rgba(0,0,0,.5)}}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__drawer-button,.mdl-layout--no-desktop-drawer-button .mdl-layout__drawer-button{display:none}}.mdl-layout--no-drawer-button .mdl-layout__drawer-button{display:none}.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;margin:0;padding:0;border:none;min-height:64px;max-height:1000px;z-index:3;background-color:#3f51b5;color:#fff;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:max-height,box-shadow}@media screen and (max-width:1024px){.mdl-layout__header{min-height:56px}}.mdl-layout--fixed-drawer.is-upgraded:not(.is-small-screen)>.mdl-layout__header{margin-left:240px;width:calc(100% - 240px)}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__header .mdl-layout__header-row{padding-left:40px}}.mdl-layout__header>.mdl-layout-icon{position:absolute;left:40px;top:16px;height:32px;width:32px;overflow:hidden;z-index:3;display:block}@media screen and (max-width:1024px){.mdl-layout__header>.mdl-layout-icon{left:16px;top:12px}}.mdl-layout.has-drawer .mdl-layout__header>.mdl-layout-icon{display:none}.mdl-layout__header.is-compact{max-height:64px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact{max-height:56px}}.mdl-layout__header.is-compact.has-tabs{height:112px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact.has-tabs{min-height:104px}}@media screen and (max-width:1024px){.mdl-layout__header{display:none}.mdl-layout--fixed-header>.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex}}.mdl-layout__header--transparent.mdl-layout__header--transparent{background-color:transparent;box-shadow:none}.mdl-layout__header--seamed,.mdl-layout__header--scroll{box-shadow:none}.mdl-layout__header--waterfall{box-shadow:none;overflow:hidden}.mdl-layout__header--waterfall.is-casting-shadow{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-layout__header--waterfall.mdl-layout__header--waterfall-hide-top{-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.mdl-layout__header-row{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;box-sizing:border-box;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:64px;margin:0;padding:0 40px 0 80px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:40px}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__header-row{padding-left:40px}}@media screen and (max-width:1024px){.mdl-layout__header-row{height:56px;padding:0 16px 0 72px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:16px}}.mdl-layout__header-row>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__header--scroll .mdl-layout__header-row{width:100%}.mdl-layout__header-row .mdl-navigation{margin:0;padding:0;height:64px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-ms-flex-align:center;-ms-grid-row-align:center;align-items:center}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation{height:56px}}.mdl-layout__header-row .mdl-navigation__link{display:block;color:#fff;line-height:64px;padding:0 24px}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation__link{line-height:56px;padding:0 16px}}.mdl-layout__obfuscator{background-color:transparent;position:absolute;top:0;left:0;height:100%;width:100%;z-index:4;visibility:hidden;transition-property:background-color;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-layout__obfuscator.is-visible{background-color:rgba(0,0,0,.5);visibility:visible}@supports (pointer-events:auto){.mdl-layout__obfuscator{background-color:rgba(0,0,0,.5);opacity:0;transition-property:opacity;visibility:visible;pointer-events:none}.mdl-layout__obfuscator.is-visible{pointer-events:auto;opacity:1}}.mdl-layout__content{-ms-flex:0 1 auto;position:relative;display:inline-block;overflow-y:auto;overflow-x:hidden;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;z-index:1;-webkit-overflow-scrolling:touch}.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:240px}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow:visible}@media screen and (max-width:1024px){.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:0}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow-y:auto;overflow-x:hidden}}.mdl-layout__tab-bar{height:96px;margin:0;width:calc(100% - 112px);padding:0 0 0 56px;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:#3f51b5;overflow-y:hidden;overflow-x:scroll}.mdl-layout__tab-bar::-webkit-scrollbar{display:none}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}}@media screen and (max-width:1024px){.mdl-layout__tab-bar{width:calc(100% - 60px);padding:0 0 0 60px}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{width:calc(100% - 8px);padding-left:4px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar{padding:0;overflow:hidden;width:100%}.mdl-layout__tab-bar-container{position:relative;height:48px;width:100%;border:none;margin:0;z-index:2;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.mdl-layout__container>.mdl-layout__tab-bar-container{position:absolute;top:0;left:0}.mdl-layout__tab-bar-button{display:inline-block;position:absolute;top:0;height:48px;width:56px;z-index:4;text-align:center;background-color:#3f51b5;color:transparent;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button{width:16px}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button .material-icons,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button .material-icons{position:relative;left:-4px}@media screen and (max-width:1024px){.mdl-layout__tab-bar-button{display:none;width:60px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar-button{display:none}.mdl-layout__tab-bar-button .material-icons{line-height:48px}.mdl-layout__tab-bar-button.is-active{color:#fff}.mdl-layout__tab-bar-left-button{left:0}.mdl-layout__tab-bar-right-button{right:0}.mdl-layout__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(255,255,255,.6);overflow:hidden}@media screen and (max-width:1024px){.mdl-layout__tab{padding:0 12px}}.mdl-layout--fixed-tabs .mdl-layout__tab{float:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0}.mdl-layout.is-upgraded .mdl-layout__tab.is-active{color:#fff}.mdl-layout.is-upgraded .mdl-layout__tab.is-active::after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#ff4081;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-layout__tab .mdl-layout__tab-ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-layout__tab .mdl-layout__tab-ripple-container .mdl-ripple{background-color:#fff}.mdl-layout__tab-panel{display:block}.mdl-layout.is-upgraded .mdl-layout__tab-panel{display:none}.mdl-layout.is-upgraded .mdl-layout__tab-panel.is-active{display:block}.mdl-radio{position:relative;font-size:16px;line-height:24px;display:inline-block;box-sizing:border-box;margin:0;padding-left:0}.mdl-radio.is-upgraded{padding-left:24px}.mdl-radio__button{line-height:24px}.mdl-radio.is-upgraded .mdl-radio__button{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-radio__outer-circle{position:absolute;top:4px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;border:2px solid rgba(0,0,0,.54);border-radius:50%;z-index:2}.mdl-radio.is-checked .mdl-radio__outer-circle{border:2px solid #3f51b5}.mdl-radio__outer-circle fieldset[disabled] .mdl-radio,.mdl-radio.is-disabled .mdl-radio__outer-circle{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-radio__inner-circle{position:absolute;z-index:1;margin:0;top:8px;left:4px;box-sizing:border-box;width:8px;height:8px;cursor:pointer;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;-webkit-transform:scale3d(0,0,0);transform:scale3d(0,0,0);border-radius:50%;background:#3f51b5}.mdl-radio.is-checked .mdl-radio__inner-circle{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}fieldset[disabled] .mdl-radio .mdl-radio__inner-circle,.mdl-radio.is-disabled .mdl-radio__inner-circle{background:rgba(0,0,0,.26);cursor:auto}.mdl-radio.is-focused .mdl-radio__inner-circle{box-shadow:0 0 0 10px rgba(0,0,0,.1)}.mdl-radio__label{cursor:pointer}fieldset[disabled] .mdl-radio .mdl-radio__label,.mdl-radio.is-disabled .mdl-radio__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-radio__ripple-container{position:absolute;z-index:2;top:-9px;left:-13px;box-sizing:border-box;width:42px;height:42px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-radio__ripple-container .mdl-ripple{background:#3f51b5}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container,.mdl-radio.is-disabled .mdl-radio__ripple-container{cursor:auto}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container .mdl-ripple,.mdl-radio.is-disabled .mdl-radio__ripple-container .mdl-ripple{background:0 0}_:-ms-input-placeholder,:root .mdl-slider.mdl-slider.is-upgraded{-ms-appearance:none;height:32px;margin:0}.mdl-slider{width:calc(100% - 40px);margin:0 20px}.mdl-slider.is-upgraded{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:2px;background:0 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0;padding:0;color:#3f51b5;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;z-index:1;cursor:pointer}.mdl-slider.is-upgraded::-moz-focus-outer{border:0}.mdl-slider.is-upgraded::-ms-tooltip{display:none}.mdl-slider.is-upgraded::-webkit-slider-runnable-track{background:0 0}.mdl-slider.is-upgraded::-moz-range-track{background:0 0;border:none}.mdl-slider.is-upgraded::-ms-track{background:0 0;color:transparent;height:2px;width:100%;border:none}.mdl-slider.is-upgraded::-ms-fill-lower{padding:0;background:linear-gradient(to right,transparent,transparent 16px,#3f51b5 16px,#3f51b5 0)}.mdl-slider.is-upgraded::-ms-fill-upper{padding:0;background:linear-gradient(to left,transparent,transparent 16px,rgba(0,0,0,.26)16px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:#3f51b5;border:none;transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded::-moz-range-thumb{-moz-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background-image:none;background:#3f51b5;border:none}.mdl-slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.mdl-slider.is-upgraded:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.mdl-slider.is-upgraded:active::-webkit-slider-thumb{background-image:none;background:#3f51b5;-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded:active::-moz-range-thumb{background-image:none;background:#3f51b5;transform:scale(1.5)}.mdl-slider.is-upgraded::-ms-thumb{width:32px;height:32px;border:none;border-radius:50%;background:#3f51b5;transform:scale(.375);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,#3f51b5 0%,#3f51b5 37.5%,rgba(63,81,181,.26)37.5%,rgba(63,81,181,.26)100%);transform:scale(1)}.mdl-slider.is-upgraded:active::-ms-thumb{background:#3f51b5;transform:scale(.5625)}.mdl-slider.is-upgraded.is-lowest-value::-webkit-slider-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-moz-range-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb{border:1.6px solid rgba(0,0,0,.26);-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:9px}.mdl-slider.is-upgraded.is-lowest-value:active::-moz-range-thumb{border:1.5px solid rgba(0,0,0,.26);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value::-ms-thumb{background:radial-gradient(circle closest-side,transparent 0%,transparent 66.67%,rgba(0,0,0,.26)66.67%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgba(0,0,0,.12)0%,rgba(0,0,0,.12)25%,rgba(0,0,0,.26)25%,rgba(0,0,0,.26)37.5%,rgba(0,0,0,.12)37.5%,rgba(0,0,0,.12)100%);transform:scale(1)}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-thumb{transform:scale(.5625);background:radial-gradient(circle closest-side,transparent 0%,transparent 77.78%,rgba(0,0,0,.26)77.78%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-lower{background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-fill-upper{margin-left:9px}.mdl-slider.is-upgraded:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled::-webkit-slider-thumb{-webkit-transform:scale(.667);transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded:disabled::-moz-range-thumb{transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-lower{background-color:rgba(0,0,0,.26);left:-6px}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-webkit-slider-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;-webkit-transform:scale(.667);transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-moz-range-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded:disabled:active::-ms-thumb,.mdl-slider.is-upgraded:disabled::-ms-thumb{transform:scale(.25);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-ms-thumb{transform:scale(.25);background:radial-gradient(circle closest-side,transparent 0%,transparent 50%,rgba(0,0,0,.26)50%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded:disabled::-ms-fill-lower{margin-right:6px;background:linear-gradient(to right,transparent,transparent 25px,rgba(0,0,0,.26)25px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded:disabled::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-fill-upper{margin-left:6px}.mdl-slider__ie-container{height:18px;overflow:visible;border:none;margin:none;padding:none}.mdl-slider__container{height:18px;position:relative;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.mdl-slider__container,.mdl-slider__background-flex{background:0 0;display:-webkit-flex;display:-ms-flexbox;display:flex}.mdl-slider__background-flex{position:absolute;height:2px;width:calc(100% - 52px);top:50%;left:0;margin:0 26px;overflow:hidden;border:0;padding:0;-webkit-transform:translate(0,-1px);transform:translate(0,-1px)}.mdl-slider__background-lower{background:#3f51b5}.mdl-slider__background-lower,.mdl-slider__background-upper{-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0}.mdl-slider__background-upper{background:rgba(0,0,0,.26);transition:left .18s cubic-bezier(.4,0,.2,1)}.mdl-snackbar{position:fixed;bottom:0;left:50%;cursor:default;background-color:#323232;z-index:3;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;font-family:"Roboto","Helvetica","Arial",sans-serif;will-change:transform;-webkit-transform:translate(0,80px);transform:translate(0,80px);transition:transform .25s cubic-bezier(.4,0,1,1);transition:transform .25s cubic-bezier(.4,0,1,1),-webkit-transform .25s cubic-bezier(.4,0,1,1);pointer-events:none}@media (max-width:479px){.mdl-snackbar{width:100%;left:0;min-height:48px;max-height:80px}}@media (min-width:480px){.mdl-snackbar{min-width:288px;max-width:568px;border-radius:2px;-webkit-transform:translate(-50%,80px);transform:translate(-50%,80px)}}.mdl-snackbar--active{-webkit-transform:translate(0,0);transform:translate(0,0);pointer-events:auto;transition:transform .25s cubic-bezier(0,0,.2,1);transition:transform .25s cubic-bezier(0,0,.2,1),-webkit-transform .25s cubic-bezier(0,0,.2,1)}@media (min-width:480px){.mdl-snackbar--active{-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}}.mdl-snackbar__text{padding:14px 12px 14px 24px;vertical-align:middle;color:#fff;float:left}.mdl-snackbar__action{background:0 0;border:none;color:#ff4081;float:right;padding:14px 24px 14px 12px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;line-height:1;letter-spacing:0;overflow:hidden;outline:none;opacity:0;pointer-events:none;cursor:pointer;text-decoration:none;text-align:center;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.mdl-snackbar__action::-moz-focus-inner{border:0}.mdl-snackbar__action:not([aria-hidden]){opacity:1;pointer-events:auto}.mdl-spinner{display:inline-block;position:relative;width:28px;height:28px}.mdl-spinner:not(.is-upgraded).is-active:after{content:"Loading..."}.mdl-spinner.is-upgraded.is-active{-webkit-animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite;animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite}@-webkit-keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.mdl-spinner__layer{position:absolute;width:100%;height:100%;opacity:0}.mdl-spinner__layer-1{border-color:#42a5f5}.mdl-spinner--single-color .mdl-spinner__layer-1{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-1{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-2{border-color:#f44336}.mdl-spinner--single-color .mdl-spinner__layer-2{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-2{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-3{border-color:#fdd835}.mdl-spinner--single-color .mdl-spinner__layer-3{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-3{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-4{border-color:#4caf50}.mdl-spinner--single-color .mdl-spinner__layer-4{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-4{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@-webkit-keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}@keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}.mdl-spinner__gap-patch{position:absolute;box-sizing:border-box;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__gap-patch .mdl-spinner__circle{width:1000%;left:-450%}.mdl-spinner__circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__circle-clipper .mdl-spinner__circle{width:200%}.mdl-spinner__circle{box-sizing:border-box;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent!important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0;left:0}.mdl-spinner__left .mdl-spinner__circle{border-right-color:transparent!important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.mdl-spinner.is-active .mdl-spinner__left .mdl-spinner__circle{-webkit-animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__right .mdl-spinner__circle{left:-100%;border-left-color:transparent!important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.mdl-spinner.is-active .mdl-spinner__right .mdl-spinner__circle{-webkit-animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}@keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}.mdl-switch{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0;overflow:visible;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-switch.is-upgraded{padding-left:28px}.mdl-switch__input{line-height:24px}.mdl-switch.is-upgraded .mdl-switch__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-switch__track{background:rgba(0,0,0,.26);position:absolute;left:0;top:5px;height:14px;width:36px;border-radius:14px;cursor:pointer}.mdl-switch.is-checked .mdl-switch__track{background:rgba(63,81,181,.5)}.mdl-switch__track fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__track{background:rgba(0,0,0,.12);cursor:auto}.mdl-switch__thumb{background:#fafafa;position:absolute;left:0;top:2px;height:20px;width:20px;border-radius:50%;cursor:pointer;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:left}.mdl-switch.is-checked .mdl-switch__thumb{background:#3f51b5;left:16px;box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-switch__thumb fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__thumb{background:#bdbdbd;cursor:auto}.mdl-switch__focus-helper{position:absolute;top:50%;left:50%;-webkit-transform:translate(-4px,-4px);transform:translate(-4px,-4px);display:inline-block;box-sizing:border-box;width:8px;height:8px;border-radius:50%;background-color:transparent}.mdl-switch.is-focused .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-switch.is-focused.is-checked .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.mdl-switch__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0;left:24px}.mdl-switch__label fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__label{color:#bdbdbd;cursor:auto}.mdl-switch__ripple-container{position:absolute;z-index:2;top:-12px;left:-14px;box-sizing:border-box;width:48px;height:48px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000);transition-duration:.4s;transition-timing-function:step-end;transition-property:left}.mdl-switch__ripple-container .mdl-ripple{background:#3f51b5}.mdl-switch__ripple-container fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__ripple-container{cursor:auto}fieldset[disabled] .mdl-switch .mdl-switch__ripple-container .mdl-ripple,.mdl-switch.is-disabled .mdl-switch__ripple-container .mdl-ripple{background:0 0}.mdl-switch.is-checked .mdl-switch__ripple-container{left:2px}.mdl-tabs{display:block;width:100%}.mdl-tabs__tab-bar{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:space-between;-ms-flex-line-pack:justify;align-content:space-between;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;height:48px;padding:0;margin:0;border-bottom:1px solid #e0e0e0}.mdl-tabs__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(0,0,0,.54);overflow:hidden}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active{color:rgba(0,0,0,.87)}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#3f51b5;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-tabs__tab .mdl-tabs__ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-tabs__tab .mdl-tabs__ripple-container .mdl-ripple{background:#3f51b5}.mdl-tabs__panel{display:block}.mdl-tabs.is-upgraded .mdl-tabs__panel{display:none}.mdl-tabs.is-upgraded .mdl-tabs__panel.is-active{display:block}@-webkit-keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}@keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}.mdl-textfield{position:relative;font-size:16px;display:inline-block;box-sizing:border-box;width:300px;max-width:100%;margin:0;padding:20px 0}.mdl-textfield .mdl-button{position:absolute;bottom:20px}.mdl-textfield--align-right{text-align:right}.mdl-textfield--full-width{width:100%}.mdl-textfield--expandable{min-width:32px;width:auto;min-height:32px}.mdl-textfield__input{border:none;border-bottom:1px solid rgba(0,0,0,.12);display:block;font-size:16px;font-family:"Helvetica","Arial",sans-serif;margin:0;padding:4px 0;width:100%;background:0 0;text-align:left;color:inherit}.mdl-textfield__input[type="number"]{-moz-appearance:textfield}.mdl-textfield__input[type="number"]::-webkit-inner-spin-button,.mdl-textfield__input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.mdl-textfield.is-focused .mdl-textfield__input{outline:none}.mdl-textfield.is-invalid .mdl-textfield__input{border-color:#d50000;box-shadow:none}fieldset[disabled] .mdl-textfield .mdl-textfield__input,.mdl-textfield.is-disabled .mdl-textfield__input{background-color:transparent;border-bottom:1px dotted rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-textfield textarea.mdl-textfield__input{display:block}.mdl-textfield__label{bottom:0;color:rgba(0,0,0,.26);font-size:16px;left:0;right:0;pointer-events:none;position:absolute;display:block;top:24px;width:100%;overflow:hidden;white-space:nowrap;text-align:left}.mdl-textfield.is-dirty .mdl-textfield__label,.mdl-textfield.has-placeholder .mdl-textfield__label{visibility:hidden}.mdl-textfield--floating-label .mdl-textfield__label{transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{transition:none}fieldset[disabled] .mdl-textfield .mdl-textfield__label,.mdl-textfield.is-disabled.is-disabled .mdl-textfield__label{color:rgba(0,0,0,.26)}.mdl-textfield--floating-label.is-focused .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{color:#3f51b5;font-size:12px;top:4px;visibility:visible}.mdl-textfield--floating-label.is-focused .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__expandable-holder .mdl-textfield__label{top:-16px}.mdl-textfield--floating-label.is-invalid .mdl-textfield__label{color:#d50000;font-size:12px}.mdl-textfield__label:after{background-color:#3f51b5;bottom:20px;content:'';height:2px;left:45%;position:absolute;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden;width:10px}.mdl-textfield.is-focused .mdl-textfield__label:after{left:0;visibility:visible;width:100%}.mdl-textfield.is-invalid .mdl-textfield__label:after{background-color:#d50000}.mdl-textfield__error{color:#d50000;position:absolute;font-size:12px;margin-top:3px;visibility:hidden;display:block}.mdl-textfield.is-invalid .mdl-textfield__error{visibility:visible}.mdl-textfield__expandable-holder{display:inline-block;position:relative;margin-left:32px;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:inline-block;max-width:.1px}.mdl-textfield.is-focused .mdl-textfield__expandable-holder,.mdl-textfield.is-dirty .mdl-textfield__expandable-holder{max-width:600px}.mdl-textfield__expandable-holder .mdl-textfield__label:after{bottom:0}.mdl-tooltip{-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:top center;transform-origin:top center;will-change:transform;z-index:999;background:rgba(97,97,97,.9);border-radius:2px;color:#fff;display:inline-block;font-size:10px;font-weight:500;line-height:14px;max-width:170px;position:fixed;top:-500px;left:-500px;padding:8px;text-align:center}.mdl-tooltip.is-active{-webkit-animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards;animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards}.mdl-tooltip--large{line-height:14px;font-size:14px;padding:16px}@-webkit-keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}@keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}.mdl-shadow--2dp{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.mdl-shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.mdl-shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.mdl-shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.mdl-shadow--24dp{box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2)}.mdl-grid{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;margin:0 auto;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.mdl-grid.mdl-grid--no-spacing{padding:0}.mdl-cell{box-sizing:border-box}.mdl-cell--top{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.mdl-cell--middle{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.mdl-cell--bottom{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.mdl-cell--stretch{-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch}.mdl-grid.mdl-grid--no-spacing>.mdl-cell{margin:0}.mdl-cell--order-1{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12{-webkit-order:12;-ms-flex-order:12;order:12}@media (max-width:479px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:100%}.mdl-cell--hide-phone{display:none!important}.mdl-cell--order-1-phone.mdl-cell--order-1-phone{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-phone.mdl-cell--order-2-phone{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-phone.mdl-cell--order-3-phone{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-phone.mdl-cell--order-4-phone{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-phone.mdl-cell--order-5-phone{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-phone.mdl-cell--order-6-phone{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-phone.mdl-cell--order-7-phone{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-phone.mdl-cell--order-8-phone{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-phone.mdl-cell--order-9-phone{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-phone.mdl-cell--order-10-phone{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-phone.mdl-cell--order-11-phone{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-phone.mdl-cell--order-12-phone{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:25%}.mdl-cell--2-col,.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:50%}.mdl-cell--3-col,.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:75%}.mdl-cell--4-col,.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:100%}.mdl-cell--5-col,.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:100%}.mdl-cell--6-col,.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:100%}.mdl-cell--7-col,.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:100%}.mdl-cell--8-col,.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:25%}.mdl-cell--2-offset,.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:50%}.mdl-cell--3-offset,.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:75%}}@media (min-width:480px) and (max-width:839px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:50%}.mdl-cell--hide-tablet{display:none!important}.mdl-cell--order-1-tablet.mdl-cell--order-1-tablet{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-tablet.mdl-cell--order-2-tablet{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-tablet.mdl-cell--order-3-tablet{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-tablet.mdl-cell--order-4-tablet{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-tablet.mdl-cell--order-5-tablet{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-tablet.mdl-cell--order-6-tablet{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-tablet.mdl-cell--order-7-tablet{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-tablet.mdl-cell--order-8-tablet{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-tablet.mdl-cell--order-9-tablet{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-tablet.mdl-cell--order-10-tablet{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-tablet.mdl-cell--order-11-tablet{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-tablet.mdl-cell--order-12-tablet{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:calc(12.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:12.5%}.mdl-cell--2-col,.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:25%}.mdl-cell--3-col,.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:calc(37.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:37.5%}.mdl-cell--4-col,.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:50%}.mdl-cell--5-col,.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:calc(62.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:62.5%}.mdl-cell--6-col,.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:75%}.mdl-cell--7-col,.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:calc(87.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:87.5%}.mdl-cell--8-col,.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:calc(12.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:12.5%}.mdl-cell--2-offset,.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:25%}.mdl-cell--3-offset,.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:calc(37.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:37.5%}.mdl-cell--4-offset,.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:50%}.mdl-cell--5-offset,.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:calc(62.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:62.5%}.mdl-cell--6-offset,.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:75%}.mdl-cell--7-offset,.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:calc(87.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:87.5%}}@media (min-width:840px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:33.3333333333%}.mdl-cell--hide-desktop{display:none!important}.mdl-cell--order-1-desktop.mdl-cell--order-1-desktop{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-desktop.mdl-cell--order-2-desktop{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-desktop.mdl-cell--order-3-desktop{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-desktop.mdl-cell--order-4-desktop{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-desktop.mdl-cell--order-5-desktop{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-desktop.mdl-cell--order-6-desktop{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-desktop.mdl-cell--order-7-desktop{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-desktop.mdl-cell--order-8-desktop{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-desktop.mdl-cell--order-9-desktop{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-desktop.mdl-cell--order-10-desktop{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-desktop.mdl-cell--order-11-desktop{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-desktop.mdl-cell--order-12-desktop{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:calc(8.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:8.3333333333%}.mdl-cell--2-col,.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:calc(16.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:16.6666666667%}.mdl-cell--3-col,.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:25%}.mdl-cell--4-col,.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:33.3333333333%}.mdl-cell--5-col,.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:calc(41.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:41.6666666667%}.mdl-cell--6-col,.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:50%}.mdl-cell--7-col,.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:calc(58.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:58.3333333333%}.mdl-cell--8-col,.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:calc(66.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:66.6666666667%}.mdl-cell--9-col,.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:75%}.mdl-cell--10-col,.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:calc(83.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:83.3333333333%}.mdl-cell--11-col,.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:calc(91.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:91.6666666667%}.mdl-cell--12-col,.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:calc(8.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:8.3333333333%}.mdl-cell--2-offset,.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:calc(16.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:16.6666666667%}.mdl-cell--3-offset,.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:25%}.mdl-cell--4-offset,.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:calc(33.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:33.3333333333%}.mdl-cell--5-offset,.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:calc(41.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:41.6666666667%}.mdl-cell--6-offset,.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:50%}.mdl-cell--7-offset,.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:calc(58.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:58.3333333333%}.mdl-cell--8-offset,.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:calc(66.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:66.6666666667%}.mdl-cell--9-offset,.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:75%}.mdl-cell--10-offset,.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:calc(83.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:83.3333333333%}.mdl-cell--11-offset,.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:calc(91.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:91.6666666667%}} +/*# sourceMappingURL=material.min.css.map */ diff --git a/dottydoc/js/static/material.min.js b/dottydoc/js/static/material.min.js new file mode 100644 index 000000000000..c9efeaf98f43 --- /dev/null +++ b/dottydoc/js/static/material.min.js @@ -0,0 +1,10 @@ +/** + * material-design-lite - Material Design Components in CSS, JS and HTML + * @version v1.1.3 + * @license Apache-2.0 + * @copyright 2015 Google, Inc. + * @link https://github.com/google/material-design-lite + */ +!function(){"use strict";function e(e,t){if(e){if(t.element_.classList.contains(t.CssClasses_.MDL_JS_RIPPLE_EFFECT)){var s=document.createElement("span");s.classList.add(t.CssClasses_.MDL_RIPPLE_CONTAINER),s.classList.add(t.CssClasses_.MDL_JS_RIPPLE_EFFECT);var i=document.createElement("span");i.classList.add(t.CssClasses_.MDL_RIPPLE),s.appendChild(i),e.appendChild(s)}e.addEventListener("click",function(s){s.preventDefault();var i=e.href.split("#")[1],n=t.element_.querySelector("#"+i);t.resetTabState_(),t.resetPanelState_(),e.classList.add(t.CssClasses_.ACTIVE_CLASS),n.classList.add(t.CssClasses_.ACTIVE_CLASS)})}}function t(e,t,s,i){function n(){var n=e.href.split("#")[1],a=i.content_.querySelector("#"+n);i.resetTabState_(t),i.resetPanelState_(s),e.classList.add(i.CssClasses_.IS_ACTIVE),a.classList.add(i.CssClasses_.IS_ACTIVE)}if(i.tabBar_.classList.contains(i.CssClasses_.JS_RIPPLE_EFFECT)){var a=document.createElement("span");a.classList.add(i.CssClasses_.RIPPLE_CONTAINER),a.classList.add(i.CssClasses_.JS_RIPPLE_EFFECT);var l=document.createElement("span");l.classList.add(i.CssClasses_.RIPPLE),a.appendChild(l),e.appendChild(a)}e.addEventListener("click",function(t){"#"===e.getAttribute("href").charAt(0)&&(t.preventDefault(),n())}),e.show=n}var s={upgradeDom:function(e,t){},upgradeElement:function(e,t){},upgradeElements:function(e){},upgradeAllRegistered:function(){},registerUpgradedCallback:function(e,t){},register:function(e){},downgradeElements:function(e){}};s=function(){function e(e,t){for(var s=0;s_;_++){if(r=l[_],!r)throw new Error("Unable to find a registered component for the given class.");a.push(r.className),i.setAttribute("data-upgraded",a.join(","));var C=new r.classConstructor(i);C[p]=r,c.push(C);for(var u=0,E=r.callbacks.length;E>u;u++)r.callbacks[u](i);r.widget&&(i[r.className]=C);var m;"CustomEvent"in window&&"function"==typeof window.CustomEvent?m=new Event("mdl-componentupgraded",{bubbles:!0,cancelable:!1}):(m=document.createEvent("Events"),m.initEvent("mdl-componentupgraded",!0,!0)),i.dispatchEvent(m)}}function a(e){Array.isArray(e)||(e="function"==typeof e.item?Array.prototype.slice.call(e):[e]);for(var t,s=0,i=e.length;i>s;s++)t=e[s],t instanceof HTMLElement&&(n(t),t.children.length>0&&a(t.children))}function l(t){var s="undefined"==typeof t.widget&&"undefined"==typeof t.widget,i=!0;s||(i=t.widget||t.widget);var n={classConstructor:t.constructor||t.constructor,className:t.classAsString||t.classAsString,cssClass:t.cssClass||t.cssClass,widget:i,callbacks:[]};if(h.forEach(function(e){if(e.cssClass===n.cssClass)throw new Error("The provided cssClass has already been registered: "+e.cssClass);if(e.className===n.className)throw new Error("The provided className has already been registered")}),t.constructor.prototype.hasOwnProperty(p))throw new Error("MDL component classes must not have "+p+" defined as a property.");var a=e(t.classAsString,n);a||h.push(n)}function o(t,s){var i=e(t);i&&i.callbacks.push(s)}function r(){for(var e=0;e0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)&&(e.keyCode===this.Keycodes_.UP_ARROW?(e.preventDefault(),t[t.length-1].focus()):e.keyCode===this.Keycodes_.DOWN_ARROW&&(e.preventDefault(),t[0].focus()))}},d.prototype.handleItemKeyboardEvent_=function(e){if(this.element_&&this.container_){var t=this.element_.querySelectorAll("."+this.CssClasses_.ITEM+":not([disabled])");if(t&&t.length>0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)){var s=Array.prototype.slice.call(t).indexOf(e.target);if(e.keyCode===this.Keycodes_.UP_ARROW)e.preventDefault(),s>0?t[s-1].focus():t[t.length-1].focus();else if(e.keyCode===this.Keycodes_.DOWN_ARROW)e.preventDefault(),t.length>s+1?t[s+1].focus():t[0].focus();else if(e.keyCode===this.Keycodes_.SPACE||e.keyCode===this.Keycodes_.ENTER){e.preventDefault();var i=new MouseEvent("mousedown");e.target.dispatchEvent(i),i=new MouseEvent("mouseup"),e.target.dispatchEvent(i),e.target.click()}else e.keyCode===this.Keycodes_.ESCAPE&&(e.preventDefault(),this.hide())}}},d.prototype.handleItemClick_=function(e){e.target.hasAttribute("disabled")?e.stopPropagation():(this.closing_=!0,window.setTimeout(function(e){this.hide(),this.closing_=!1}.bind(this),this.Constant_.CLOSE_TIMEOUT))},d.prototype.applyClip_=function(e,t){this.element_.classList.contains(this.CssClasses_.UNALIGNED)?this.element_.style.clip="":this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)?this.element_.style.clip="rect(0 "+t+"px 0 "+t+"px)":this.element_.classList.contains(this.CssClasses_.TOP_LEFT)?this.element_.style.clip="rect("+e+"px 0 "+e+"px 0)":this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?this.element_.style.clip="rect("+e+"px "+t+"px "+e+"px "+t+"px)":this.element_.style.clip=""},d.prototype.removeAnimationEndListener_=function(e){e.target.classList.remove(d.prototype.CssClasses_.IS_ANIMATING)},d.prototype.addAnimationEndListener_=function(){this.element_.addEventListener("transitionend",this.removeAnimationEndListener_),this.element_.addEventListener("webkitTransitionEnd",this.removeAnimationEndListener_)},d.prototype.show=function(e){if(this.element_&&this.container_&&this.outline_){var t=this.element_.getBoundingClientRect().height,s=this.element_.getBoundingClientRect().width;this.container_.style.width=s+"px",this.container_.style.height=t+"px",this.outline_.style.width=s+"px",this.outline_.style.height=t+"px";for(var i=this.Constant_.TRANSITION_DURATION_SECONDS*this.Constant_.TRANSITION_DURATION_FRACTION,n=this.element_.querySelectorAll("."+this.CssClasses_.ITEM),a=0;a0&&this.showSnackbar(this.queuedNotifications_.shift())},C.prototype.cleanup_=function(){this.element_.classList.remove(this.cssClasses_.ACTIVE),setTimeout(function(){this.element_.setAttribute("aria-hidden","true"),this.textElement_.textContent="",Boolean(this.actionElement_.getAttribute("aria-hidden"))||(this.setActionHidden_(!0),this.actionElement_.textContent="",this.actionElement_.removeEventListener("click",this.actionHandler_)),this.actionHandler_=void 0,this.message_=void 0,this.actionText_=void 0,this.active=!1,this.checkQueue_()}.bind(this),this.Constant_.ANIMATION_LENGTH)},C.prototype.setActionHidden_=function(e){e?this.actionElement_.setAttribute("aria-hidden","true"):this.actionElement_.removeAttribute("aria-hidden")},s.register({constructor:C,classAsString:"MaterialSnackbar",cssClass:"mdl-js-snackbar",widget:!0});var u=function(e){this.element_=e,this.init()};window.MaterialSpinner=u,u.prototype.Constant_={MDL_SPINNER_LAYER_COUNT:4},u.prototype.CssClasses_={MDL_SPINNER_LAYER:"mdl-spinner__layer",MDL_SPINNER_CIRCLE_CLIPPER:"mdl-spinner__circle-clipper",MDL_SPINNER_CIRCLE:"mdl-spinner__circle",MDL_SPINNER_GAP_PATCH:"mdl-spinner__gap-patch",MDL_SPINNER_LEFT:"mdl-spinner__left",MDL_SPINNER_RIGHT:"mdl-spinner__right"},u.prototype.createLayer=function(e){var t=document.createElement("div");t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER),t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER+"-"+e);var s=document.createElement("div");s.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),s.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);var i=document.createElement("div");i.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);var n=document.createElement("div");n.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),n.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);for(var a=[s,i,n],l=0;l=this.maxRows&&e.preventDefault()},L.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},L.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.onReset_=function(e){this.updateClasses_()},L.prototype.updateClasses_=function(){this.checkDisabled(),this.checkValidity(),this.checkDirty(),this.checkFocus()},L.prototype.checkDisabled=function(){this.input_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},L.prototype.checkDisabled=L.prototype.checkDisabled,L.prototype.checkFocus=function(){Boolean(this.element_.querySelector(":focus"))?this.element_.classList.add(this.CssClasses_.IS_FOCUSED):this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.checkFocus=L.prototype.checkFocus,L.prototype.checkValidity=function(){this.input_.validity&&(this.input_.validity.valid?this.element_.classList.remove(this.CssClasses_.IS_INVALID):this.element_.classList.add(this.CssClasses_.IS_INVALID))},L.prototype.checkValidity=L.prototype.checkValidity,L.prototype.checkDirty=function(){this.input_.value&&this.input_.value.length>0?this.element_.classList.add(this.CssClasses_.IS_DIRTY):this.element_.classList.remove(this.CssClasses_.IS_DIRTY)},L.prototype.checkDirty=L.prototype.checkDirty,L.prototype.disable=function(){this.input_.disabled=!0,this.updateClasses_()},L.prototype.disable=L.prototype.disable,L.prototype.enable=function(){this.input_.disabled=!1,this.updateClasses_()},L.prototype.enable=L.prototype.enable,L.prototype.change=function(e){this.input_.value=e||"",this.updateClasses_()},L.prototype.change=L.prototype.change,L.prototype.init=function(){if(this.element_&&(this.label_=this.element_.querySelector("."+this.CssClasses_.LABEL),this.input_=this.element_.querySelector("."+this.CssClasses_.INPUT),this.input_)){this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)&&(this.maxRows=parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE),10),isNaN(this.maxRows)&&(this.maxRows=this.Constant_.NO_MAX_ROWS)),this.input_.hasAttribute("placeholder")&&this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER),this.boundUpdateClassesHandler=this.updateClasses_.bind(this),this.boundFocusHandler=this.onFocus_.bind(this),this.boundBlurHandler=this.onBlur_.bind(this),this.boundResetHandler=this.onReset_.bind(this),this.input_.addEventListener("input",this.boundUpdateClassesHandler),this.input_.addEventListener("focus",this.boundFocusHandler),this.input_.addEventListener("blur",this.boundBlurHandler),this.input_.addEventListener("reset",this.boundResetHandler),this.maxRows!==this.Constant_.NO_MAX_ROWS&&(this.boundKeyDownHandler=this.onKeyDown_.bind(this),this.input_.addEventListener("keydown",this.boundKeyDownHandler));var e=this.element_.classList.contains(this.CssClasses_.IS_INVALID);this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED),e&&this.element_.classList.add(this.CssClasses_.IS_INVALID),this.input_.hasAttribute("autofocus")&&(this.element_.focus(),this.checkFocus())}},s.register({constructor:L,classAsString:"MaterialTextfield",cssClass:"mdl-js-textfield",widget:!0});var I=function(e){this.element_=e,this.init()};window.MaterialTooltip=I,I.prototype.Constant_={},I.prototype.CssClasses_={IS_ACTIVE:"is-active",BOTTOM:"mdl-tooltip--bottom",LEFT:"mdl-tooltip--left",RIGHT:"mdl-tooltip--right",TOP:"mdl-tooltip--top"},I.prototype.handleMouseEnter_=function(e){var t=e.target.getBoundingClientRect(),s=t.left+t.width/2,i=t.top+t.height/2,n=-1*(this.element_.offsetWidth/2),a=-1*(this.element_.offsetHeight/2);this.element_.classList.contains(this.CssClasses_.LEFT)||this.element_.classList.contains(this.CssClasses_.RIGHT)?(s=t.width/2,0>i+a?(this.element_.style.top=0,this.element_.style.marginTop=0):(this.element_.style.top=i+"px",this.element_.style.marginTop=a+"px")):0>s+n?(this.element_.style.left=0,this.element_.style.marginLeft=0):(this.element_.style.left=s+"px",this.element_.style.marginLeft=n+"px"),this.element_.classList.contains(this.CssClasses_.TOP)?this.element_.style.top=t.top-this.element_.offsetHeight-10+"px":this.element_.classList.contains(this.CssClasses_.RIGHT)?this.element_.style.left=t.left+t.width+10+"px":this.element_.classList.contains(this.CssClasses_.LEFT)?this.element_.style.left=t.left-this.element_.offsetWidth-10+"px":this.element_.style.top=t.top+t.height+10+"px",this.element_.classList.add(this.CssClasses_.IS_ACTIVE)},I.prototype.handleMouseLeave_=function(){this.element_.classList.remove(this.CssClasses_.IS_ACTIVE)},I.prototype.init=function(){if(this.element_){var e=this.element_.getAttribute("for");e&&(this.forElement_=document.getElementById(e)),this.forElement_&&(this.forElement_.hasAttribute("tabindex")||this.forElement_.setAttribute("tabindex","0"),this.boundMouseEnterHandler=this.handleMouseEnter_.bind(this),this.boundMouseLeaveHandler=this.handleMouseLeave_.bind(this),this.forElement_.addEventListener("mouseenter",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("touchend",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("mouseleave",this.boundMouseLeaveHandler,!1),window.addEventListener("touchstart",this.boundMouseLeaveHandler))}},s.register({constructor:I,classAsString:"MaterialTooltip",cssClass:"mdl-tooltip"});var f=function(e){this.element_=e,this.init()};window.MaterialLayout=f,f.prototype.Constant_={MAX_WIDTH:"(max-width: 1024px)",TAB_SCROLL_PIXELS:100,RESIZE_TIMEOUT:100,MENU_ICON:"",CHEVRON_LEFT:"chevron_left",CHEVRON_RIGHT:"chevron_right"},f.prototype.Keycodes_={ENTER:13,ESCAPE:27,SPACE:32},f.prototype.Mode_={STANDARD:0,SEAMED:1,WATERFALL:2,SCROLL:3},f.prototype.CssClasses_={CONTAINER:"mdl-layout__container",HEADER:"mdl-layout__header",DRAWER:"mdl-layout__drawer",CONTENT:"mdl-layout__content",DRAWER_BTN:"mdl-layout__drawer-button",ICON:"material-icons",JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_CONTAINER:"mdl-layout__tab-ripple-container",RIPPLE:"mdl-ripple",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",HEADER_SEAMED:"mdl-layout__header--seamed",HEADER_WATERFALL:"mdl-layout__header--waterfall",HEADER_SCROLL:"mdl-layout__header--scroll",FIXED_HEADER:"mdl-layout--fixed-header",OBFUSCATOR:"mdl-layout__obfuscator",TAB_BAR:"mdl-layout__tab-bar",TAB_CONTAINER:"mdl-layout__tab-bar-container",TAB:"mdl-layout__tab",TAB_BAR_BUTTON:"mdl-layout__tab-bar-button",TAB_BAR_LEFT_BUTTON:"mdl-layout__tab-bar-left-button",TAB_BAR_RIGHT_BUTTON:"mdl-layout__tab-bar-right-button",PANEL:"mdl-layout__tab-panel",HAS_DRAWER:"has-drawer",HAS_TABS:"has-tabs",HAS_SCROLLING_HEADER:"has-scrolling-header",CASTING_SHADOW:"is-casting-shadow",IS_COMPACT:"is-compact",IS_SMALL_SCREEN:"is-small-screen",IS_DRAWER_OPEN:"is-visible",IS_ACTIVE:"is-active",IS_UPGRADED:"is-upgraded",IS_ANIMATING:"is-animating",ON_LARGE_SCREEN:"mdl-layout--large-screen-only",ON_SMALL_SCREEN:"mdl-layout--small-screen-only"},f.prototype.contentScrollHandler_=function(){if(!this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)){var e=!this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN)||this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);this.content_.scrollTop>0&&!this.header_.classList.contains(this.CssClasses_.IS_COMPACT)?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.header_.classList.add(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING)):this.content_.scrollTop<=0&&this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.header_.classList.remove(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING))}},f.prototype.keyboardEventHandler_=function(e){e.keyCode===this.Keycodes_.ESCAPE&&this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)&&this.toggleDrawer()},f.prototype.screenSizeHandler_=function(){this.screenSizeMediaQuery_.matches?this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN):(this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN),this.drawer_&&(this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN),this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN)))},f.prototype.drawerToggleHandler_=function(e){if(e&&"keydown"===e.type){if(e.keyCode!==this.Keycodes_.SPACE&&e.keyCode!==this.Keycodes_.ENTER)return;e.preventDefault()}this.toggleDrawer()},f.prototype.headerTransitionEndHandler_=function(){this.header_.classList.remove(this.CssClasses_.IS_ANIMATING)},f.prototype.headerClickHandler_=function(){this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.IS_COMPACT),this.header_.classList.add(this.CssClasses_.IS_ANIMATING))},f.prototype.resetTabState_=function(e){for(var t=0;ta;a++){var l=i[a];l.classList&&l.classList.contains(this.CssClasses_.HEADER)&&(this.header_=l),l.classList&&l.classList.contains(this.CssClasses_.DRAWER)&&(this.drawer_=l),l.classList&&l.classList.contains(this.CssClasses_.CONTENT)&&(this.content_=l)}window.addEventListener("pageshow",function(e){e.persisted&&(this.element_.style.overflowY="hidden",requestAnimationFrame(function(){this.element_.style.overflowY=""}.bind(this)))}.bind(this),!1),this.header_&&(this.tabBar_=this.header_.querySelector("."+this.CssClasses_.TAB_BAR));var o=this.Mode_.STANDARD;if(this.header_&&(this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)?o=this.Mode_.SEAMED:this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)?(o=this.Mode_.WATERFALL,this.header_.addEventListener("transitionend",this.headerTransitionEndHandler_.bind(this)),this.header_.addEventListener("click",this.headerClickHandler_.bind(this))):this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)&&(o=this.Mode_.SCROLL,e.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER)),o===this.Mode_.STANDARD?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.SEAMED||o===this.Mode_.SCROLL?(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.WATERFALL&&(this.content_.addEventListener("scroll",this.contentScrollHandler_.bind(this)),this.contentScrollHandler_())),this.drawer_){var r=this.element_.querySelector("."+this.CssClasses_.DRAWER_BTN);if(!r){r=document.createElement("div"),r.setAttribute("aria-expanded","false"),r.setAttribute("role","button"),r.setAttribute("tabindex","0"),r.classList.add(this.CssClasses_.DRAWER_BTN);var _=document.createElement("i");_.classList.add(this.CssClasses_.ICON),_.innerHTML=this.Constant_.MENU_ICON,r.appendChild(_)}this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)?r.classList.add(this.CssClasses_.ON_LARGE_SCREEN):this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)&&r.classList.add(this.CssClasses_.ON_SMALL_SCREEN),r.addEventListener("click",this.drawerToggleHandler_.bind(this)),r.addEventListener("keydown",this.drawerToggleHandler_.bind(this)),this.element_.classList.add(this.CssClasses_.HAS_DRAWER),this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)?this.header_.insertBefore(r,this.header_.firstChild):this.element_.insertBefore(r,this.content_);var d=document.createElement("div");d.classList.add(this.CssClasses_.OBFUSCATOR),this.element_.appendChild(d),d.addEventListener("click",this.drawerToggleHandler_.bind(this)),this.obfuscator_=d,this.drawer_.addEventListener("keydown",this.keyboardEventHandler_.bind(this)),this.drawer_.setAttribute("aria-hidden","true")}if(this.screenSizeMediaQuery_=window.matchMedia(this.Constant_.MAX_WIDTH),this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)),this.screenSizeHandler_(),this.header_&&this.tabBar_){this.element_.classList.add(this.CssClasses_.HAS_TABS);var h=document.createElement("div");h.classList.add(this.CssClasses_.TAB_CONTAINER),this.header_.insertBefore(h,this.tabBar_),this.header_.removeChild(this.tabBar_);var c=document.createElement("div");c.classList.add(this.CssClasses_.TAB_BAR_BUTTON),c.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);var p=document.createElement("i");p.classList.add(this.CssClasses_.ICON),p.textContent=this.Constant_.CHEVRON_LEFT,c.appendChild(p),c.addEventListener("click",function(){this.tabBar_.scrollLeft-=this.Constant_.TAB_SCROLL_PIXELS}.bind(this));var C=document.createElement("div");C.classList.add(this.CssClasses_.TAB_BAR_BUTTON),C.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);var u=document.createElement("i");u.classList.add(this.CssClasses_.ICON),u.textContent=this.Constant_.CHEVRON_RIGHT,C.appendChild(u),C.addEventListener("click",function(){this.tabBar_.scrollLeft+=this.Constant_.TAB_SCROLL_PIXELS}.bind(this)),h.appendChild(c),h.appendChild(this.tabBar_),h.appendChild(C);var E=function(){this.tabBar_.scrollLeft>0?c.classList.add(this.CssClasses_.IS_ACTIVE):c.classList.remove(this.CssClasses_.IS_ACTIVE),this.tabBar_.scrollLeft0)return;this.setFrameCount(1);var i,n,a=e.currentTarget.getBoundingClientRect();if(0===e.clientX&&0===e.clientY)i=Math.round(a.width/2),n=Math.round(a.height/2);else{var l=e.clientX?e.clientX:e.touches[0].clientX,o=e.clientY?e.clientY:e.touches[0].clientY;i=Math.round(l-a.left),n=Math.round(o-a.top)}this.setRippleXY(i,n),this.setRippleStyles(!0),window.requestAnimationFrame(this.animFrameHandler.bind(this))}},y.prototype.upHandler_=function(e){e&&2!==e.detail&&window.setTimeout(function(){this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE)}.bind(this),0)},y.prototype.init=function(){if(this.element_){var e=this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)||(this.rippleElement_=this.element_.querySelector("."+this.CssClasses_.RIPPLE),this.frameCount_=0,this.rippleSize_=0,this.x_=0,this.y_=0,this.ignoringMouseDown_=!1,this.boundDownHandler=this.downHandler_.bind(this),this.element_.addEventListener("mousedown",this.boundDownHandler),this.element_.addEventListener("touchstart",this.boundDownHandler),this.boundUpHandler=this.upHandler_.bind(this),this.element_.addEventListener("mouseup",this.boundUpHandler),this.element_.addEventListener("mouseleave",this.boundUpHandler),this.element_.addEventListener("touchend",this.boundUpHandler),this.element_.addEventListener("blur",this.boundUpHandler),this.getFrameCount=function(){return this.frameCount_},this.setFrameCount=function(e){this.frameCount_=e},this.getRippleElement=function(){return this.rippleElement_},this.setRippleXY=function(e,t){this.x_=e,this.y_=t},this.setRippleStyles=function(t){if(null!==this.rippleElement_){var s,i,n,a="translate("+this.x_+"px, "+this.y_+"px)";t?(i=this.Constant_.INITIAL_SCALE,n=this.Constant_.INITIAL_SIZE):(i=this.Constant_.FINAL_SCALE,n=this.rippleSize_+"px",e&&(a="translate("+this.boundWidth/2+"px, "+this.boundHeight/2+"px)")),s="translate(-50%, -50%) "+a+i,this.rippleElement_.style.webkitTransform=s,this.rippleElement_.style.msTransform=s,this.rippleElement_.style.transform=s,t?this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING):this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING)}},this.animFrameHandler=function(){this.frameCount_-- >0?window.requestAnimationFrame(this.animFrameHandler.bind(this)):this.setRippleStyles(!1)})}},s.register({constructor:y,classAsString:"MaterialRipple",cssClass:"mdl-js-ripple-effect",widget:!1})}(); +//# sourceMappingURL=material.min.js.map diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala new file mode 100644 index 000000000000..1c24b67a7ce3 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -0,0 +1,40 @@ +package dotty.tools +package dottydoc + +import core.Phases.DocPhase +import dotc.config.CompilerCommand +import dotc.config.Printers.dottydoc +import dotc.core.Contexts.Context +import dotc.core.Phases.Phase +import dotc.typer.FrontEnd +import dotc.{Compiler, Driver} + +/** Custom Compiler with phases for the documentation tool + * + * The idea here is to structure `dottydoc` around the new infrastructure. As + * such, dottydoc will itself be a compiler. It will, however, produce a format + * that can be used by other tools or web-browsers. + * + * Example: + * 1. Use the existing FrontEnd to typecheck the code being fed to dottydoc + * 2. Create JSON from the results of the FrontEnd phase + */ +case object DottyDocCompiler extends Compiler { + override def phases: List[List[Phase]] = + List(new FrontEnd) :: + List(new DocPhase) :: + Nil +} + +object DottyDoc extends Driver { + override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { + val ctx = rootCtx.fresh + val summary = CompilerCommand.distill(args)(ctx) + ctx.setSettings(summary.sstate) + ctx.setSetting(ctx.settings.YkeepComments, true) + val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx) + (fileNames, ctx) + } + + override def newCompiler(implicit ctx: Context): Compiler = DottyDocCompiler +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala new file mode 100644 index 000000000000..a525723639c4 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -0,0 +1,104 @@ +package dotty.tools +package dottydoc +package core + +/** Dotty and Dottydoc imports */ +import dotc.ast.Trees._ +import dotc.CompilationUnit +import dotc.config.Printers.dottydoc +import dotc.core.Contexts.Context +import dotc.core.Phases.Phase +import dotc.core.Symbols.Symbol + +object Phases { + + class DocPhase extends Phase { + import model.comment.Comment + import model.CommentParsers.wikiParser + import model.Entities._ + import model.EntityFactories._ + import dotty.tools.dotc.core.Flags + import dotty.tools.dotc.ast.tpd._ + + def phaseName = "docphase" + + /** Build documentation hierarchy from existing tree */ + def collect(tree: Tree)(implicit ctx: Context): Entity = { + + def collectList(xs: List[Tree])(implicit ctx: Context): List[Entity] = + xs.map(collect).filter(_ != NonEntity) + + def collectPackageMembers(xs: List[Tree])(implicit ctx: Context): List[PackageMember] = + collectList(xs).asInstanceOf[List[PackageMember]] + + def collectMembers(tree: Tree)(implicit ctx: Context): List[Entity] = tree match { + case t: Template => collectList(t.body) + case _ => Nil + } + + val comment = + ctx.base.docstring(tree.symbol).map(c => Comment(wikiParser.parseHtml(c))) + + tree match { + /** package */ + case p @ PackageDef(pid, st) => + val name = pid.name.toString + Package(name, collectPackageMembers(st), comment, path(p, name)) + + /** trait */ + case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => + val name = n.toString + Trait(name, collectMembers(rhs), comment, flags(t), path(t, name)) + + /** objects, on the format "Object$" so drop the last letter */ + case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => + val name = n.toString.dropRight(1) + Object(name, collectMembers(rhs), comment, flags(o), path(o, name)) + + /** class / case class */ + case c @ TypeDef(name, rhs) if c.symbol.isClass => + (name.toString, collectMembers(rhs), comment, flags(c), path(c, name.toString)) match { + case x if c.symbol.is(Flags.CaseClass) => CaseClass.tupled(x) + case x => Class.tupled(x) + } + + /** def */ + case d: DefDef => + Def(d.name.toString, comment, flags(d), path(d, d.name.toString)) + + /** val */ + case v: ValDef if !v.symbol.is(Flags.ModuleVal) => + Val(v.name.toString, comment, flags(v), path(v, v.name.toString)) + + case x => { + dottydoc.println(s"Found unwanted entity: $x (${x.pos}, ${comment})\n${x.show}") + NonEntity + } + } + } + + var packages: Map[String, Package] = Map.empty + + def addEntity(p: Package): Unit = { + val path = p.path.mkString(".") + packages = packages + (path -> packages.get(path).map { ex => + val children = (ex.children ::: p.children).distinct.sortBy(_.name) + val comment = ex.comment.orElse(p.comment) + Package(p.name, children, comment, p.path) + }.getOrElse(p)) + } + + override def run(implicit ctx: Context): Unit = + collect(ctx.compilationUnit.tpdTree) match { + case p: Package => addEntity(p) + case _ => () + } + + override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { + val compUnits = super.runOn(units) + util.IndexWriters.writeJs(packages, "../js/out") + compUnits + } + } + +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala new file mode 100644 index 000000000000..dce8f4a69baf --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -0,0 +1,16 @@ +package dotty.tools +package dottydoc +package model + +object CommentParsers { + import comment._ + import BodyParsers._ + + sealed class WikiParser + extends CommentCleaner with CommentParser with CommentCooker { + def parseHtml(str: String): String = + parse(clean(str), str).toHtml + } + + val wikiParser = new WikiParser +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala new file mode 100644 index 000000000000..4fb9168b719c --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala @@ -0,0 +1,37 @@ +package dotty.tools.dottydoc +package model + +import scalatags.Text.all._ + +object Html { + import prickle._ + import Entities._ + + private def relPath(to: String, from: Entity) = + "../" * from.path.length + to + + def entityHtml(ent: Entity) = "" + html( + head( + meta(charset := "utf-8"), + meta(name := "viewport", + content := "width=device-width, initial-scale=1, shrink-to-fit=no"), + meta("http-equiv".attr := "x-ua-compatible", content := "ie=edge"), + + script(`type` := "text/javascript", src := relPath("static/material.min.js", ent)), + script(`type` := "text/javascript", src := relPath("static/highlight.pack.js", ent)), + script(`type` := "text/javascript", src := relPath("index.js", ent)), + script(`type` := "text/javascript", src := relPath("target/scala-2.11/dottydoc-fastopt.js", ent)), + link(rel := "stylesheet", href := relPath("static/material.min.css", ent)), + link(rel := "stylesheet", href := relPath("static/github.css", ent)), + link(rel := "stylesheet", href := relPath("static/index.css", ent)), + link(rel := "stylesheet", href := "https://fonts.googleapis.com/icon?family=Material+Icons") + + ), + body(div(id := "main-container")), + script(raw( + s"""|Index.currentEntity = ${Pickle.intoString(ent)}; + |dotty.tools.dottydoc.js.DottyDocJS() + | .main(document.getElementById("main-container")); + """.stripMargin)) + ) +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala new file mode 100644 index 000000000000..e06789e9845b --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -0,0 +1,88 @@ +package dotty.tools.dottydoc +package model +package comment + +import scala.collection._ + +/** A body of text. A comment has a single body, which is composed of + * at least one block. Inside every body is exactly one summary (see + * [[scala.tools.nsc.doc.model.comment.Summary]]). */ +final case class Body(blocks: Seq[Block]) { + + /** The summary text of the comment body. */ + lazy val summary: Option[Inline] = { + def summaryInBlock(block: Block): Seq[Inline] = block match { + case Title(text, _) => summaryInInline(text) + case Paragraph(text) => summaryInInline(text) + case UnorderedList(items) => items flatMap summaryInBlock + case OrderedList(items, _) => items flatMap summaryInBlock + case DefinitionList(items) => items.values.toSeq flatMap summaryInBlock + case _ => Nil + } + def summaryInInline(text: Inline): Seq[Inline] = text match { + case Summary(text) => List(text) + case Chain(items) => items flatMap summaryInInline + case Italic(text) => summaryInInline(text) + case Bold(text) => summaryInInline(text) + case Underline(text) => summaryInInline(text) + case Superscript(text) => summaryInInline(text) + case Subscript(text) => summaryInInline(text) + case Link(_, title) => summaryInInline(title) + case _ => Nil + } + (blocks flatMap { summaryInBlock(_) }).toList match { + case Nil => None + case inline :: Nil => Some(inline) + case inlines => Some(Chain(inlines)) + } + } +} + +/** A block-level element of text, such as a paragraph or code block. */ +sealed abstract class Block + +final case class Title(text: Inline, level: Int) extends Block +final case class Paragraph(text: Inline) extends Block +final case class Code(data: String) extends Block +final case class UnorderedList(items: Seq[Block]) extends Block +final case class OrderedList(items: Seq[Block], style: String) extends Block +final case class DefinitionList(items: SortedMap[Inline, Block]) extends Block +final case class HorizontalRule() extends Block + +/** An section of text inside a block, possibly with formatting. */ +sealed abstract class Inline + +final case class Chain(items: Seq[Inline]) extends Inline +final case class Italic(text: Inline) extends Inline +final case class Bold(text: Inline) extends Inline +final case class Underline(text: Inline) extends Inline +final case class Superscript(text: Inline) extends Inline +final case class Subscript(text: Inline) extends Inline +final case class Link(target: String, title: Inline) extends Inline +final case class Monospace(text: Inline) extends Inline +final case class Text(text: String) extends Inline +//TODO: this should be used +//abstract class EntityLink(val title: Inline) extends Inline { def link: LinkTo } +//object EntityLink { +// def apply(title: Inline, linkTo: LinkTo) = new EntityLink(title) { def link: LinkTo = linkTo } +// def unapply(el: EntityLink): Option[(Inline, LinkTo)] = Some((el.title, el.link)) +//} +final case class HtmlTag(data: String) extends Inline { + private val Pattern = """(?ms)\A<(/?)(.*?)[\s>].*\z""".r + private val (isEnd, tagName) = data match { + case Pattern(s1, s2) => + (! s1.isEmpty, Some(s2.toLowerCase)) + case _ => + (false, None) + } + + def canClose(open: HtmlTag) = { + isEnd && tagName == open.tagName + } + + private val TagsNotToClose = Set("br", "img") + def close = tagName collect { case name if !TagsNotToClose(name) => HtmlTag(s"") } +} + +/** The summary of a comment, usually its first sentence. There must be exactly one summary per body. */ +final case class Summary(text: Inline) extends Inline diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala new file mode 100644 index 000000000000..9b6ec600d4b8 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala @@ -0,0 +1,57 @@ +package dotty.tools.dottydoc +package model +package comment + +object BodyParsers { + implicit class BodyToHtml(val body: Body) extends AnyVal { + def toHtml: String = bodyToHtml(body) + + private def inlineToHtml(inl: Inline): String = inl match { + case Chain(items) => (items map inlineToHtml).mkString + case Italic(in) => s"${inlineToHtml(in)}" + case Bold(in) => s"${inlineToHtml(in)}" + case Underline(in) => s"${inlineToHtml(in)}" + case Superscript(in) => s"${inlineToHtml(in)}" + case Subscript(in) => s"${inlineToHtml(in) }" + case Link(raw, title) => s"""${inlineToHtml(title)}""" + case Monospace(in) => s"${inlineToHtml(in)}" + case Text(text) => text + case Summary(in) => inlineToHtml(in) + case HtmlTag(tag) => tag + //TODO: when we have EntityLinks, they should be enabled here too + //case EntityLink(target, link) => linkToHtml(target, link, hasLinks = true) + } + + private def bodyToHtml(body: Body): String = + (body.blocks map blockToHtml).mkString + + private def blockToHtml(block: Block): String = block match { + case Title(in, 1) => s"

${inlineToHtml(in)}

" + case Title(in, 2) => s"

${inlineToHtml(in)}

" + case Title(in, 3) => s"

${inlineToHtml(in)}

" + case Title(in, _) => s"

${inlineToHtml(in)}

" + case Paragraph(in) => s"

${inlineToHtml(in)}

" + case Code(data) => s"""
$data
""" + case UnorderedList(items) => + s"
    ${listItemsToHtml(items)}
" + case OrderedList(items, listStyle) => + s"
    ${listItemsToHtml(items)}
" + case DefinitionList(items) => + s"
${items map { case (t, d) => s"
${inlineToHtml(t)}
${blockToHtml(d)}
" } }
" + case HorizontalRule() => + "
" + } + + private def listItemsToHtml(items: Seq[Block]) = + items.foldLeft(""){ (list, item) => + item match { + case OrderedList(_, _) | UnorderedList(_) => // html requires sub ULs to be put into the last LI + list + s"
  • ${blockToHtml(item)}
  • " + case Paragraph(inline) => + list + s"
  • ${inlineToHtml(inline)}
  • " // LIs are blocks, no need to use Ps + case block => + list + s"
  • ${blockToHtml(block)}
  • " + } + } + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala new file mode 100644 index 000000000000..5eb64c6125bf --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala @@ -0,0 +1,25 @@ +package dotty.tools.dottydoc +package model +package comment + +trait CommentCleaner { + import Regexes._ + + def clean(comment: String): List[String] = { + def cleanLine(line: String): String = { + // Remove trailing whitespaces + TrailingWhitespace.replaceAllIn(line, "") match { + case CleanCommentLine(ctl) => ctl + case tl => tl + } + } + val strippedComment = comment.trim.stripPrefix("/*").stripSuffix("*/") + val safeComment = DangerousTags.replaceAllIn(strippedComment, { htmlReplacement(_) }) + val javadoclessComment = JavadocTags.replaceAllIn(safeComment, { javadocReplacement(_) }) + val markedTagComment = + SafeTags.replaceAllIn(javadoclessComment, { mtch => + java.util.regex.Matcher.quoteReplacement(safeTagMarker + mtch.matched + safeTagMarker) + }) + markedTagComment.lines.toList map (cleanLine(_)) + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala new file mode 100644 index 000000000000..4d4474d52853 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala @@ -0,0 +1,8 @@ +package dotty.tools.dottydoc +package model +package comment + +trait CommentCooker { + trait Context + def cook(comment: String)(implicit ctx: Context): String = "" +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala new file mode 100644 index 000000000000..5ba05fbfe4eb --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala @@ -0,0 +1,779 @@ +package dotty.tools.dottydoc +package model +package comment + +import dotty.tools.dotc.util.Positions._ +import dotty.tools.dotc.core.Symbols._ +import scala.collection.mutable +import dotty.tools.dotc.config.Printers.dottydoc +import scala.util.matching.Regex + +//TODO: re-enable pos? +trait CommentParser { + import Regexes._ + + /** Parses a raw comment string into a `Comment` object. + * @param cleanComment a cleaned comment to be parsed + * @param src the raw comment source string. + * @param pos the position of the comment in source. + */ + def parse(comment: List[String], src: String, /*pos: Position,*/ site: Symbol = NoSymbol): Body = { + + /** Parses a comment (in the form of a list of lines) to a `Comment` + * instance, recursively on lines. To do so, it splits the whole comment + * into main body and tag bodies, then runs the `WikiParser` on each body + * before creating the comment instance. + * + * @param docBody The body of the comment parsed until now. + * @param tags All tags parsed until now. + * @param lastTagKey The last parsed tag, or `None` if the tag section + * hasn't started. Lines that are not tagged are part + * of the previous tag or, if none exists, of the body. + * @param remaining The lines that must still recursively be parsed. + * @param inCodeBlock Whether the next line is part of a code block (in + * which no tags must be read). + */ + def parseComment ( + docBody: StringBuilder, + tags: Map[TagKey, List[String]], + lastTagKey: Option[TagKey], + remaining: List[String], + inCodeBlock: Boolean + ): Body = remaining match { + + case CodeBlockStartRegex(before, marker, after) :: ls if (!inCodeBlock) => + if (!before.trim.isEmpty && !after.trim.isEmpty) + parseComment(docBody, tags, lastTagKey, before :: marker :: after :: ls, inCodeBlock = false) + else if (!before.trim.isEmpty) + parseComment(docBody, tags, lastTagKey, before :: marker :: ls, inCodeBlock = false) + else if (!after.trim.isEmpty) + parseComment(docBody, tags, lastTagKey, marker :: after :: ls, inCodeBlock = true) + else lastTagKey match { + case Some(key) => + val value = + ((tags get key): @unchecked) match { + case Some(b :: bs) => (b + endOfLine + marker) :: bs + case None => oops("lastTagKey set when no tag exists for key") + } + parseComment(docBody, tags + (key -> value), lastTagKey, ls, inCodeBlock = true) + case None => + parseComment(docBody append endOfLine append marker, tags, lastTagKey, ls, inCodeBlock = true) + } + + case CodeBlockEndRegex(before, marker, after) :: ls => { + if (!before.trim.isEmpty && !after.trim.isEmpty) + parseComment(docBody, tags, lastTagKey, before :: marker :: after :: ls, inCodeBlock = true) + if (!before.trim.isEmpty) + parseComment(docBody, tags, lastTagKey, before :: marker :: ls, inCodeBlock = true) + else if (!after.trim.isEmpty) + parseComment(docBody, tags, lastTagKey, marker :: after :: ls, inCodeBlock = false) + else lastTagKey match { + case Some(key) => + val value = + ((tags get key): @unchecked) match { + case Some(b :: bs) => (b + endOfLine + marker) :: bs + case None => oops("lastTagKey set when no tag exists for key") + } + parseComment(docBody, tags + (key -> value), lastTagKey, ls, inCodeBlock = false) + case None => + parseComment(docBody append endOfLine append marker, tags, lastTagKey, ls, inCodeBlock = false) + } + } + + case SymbolTagRegex(name, sym, body) :: ls if (!inCodeBlock) => { + val key = SymbolTagKey(name, sym) + val value = body :: tags.getOrElse(key, Nil) + parseComment(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) + } + + case SimpleTagRegex(name, body) :: ls if (!inCodeBlock) => { + val key = SimpleTagKey(name) + val value = body :: tags.getOrElse(key, Nil) + parseComment(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) + } + + case SingleTagRegex(name) :: ls if (!inCodeBlock) => { + val key = SimpleTagKey(name) + val value = "" :: tags.getOrElse(key, Nil) + parseComment(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) + } + + case line :: ls if (lastTagKey.isDefined) => { + val newtags = if (!line.isEmpty) { + val key = lastTagKey.get + val value = + ((tags get key): @unchecked) match { + case Some(b :: bs) => (b + endOfLine + line) :: bs + case None => oops("lastTagKey set when no tag exists for key") + } + tags + (key -> value) + } else tags + parseComment(docBody, newtags, lastTagKey, ls, inCodeBlock) + } + + case line :: ls => { + if (docBody.length > 0) docBody append endOfLine + docBody append line + parseComment(docBody, tags, lastTagKey, ls, inCodeBlock) + } + + case Nil => { + // Take the {inheritance, content} diagram keys aside, as it doesn't need any parsing + val inheritDiagramTag = SimpleTagKey("inheritanceDiagram") + val contentDiagramTag = SimpleTagKey("contentDiagram") + + val inheritDiagramText: List[String] = tags.get(inheritDiagramTag) match { + case Some(list) => list + case None => List.empty + } + + val contentDiagramText: List[String] = tags.get(contentDiagramTag) match { + case Some(list) => list + case None => List.empty + } + + val stripTags=List(inheritDiagramTag, contentDiagramTag, SimpleTagKey("template"), SimpleTagKey("documentable")) + val tagsWithoutDiagram = tags.filterNot(pair => stripTags.contains(pair._1)) + + val bodyTags: mutable.Map[TagKey, List[Body]] = + mutable.Map((tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(_, /*pos,*/ site))}).toSeq: _*) + + def oneTag(key: SimpleTagKey, filterEmpty: Boolean = true): Option[Body] = + ((bodyTags remove key): @unchecked) match { + case Some(r :: rs) if !(filterEmpty && r.blocks.isEmpty) => + //if (!rs.isEmpty) dottydoc.println(s"$pos: only one '@${key.name}' tag is allowed") + Some(r) + case _ => None + } + + def allTags(key: SimpleTagKey): List[Body] = + (bodyTags remove key).getOrElse(Nil).filterNot(_.blocks.isEmpty) + + def allSymsOneTag(key: TagKey, filterEmpty: Boolean = true): Map[String, Body] = { + val keys: Seq[SymbolTagKey] = + bodyTags.keys.toSeq flatMap { + case stk: SymbolTagKey if (stk.name == key.name) => Some(stk) + case stk: SimpleTagKey if (stk.name == key.name) => + //dottydoc.println(s"$pos: tag '@${stk.name}' must be followed by a symbol name") + None + case _ => None + } + val pairs: Seq[(String, Body)] = + for (key <- keys) yield { + val bs = (bodyTags remove key).get + //if (bs.length > 1) + //dottydoc.println(s"$pos: only one '@${key.name}' tag for symbol ${key.symbol} is allowed") + (key.symbol, bs.head) + } + Map.empty[String, Body] ++ (if (filterEmpty) pairs.filterNot(_._2.blocks.isEmpty) else pairs) + } + + def linkedExceptions: Map[String, Body] = { + val m = allSymsOneTag(SimpleTagKey("throws"), filterEmpty = false) + + m.map { case (name,body) => + //val link = memberLookup(pos, name, site) + val newBody = body match { + case Body(List(Paragraph(Chain(content)))) => + val descr = Text(" ") +: content + //val entityLink = EntityLink(Monospace(Text(name)), link) + Body(List(Paragraph(Chain(/*entityLink +: */descr)))) + case _ => body + } + (name, newBody) + } + } + + // TODO: this method should return a parsed comment with the members below + //val com = createComment ( + // body0 = Some(parseWikiAtSymbol(docBody.toString, pos, site)), + // authors0 = allTags(SimpleTagKey("author")), + // see0 = allTags(SimpleTagKey("see")), + // result0 = oneTag(SimpleTagKey("return")), + // throws0 = linkedExceptions, + // valueParams0 = allSymsOneTag(SimpleTagKey("param")), + // typeParams0 = allSymsOneTag(SimpleTagKey("tparam")), + // version0 = oneTag(SimpleTagKey("version")), + // since0 = oneTag(SimpleTagKey("since")), + // todo0 = allTags(SimpleTagKey("todo")), + // deprecated0 = oneTag(SimpleTagKey("deprecated"), filterEmpty = false), + // note0 = allTags(SimpleTagKey("note")), + // example0 = allTags(SimpleTagKey("example")), + // constructor0 = oneTag(SimpleTagKey("constructor")), + // source0 = Some(clean(src).mkString("\n")), + // inheritDiagram0 = inheritDiagramText, + // contentDiagram0 = contentDiagramText, + // group0 = oneTag(SimpleTagKey("group")), + // groupDesc0 = allSymsOneTag(SimpleTagKey("groupdesc")), + // groupNames0 = allSymsOneTag(SimpleTagKey("groupname")), + // groupPrio0 = allSymsOneTag(SimpleTagKey("groupprio")), + // hideImplicitConversions0 = allTags(SimpleTagKey("hideImplicitConversion")), + // shortDescription0 = allTags(SimpleTagKey("shortDescription")) + //) + // + //for ((key, _) <- bodyTags) + // dottydoc.println(s"$pos: Tag '@${key.name}' is not recognised") + + parseWikiAtSymbol(docBody.toString, /*pos,*/ site) + } + } + + parseComment(new StringBuilder(comment.size), Map.empty, None, comment, inCodeBlock = false) + } + + /** A key used for a tag map. The key is built from the name of the tag and + * from the linked symbol if the tag has one. + * Equality on tag keys is structural. */ + private sealed abstract class TagKey { + def name: String + } + + private final case class SimpleTagKey(name: String) extends TagKey + private final case class SymbolTagKey(name: String, symbol: String) extends TagKey + + /** Something that should not have happened, happened, and Scaladoc should exit. */ + private def oops(msg: String): Nothing = + throw new IllegalArgumentException("program logic: " + msg) + + /** Parses a string containing wiki syntax into a `Comment` object. + * Note that the string is assumed to be clean: + * - Removed Scaladoc start and end markers. + * - Removed start-of-line star and one whitespace afterwards (if present). + * - Removed all end-of-line whitespace. + * - Only `endOfLine` is used to mark line endings. */ + def parseWikiAtSymbol(string: String, /*pos: Position,*/ site: Symbol): Body = new WikiParser(string, /*pos,*/ site).document() + + /** TODO + * + * @author Ingo Maier + * @author Manohar Jonnalagedda + * @author Gilles Dubochet */ + protected final class WikiParser(val buffer: String, /*pos: Position,*/ site: Symbol) extends CharReader(buffer) { wiki => + var summaryParsed = false + + def document(): Body = { + val blocks = new mutable.ListBuffer[Block] + while (char != endOfText) + blocks += block() + Body(blocks.toList) + } + + /* BLOCKS */ + + /** {{{ block ::= code | title | hrule | listBlock | para }}} */ + def block(): Block = { + if (checkSkipInitWhitespace("{{{")) + code() + else if (checkSkipInitWhitespace('=')) + title() + else if (checkSkipInitWhitespace("----")) + hrule() + else if (checkList) + listBlock + else { + para() + } + } + + /** listStyle ::= '-' spc | '1.' spc | 'I.' spc | 'i.' spc | 'A.' spc | 'a.' spc + * Characters used to build lists and their constructors */ + protected val listStyles = Map[String, (Seq[Block] => Block)]( // TODO Should this be defined at some list companion? + "- " -> ( UnorderedList(_) ), + "1. " -> ( OrderedList(_,"decimal") ), + "I. " -> ( OrderedList(_,"upperRoman") ), + "i. " -> ( OrderedList(_,"lowerRoman") ), + "A. " -> ( OrderedList(_,"upperAlpha") ), + "a. " -> ( OrderedList(_,"lowerAlpha") ) + ) + + /** Checks if the current line is formed with more than one space and one the listStyles */ + def checkList = + (countWhitespace > 0) && (listStyles.keys exists { checkSkipInitWhitespace(_) }) + + /** {{{ + * nListBlock ::= nLine { mListBlock } + * nLine ::= nSpc listStyle para '\n' + * }}} + * Where n and m stand for the number of spaces. When `m > n`, a new list is nested. */ + def listBlock(): Block = { + + /** Consumes one list item block and returns it, or None if the block is + * not a list or a different list. */ + def listLine(indent: Int, style: String): Option[Block] = + if (countWhitespace > indent && checkList) + Some(listBlock) + else if (countWhitespace != indent || !checkSkipInitWhitespace(style)) + None + else { + jumpWhitespace() + jump(style) + val p = Paragraph(inline(isInlineEnd = false)) + blockEnded("end of list line ") + Some(p) + } + + /** Consumes all list item blocks (possibly with nested lists) of the + * same list and returns the list block. */ + def listLevel(indent: Int, style: String): Block = { + val lines = mutable.ListBuffer.empty[Block] + var line: Option[Block] = listLine(indent, style) + while (line.isDefined) { + lines += line.get + line = listLine(indent, style) + } + val constructor = listStyles(style) + constructor(lines) + } + + val indent = countWhitespace + val style = (listStyles.keys find { checkSkipInitWhitespace(_) }).getOrElse(listStyles.keys.head) + listLevel(indent, style) + } + + def code(): Block = { + jumpWhitespace() + jump("{{{") + val str = readUntil("}}}") + if (char == endOfText) + reportError(/*pos,*/ "unclosed code block") + else + jump("}}}") + blockEnded("code block") + Code(normalizeIndentation(str)) + } + + /** {{{ title ::= ('=' inline '=' | "==" inline "==" | ...) '\n' }}} */ + def title(): Block = { + jumpWhitespace() + val inLevel = repeatJump('=') + val text = inline(check("=" * inLevel)) + val outLevel = repeatJump('=', inLevel) + if (inLevel != outLevel) + reportError(/*pos,*/ "unbalanced or unclosed heading") + blockEnded("heading") + Title(text, inLevel) + } + + /** {{{ hrule ::= "----" { '-' } '\n' }}} */ + def hrule(): Block = { + jumpWhitespace() + repeatJump('-') + blockEnded("horizontal rule") + HorizontalRule() + } + + /** {{{ para ::= inline '\n' }}} */ + def para(): Block = { + val p = + if (summaryParsed) + Paragraph(inline(isInlineEnd = false)) + else { + val s = summary() + val r = + if (checkParaEnded()) List(s) else List(s, inline(isInlineEnd = false)) + summaryParsed = true + Paragraph(Chain(r)) + } + while (char == endOfLine && char != endOfText) + nextChar() + p + } + + /* INLINES */ + + val OPEN_TAG = "^<([A-Za-z]+)( [^>]*)?(/?)>$".r + val CLOSE_TAG = "^$".r + private def readHTMLFrom(begin: HtmlTag): String = { + val list = mutable.ListBuffer.empty[String] + val stack = mutable.ListBuffer.empty[String] + + begin.close match { + case Some(HtmlTag(CLOSE_TAG(s))) => + stack += s + case _ => + return "" + } + + do { + val str = readUntil { char == safeTagMarker || char == endOfText } + nextChar() + + list += str + + str match { + case OPEN_TAG(s, _, standalone) => { + if (standalone != "/") { + stack += s + } + } + case CLOSE_TAG(s) => { + if (s == stack.last) { + stack.remove(stack.length-1) + } + } + case _ => ; + } + } while (stack.length > 0 && char != endOfText) + + list mkString "" + } + + def inline(isInlineEnd: => Boolean): Inline = { + + def inline0(): Inline = { + if (char == safeTagMarker) { + val tag = htmlTag() + HtmlTag(tag.data + readHTMLFrom(tag)) + } + else if (check("'''")) bold() + else if (check("''")) italic() + else if (check("`")) monospace() + else if (check("__")) underline() + else if (check("^")) superscript() + else if (check(",,")) subscript() + else if (check("[[")) link() + else { + val str = readUntil { + char == safeTagMarker || + check("''") || + char == '`' || + check("__") || + char == '^' || + check(",,") || + check("[[") || + isInlineEnd || + checkParaEnded || + char == endOfLine + } + Text(str) + } + } + + val inlines: List[Inline] = { + val iss = mutable.ListBuffer.empty[Inline] + iss += inline0() + while (!isInlineEnd && !checkParaEnded) { + val skipEndOfLine = if (char == endOfLine) { + nextChar() + true + } else { + false + } + + val current = inline0() + (iss.last, current) match { + case (Text(t1), Text(t2)) if skipEndOfLine => + iss.update(iss.length - 1, Text(t1 + endOfLine + t2)) + case (i1, i2) if skipEndOfLine => + iss ++= List(Text(endOfLine.toString), i2) + case _ => iss += current + } + } + iss.toList + } + + inlines match { + case Nil => Text("") + case i :: Nil => i + case is => Chain(is) + } + + } + + def htmlTag(): HtmlTag = { + jump(safeTagMarker) + val read = readUntil(safeTagMarker) + if (char != endOfText) jump(safeTagMarker) + HtmlTag(read) + } + + def bold(): Inline = { + jump("'''") + val i = inline(check("'''")) + jump("'''") + Bold(i) + } + + def italic(): Inline = { + jump("''") + val i = inline(check("''")) + jump("''") + Italic(i) + } + + def monospace(): Inline = { + jump("`") + val i = inline(check("`")) + jump("`") + Monospace(i) + } + + def underline(): Inline = { + jump("__") + val i = inline(check("__")) + jump("__") + Underline(i) + } + + def superscript(): Inline = { + jump("^") + val i = inline(check("^")) + if (jump("^")) { + Superscript(i) + } else { + Chain(Seq(Text("^"), i)) + } + } + + def subscript(): Inline = { + jump(",,") + val i = inline(check(",,")) + jump(",,") + Subscript(i) + } + + def summary(): Inline = { + val i = inline(checkSentenceEnded()) + Summary( + if (jump(".")) + Chain(List(i, Text("."))) + else + i + ) + } + + def link(): Inline = { + val SchemeUri = """([a-z]+:.*)""".r + jump("[[") + val parens = 2 + repeatJump('[') + val stop = "]" * parens + val target = readUntil { check(stop) || isWhitespaceOrNewLine(char) } + val title = + if (!check(stop)) Some({ + jumpWhitespaceOrNewLine() + inline(check(stop)) + }) + else None + jump(stop) + + (target, title) match { + case (SchemeUri(uri), optTitle) => + Link(uri, optTitle getOrElse Text(uri)) + case (qualName, optTitle) => + //TODO: this should be enabled + //makeEntityLink(optTitle getOrElse Text(target), pos, target, site) + title.getOrElse(Text("broken link")) + } + } + + /* UTILITY */ + + /** {{{ eol ::= { whitespace } '\n' }}} */ + def blockEnded(blockType: String): Unit = { + if (char != endOfLine && char != endOfText) { + reportError(/*pos,*/ "no additional content on same line after " + blockType) + jumpUntil(endOfLine) + } + while (char == endOfLine) + nextChar() + } + + /** + * Eliminates the (common) leading spaces in all lines, based on the first line + * For indented pieces of code, it reduces the indent to the least whitespace prefix: + * {{{ + * indented example + * another indented line + * if (condition) + * then do something; + * ^ this is the least whitespace prefix + * }}} + */ + def normalizeIndentation(_code: String): String = { + + val code = _code.replaceAll("\\s+$", "").dropWhile(_ == '\n') // right-trim + remove all leading '\n' + val lines = code.split("\n") + + // maxSkip - size of the longest common whitespace prefix of non-empty lines + val nonEmptyLines = lines.filter(_.trim.nonEmpty) + val maxSkip = if (nonEmptyLines.isEmpty) 0 else nonEmptyLines.map(line => line.prefixLength(_ == ' ')).min + + // remove common whitespace prefix + lines.map(line => if (line.trim.nonEmpty) line.substring(maxSkip) else line).mkString("\n") + } + + def checkParaEnded(): Boolean = { + (char == endOfText) || + ((char == endOfLine) && { + val poff = offset + nextChar() // read EOL + val ok = { + checkSkipInitWhitespace(endOfLine) || + checkSkipInitWhitespace('=') || + checkSkipInitWhitespace("{{{") || + checkList || + checkSkipInitWhitespace('\u003D') + } + offset = poff + ok + }) + } + + def checkSentenceEnded(): Boolean = { + (char == '.') && { + val poff = offset + nextChar() // read '.' + val ok = char == endOfText || char == endOfLine || isWhitespace(char) + offset = poff + ok + } + } + + def reportError(/*pos: Position,*/ message: String) = + //dottydoc.println(s"$pos: $message") + dottydoc.println(s"$message") + } + + protected sealed class CharReader(buffer: String) { reader => + + var offset: Int = 0 + def char: Char = + if (offset >= buffer.length) endOfText else buffer charAt offset + + final def nextChar() = + offset += 1 + + final def check(chars: String): Boolean = { + val poff = offset + val ok = jump(chars) + offset = poff + ok + } + + def checkSkipInitWhitespace(c: Char): Boolean = { + val poff = offset + jumpWhitespace() + val ok = jump(c) + offset = poff + ok + } + + def checkSkipInitWhitespace(chars: String): Boolean = { + val poff = offset + jumpWhitespace() + val (ok0, chars0) = + if (chars.charAt(0) == ' ') + (offset > poff, chars substring 1) + else + (true, chars) + val ok = ok0 && jump(chars0) + offset = poff + ok + } + + def countWhitespace: Int = { + var count = 0 + val poff = offset + while (isWhitespace(char) && char != endOfText) { + nextChar() + count += 1 + } + offset = poff + count + } + + /* Jumpers */ + + /** Jumps a character and consumes it + * @return true only if the correct character has been jumped */ + final def jump(ch: Char): Boolean = { + if (char == ch) { + nextChar() + true + } + else false + } + + /** Jumps all the characters in chars, consuming them in the process. + * @return true only if the correct characters have been jumped + */ + final def jump(chars: String): Boolean = { + var index = 0 + while (index < chars.length && char == chars.charAt(index) && char != endOfText) { + nextChar() + index += 1 + } + index == chars.length + } + + final def repeatJump(c: Char, max: Int = Int.MaxValue): Int = { + var count = 0 + while (jump(c) && count < max) + count += 1 + count + } + + final def jumpUntil(ch: Char): Int = { + var count = 0 + while (char != ch && char != endOfText) { + nextChar() + count += 1 + } + count + } + + final def jumpUntil(pred: => Boolean): Int = { + var count = 0 + while (!pred && char != endOfText) { + nextChar() + count += 1 + } + count + } + + def jumpWhitespace() = jumpUntil(!isWhitespace(char)) + + def jumpWhitespaceOrNewLine() = jumpUntil(!isWhitespaceOrNewLine(char)) + + + /* Readers */ + final def readUntil(c: Char): String = { + withRead { + while (char != c && char != endOfText) { + nextChar() + } + } + } + + final def readUntil(chars: String): String = { + assert(chars.length > 0) + withRead { + val c = chars.charAt(0) + while (!check(chars) && char != endOfText) { + nextChar() + while (char != c && char != endOfText) + nextChar() + } + } + } + + final def readUntil(pred: => Boolean): String = { + withRead { + while (char != endOfText && !pred) { + nextChar() + } + } + } + + private def withRead(read: => Unit): String = { + val start = offset + read + buffer.substring(start, offset) + } + + /* Chars classes */ + def isWhitespace(c: Char) = c == ' ' || c == '\t' + + def isWhitespaceOrNewLine(c: Char) = isWhitespace(c) || c == '\n' + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala new file mode 100644 index 000000000000..2d75b0c668ab --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala @@ -0,0 +1,84 @@ +package dotty.tools.dottydoc +package model +package comment + +import scala.util.matching.Regex + +object Regexes { + val TrailingWhitespace = """\s+$""".r + + /** The body of a line, dropping the (optional) start star-marker, + * one leading whitespace and all trailing whitespace + */ + val CleanCommentLine = + new Regex("""(?:\s*\*\s?)?(.*)""") + + /** Dangerous HTML tags that should be replaced by something safer, + * such as wiki syntax, or that should be dropped + */ + val DangerousTags = + new Regex("""<(/?(div|ol|ul|li|h[1-6]|p))( [^>]*)?/?>|""") + + /** Javadoc tags that should be replaced by something useful, such as wiki + * syntax, or that should be dropped. */ + val JavadocTags = + new Regex("""\{\@(code|docRoot|linkplain|link|literal|value)\p{Zs}*([^}]*)\}""") + + /** Maps a javadoc tag to a useful wiki replacement, or an empty string if it cannot be salvaged. */ + def javadocReplacement(mtch: Regex.Match): String = { + mtch.group(1) match { + case "code" => "" + mtch.group(2) + "" + case "docRoot" => "" + case "link" => "`[[" + mtch.group(2) + "]]`" + case "linkplain" => "[[" + mtch.group(2) + "]]" + case "literal" => "`" + mtch.group(2) + "`" + case "value" => "`" + mtch.group(2) + "`" + case _ => "" + } + } + + /** Maps a dangerous HTML tag to a safe wiki replacement, or an empty string + * if it cannot be salvaged. */ + def htmlReplacement(mtch: Regex.Match): String = mtch.group(1) match { + case "p" | "div" => "\n\n" + case "h1" => "\n= " + case "/h1" => " =\n" + case "h2" => "\n== " + case "/h2" => " ==\n" + case "h3" => "\n=== " + case "/h3" => " ===\n" + case "h4" | "h5" | "h6" => "\n==== " + case "/h4" | "/h5" | "/h6" => " ====\n" + case "li" => "\n * - " + case _ => "" + } + + /** Safe HTML tags that can be kept. */ + val SafeTags = + new Regex("""((&\w+;)|(&#\d+;)|(]*)?/?>))""") + + val safeTagMarker = '\u000E' + val endOfLine = '\u000A' + val endOfText = '\u0003' + + /** A Scaladoc tag not linked to a symbol and not followed by text */ + val SingleTagRegex = + new Regex("""\s*@(\S+)\s*""") + + /** A Scaladoc tag not linked to a symbol. Returns the name of the tag, and the rest of the line. */ + val SimpleTagRegex = + new Regex("""\s*@(\S+)\s+(.*)""") + + /** A Scaladoc tag linked to a symbol. Returns the name of the tag, the name + * of the symbol, and the rest of the line. */ + val SymbolTagRegex = + new Regex("""\s*@(param|tparam|throws|groupdesc|groupname|groupprio)\s+(\S*)\s*(.*)""") + + /** The start of a Scaladoc code block */ + val CodeBlockStartRegex = + new Regex("""(.*?)((?:\{\{\{)|(?:\u000E]*)?>\u000E))(.*)""") + + /** The end of a Scaladoc code block */ + val CodeBlockEndRegex = + new Regex("""(.*?)((?:\}\}\})|(?:\u000E\u000E))(.*)""") +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala new file mode 100644 index 000000000000..4f9a8794996f --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -0,0 +1,43 @@ +package dotty.tools.dottydoc +package util + +object IndexWriters { + import prickle._ + import model.Entities._ + import model.Html._ + + def writeJs(packs: Map[String, Package], outPath: String): Unit = { + for ((_, pack) <- packs) { + println(s"""Writing '${pack.path.mkString(".")}'""") + writeFile( + entityHtml(pack), + outPath + pack.path.tail.mkString("/", "/", "/"), + "index.html") + + for (child <- pack.children) { + println(s"""Writing '${child.path.mkString(".")}'""") + writeFile( + entityHtml(child), + outPath + child.path.dropRight(1).mkString("/", "/", "/"), + child.path.last + ".html") + } + } + + val pickled = Pickle.intoString(packs) + val js = "Index = {}; Index.packages = " + pickled + ";" + println("Writing index.js...") + writeFile(js, outPath + "/../", "index.js") + println("Done writing static material, building js-app") + + } + + def writeFile(str: String, path: String, file: String): Unit = { + def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) { + val p = new java.io.PrintWriter(f) + try { op(p) } finally { p.close() } + } + + new java.io.File(path).mkdirs() + printToFile(new java.io.File(path + file))(_.println(str)) + } +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala new file mode 100644 index 000000000000..9bd175fde230 --- /dev/null +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala @@ -0,0 +1,126 @@ +package dotty.tools.dottydoc +package model + +import comment.Comment + +object Entities { + import prickle._ + + type PackageMember = Entity with Members with Modifiers + + sealed trait Entity { + def name: String + + def path: List[String] + + def comment: Option[Comment] + + val sourceUrl: String = "#" + + val kind: String + } + + sealed trait Members { + def members: List[Entity] + } + + sealed trait Modifiers { + def modifiers: List[String] + + val isPrivate: Boolean = + modifiers.contains("private") + } + + final case class Package( + name: String, + members: List[Entity], + comment: Option[Comment], + path: List[String] + ) extends Entity { + override val kind = "package" + + val children: List[PackageMember] = + members.collect { case x: PackageMember => x } + } + + final case class Class( + name: String, + members: List[Entity], + comment: Option[Comment], + modifiers: List[String], + path: List[String] + ) extends Entity with Members with Modifiers { + override val kind = "class" + } + + final case class CaseClass( + name: String, + members: List[Entity], + comment: Option[Comment], + modifiers: List[String], + path: List[String] + ) extends Entity with Members with Modifiers { + override val kind = "case class" + } + + final case class Trait( + name: String, + members: List[Entity], + comment: Option[Comment], + modifiers: List[String], + path: List[String] + ) extends Entity with Members with Modifiers { + override val kind = "trait" + } + + final case class Object( + name: String, + members: List[Entity], + comment: Option[Comment], + modifiers: List[String], + path: List[String] + ) extends Entity with Members with Modifiers { + override val kind = "object" + } + + final case class Def( + name: String, + comment: Option[Comment], + modifiers: List[String], + path: List[String] + ) extends Entity with Modifiers { + override val kind = "def" + } + + final case class Val( + name: String, + comment: Option[Comment], + modifiers: List[String], + path: List[String] + ) extends Entity with Modifiers { + override val kind = "val" + } + + /** This object is used to represent entities that are to be filtered out */ + final case object NonEntity extends Entity { + override val name = "" + override val comment = None + override val path = Nil + override val kind = "" + } + + //implicit val pMPickler: PicklerPair[PackageMember] = CompositePickler[PackageMember] + // .concreteType[Class] + // .concreteType[CaseClass] + // .concreteType[Object] + // .concreteType[Trait] + + implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity] + .concreteType[Val] + .concreteType[Def] + .concreteType[Class] + .concreteType[CaseClass] + .concreteType[Object] + .concreteType[Trait] + .concreteType[Package] +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala new file mode 100644 index 000000000000..5e459a766e83 --- /dev/null +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala @@ -0,0 +1,37 @@ +package dotty.tools.dottydoc +package model + +import dotty.tools.dotc +import dotc.core.Types._ +import dotc.core.Contexts.Context +import dotc.core.Symbols.Symbol +import dotc.core.{ Flags => DottyFlags } +import dotc.ast.Trees._ +import DottyFlags.FlagSet + +object EntityFactories { + import dotty.tools.dotc.ast.tpd._ + import DottyFlags._ + + def flags(t: Tree)(implicit ctx: Context): List[String] = + (t.symbol.flags & SourceModifierFlags).flagStrings.toList + + def path(t: Tree, name: String)(implicit ctx: Context): List[String] = { + def pathList(tpe: Type): List[String] = tpe match { + case t: ThisType => + pathList(t.tref) + case t: NamedType if t.prefix == NoPrefix && t.name.toString == "" => + Nil + case t: NamedType if t.prefix == NoPrefix => + t.name.toString :: Nil + case t: NamedType => + pathList(t.prefix) :+ t.name.toString + } + + val ref = + if (t.symbol.isTerm) t.symbol.termRef + else t.symbol.typeRef + + pathList(ref) + } +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala new file mode 100644 index 000000000000..cf37564b9e8c --- /dev/null +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala @@ -0,0 +1,6 @@ +package dotty.tools +package dottydoc +package model +package comment + +case class Comment(body: String) diff --git a/project/Build.scala b/project/Build.scala index b7822907df28..7322f131bd35 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -264,6 +264,63 @@ object DottyInjectedPlugin extends AutoPlugin { settings(publishing) + lazy val dottydoc = crossProject.in(file("dottydoc")) + .jsSettings( + libraryDependencies ++= Seq( + "org.scala-js" %%% "scalajs-dom" % "0.8.0", + "com.github.benhutchison" %%% "prickle" % "1.1.10", + "com.lihaoyi" %%% "scalatags" % "0.5.4" + ) + ) + + lazy val dottydocJS = dottydoc.js.dependsOn(dotty).settings( + scalaSource in Compile := baseDirectory.value / "src" + ) + + lazy val dottydocJVM = dottydoc.jvm.dependsOn(dotty).settings( + (resources in Compile) += (fastOptJS in (dottydocJS, Compile)).value.data, + scalaSource in Compile := baseDirectory.value / "src", + libraryDependencies ++= Seq( + "com.github.benhutchison" %% "prickle" % "1.1.10", + "com.lihaoyi" %% "scalatags" % "0.5.4" + ), + + // enable improved incremental compilation algorithm + incOptions := incOptions.value.withNameHashing(true), + + mainClass in (Compile, run) := Some("dotty.tools.dottydoc.DottyDoc"), + fork in run := true, + fork in Test := true, + parallelExecution in Test := false, + + // http://grokbase.com/t/gg/simple-build-tool/135ke5y90p/sbt-setting-jvm-boot-paramaters-for-scala + javaOptions <++= (dependencyClasspath in Runtime, packageBin in Compile) map { (attList, bin) => + // put the Scala {library, reflect} in the classpath + val path = for { + file <- attList.map(_.data) + path = file.getAbsolutePath + } yield "-Xbootclasspath/p:" + path + // dotty itself needs to be in the bootclasspath + val fullpath = ("-Xbootclasspath/a:" + bin) :: path.toList + // System.err.println("BOOTPATH: " + fullpath) + + val travis_build = // propagate if this is a travis build + if (sys.props.isDefinedAt(JENKINS_BUILD)) + List(s"-D$JENKINS_BUILD=${sys.props(JENKINS_BUILD)}") ::: jenkinsMemLimit + else + List() + + val tuning = + if (sys.props.isDefinedAt("Oshort")) + // Optimize for short-running applications, see https://github.com/lampepfl/dotty/issues/222 + List("-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1") + else + List() + + ("-DpartestParentID=" + pid) :: tuning ::: agentOptions ::: travis_build ::: fullpath + } + ) + /** A sandbox to play with the Scala.js back-end of dotty. * * This sandbox is compiled with dotty with support for Scala.js. It can be From 1b20568bdbf7b561fb836faf095bb67a52895a58 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 13 Apr 2016 11:26:02 +0200 Subject: [PATCH 002/100] Port cooking of strings from NSC --- dottydoc/js/src/html/Layout.scala | 12 +- .../dotty/tools/dottydoc/core/Phases.scala | 3 +- .../tools/dottydoc/model/CommentParsers.scala | 18 +- .../model/comment/CommentCooker.scala | 8 - .../model/comment/CommentExpander.scala | 344 ++++++++++++++++++ .../model/comment/CommentParser.scala | 2 +- .../dottydoc/model/comment/CommentUtils.scala | 224 ++++++++++++ src/dotty/tools/dotc/ast/Trees.scala | 7 +- src/dotty/tools/dotc/config/Printers.scala | 2 +- src/dotty/tools/dotc/core/Contexts.scala | 7 +- src/dotty/tools/dotc/parsing/Parsers.scala | 23 +- src/dotty/tools/dotc/parsing/Scanners.scala | 4 +- 12 files changed, 619 insertions(+), 35 deletions(-) delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala index 59d27a15d550..a57655d3fbbe 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/js/src/html/Layout.scala @@ -33,7 +33,8 @@ object Index { span( cls := "mdl-layout-title", "Packages" - ) + ), + packageView ), main( cls := "mdl-layout__content", @@ -50,6 +51,15 @@ object Index { ) ) + def packageView = nav( + cls := "mdl-navigation", + ParsedIndex.packages.keys.flatMap { k => + ParsedIndex.packages(k).children.sortBy(_.name).map { c => + a(cls := "mdl-navigation__link", href := "#", c.name) + } + }.toList + ) + def companionHref(m: Entity): Option[PackageMember] = { val pack = m.path.dropRight(1).mkString(".") println(pack) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index a525723639c4..f76d013a6e08 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -36,8 +36,7 @@ object Phases { case _ => Nil } - val comment = - ctx.base.docstring(tree.symbol).map(c => Comment(wikiParser.parseHtml(c))) + val comment = wikiParser.parseHtml(tree.symbol) tree match { /** package */ diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala index dce8f4a69baf..cc7bf6949aa7 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -2,14 +2,26 @@ package dotty.tools package dottydoc package model +import dotc.core.Symbols.Symbol +import dotc.core.Contexts.Context + object CommentParsers { import comment._ import BodyParsers._ sealed class WikiParser - extends CommentCleaner with CommentParser with CommentCooker { - def parseHtml(str: String): String = - parse(clean(str), str).toHtml + extends CommentCleaner with CommentParser with CommentExpander { + def parseHtml(sym: Symbol)(implicit ctx: Context): Option[Comment]= { + println("Original ---------------------") + println(ctx.base.docstring(sym).map(_.chrs).getOrElse("")) + val expanded = expand(sym) + println("Expanded ---------------------") + println(expanded) + parse(clean(expanded), expanded).toHtml match { + case "" => None + case x => Some(Comment(x)) + } + } } val wikiParser = new WikiParser diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala deleted file mode 100644 index 4d4474d52853..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCooker.scala +++ /dev/null @@ -1,8 +0,0 @@ -package dotty.tools.dottydoc -package model -package comment - -trait CommentCooker { - trait Context - def cook(comment: String)(implicit ctx: Context): String = "" -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala new file mode 100644 index 000000000000..f90e95f33f5c --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala @@ -0,0 +1,344 @@ +/* + * Port of DocComment.scala from nsc + * @author Martin Odersky + * @author Felix Mulder + */ + +package dotty.tools +package dottydoc +package model +package comment + +import dotc.config.Printers.dottydoc +import dotc.core.Contexts.Context +import dotc.core.Symbols._ +import dotc.core.Flags +import dotc.util.Positions._ + +import scala.collection.mutable + +trait CommentExpander { + import CommentUtils._ + + def expand(sym: Symbol)(implicit ctx: Context): String = { + defineVariables(sym) + expandedDocComment(sym, sym) + } + + /** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing. + * + * @param sym The symbol for which doc comment is returned + * @param site The class for which doc comments are generated + * @throws ExpansionLimitExceeded when more than 10 successive expansions + * of the same string are done, which is + * interpreted as a recursive variable definition. + */ + def expandedDocComment(sym: Symbol, site: Symbol, docStr: String = "")(implicit ctx: Context): String = { + // when parsing a top level class or module, use the (module-)class itself to look up variable definitions + val site1 = if ((sym.is(Flags.Module) || sym.isClass) && site.is(Flags.Package)) sym + else site + expandVariables(cookedDocComment(sym, docStr), sym, site1) + } + + private def template(raw: String): String = { + val sections = tagIndex(raw) + + val defines = sections filter { startsWithTag(raw, _, "@define") } + val usecases = sections filter { startsWithTag(raw, _, "@usecase") } + + val end = startTag(raw, (defines ::: usecases).sortBy(_._1)) + + if (end == raw.length - 2) raw else raw.substring(0, end) + "*/" + } + + def defines(raw: String): List[String] = { + val sections = tagIndex(raw) + val defines = sections filter { startsWithTag(raw, _, "@define") } + val usecases = sections filter { startsWithTag(raw, _, "@usecase") } + val end = startTag(raw, (defines ::: usecases).sortBy(_._1)) + + defines map { case (start, end) => raw.substring(start, end) } + } + + private def replaceInheritDocToInheritdoc(docStr: String): String = + docStr.replaceAll("""\{@inheritDoc\p{Zs}*\}""", "@inheritdoc") + + /** The cooked doc comment of an overridden symbol */ + protected def superComment(sym: Symbol)(implicit ctx: Context): Option[String] = + allInheritedOverriddenSymbols(sym).iterator map (x => cookedDocComment(x)) find (_ != "") + + private val cookedDocComments = mutable.HashMap[Symbol, String]() + + /** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by + * missing sections of an inherited doc comment. + * If a symbol does not have a doc comment but some overridden version of it does, + * the doc comment of the overridden version is copied instead. + */ + + def cookedDocComment(sym: Symbol, docStr: String = "")(implicit ctx: Context): String = cookedDocComments.getOrElseUpdate(sym, { + var ownComment = + if (docStr.length == 0) ctx.base.docstring(sym).map(c => template(c.chrs)).getOrElse("") + else template(docStr) + ownComment = replaceInheritDocToInheritdoc(ownComment) + + superComment(sym) match { + case None => + // SI-8210 - The warning would be false negative when this symbol is a setter + if (ownComment.indexOf("@inheritdoc") != -1 && ! sym.isSetter) + dottydoc.println(s"${sym.pos}: the comment for ${sym} contains @inheritdoc, but no parent comment is available to inherit from.") + ownComment.replaceAllLiterally("@inheritdoc", "") + case Some(sc) => + if (ownComment == "") sc + else expandInheritdoc(sc, merge(sc, ownComment, sym), sym) + } + }) + + private def isMovable(str: String, sec: (Int, Int)): Boolean = + startsWithTag(str, sec, "@param") || + startsWithTag(str, sec, "@tparam") || + startsWithTag(str, sec, "@return") + + def merge(src: String, dst: String, sym: Symbol, copyFirstPara: Boolean = false): String = { + val srcSections = tagIndex(src) + val dstSections = tagIndex(dst) + val srcParams = paramDocs(src, "@param", srcSections) + val dstParams = paramDocs(dst, "@param", dstSections) + val srcTParams = paramDocs(src, "@tparam", srcSections) + val dstTParams = paramDocs(dst, "@tparam", dstSections) + val out = new StringBuilder + var copied = 0 + var tocopy = startTag(dst, dstSections dropWhile (!isMovable(dst, _))) + + if (copyFirstPara) { + val eop = // end of comment body (first para), which is delimited by blank line, or tag, or end of comment + (findNext(src, 0)(src.charAt(_) == '\n')) min startTag(src, srcSections) + out append src.substring(0, eop).trim + copied = 3 + tocopy = 3 + } + + def mergeSection(srcSec: Option[(Int, Int)], dstSec: Option[(Int, Int)]) = dstSec match { + case Some((start, end)) => + if (end > tocopy) tocopy = end + case None => + srcSec match { + case Some((start1, end1)) => { + out append dst.substring(copied, tocopy).trim + out append "\n" + copied = tocopy + out append src.substring(start1, end1).trim + } + case None => + } + } + + //TODO: enable this once you know how to get `sym.paramss` + /* + for (params <- sym.paramss; param <- params) + mergeSection(srcParams get param.name.toString, dstParams get param.name.toString) + for (tparam <- sym.typeParams) + mergeSection(srcTParams get tparam.name.toString, dstTParams get tparam.name.toString) + + mergeSection(returnDoc(src, srcSections), returnDoc(dst, dstSections)) + mergeSection(groupDoc(src, srcSections), groupDoc(dst, dstSections)) + */ + + if (out.length == 0) dst + else { + out append dst.substring(copied) + out.toString + } + } + + /** + * Expand inheritdoc tags + * - for the main comment we transform the inheritdoc into the super variable, + * and the variable expansion can expand it further + * - for the param, tparam and throws sections we must replace comments on the spot + * + * This is done separately, for two reasons: + * 1. It takes longer to run compared to merge + * 2. The inheritdoc annotation should not be used very often, as building the comment from pieces severely + * impacts performance + * + * @param parent The source (or parent) comment + * @param child The child (overriding member or usecase) comment + * @param sym The child symbol + * @return The child comment with the inheritdoc sections expanded + */ + def expandInheritdoc(parent: String, child: String, sym: Symbol): String = + if (child.indexOf("@inheritdoc") == -1) + child + else { + val parentSections = tagIndex(parent) + val childSections = tagIndex(child) + val parentTagMap = sectionTagMap(parent, parentSections) + val parentNamedParams = Map() + + ("@param" -> paramDocs(parent, "@param", parentSections)) + + ("@tparam" -> paramDocs(parent, "@tparam", parentSections)) + + ("@throws" -> paramDocs(parent, "@throws", parentSections)) + + val out = new StringBuilder + + def replaceInheritdoc(childSection: String, parentSection: => String) = + if (childSection.indexOf("@inheritdoc") == -1) + childSection + else + childSection.replaceAllLiterally("@inheritdoc", parentSection) + + def getParentSection(section: (Int, Int)): String = { + + def getSectionHeader = extractSectionTag(child, section) match { + case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(child, section) + case other => other + } + + def sectionString(param: String, paramMap: Map[String, (Int, Int)]): String = + paramMap.get(param) match { + case Some(section) => + // Cleanup the section tag and parameter + val sectionTextBounds = extractSectionText(parent, section) + cleanupSectionText(parent.substring(sectionTextBounds._1, sectionTextBounds._2)) + case None => + dottydoc.println(s"""${sym.pos}: the """" + getSectionHeader + "\" annotation of the " + sym + + " comment contains @inheritdoc, but the corresponding section in the parent is not defined.") + "" + } + + child.substring(section._1, section._1 + 7) match { + case param@("@param "|"@tparam"|"@throws") => + sectionString(extractSectionParam(child, section), parentNamedParams(param.trim)) + case _ => + sectionString(extractSectionTag(child, section), parentTagMap) + } + } + + def mainComment(str: String, sections: List[(Int, Int)]): String = + if (str.trim.length > 3) + str.trim.substring(3, startTag(str, sections)) + else + "" + + // Append main comment + out.append("/**") + out.append(replaceInheritdoc(mainComment(child, childSections), mainComment(parent, parentSections))) + + // Append sections + for (section <- childSections) + out.append(replaceInheritdoc(child.substring(section._1, section._2), getParentSection(section))) + + out.append("*/") + out.toString + } + + protected def expandVariables(initialStr: String, sym: Symbol, site: Symbol)(implicit ctx: Context): String = { + val expandLimit = 10 + + def expandInternal(str: String, depth: Int): String = { + if (depth >= expandLimit) + throw new ExpansionLimitExceeded(str) + + val out = new StringBuilder + var copied, idx = 0 + // excluding variables written as \$foo so we can use them when + // necessary to document things like Symbol#decode + def isEscaped = idx > 0 && str.charAt(idx - 1) == '\\' + while (idx < str.length) { + if ((str charAt idx) != '$' || isEscaped) + idx += 1 + else { + val vstart = idx + idx = skipVariable(str, idx + 1) + def replaceWith(repl: String) { + out append str.substring(copied, vstart) + out append repl + copied = idx + } + variableName(str.substring(vstart + 1, idx)) match { + case "super" => + superComment(sym) foreach { sc => + val superSections = tagIndex(sc) + replaceWith(sc.substring(3, startTag(sc, superSections))) + for (sec @ (start, end) <- superSections) + if (!isMovable(sc, sec)) out append sc.substring(start, end) + } + case "" => idx += 1 + case vname => + lookupVariable(vname, site) match { + case Some(replacement) => replaceWith(replacement) + case None => + dottydoc.println(s"Variable $vname undefined in comment for $sym in $site") + } + } + } + } + if (out.length == 0) str + else { + out append str.substring(copied) + expandInternal(out.toString, depth + 1) + } + } + + // We suppressed expanding \$ throughout the recursion, and now we + // need to replace \$ with $ so it looks as intended. + expandInternal(initialStr, 0).replaceAllLiterally("""\$""", "$") + } + + def defineVariables(sym: Symbol)(implicit ctx: Context) = { + val Trim = "(?s)^[\\s&&[^\n\r]]*(.*?)\\s*$".r + + val raw = ctx.base.docstring(sym).map(_.chrs).getOrElse("") + defs(sym) ++= defines(raw).map { + str => { + val start = skipWhitespace(str, "@define".length) + val (key, value) = str.splitAt(skipVariable(str, start)) + key.drop(start) -> value + } + } map { + case (key, Trim(value)) => + variableName(key) -> value.replaceAll("\\s+\\*+$", "") + } + } + + /** Maps symbols to the variable -> replacement maps that are defined + * in their doc comments + */ + private val defs = mutable.HashMap[Symbol, Map[String, String]]() withDefaultValue Map() + + /** Lookup definition of variable. + * + * @param vble The variable for which a definition is searched + * @param site The class for which doc comments are generated + */ + def lookupVariable(vble: String, site: Symbol)(implicit ctx: Context): Option[String] = site match { + case NoSymbol => None + case _ => + val searchList = + if (site.flags.is(Flags.Module)) site :: site.info.baseClasses + else site.info.baseClasses + + searchList collectFirst { case x if defs(x) contains vble => defs(x)(vble) } match { + case Some(str) if str startsWith "$" => lookupVariable(str.tail, site) + case res => res orElse lookupVariable(vble, site.owner) + } + } + + /** The position of the raw doc comment of symbol `sym`, or NoPosition if missing + * If a symbol does not have a doc comment but some overridden version of it does, + * the position of the doc comment of the overridden version is returned instead. + */ + def docCommentPos(sym: Symbol)(implicit ctx: Context): Position = + ctx.base.docstring(sym).map(_.pos).getOrElse(NoPosition) + + /** A version which doesn't consider self types, as a temporary measure: + * an infinite loop has broken out between superComment and cookedDocComment + * since r23926. + */ + private def allInheritedOverriddenSymbols(sym: Symbol)(implicit ctx: Context): List[Symbol] = { + if (!sym.owner.isClass) Nil + else sym.allOverriddenSymbols.toList.filter(_ != NoSymbol) //TODO: could also be `sym.owner.allOverrid..` + //else sym.owner.ancestors map (sym overriddenSymbol _) filter (_ != NoSymbol) + } + + class ExpansionLimitExceeded(str: String) extends Exception +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala index 5ba05fbfe4eb..b0ea0773aa64 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala @@ -562,7 +562,7 @@ trait CommentParser { case (qualName, optTitle) => //TODO: this should be enabled //makeEntityLink(optTitle getOrElse Text(target), pos, target, site) - title.getOrElse(Text("broken link")) + title.getOrElse(Text(qualName)) } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala new file mode 100644 index 000000000000..e5307bd3c559 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala @@ -0,0 +1,224 @@ +/* + * Port of DocStrings.scala from nsc + * @author Martin Odersky + * @author Felix Mulder + */ + +package dotty.tools +package dottydoc +package model +package comment + +import scala.reflect.internal.Chars._ + +object CommentUtils { + + /** Returns index of string `str` following `start` skipping longest + * sequence of whitespace characters characters (but no newlines) + */ + def skipWhitespace(str: String, start: Int): Int = + if (start < str.length && isWhitespace(str charAt start)) skipWhitespace(str, start + 1) + else start + + /** Returns index of string `str` following `start` skipping + * sequence of identifier characters. + */ + def skipIdent(str: String, start: Int): Int = + if (start < str.length && isIdentifierPart(str charAt start)) skipIdent(str, start + 1) + else start + + /** Returns index of string `str` following `start` skipping + * sequence of identifier characters. + */ + def skipTag(str: String, start: Int): Int = + if (start < str.length && (str charAt start) == '@') skipIdent(str, start + 1) + else start + + + /** Returns index of string `str` after `start` skipping longest + * sequence of space and tab characters, possibly also containing + * a single `*` character or the `/``**` sequence. + * @pre start == str.length || str(start) == `\n` + */ + def skipLineLead(str: String, start: Int): Int = + if (start == str.length) start + else { + val idx = skipWhitespace(str, start + 1) + if (idx < str.length && (str charAt idx) == '*') skipWhitespace(str, idx + 1) + else if (idx + 2 < str.length && (str charAt idx) == '/' && (str charAt (idx + 1)) == '*' && (str charAt (idx + 2)) == '*') + skipWhitespace(str, idx + 3) + else idx + } + + /** Skips to next occurrence of `\n` or to the position after the `/``**` sequence following index `start`. + */ + def skipToEol(str: String, start: Int): Int = + if (start + 2 < str.length && (str charAt start) == '/' && (str charAt (start + 1)) == '*' && (str charAt (start + 2)) == '*') start + 3 + else if (start < str.length && (str charAt start) != '\n') skipToEol(str, start + 1) + else start + + /** Returns first index following `start` and starting a line (i.e. after skipLineLead) or starting the comment + * which satisfies predicate `p`. + */ + def findNext(str: String, start: Int)(p: Int => Boolean): Int = { + val idx = skipLineLead(str, skipToEol(str, start)) + if (idx < str.length && !p(idx)) findNext(str, idx)(p) + else idx + } + + /** Return first index following `start` and starting a line (i.e. after skipLineLead) + * which satisfies predicate `p`. + */ + def findAll(str: String, start: Int)(p: Int => Boolean): List[Int] = { + val idx = findNext(str, start)(p) + if (idx == str.length) List() + else idx :: findAll(str, idx)(p) + } + + /** Produces a string index, which is a list of `sections`, i.e + * pairs of start/end positions of all tagged sections in the string. + * Every section starts with an at sign and extends to the next at sign, + * or to the end of the comment string, but excluding the final two + * characters which terminate the comment. + * + * Also take usecases into account - they need to expand until the next + * usecase or the end of the string, as they might include other sections + * of their own + */ + def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] = { + var indices = findAll(str, 0) (idx => str(idx) == '@' && p(idx)) + indices = mergeUsecaseSections(str, indices) + indices = mergeInheritdocSections(str, indices) + + indices match { + case List() => List() + case idxs => idxs zip (idxs.tail ::: List(str.length - 2)) + } + } + + /** + * Merge sections following an usecase into the usecase comment, so they + * can override the parent symbol's sections + */ + def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = { + idxs.indexWhere(str.startsWith("@usecase", _)) match { + case firstUCIndex if firstUCIndex != -1 => + val commentSections = idxs.take(firstUCIndex) + val usecaseSections = idxs.drop(firstUCIndex).filter(str.startsWith("@usecase", _)) + commentSections ::: usecaseSections + case _ => + idxs + } + } + + /** + * Merge the inheritdoc sections, as they never make sense on their own + */ + def mergeInheritdocSections(str: String, idxs: List[Int]): List[Int] = + idxs.filterNot(str.startsWith("@inheritdoc", _)) + + /** Does interval `iv` start with given `tag`? + */ + def startsWithTag(str: String, section: (Int, Int), tag: String): Boolean = + startsWithTag(str, section._1, tag) + + def startsWithTag(str: String, start: Int, tag: String): Boolean = + str.startsWith(tag, start) && !isIdentifierPart(str charAt (start + tag.length)) + + /** The first start tag of a list of tag intervals, + * or the end of the whole comment string - 2 if list is empty + */ + def startTag(str: String, sections: List[(Int, Int)]) = sections match { + case Nil => str.length - 2 + case (start, _) :: _ => start + } + + /** A map from parameter names to start/end indices describing all parameter + * sections in `str` tagged with `tag`, where `sections` is the index of `str`. + */ + def paramDocs(str: String, tag: String, sections: List[(Int, Int)]): Map[String, (Int, Int)] = + Map() ++ { + for (section <- sections if startsWithTag(str, section, tag)) yield { + val start = skipWhitespace(str, section._1 + tag.length) + str.substring(start, skipIdent(str, start)) -> section + } + } + + /** Optionally start and end index of return section in `str`, or `None` + * if `str` does not have a @group. */ + def groupDoc(str: String, sections: List[(Int, Int)]): Option[(Int, Int)] = + sections find (startsWithTag(str, _, "@group")) + + + /** Optionally start and end index of return section in `str`, or `None` + * if `str` does not have a @return. + */ + def returnDoc(str: String, sections: List[(Int, Int)]): Option[(Int, Int)] = + sections find (startsWithTag(str, _, "@return")) + + /** Extracts variable name from a string, stripping any pair of surrounding braces */ + def variableName(str: String): String = + if (str.length >= 2 && (str charAt 0) == '{' && (str charAt (str.length - 1)) == '}') + str.substring(1, str.length - 1) + else + str + + /** Returns index following variable, or start index if no variable was recognized + */ + def skipVariable(str: String, start: Int): Int = { + var idx = start + if (idx < str.length && (str charAt idx) == '{') { + do idx += 1 + while (idx < str.length && (str charAt idx) != '}') + if (idx < str.length) idx + 1 else start + } else { + while (idx < str.length && isVarPart(str charAt idx)) + idx += 1 + idx + } + } + + /** A map from the section tag to section parameters */ + def sectionTagMap(str: String, sections: List[(Int, Int)]): Map[String, (Int, Int)] = + Map() ++ { + for (section <- sections) yield + extractSectionTag(str, section) -> section + } + + /** Extract the section tag, treating the section tag as an identifier */ + def extractSectionTag(str: String, section: (Int, Int)): String = + str.substring(section._1, skipTag(str, section._1)) + + /** Extract the section parameter */ + def extractSectionParam(str: String, section: (Int, Int)): String = { + val (beg, _) = section + assert(str.startsWith("@param", beg) || + str.startsWith("@tparam", beg) || + str.startsWith("@throws", beg)) + + val start = skipWhitespace(str, skipTag(str, beg)) + val finish = skipIdent(str, start) + + str.substring(start, finish) + } + + /** Extract the section text, except for the tag and comment newlines */ + def extractSectionText(str: String, section: (Int, Int)): (Int, Int) = { + val (beg, end) = section + if (str.startsWith("@param", beg) || + str.startsWith("@tparam", beg) || + str.startsWith("@throws", beg)) + (skipWhitespace(str, skipIdent(str, skipWhitespace(str, skipTag(str, beg)))), end) + else + (skipWhitespace(str, skipTag(str, beg)), end) + } + + /** Cleanup section text */ + def cleanupSectionText(str: String) = { + var result = str.trim.replaceAll("\n\\s+\\*\\s+", " \n") + while (result.endsWith("\n")) + result = result.substring(0, str.length - 1) + result + } + +} diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 20ae02994bbf..cf11c27faa12 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -15,6 +15,7 @@ import printing.Printer import util.{Stats, Attachment, DotClass} import annotation.unchecked.uncheckedVariance import language.implicitConversions +import parsing.Scanners.Comment object Trees { @@ -30,7 +31,7 @@ object Trees { @sharable var ntrees = 0 /** Attachment key for trees with documentation strings attached */ - val DocComment = new Attachment.Key[String] + val DocComment = new Attachment.Key[Comment] /** Modifiers and annotations for definitions * @param flags The set flags @@ -324,7 +325,7 @@ object Trees { private[ast] def rawMods: Modifiers[T] = if (myMods == null) genericEmptyModifiers else myMods - def rawComment: Option[String] = getAttachment(DocComment) + def rawComment: Option[Comment] = getAttachment(DocComment) def withMods(mods: Modifiers[Untyped]): ThisTree[Untyped] = { val tree = if (myMods == null || (myMods == mods)) this else clone.asInstanceOf[MemberDef[Untyped]] @@ -334,7 +335,7 @@ object Trees { def withFlags(flags: FlagSet): ThisTree[Untyped] = withMods(Modifiers(flags)) - def setComment(comment: Option[String]): ThisTree[Untyped] = { + def setComment(comment: Option[Comment]): ThisTree[Untyped] = { comment.map(putAttachment(DocComment, _)) asInstanceOf[ThisTree[Untyped]] } diff --git a/src/dotty/tools/dotc/config/Printers.scala b/src/dotty/tools/dotc/config/Printers.scala index fa36ad12cb4c..31c9d06cd2c1 100644 --- a/src/dotty/tools/dotc/config/Printers.scala +++ b/src/dotty/tools/dotc/config/Printers.scala @@ -13,7 +13,7 @@ object Printers { } val default: Printer = new Printer - val dottydoc: Printer = noPrinter + val dottydoc: Printer = new Printer val core: Printer = noPrinter val typr: Printer = noPrinter val constr: Printer = noPrinter diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 262443314598..4a3f7c685221 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -29,6 +29,7 @@ import printing._ import config.{Settings, ScalaSettings, Platform, JavaPlatform, SJSPlatform} import language.implicitConversions import DenotTransformers.DenotTransformer +import parsing.Scanners.Comment import xsbti.AnalysisCallback object Contexts { @@ -568,12 +569,12 @@ object Contexts { allPhases.find(_.period.containsPhaseId(p.id)).getOrElse(NoPhase) } - val _docstrings: mutable.Map[Symbol, String] = + val _docstrings: mutable.Map[Symbol, Comment] = mutable.Map.empty - def docstring(sym: Symbol): Option[String] = _docstrings.get(sym) + def docstring(sym: Symbol): Option[Comment] = _docstrings.get(sym) - def addDocstring(sym: Symbol, doc: Option[String]): Unit = + def addDocstring(sym: Symbol, doc: Option[Comment]): Unit = doc.map(d => _docstrings += (sym -> d)) } diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index 600707cbfc41..378aa6ed71f8 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -22,6 +22,7 @@ import ScriptParsers._ import scala.annotation.{tailrec, switch} import util.DotClass import rewrite.Rewrites.patch +import Scanners.Comment object Parsers { @@ -1778,13 +1779,13 @@ object Parsers { */ def defOrDcl(start: Int, mods: Modifiers): Tree = in.token match { case VAL => - patDefOrDcl(posMods(start, mods), in.getDocString(start)) + patDefOrDcl(posMods(start, mods), in.getDocComment(start)) case VAR => - patDefOrDcl(posMods(start, addFlag(mods, Mutable)), in.getDocString(start)) + patDefOrDcl(posMods(start, addFlag(mods, Mutable)), in.getDocComment(start)) case DEF => - defDefOrDcl(posMods(start, mods), in.getDocString(start)) + defDefOrDcl(posMods(start, mods), in.getDocComment(start)) case TYPE => - typeDefOrDcl(posMods(start, mods), in.getDocString(start)) + typeDefOrDcl(posMods(start, mods), in.getDocComment(start)) case _ => tmplDef(start, mods) } @@ -1794,7 +1795,7 @@ object Parsers { * ValDcl ::= Id {`,' Id} `:' Type * VarDcl ::= Id {`,' Id} `:' Type */ - def patDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = { + def patDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = { val lhs = commaSeparated(pattern2) val tpt = typedOpt() val rhs = @@ -1820,7 +1821,7 @@ object Parsers { * DefDcl ::= DefSig `:' Type * DefSig ::= id [DefTypeParamClause] ParamClauses */ - def defDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = atPos(tokenRange) { + def defDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = atPos(tokenRange) { def scala2ProcedureSyntax(resultTypeStr: String) = { val toInsert = if (in.token == LBRACE) s"$resultTypeStr =" @@ -1895,7 +1896,7 @@ object Parsers { /** TypeDef ::= type Id [TypeParamClause] `=' Type * TypeDcl ::= type Id [TypeParamClause] TypeBounds */ - def typeDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = { + def typeDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = { newLinesOpt() atPos(tokenRange) { val name = ident().toTypeName @@ -1917,7 +1918,7 @@ object Parsers { * | [`case'] `object' ObjectDef */ def tmplDef(start: Int, mods: Modifiers): Tree = { - val docstring = in.getDocString(start) + val docstring = in.getDocComment(start) in.token match { case TRAIT => classDef(posMods(start, addFlag(mods, Trait)), docstring) @@ -1938,7 +1939,7 @@ object Parsers { /** ClassDef ::= Id [ClsTypeParamClause] * [ConstrMods] ClsParamClauses TemplateOpt */ - def classDef(mods: Modifiers, docstring: Option[String]): TypeDef = atPos(tokenRange) { + def classDef(mods: Modifiers, docstring: Option[Comment]): TypeDef = atPos(tokenRange) { val name = ident().toTypeName val constr = atPos(in.offset) { val tparams = typeParamClauseOpt(ParamOwner.Class) @@ -1965,7 +1966,7 @@ object Parsers { /** ObjectDef ::= Id TemplateOpt */ - def objectDef(mods: Modifiers, docstring: Option[String] = None): ModuleDef = { + def objectDef(mods: Modifiers, docstring: Option[Comment] = None): ModuleDef = { val name = ident() val template = templateOpt(emptyConstructor()) @@ -2190,7 +2191,7 @@ object Parsers { if (in.token == PACKAGE) { in.nextToken() if (in.token == OBJECT) { - val docstring = in.getDocString(start) + val docstring = in.getDocComment(start) ts += objectDef(atPos(start, in.skipToken()) { Modifiers(Package) }, docstring) if (in.token != EOF) { acceptStatSep() diff --git a/src/dotty/tools/dotc/parsing/Scanners.scala b/src/dotty/tools/dotc/parsing/Scanners.scala index 1355ea386bf9..b46ab634877f 100644 --- a/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/src/dotty/tools/dotc/parsing/Scanners.scala @@ -193,7 +193,7 @@ object Scanners { } /** Returns the closest docstring preceding the position supplied */ - def getDocString(pos: Int): Option[String] = { + def getDocComment(pos: Int): Option[Comment] = { def closest(c: Comment, docstrings: List[Comment]): Comment = docstrings match { case x :: xs if (c.pos.end < x.pos.end && x.pos.end <= pos) => closest(x, xs) case Nil => c @@ -203,7 +203,7 @@ object Scanners { case (list @ (x :: xs)) :: _ => { val c = closest(x, xs) docsPerBlockStack = list.dropWhile(_ != c).tail :: docsPerBlockStack.tail - Some(c.chrs) + Some(c) } case _ => None } From 9d4df20500e87a679b92cff997c8d8896d949d65 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 15 Apr 2016 13:44:16 +0200 Subject: [PATCH 003/100] Add module member lookup --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 5 +- .../dotty/tools/dottydoc/core/Phases.scala | 84 ++++++++++++-- .../tools/dottydoc/model/CommentParsers.scala | 20 ++-- .../dottydoc/model/comment/BodyEntities.scala | 18 ++- .../dottydoc/model/comment/BodyParsers.scala | 109 ++++++++++-------- .../model/comment/CommentParser.scala | 76 +++++++----- .../tools/dottydoc/util/MemberLookup.scala | 74 ++++++++++++ .../dotty/tools/dottydoc/model/Entity.scala | 57 ++++++--- .../dottydoc/model/EntityFactories.scala | 2 +- .../tools/dottydoc/util/Traversing.scala | 13 +++ src/dotty/tools/dotc/config/Printers.scala | 2 +- test/test/DottyDocParsingTests.scala | 90 +++++++-------- 12 files changed, 380 insertions(+), 170 deletions(-) create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala create mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 1c24b67a7ce3..11957b01a527 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -4,7 +4,7 @@ package dottydoc import core.Phases.DocPhase import dotc.config.CompilerCommand import dotc.config.Printers.dottydoc -import dotc.core.Contexts.Context +import dotc.core.Contexts.{FreshContext, Context} import dotc.core.Phases.Phase import dotc.typer.FrontEnd import dotc.{Compiler, Driver} @@ -17,7 +17,8 @@ import dotc.{Compiler, Driver} * * Example: * 1. Use the existing FrontEnd to typecheck the code being fed to dottydoc - * 2. Create JSON from the results of the FrontEnd phase + * 2. Create an AST that is serializable + * 3. Serialize to JSON */ case object DottyDocCompiler extends Compiler { override def phases: List[List[Phase]] = diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index f76d013a6e08..2e24d02d70a3 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -19,11 +19,24 @@ object Phases { import model.EntityFactories._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.ast.tpd._ + import util.Traversing._ def phaseName = "docphase" + private[this] var commentCache: Map[Entity, (Entity, Map[String, Package]) => Option[Comment]] = Map.empty + + /** Saves the commentParser function for later evaluation, for when the AST has been filled */ + def track(symbol: Symbol, ctx: Context)(op: => Entity) = { + val entity = op + val commentParser = { (entity: Entity, packs: Map[String, Package]) => + wikiParser.parseHtml(symbol, entity, packs)(ctx) + } + commentCache = commentCache + (entity -> commentParser) + entity + } + /** Build documentation hierarchy from existing tree */ - def collect(tree: Tree)(implicit ctx: Context): Entity = { + def collect(tree: Tree)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { def collectList(xs: List[Tree])(implicit ctx: Context): List[Entity] = xs.map(collect).filter(_ != NonEntity) @@ -36,41 +49,39 @@ object Phases { case _ => Nil } - val comment = wikiParser.parseHtml(tree.symbol) - tree match { /** package */ case p @ PackageDef(pid, st) => val name = pid.name.toString - Package(name, collectPackageMembers(st), comment, path(p, name)) + Package(name, collectPackageMembers(st), path(p)) /** trait */ case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => val name = n.toString - Trait(name, collectMembers(rhs), comment, flags(t), path(t, name)) + Trait(name, collectMembers(rhs), flags(t), path(t)) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => val name = n.toString.dropRight(1) - Object(name, collectMembers(rhs), comment, flags(o), path(o, name)) + Object(name, collectMembers(rhs), flags(o), path(o)) /** class / case class */ case c @ TypeDef(name, rhs) if c.symbol.isClass => - (name.toString, collectMembers(rhs), comment, flags(c), path(c, name.toString)) match { + (name.toString, collectMembers(rhs), flags(c), path(c), None) match { case x if c.symbol.is(Flags.CaseClass) => CaseClass.tupled(x) case x => Class.tupled(x) } /** def */ case d: DefDef => - Def(d.name.toString, comment, flags(d), path(d, d.name.toString)) + Def(d.name.toString, flags(d), path(d)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - Val(v.name.toString, comment, flags(v), path(v, v.name.toString)) + Val(v.name.toString, flags(v), path(v)) case x => { - dottydoc.println(s"Found unwanted entity: $x (${x.pos}, ${comment})\n${x.show}") + //dottydoc.println(s"Found unwanted entity: $x (${x.pos}, ${comment})\n${x.show}") NonEntity } } @@ -82,8 +93,7 @@ object Phases { val path = p.path.mkString(".") packages = packages + (path -> packages.get(path).map { ex => val children = (ex.children ::: p.children).distinct.sortBy(_.name) - val comment = ex.comment.orElse(p.comment) - Package(p.name, children, comment, p.path) + Package(p.name, children, p.path, None) }.getOrElse(p)) } @@ -94,8 +104,58 @@ object Phases { } override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { + // (1) Create package structure for all `units`, this will give us a complete structure val compUnits = super.runOn(units) + + // (2) Set parent of all package children + def setParent(ent: Entity, to: Entity): Unit = + ent match { + case e: Class => + e.parent = Some(to) + e.members.foreach(setParent(_, e)) + case e: CaseClass => + e.parent = Some(to) + e.members.foreach(setParent(_, e)) + case e: Object => + e.parent = Some(to) + e.members.foreach(setParent(_, e)) + case e: Trait => + e.parent = Some(to) + e.members.foreach(setParent(_, e)) + case e: Val => + e.parent = Some(to) + case e: Def => + e.parent = Some(to) + case _ => () + } + + for { + parent <- packages.values + child <- parent.children + } setParent(child, to = parent) + + // (3) Create documentation template from docstrings, with internal links + packages.values.foreach { p => + mutateEntities(p) { + case e: Package => e.comment = commentCache(e)(e, packages) + case e: Class => e.comment = commentCache(e)(e, packages) + case e: CaseClass => e.comment = commentCache(e)(e, packages) + case e: Object => e.comment = commentCache(e)(e, packages) + case e: Trait => e.comment = commentCache(e)(e, packages) + case e: Val => e.comment = commentCache(e)(e, packages) + case e: Def => e.comment = commentCache(e)(e, packages) + case _ => () + } + } + + // (4) Write the finished model to JSON util.IndexWriters.writeJs(packages, "../js/out") + + + // (5) Clear caches + commentCache = Map.empty + + // Return super's result compUnits } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala index cc7bf6949aa7..08d9d4a5ad64 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -8,21 +8,19 @@ import dotc.core.Contexts.Context object CommentParsers { import comment._ import BodyParsers._ + import Entities.{Entity, Package} sealed class WikiParser extends CommentCleaner with CommentParser with CommentExpander { - def parseHtml(sym: Symbol)(implicit ctx: Context): Option[Comment]= { - println("Original ---------------------") - println(ctx.base.docstring(sym).map(_.chrs).getOrElse("")) - val expanded = expand(sym) - println("Expanded ---------------------") - println(expanded) - parse(clean(expanded), expanded).toHtml match { - case "" => None - case x => Some(Comment(x)) - } + def parseHtml(sym: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): Option[Comment] = + ctx.base.docstring(sym).map { d => + val expanded = expand(sym) + parse(entity, packages, clean(expanded), expanded, d.pos).toHtml(entity) match { + case "" => None + case x => Some(Comment(x)) + } + }.flatten } - } val wikiParser = new WikiParser } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala index e06789e9845b..683fc6b19c4c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -3,6 +3,7 @@ package model package comment import scala.collection._ +import Entities.Entity /** A body of text. A comment has a single body, which is composed of * at least one block. Inside every body is exactly one summary (see @@ -61,12 +62,11 @@ final case class Subscript(text: Inline) extends Inline final case class Link(target: String, title: Inline) extends Inline final case class Monospace(text: Inline) extends Inline final case class Text(text: String) extends Inline -//TODO: this should be used -//abstract class EntityLink(val title: Inline) extends Inline { def link: LinkTo } -//object EntityLink { -// def apply(title: Inline, linkTo: LinkTo) = new EntityLink(title) { def link: LinkTo = linkTo } -// def unapply(el: EntityLink): Option[(Inline, LinkTo)] = Some((el.title, el.link)) -//} +abstract class EntityLink(val title: Inline) extends Inline { def link: LinkTo } +object EntityLink { + def apply(title: Inline, linkTo: LinkTo) = new EntityLink(title) { def link: LinkTo = linkTo } + def unapply(el: EntityLink): Option[(Inline, LinkTo)] = Some((el.title, el.link)) +} final case class HtmlTag(data: String) extends Inline { private val Pattern = """(?ms)\A<(/?)(.*?)[\s>].*\z""".r private val (isEnd, tagName) = data match { @@ -86,3 +86,9 @@ final case class HtmlTag(data: String) extends Inline { /** The summary of a comment, usually its first sentence. There must be exactly one summary per body. */ final case class Summary(text: Inline) extends Inline + +sealed trait LinkTo +final case class LinkToMember(mbr: Entity, parent: Entity) extends LinkTo +final case class LinkToEntity(entity: Entity) extends LinkTo +final case class LinkToExternal(name: String, url: String) extends LinkTo +final case class Tooltip(name: String) extends LinkTo diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala index 9b6ec600d4b8..6e7988f435f0 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala @@ -3,55 +3,72 @@ package model package comment object BodyParsers { + import model.Entities.{Entity, Members} + implicit class BodyToHtml(val body: Body) extends AnyVal { - def toHtml: String = bodyToHtml(body) - - private def inlineToHtml(inl: Inline): String = inl match { - case Chain(items) => (items map inlineToHtml).mkString - case Italic(in) => s"${inlineToHtml(in)}" - case Bold(in) => s"${inlineToHtml(in)}" - case Underline(in) => s"${inlineToHtml(in)}" - case Superscript(in) => s"${inlineToHtml(in)}" - case Subscript(in) => s"${inlineToHtml(in) }" - case Link(raw, title) => s"""${inlineToHtml(title)}""" - case Monospace(in) => s"${inlineToHtml(in)}" - case Text(text) => text - case Summary(in) => inlineToHtml(in) - case HtmlTag(tag) => tag - //TODO: when we have EntityLinks, they should be enabled here too - //case EntityLink(target, link) => linkToHtml(target, link, hasLinks = true) - } + def toHtml(origin: Entity): String = { + def inlineToHtml(inl: Inline): String = inl match { + case Chain(items) => (items map inlineToHtml).mkString + case Italic(in) => s"${inlineToHtml(in)}" + case Bold(in) => s"${inlineToHtml(in)}" + case Underline(in) => s"${inlineToHtml(in)}" + case Superscript(in) => s"${inlineToHtml(in)}" + case Subscript(in) => s"${inlineToHtml(in) }" + case Link(raw, title) => s"""${inlineToHtml(title)}""" + case Monospace(in) => s"${inlineToHtml(in)}" + case Text(text) => text + case Summary(in) => inlineToHtml(in) + case HtmlTag(tag) => tag + case EntityLink(target, link) => enityLinkToHtml(target, link) + } - private def bodyToHtml(body: Body): String = - (body.blocks map blockToHtml).mkString - - private def blockToHtml(block: Block): String = block match { - case Title(in, 1) => s"

    ${inlineToHtml(in)}

    " - case Title(in, 2) => s"

    ${inlineToHtml(in)}

    " - case Title(in, 3) => s"

    ${inlineToHtml(in)}

    " - case Title(in, _) => s"

    ${inlineToHtml(in)}

    " - case Paragraph(in) => s"

    ${inlineToHtml(in)}

    " - case Code(data) => s"""
    $data
    """ - case UnorderedList(items) => - s"
      ${listItemsToHtml(items)}
    " - case OrderedList(items, listStyle) => - s"
      ${listItemsToHtml(items)}
    " - case DefinitionList(items) => - s"
    ${items map { case (t, d) => s"
    ${inlineToHtml(t)}
    ${blockToHtml(d)}
    " } }
    " - case HorizontalRule() => - "
    " - } + def enityLinkToHtml(target: Inline, link: LinkTo) = link match { + case Tooltip(_) => inlineToHtml(target) + case LinkToExternal(n, url) => s"""$n""" + case LinkToMember(mbr, parent) => + s"""${mbr.name}""" + case LinkToEntity(target: Entity) => + s"""${target.name}""" + } + + def relativePath(target: Entity) = + "../" * (origin.path.length - 1) + + target.path.mkString("/") + + ".html" + + def bodyToHtml(body: Body): String = + (body.blocks map blockToHtml).mkString + + def blockToHtml(block: Block): String = block match { + case Title(in, 1) => s"

    ${inlineToHtml(in)}

    " + case Title(in, 2) => s"

    ${inlineToHtml(in)}

    " + case Title(in, 3) => s"

    ${inlineToHtml(in)}

    " + case Title(in, _) => s"

    ${inlineToHtml(in)}

    " + case Paragraph(in) => s"

    ${inlineToHtml(in)}

    " + case Code(data) => s"""
    $data
    """ + case UnorderedList(items) => + s"
      ${listItemsToHtml(items)}
    " + case OrderedList(items, listStyle) => + s"
      ${listItemsToHtml(items)}
    " + case DefinitionList(items) => + s"
    ${items map { case (t, d) => s"
    ${inlineToHtml(t)}
    ${blockToHtml(d)}
    " } }
    " + case HorizontalRule() => + "
    " + } + + def listItemsToHtml(items: Seq[Block]) = + items.foldLeft(""){ (list, item) => + item match { + case OrderedList(_, _) | UnorderedList(_) => // html requires sub ULs to be put into the last LI + list + s"
  • ${blockToHtml(item)}
  • " + case Paragraph(inline) => + list + s"
  • ${inlineToHtml(inline)}
  • " // LIs are blocks, no need to use Ps + case block => + list + s"
  • ${blockToHtml(block)}
  • " + } + } - private def listItemsToHtml(items: Seq[Block]) = - items.foldLeft(""){ (list, item) => - item match { - case OrderedList(_, _) | UnorderedList(_) => // html requires sub ULs to be put into the last LI - list + s"
  • ${blockToHtml(item)}
  • " - case Paragraph(inline) => - list + s"
  • ${inlineToHtml(inline)}
  • " // LIs are blocks, no need to use Ps - case block => - list + s"
  • ${blockToHtml(block)}
  • " - } + bodyToHtml(body) } } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala index b0ea0773aa64..3c5411c5cfc5 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala @@ -4,20 +4,29 @@ package comment import dotty.tools.dotc.util.Positions._ import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Contexts.Context import scala.collection.mutable import dotty.tools.dotc.config.Printers.dottydoc import scala.util.matching.Regex +import Entities.{Entity, Package} -//TODO: re-enable pos? -trait CommentParser { +trait CommentParser extends util.MemberLookup { import Regexes._ /** Parses a raw comment string into a `Comment` object. + * @param packages all packages parsed by Scaladoc tool, used for lookup * @param cleanComment a cleaned comment to be parsed * @param src the raw comment source string. * @param pos the position of the comment in source. */ - def parse(comment: List[String], src: String, /*pos: Position,*/ site: Symbol = NoSymbol): Body = { + def parse( + entity: Entity, + packages: Map[String, Package], + comment: List[String], + src: String, + pos: Position, + site: Symbol = NoSymbol + )(implicit ctx: Context): Body = { /** Parses a comment (in the form of a list of lines) to a `Comment` * instance, recursively on lines. To do so, it splits the whole comment @@ -136,12 +145,12 @@ trait CommentParser { val tagsWithoutDiagram = tags.filterNot(pair => stripTags.contains(pair._1)) val bodyTags: mutable.Map[TagKey, List[Body]] = - mutable.Map((tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(_, /*pos,*/ site))}).toSeq: _*) + mutable.Map((tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(entity, packages, _, pos, site))}).toSeq: _*) def oneTag(key: SimpleTagKey, filterEmpty: Boolean = true): Option[Body] = ((bodyTags remove key): @unchecked) match { case Some(r :: rs) if !(filterEmpty && r.blocks.isEmpty) => - //if (!rs.isEmpty) dottydoc.println(s"$pos: only one '@${key.name}' tag is allowed") + if (!rs.isEmpty) dottydoc.println(s"$pos: only one '@${key.name}' tag is allowed") Some(r) case _ => None } @@ -154,15 +163,15 @@ trait CommentParser { bodyTags.keys.toSeq flatMap { case stk: SymbolTagKey if (stk.name == key.name) => Some(stk) case stk: SimpleTagKey if (stk.name == key.name) => - //dottydoc.println(s"$pos: tag '@${stk.name}' must be followed by a symbol name") + dottydoc.println(s"$pos: tag '@${stk.name}' must be followed by a symbol name") None case _ => None } val pairs: Seq[(String, Body)] = for (key <- keys) yield { val bs = (bodyTags remove key).get - //if (bs.length > 1) - //dottydoc.println(s"$pos: only one '@${key.name}' tag for symbol ${key.symbol} is allowed") + if (bs.length > 1) + dottydoc.println(s"$pos: only one '@${key.name}' tag for symbol ${key.symbol} is allowed") (key.symbol, bs.head) } Map.empty[String, Body] ++ (if (filterEmpty) pairs.filterNot(_._2.blocks.isEmpty) else pairs) @@ -171,16 +180,16 @@ trait CommentParser { def linkedExceptions: Map[String, Body] = { val m = allSymsOneTag(SimpleTagKey("throws"), filterEmpty = false) - m.map { case (name,body) => - //val link = memberLookup(pos, name, site) + m.map { case (targetStr,body) => + val link = lookup(entity, packages, targetStr, pos) val newBody = body match { case Body(List(Paragraph(Chain(content)))) => val descr = Text(" ") +: content - //val entityLink = EntityLink(Monospace(Text(name)), link) - Body(List(Paragraph(Chain(/*entityLink +: */descr)))) + val entityLink = EntityLink(Monospace(Text(targetStr)), link) + Body(List(Paragraph(Chain(entityLink +: descr)))) case _ => body } - (name, newBody) + (targetStr, newBody) } } @@ -214,7 +223,7 @@ trait CommentParser { //for ((key, _) <- bodyTags) // dottydoc.println(s"$pos: Tag '@${key.name}' is not recognised") - parseWikiAtSymbol(docBody.toString, /*pos,*/ site) + parseWikiAtSymbol(entity, packages, docBody.toString, pos, site) } } @@ -241,14 +250,26 @@ trait CommentParser { * - Removed start-of-line star and one whitespace afterwards (if present). * - Removed all end-of-line whitespace. * - Only `endOfLine` is used to mark line endings. */ - def parseWikiAtSymbol(string: String, /*pos: Position,*/ site: Symbol): Body = new WikiParser(string, /*pos,*/ site).document() - - /** TODO - * + def parseWikiAtSymbol( + entity: Entity, + packages: Map[String, Package], + string: String, + pos: Position, + site: Symbol + )(implicit ctx: Context): Body = new WikiParser(entity, packages, string, pos, site).document() + + /** Original wikiparser from NSC * @author Ingo Maier * @author Manohar Jonnalagedda - * @author Gilles Dubochet */ - protected final class WikiParser(val buffer: String, /*pos: Position,*/ site: Symbol) extends CharReader(buffer) { wiki => + * @author Gilles Dubochet + */ + protected final class WikiParser( + entity: Entity, + packages: Map[String, Package], + val buffer: String, + pos: Position, + site: Symbol + )(implicit ctx: Context) extends CharReader(buffer) { wiki => var summaryParsed = false def document(): Body = { @@ -335,7 +356,7 @@ trait CommentParser { jump("{{{") val str = readUntil("}}}") if (char == endOfText) - reportError(/*pos,*/ "unclosed code block") + reportError(pos, "unclosed code block") else jump("}}}") blockEnded("code block") @@ -349,7 +370,7 @@ trait CommentParser { val text = inline(check("=" * inLevel)) val outLevel = repeatJump('=', inLevel) if (inLevel != outLevel) - reportError(/*pos,*/ "unbalanced or unclosed heading") + reportError(pos, "unbalanced or unclosed heading") blockEnded("heading") Title(text, inLevel) } @@ -560,9 +581,7 @@ trait CommentParser { case (SchemeUri(uri), optTitle) => Link(uri, optTitle getOrElse Text(uri)) case (qualName, optTitle) => - //TODO: this should be enabled - //makeEntityLink(optTitle getOrElse Text(target), pos, target, site) - title.getOrElse(Text(qualName)) + makeEntityLink(entity, packages, optTitle getOrElse Text(target), pos, target) } } @@ -571,7 +590,7 @@ trait CommentParser { /** {{{ eol ::= { whitespace } '\n' }}} */ def blockEnded(blockType: String): Unit = { if (char != endOfLine && char != endOfText) { - reportError(/*pos,*/ "no additional content on same line after " + blockType) + reportError(pos, "no additional content on same line after " + blockType) jumpUntil(endOfLine) } while (char == endOfLine) @@ -629,9 +648,8 @@ trait CommentParser { } } - def reportError(/*pos: Position,*/ message: String) = - //dottydoc.println(s"$pos: $message") - dottydoc.println(s"$message") + def reportError(pos: Position, message: String) = + dottydoc.println(s"$pos: $message") } protected sealed class CharReader(buffer: String) { reader => diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala new file mode 100644 index 000000000000..ad8d993411ce --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala @@ -0,0 +1,74 @@ +package dotty.tools +package dottydoc +package util + +import dotc.config.Printers.dottydoc +import dotc.core.Contexts.Context +import dotc.core.Flags +import dotc.core.Names._ +import dotc.core.Symbols._ +import dotc.core.Types._ +import dotc.core.Names._ +import dotc.util.Positions._ +import model.comment._ +import model.Entities._ + +trait MemberLookup { + def lookup( + entity: Entity, + packages: Map[String, Package], + query: String, + pos: Position + ): LinkTo = { + val notFound: LinkTo = Tooltip(query) + val querys = query.split("\\.").toList + + def localLookup(ent: Entity with Members, searchStr: String): LinkTo = + ent.members.find(_.name == searchStr).fold(notFound)(e => LinkToEntity(e)) + + def downwardLookup(ent: Entity with Members, search: List[String]): LinkTo = + search match { + case Nil => notFound + case x :: Nil => + localLookup(ent, x) + case x :: xs => + ent + .members + .collect { case e: Entity with Members => e } + .find(_.name == x) + .fold(notFound)(e => downwardLookup(e, xs)) + } + + def globalLookup: LinkTo = { + def longestMatch(list: List[String]): List[String] = + if (list == Nil) Nil + else + packages + .get(list.mkString(".")) + .map(_ => list) + .getOrElse(longestMatch(list.dropRight(1))) + + longestMatch(querys) match { + case Nil => notFound + case xs => downwardLookup(packages(xs.mkString(".")), querys diff xs) + } + } + + (querys, entity) match { + case (x :: Nil, e: Entity with Members) => + localLookup(e, x) + case (x :: _, e: Entity with Members) if x == entity.name => + downwardLookup(e, querys) + case _ => + globalLookup + } + } + + def makeEntityLink( + entity: Entity, + packages: Map[String, Package], + title: Inline, + pos: Position, + query: String + ): Inline = EntityLink(title, lookup(entity, packages, query, pos)) +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala index 9bd175fde230..675bc8319fd2 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala @@ -11,13 +11,20 @@ object Entities { sealed trait Entity { def name: String + /** Path from root, i.e. `scala.Option$` */ def path: List[String] def comment: Option[Comment] - val sourceUrl: String = "#" + def sourceUrl: String = "#" - val kind: String + def kind: String + + def parent: Option[Entity] + + /** All parents from package level i.e. Package to Object to Member etc */ + def parents: List[Entity] = + parent.map(p => p :: p.parents).getOrElse(Nil) } sealed trait Members { @@ -34,11 +41,12 @@ object Entities { final case class Package( name: String, members: List[Entity], - comment: Option[Comment], - path: List[String] - ) extends Entity { + path: List[String], + var comment: Option[Comment] = None + ) extends Entity with Members { override val kind = "package" + var parent: Option[Entity] = None val children: List[PackageMember] = members.collect { case x: PackageMember => x } } @@ -46,59 +54,65 @@ object Entities { final case class Class( name: String, members: List[Entity], - comment: Option[Comment], modifiers: List[String], - path: List[String] + path: List[String], + var comment: Option[Comment] = None ) extends Entity with Members with Modifiers { override val kind = "class" + var parent: Option[Entity] = None } final case class CaseClass( name: String, members: List[Entity], - comment: Option[Comment], modifiers: List[String], - path: List[String] + path: List[String], + var comment: Option[Comment] = None ) extends Entity with Members with Modifiers { override val kind = "case class" + var parent: Option[Entity] = None } final case class Trait( name: String, members: List[Entity], - comment: Option[Comment], modifiers: List[String], - path: List[String] + path: List[String], + var comment: Option[Comment] = None ) extends Entity with Members with Modifiers { override val kind = "trait" + var parent: Option[Entity] = None } final case class Object( name: String, members: List[Entity], - comment: Option[Comment], modifiers: List[String], - path: List[String] + path: List[String], + var comment: Option[Comment] = None ) extends Entity with Members with Modifiers { override val kind = "object" + var parent: Option[Entity] = None } final case class Def( name: String, - comment: Option[Comment], modifiers: List[String], - path: List[String] + path: List[String], + var comment: Option[Comment] = None ) extends Entity with Modifiers { override val kind = "def" + var parent: Option[Entity] = None } final case class Val( name: String, - comment: Option[Comment], modifiers: List[String], - path: List[String] + path: List[String], + var comment: Option[Comment] = None ) extends Entity with Modifiers { override val kind = "val" + var parent: Option[Entity] = None } /** This object is used to represent entities that are to be filtered out */ @@ -107,6 +121,15 @@ object Entities { override val comment = None override val path = Nil override val kind = "" + override val parent = None + } + + final case object RootEntity extends Entity { + override val name = "root" + override val comment = None + override val path = Nil + override val kind = "" + override val parent = None } //implicit val pMPickler: PicklerPair[PackageMember] = CompositePickler[PackageMember] diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala index 5e459a766e83..09510a1f80f7 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala @@ -16,7 +16,7 @@ object EntityFactories { def flags(t: Tree)(implicit ctx: Context): List[String] = (t.symbol.flags & SourceModifierFlags).flagStrings.toList - def path(t: Tree, name: String)(implicit ctx: Context): List[String] = { + def path(t: Tree)(implicit ctx: Context): List[String] = { def pathList(tpe: Type): List[String] = tpe match { case t: ThisType => pathList(t.tref) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala new file mode 100644 index 000000000000..1aa07dec1352 --- /dev/null +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala @@ -0,0 +1,13 @@ +package dotty.tools.dottydoc +package util + +object Traversing { + import model.Entities._ + + def mutateEntities(e: Entity)(trans: Entity => Unit): Unit = e match { + case e: Entity with Members => + trans(e) + e.members.map(mutateEntities(_)(trans)) + case e: Entity => trans(e) + } +} diff --git a/src/dotty/tools/dotc/config/Printers.scala b/src/dotty/tools/dotc/config/Printers.scala index 31c9d06cd2c1..fa36ad12cb4c 100644 --- a/src/dotty/tools/dotc/config/Printers.scala +++ b/src/dotty/tools/dotc/config/Printers.scala @@ -13,7 +13,7 @@ object Printers { } val default: Printer = new Printer - val dottydoc: Printer = new Printer + val dottydoc: Printer = noPrinter val core: Printer = noPrinter val typr: Printer = noPrinter val constr: Printer = noPrinter diff --git a/test/test/DottyDocParsingTests.scala b/test/test/DottyDocParsingTests.scala index b09d048da225..ed89c611482a 100644 --- a/test/test/DottyDocParsingTests.scala +++ b/test/test/DottyDocParsingTests.scala @@ -14,7 +14,7 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case PackageDef(_, Seq(c: TypeDef)) => - assert(c.rawComment == None, "Should not have a comment, mainly used for exhaustive tests") + assert(c.rawComment.map(_.chrs) == None, "Should not have a comment, mainly used for exhaustive tests") } } @@ -29,7 +29,7 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" => - checkDocString(t.rawComment, "/** Hello world! */") + checkDocString(t.rawComment.map(_.chrs), "/** Hello world! */") } } @@ -44,7 +44,7 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" => - checkDocString(t.rawComment, "/** Hello /* multiple open */ world! */") + checkDocString(t.rawComment.map(_.chrs), "/** Hello /* multiple open */ world! */") } } @Test def multipleClassesInPackage = { @@ -62,8 +62,8 @@ class DottyDocParsingTests extends DottyDocTest { checkCompile("frontend", source) { (_, ctx) => ctx.compilationUnit.untpdTree match { case PackageDef(_, Seq(c1 @ TypeDef(_,_), c2 @ TypeDef(_,_))) => { - checkDocString(c1.rawComment, "/** Class1 docstring */") - checkDocString(c2.rawComment, "/** Class2 docstring */") + checkDocString(c1.rawComment.map(_.chrs), "/** Class1 docstring */") + checkDocString(c2.rawComment.map(_.chrs), "/** Class2 docstring */") } } } @@ -77,7 +77,7 @@ class DottyDocParsingTests extends DottyDocTest { """.stripMargin checkFrontend(source) { - case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment, "/** Class without package */") + case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment.map(_.chrs), "/** Class without package */") } } @@ -85,7 +85,7 @@ class DottyDocParsingTests extends DottyDocTest { val source = "/** Trait docstring */\ntrait Trait" checkFrontend(source) { - case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment, "/** Trait docstring */") + case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment.map(_.chrs), "/** Trait docstring */") } } @@ -101,8 +101,8 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case PackageDef(_, Seq(t1 @ TypeDef(_,_), t2 @ TypeDef(_,_))) => { - checkDocString(t1.rawComment, "/** Trait1 docstring */") - checkDocString(t2.rawComment, "/** Trait2 docstring */") + checkDocString(t1.rawComment.map(_.chrs), "/** Trait1 docstring */") + checkDocString(t2.rawComment.map(_.chrs), "/** Trait2 docstring */") } } } @@ -127,10 +127,10 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case PackageDef(_, Seq(t1 @ TypeDef(_,_), c2 @ TypeDef(_,_), cc3 @ TypeDef(_,_), _, ac4 @ TypeDef(_,_))) => { - checkDocString(t1.rawComment, "/** Trait1 docstring */") - checkDocString(c2.rawComment, "/** Class2 docstring */") - checkDocString(cc3.rawComment, "/** CaseClass3 docstring */") - checkDocString(ac4.rawComment, "/** AbstractClass4 docstring */") + checkDocString(t1.rawComment.map(_.chrs), "/** Trait1 docstring */") + checkDocString(c2.rawComment.map(_.chrs), "/** Class2 docstring */") + checkDocString(cc3.rawComment.map(_.chrs), "/** CaseClass3 docstring */") + checkDocString(ac4.rawComment.map(_.chrs), "/** AbstractClass4 docstring */") } } } @@ -147,9 +147,9 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case PackageDef(_, Seq(outer @ TypeDef(_, tpl @ Template(_,_,_,_)))) => { - checkDocString(outer.rawComment, "/** Outer docstring */") + checkDocString(outer.rawComment.map(_.chrs), "/** Outer docstring */") tpl.body match { - case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */") + case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.chrs), "/** Inner docstring */") case _ => assert(false, "Couldn't find inner class") } } @@ -171,10 +171,10 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case PackageDef(_, Seq(o1 @ TypeDef(_, tpl @ Template(_,_,_,_)), o2 @ TypeDef(_,_))) => { - checkDocString(o1.rawComment, "/** Outer1 docstring */") - checkDocString(o2.rawComment, "/** Outer2 docstring */") + checkDocString(o1.rawComment.map(_.chrs), "/** Outer1 docstring */") + checkDocString(o2.rawComment.map(_.chrs), "/** Outer2 docstring */") tpl.body match { - case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */") + case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.chrs), "/** Inner docstring */") case _ => assert(false, "Couldn't find inner class") } } @@ -196,9 +196,9 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case p @ PackageDef(_, Seq(o1: MemberDef[Untyped], o2: MemberDef[Untyped])) => { assertEquals(o1.name.toString, "Object1") - checkDocString(o1.rawComment, "/** Object1 docstring */") + checkDocString(o1.rawComment.map(_.chrs), "/** Object1 docstring */") assertEquals(o2.name.toString, "Object2") - checkDocString(o2.rawComment, "/** Object2 docstring */") + checkDocString(o2.rawComment.map(_.chrs), "/** Object2 docstring */") } } } @@ -223,12 +223,12 @@ class DottyDocParsingTests extends DottyDocTest { checkFrontend(source) { case p @ PackageDef(_, Seq(o1: ModuleDef, o2: ModuleDef)) => { assert(o1.name.toString == "Object1") - checkDocString(o1.rawComment, "/** Object1 docstring */") + checkDocString(o1.rawComment.map(_.chrs), "/** Object1 docstring */") assert(o2.name.toString == "Object2") - checkDocString(o2.rawComment, "/** Object2 docstring */") + checkDocString(o2.rawComment.map(_.chrs), "/** Object2 docstring */") o2.impl.body match { - case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */") + case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.chrs), "/** Inner docstring */") case _ => assert(false, "Couldn't find inner class") } } @@ -257,14 +257,14 @@ class DottyDocParsingTests extends DottyDocTest { import dotty.tools.dotc.ast.untpd._ checkFrontend(source) { case PackageDef(_, Seq(p: ModuleDef)) => { - checkDocString(p.rawComment, "/** Package object docstring */") + checkDocString(p.rawComment.map(_.chrs), "/** Package object docstring */") p.impl.body match { case (b: TypeDef) :: (t: TypeDef) :: (o: ModuleDef) :: Nil => { - checkDocString(b.rawComment, "/** Boo docstring */") - checkDocString(t.rawComment, "/** Trait docstring */") - checkDocString(o.rawComment, "/** InnerObject docstring */") - checkDocString(o.impl.body.head.asInstanceOf[TypeDef].rawComment, "/** InnerClass docstring */") + checkDocString(b.rawComment.map(_.chrs), "/** Boo docstring */") + checkDocString(t.rawComment.map(_.chrs), "/** Trait docstring */") + checkDocString(o.rawComment.map(_.chrs), "/** InnerObject docstring */") + checkDocString(o.impl.body.head.asInstanceOf[TypeDef].rawComment.map(_.chrs), "/** InnerClass docstring */") } case _ => assert(false, "Incorrect structure inside package object") } @@ -284,7 +284,7 @@ class DottyDocParsingTests extends DottyDocTest { import dotty.tools.dotc.ast.untpd._ checkFrontend(source) { case PackageDef(_, Seq(c: TypeDef)) => - checkDocString(c.rawComment, "/** Real comment */") + checkDocString(c.rawComment.map(_.chrs), "/** Real comment */") } } @@ -303,7 +303,7 @@ class DottyDocParsingTests extends DottyDocTest { import dotty.tools.dotc.ast.untpd._ checkFrontend(source) { case PackageDef(_, Seq(c: TypeDef)) => - checkDocString(c.rawComment, "/** Real comment */") + checkDocString(c.rawComment.map(_.chrs), "/** Real comment */") } } @@ -329,9 +329,9 @@ class DottyDocParsingTests extends DottyDocTest { case PackageDef(_, Seq(o: ModuleDef)) => { o.impl.body match { case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { - checkDocString(v1.rawComment, "/** val1 */") - checkDocString(v2.rawComment, "/** val2 */") - checkDocString(v3.rawComment, "/** val3 */") + checkDocString(v1.rawComment.map(_.chrs), "/** val1 */") + checkDocString(v2.rawComment.map(_.chrs), "/** val2 */") + checkDocString(v3.rawComment.map(_.chrs), "/** val3 */") } case _ => assert(false, "Incorrect structure inside object") } @@ -361,9 +361,9 @@ class DottyDocParsingTests extends DottyDocTest { case PackageDef(_, Seq(o: ModuleDef)) => { o.impl.body match { case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { - checkDocString(v1.rawComment, "/** var1 */") - checkDocString(v2.rawComment, "/** var2 */") - checkDocString(v3.rawComment, "/** var3 */") + checkDocString(v1.rawComment.map(_.chrs), "/** var1 */") + checkDocString(v2.rawComment.map(_.chrs), "/** var2 */") + checkDocString(v3.rawComment.map(_.chrs), "/** var3 */") } case _ => assert(false, "Incorrect structure inside object") } @@ -393,9 +393,9 @@ class DottyDocParsingTests extends DottyDocTest { case PackageDef(_, Seq(o: ModuleDef)) => { o.impl.body match { case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { - checkDocString(v1.rawComment, "/** def1 */") - checkDocString(v2.rawComment, "/** def2 */") - checkDocString(v3.rawComment, "/** def3 */") + checkDocString(v1.rawComment.map(_.chrs), "/** def1 */") + checkDocString(v2.rawComment.map(_.chrs), "/** def2 */") + checkDocString(v3.rawComment.map(_.chrs), "/** def3 */") } case _ => assert(false, "Incorrect structure inside object") } @@ -425,9 +425,9 @@ class DottyDocParsingTests extends DottyDocTest { case PackageDef(_, Seq(o: ModuleDef)) => { o.impl.body match { case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { - checkDocString(v1.rawComment, "/** type1 */") - checkDocString(v2.rawComment, "/** type2 */") - checkDocString(v3.rawComment, "/** type3 */") + checkDocString(v1.rawComment.map(_.chrs), "/** type1 */") + checkDocString(v2.rawComment.map(_.chrs), "/** type2 */") + checkDocString(v3.rawComment.map(_.chrs), "/** type3 */") } case _ => assert(false, "Incorrect structure inside object") } @@ -451,7 +451,7 @@ class DottyDocParsingTests extends DottyDocTest { case PackageDef(_, Seq(o: ModuleDef)) => o.impl.body match { case (foo: MemberDef) :: Nil => - expectNoDocString(foo.rawComment) + expectNoDocString(foo.rawComment.map(_.chrs)) case _ => assert(false, "Incorrect structure inside object") } } @@ -468,7 +468,7 @@ class DottyDocParsingTests extends DottyDocTest { import dotty.tools.dotc.ast.untpd._ checkFrontend(source) { case p @ PackageDef(_, Seq(_, c: TypeDef)) => - checkDocString(c.rawComment, "/** Class1 */") + checkDocString(c.rawComment.map(_.chrs), "/** Class1 */") } } @@ -483,7 +483,7 @@ class DottyDocParsingTests extends DottyDocTest { import dotty.tools.dotc.ast.untpd._ checkFrontend(source) { case p @ PackageDef(_, Seq(c: TypeDef)) => - checkDocString(c.rawComment, "/** Class1 */") + checkDocString(c.rawComment.map(_.chrs), "/** Class1 */") } } } /* End class */ From 6bd49690e4343130c6ca3061956aecbc6d85c2a3 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 15 Apr 2016 14:41:15 +0200 Subject: [PATCH 004/100] Fix compilation for multiple sources --- dottydoc/js/src/html/Layout.scala | 1 - .../src/dotty/tools/dottydoc/core/Phases.scala | 15 ++++++++++++++- .../dottydoc/model/comment/BodyEntities.scala | 1 - .../dottydoc/model/comment/BodyParsers.scala | 13 +++++++++---- .../dotty/tools/dottydoc/util/MemberLookup.scala | 11 +++++++++++ 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala index a57655d3fbbe..3977878c2220 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/js/src/html/Layout.scala @@ -62,7 +62,6 @@ object Index { def companionHref(m: Entity): Option[PackageMember] = { val pack = m.path.dropRight(1).mkString(".") - println(pack) ParsedIndex.packages.get(pack) .flatMap(_.children.find(e => e.name == m.name && e.path.last != m.path.last)) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 2e24d02d70a3..b585c2745dd6 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -28,10 +28,23 @@ object Phases { /** Saves the commentParser function for later evaluation, for when the AST has been filled */ def track(symbol: Symbol, ctx: Context)(op: => Entity) = { val entity = op + val commentParser = { (entity: Entity, packs: Map[String, Package]) => wikiParser.parseHtml(symbol, entity, packs)(ctx) } - commentCache = commentCache + (entity -> commentParser) + + entity match { + case p: Package => + val path = p.path.mkString(".") + commentCache = commentCache + (packages.get(path).map { ex => + val children = (ex.children ::: p.children).distinct.sortBy(_.name) + Package(p.name, children, p.path, None) + }.getOrElse(p) -> commentParser) + case _ => + commentCache = commentCache + (entity -> commentParser) + } + + entity } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 683fc6b19c4c..7da961a98ff5 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -88,7 +88,6 @@ final case class HtmlTag(data: String) extends Inline { final case class Summary(text: Inline) extends Inline sealed trait LinkTo -final case class LinkToMember(mbr: Entity, parent: Entity) extends LinkTo final case class LinkToEntity(entity: Entity) extends LinkTo final case class LinkToExternal(name: String, url: String) extends LinkTo final case class Tooltip(name: String) extends LinkTo diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala index 6e7988f435f0..3cfc34e41fec 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala @@ -25,10 +25,15 @@ object BodyParsers { def enityLinkToHtml(target: Inline, link: LinkTo) = link match { case Tooltip(_) => inlineToHtml(target) case LinkToExternal(n, url) => s"""$n""" - case LinkToMember(mbr, parent) => - s"""${mbr.name}""" - case LinkToEntity(target: Entity) => - s"""${target.name}""" + case LinkToEntity(t: Entity) => t match { + // Entity is a package member + case e: Entity with Members => + s"""${inlineToHtml(target)}""" + // Entity is a Val / Def + case x => x.parent.fold(inlineToHtml(target)) { xpar => + s"""${inlineToHtml(target)}""" + } + } } def relativePath(target: Entity) = diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala index ad8d993411ce..933ed682f26e 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala @@ -14,6 +14,10 @@ import model.comment._ import model.Entities._ trait MemberLookup { + /** Performs a lookup based on the provided (pruned) query string + * + * Will return a `Tooltip` if unsucessfull, otherwise a LinkToEntity or LinkToExternal + */ def lookup( entity: Entity, packages: Map[String, Package], @@ -23,9 +27,13 @@ trait MemberLookup { val notFound: LinkTo = Tooltip(query) val querys = query.split("\\.").toList + /** Looks for the specified entity among `ent`'s members */ def localLookup(ent: Entity with Members, searchStr: String): LinkTo = ent.members.find(_.name == searchStr).fold(notFound)(e => LinkToEntity(e)) + /** Looks for an entity down in the structure, if the search list is Nil, + * the search stops + */ def downwardLookup(ent: Entity with Members, search: List[String]): LinkTo = search match { case Nil => notFound @@ -39,6 +47,9 @@ trait MemberLookup { .fold(notFound)(e => downwardLookup(e, xs)) } + /** Finds package with longest matching name, then does downwardLookup in + * the package + */ def globalLookup: LinkTo = { def longestMatch(list: List[String]): List[String] = if (list == Nil) Nil From 36e63e8f3827c1239c611fc05f9d5c971065f18d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 15 Apr 2016 16:28:19 +0200 Subject: [PATCH 005/100] Add summary comment, cleanup --- dottydoc/js/src/DottyDoc.scala | 20 +++-- dottydoc/js/src/html/Layout.scala | 83 +++++++++++++------ dottydoc/js/static/index.css | 4 + .../tools/dottydoc/model/CommentParsers.scala | 6 +- .../src/dotty/tools/dottydoc/model/Html.scala | 2 +- .../dottydoc/model/comment/BodyEntities.scala | 6 +- .../tools/dottydoc/util/IndexWriters.scala | 2 +- .../dottydoc/model/comment/Comment.scala | 2 +- 8 files changed, 84 insertions(+), 41 deletions(-) diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index 33adc0aca1dd..3bc6aa9652c5 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -7,38 +7,40 @@ import js.JSApp import js.annotation.{ JSExport, JSName } import org.scalajs.dom import model.Entities._ +import html.IndexLayout @JSExport object DottyDocJS { @JSExport def main(target: dom.html.Div) = { - global.document.title = "Dotty " + ParsedIndex.currentEntity.path.mkString(".") - target.appendChild(html.Index.layout(ParsedIndex.currentEntity).render) + global.document.title = "Dotty " + Index.currentEntity.path.mkString(".") + target.appendChild(IndexLayout.layout(Index.currentEntity).render) hljs.initHighlightingOnLoad() } } -object ParsedIndex { +/** The unpickled AST available as scala classes */ +object Index { import prickle._ import model.Entities._ val packages: Map[String, Package] = Unpickle[Map[String, Package]] - .fromString(js.JSON.stringify(Index.packages)) + .fromString(js.JSON.stringify(UnparsedIndex.packages)) .toOption .getOrElse(Map.empty) val currentEntity: Entity = Unpickle[Entity] - .fromString(js.JSON.stringify(Index.currentEntity)) + .fromString(js.JSON.stringify(UnparsedIndex.currentEntity)) .toOption .getOrElse(NonEntity) } -@js.native -object Index extends js.Object { +/** Unparsed index stores the pickled AST generated by the dottydoc tool */ +@js.native object UnparsedIndex extends js.Object { def packages: js.Any = js.native def currentEntity: js.Any = js.native } -@js.native -object hljs extends js.Object { +/** Library wrapper for highlighting */ +@js.native object hljs extends js.Object { def initHighlightingOnLoad(): js.Any = js.native } diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala index 3977878c2220..823090b1e5a6 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/js/src/html/Layout.scala @@ -3,16 +3,15 @@ package js package html import scalatags.JsDom.all._ +import scalatags.JsDom.TypedTag -object Index { +object IndexLayout { import model.Entities._ import CustomTags._ - def layout(ent: Entity) = ent match { - case x: Entity with Members with Modifiers => packageMember(x) - } + def layout(ent: Entity) = entity(ent) - def packageMember(m: Entity with Members with Modifiers) = + def entity(m: Entity) = div( cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", div( @@ -41,20 +40,27 @@ object Index { div( cls := "page-content", div(raw(m.comment.fold("")(_.body))), - div( - cls := "mld-grid", - m.members - .collect { case x: Entity with Modifiers if !x.isPrivate => x} - .flatMap(member) - ) + m match { + case e: Entity with Members => + Seq( + h5("Members"), + div( + cls := "mld-grid", + e.members + .collect { case x: Entity with Modifiers if !x.isPrivate => x} + .flatMap(member) + ) + ) + case _ => () + } ) ) ) def packageView = nav( cls := "mdl-navigation", - ParsedIndex.packages.keys.flatMap { k => - ParsedIndex.packages(k).children.sortBy(_.name).map { c => + Index.packages.keys.flatMap { k => + Index.packages(k).children.sortBy(_.name).map { c => a(cls := "mdl-navigation__link", href := "#", c.name) } }.toList @@ -62,19 +68,48 @@ object Index { def companionHref(m: Entity): Option[PackageMember] = { val pack = m.path.dropRight(1).mkString(".") - ParsedIndex.packages.get(pack) + Index.packages.get(pack) .flatMap(_.children.find(e => e.name == m.name && e.path.last != m.path.last)) } - def member(m: Entity) = m match { - case m: Entity with Modifiers => Seq( - div( - cls := "mdl-cell mdl-cell--12-col", - h6(m.modifiers.mkString(" ") + " " + m.kind + " " + m.name) - ), - div( - cls := "mdl-cell mdl-cell--12-col", - raw(m.comment.fold("")(_.body))) - ) + + import org.scalajs.dom + import org.scalajs.dom.html.Div + + + def member(m: Entity) = { + def toggleBetween(short: Div, and: Div): Unit = + if (and.style.display == "none") { + and.style.display = "block" + short.style.display = "none" + } else { + and.style.display = "none" + short.style.display = "block" + } + + m match { + case m: Entity with Modifiers => + val shortComment = div( + cls := "mdl-cell mdl-cell--12-col summary-comment", + raw(m.comment.fold("")(_.short)) + ).render + val fullComment = div( + cls := "mdl-cell mdl-cell--12-col full-comment", + style := "display: none;", + raw(m.comment.fold("")(_.body)) + ).render + val divs = div( + cls := "mdl-cell mdl-cell--12-col member", + onclick := { () => toggleBetween(shortComment, and = fullComment) }, + div( + cls := "mdl-cell mdl-cell--12-col", + h6(m.modifiers.mkString(" ") + " " + m.kind + " " + m.name) + ), + shortComment, + fullComment + ) + Seq(divs) + case _ => Nil + } } } diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css index edfde01077d3..c94c4187dab2 100644 --- a/dottydoc/js/static/index.css +++ b/dottydoc/js/static/index.css @@ -7,3 +7,7 @@ span.subtitle { line-height: 0 !important; padding-top: 32px; } + +div.member:hover { + cursor: pointer; +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala index 08d9d4a5ad64..e47a17f49fe1 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -15,9 +15,11 @@ object CommentParsers { def parseHtml(sym: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): Option[Comment] = ctx.base.docstring(sym).map { d => val expanded = expand(sym) - parse(entity, packages, clean(expanded), expanded, d.pos).toHtml(entity) match { + val body = parse(entity, packages, clean(expanded), expanded, d.pos) + val summary = body.summary.map(_.toHtml(entity)).getOrElse("") + body.toHtml(entity) match { case "" => None - case x => Some(Comment(x)) + case x => Some(Comment(x, summary)) } }.flatten } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala index 4fb9168b719c..016cc6669e41 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala @@ -29,7 +29,7 @@ object Html { ), body(div(id := "main-container")), script(raw( - s"""|Index.currentEntity = ${Pickle.intoString(ent)}; + s"""|UnparsedIndex.currentEntity = ${Pickle.intoString(ent)}; |dotty.tools.dottydoc.js.DottyDocJS() | .main(document.getElementById("main-container")); """.stripMargin)) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 7da961a98ff5..cbe3cca5d67c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -11,7 +11,7 @@ import Entities.Entity final case class Body(blocks: Seq[Block]) { /** The summary text of the comment body. */ - lazy val summary: Option[Inline] = { + lazy val summary: Option[Body] = { def summaryInBlock(block: Block): Seq[Inline] = block match { case Title(text, _) => summaryInInline(text) case Paragraph(text) => summaryInInline(text) @@ -33,8 +33,8 @@ final case class Body(blocks: Seq[Block]) { } (blocks flatMap { summaryInBlock(_) }).toList match { case Nil => None - case inline :: Nil => Some(inline) - case inlines => Some(Chain(inlines)) + case inline :: Nil => Some(Body(Seq(Paragraph(inline)))) + case inlines => Some(Body(Seq(Paragraph(Chain(inlines))))) } } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index 4f9a8794996f..a911f05cad61 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -24,7 +24,7 @@ object IndexWriters { } val pickled = Pickle.intoString(packs) - val js = "Index = {}; Index.packages = " + pickled + ";" + val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + pickled + ";" println("Writing index.js...") writeFile(js, outPath + "/../", "index.js") println("Done writing static material, building js-app") diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala index cf37564b9e8c..ad53b9ae7d43 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala @@ -3,4 +3,4 @@ package dottydoc package model package comment -case class Comment(body: String) +case class Comment(body: String, short: String) From fb6c152ad3bee24e4f7385dd1262837a85a3e014 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 15 Apr 2016 16:30:52 +0200 Subject: [PATCH 006/100] Add command alias for dottydoc --- project/Build.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 7322f131bd35..b184d1f3b348 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -199,7 +199,8 @@ object DottyBuild extends Build { settings( addCommandAlias("partest", ";test:package;package;test:runMain dotc.build;lockPartestFile;test:test;runPartestRunner") ++ addCommandAlias("partest-only", ";test:package;package;test:runMain dotc.build;lockPartestFile;test:test-only dotc.tests;runPartestRunner") ++ - addCommandAlias("partest-only-no-bootstrap", ";test:package;package; lockPartestFile;test:test-only dotc.tests;runPartestRunner") + addCommandAlias("partest-only-no-bootstrap", ";test:package;package; lockPartestFile;test:test-only dotc.tests;runPartestRunner") ++ + addCommandAlias("dottydoc", ";dottydocJVM/run") ). settings(publishing) @@ -263,7 +264,6 @@ object DottyInjectedPlugin extends AutoPlugin { ). settings(publishing) - lazy val dottydoc = crossProject.in(file("dottydoc")) .jsSettings( libraryDependencies ++= Seq( From 980a662a3655f71d41d37889048516ba4f2d5eab Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 15 Apr 2016 16:33:54 +0200 Subject: [PATCH 007/100] Minify css --- dottydoc/js/static/github.css | 125 +----------------- .../dottydoc/model/comment/BodyEntities.scala | 2 +- 2 files changed, 2 insertions(+), 125 deletions(-) diff --git a/dottydoc/js/static/github.css b/dottydoc/js/static/github.css index 9b4f3aa17fbd..0ea7d8657a5d 100644 --- a/dottydoc/js/static/github.css +++ b/dottydoc/js/static/github.css @@ -1,124 +1 @@ -/* - -github.com style (c) Vasily Polovnyov - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #f8f8f8; - -webkit-text-size-adjust: none; -} - -.hljs-comment, -.diff .hljs-header, -.hljs-javadoc { - color: #998; - font-style: italic; -} - -.hljs-keyword, -.css .rule .hljs-keyword, -.hljs-winutils, -.nginx .hljs-title, -.hljs-subst, -.hljs-request, -.hljs-status { - color: #333; - font-weight: bold; -} - -.hljs-number, -.hljs-hexcolor, -.ruby .hljs-constant { - color: #008080; -} - -.hljs-string, -.hljs-tag .hljs-value, -.hljs-phpdoc, -.hljs-dartdoc, -.tex .hljs-formula { - color: #d14; -} - -.hljs-title, -.hljs-id, -.scss .hljs-preprocessor { - color: #900; - font-weight: bold; -} - -.hljs-list .hljs-keyword, -.hljs-subst { - font-weight: normal; -} - -.hljs-class .hljs-title, -.hljs-type, -.vhdl .hljs-literal, -.tex .hljs-command { - color: #458; - font-weight: bold; -} - -.hljs-tag, -.hljs-tag .hljs-title, -.hljs-rules .hljs-property, -.django .hljs-tag .hljs-keyword { - color: #000080; - font-weight: normal; -} - -.hljs-attribute, -.hljs-variable, -.lisp .hljs-body { - color: #008080; -} - -.hljs-regexp { - color: #009926; -} - -.hljs-symbol, -.ruby .hljs-symbol .hljs-string, -.lisp .hljs-keyword, -.clojure .hljs-keyword, -.scheme .hljs-keyword, -.tex .hljs-special, -.hljs-prompt { - color: #990073; -} - -.hljs-built_in { - color: #0086b3; -} - -.hljs-preprocessor, -.hljs-pragma, -.hljs-pi, -.hljs-doctype, -.hljs-shebang, -.hljs-cdata { - color: #999; - font-weight: bold; -} - -.hljs-deletion { - background: #fdd; -} - -.hljs-addition { - background: #dfd; -} - -.diff .hljs-change { - background: #0086b3; -} - -.hljs-chunk { - color: #aaa; -} +.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8;-webkit-text-size-adjust:none}.diff .hljs-header,.hljs-comment,.hljs-javadoc{color:#998;font-style:italic}.css .rule .hljs-keyword,.hljs-keyword,.hljs-request,.hljs-status,.hljs-subst,.hljs-winutils,.nginx .hljs-title{color:#333;font-weight:700}.hljs-hexcolor,.hljs-number,.ruby .hljs-constant{color:teal}.hljs-dartdoc,.hljs-phpdoc,.hljs-string,.hljs-tag .hljs-value,.tex .hljs-formula{color:#d14}.hljs-id,.hljs-title,.scss .hljs-preprocessor{color:#900;font-weight:700}.hljs-list .hljs-keyword,.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type,.tex .hljs-command,.vhdl .hljs-literal{color:#458;font-weight:700}.django .hljs-tag .hljs-keyword,.hljs-rules .hljs-property,.hljs-tag,.hljs-tag .hljs-title{color:navy;font-weight:400}.hljs-attribute,.hljs-variable,.lisp .hljs-body{color:teal}.hljs-regexp{color:#009926}.clojure .hljs-keyword,.hljs-prompt,.hljs-symbol,.lisp .hljs-keyword,.ruby .hljs-symbol .hljs-string,.scheme .hljs-keyword,.tex .hljs-special{color:#990073}.hljs-built_in{color:#0086b3}.hljs-cdata,.hljs-doctype,.hljs-pi,.hljs-pragma,.hljs-preprocessor,.hljs-shebang{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.diff .hljs-change{background:#0086b3}.hljs-chunk{color:#aaa} \ No newline at end of file diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala index cbe3cca5d67c..9f06a7a9a9ae 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -31,7 +31,7 @@ final case class Body(blocks: Seq[Block]) { case Link(_, title) => summaryInInline(title) case _ => Nil } - (blocks flatMap { summaryInBlock(_) }).toList match { + (blocks flatMap summaryInBlock).toList match { case Nil => None case inline :: Nil => Some(Body(Seq(Paragraph(inline)))) case inlines => Some(Body(Seq(Paragraph(Chain(inlines))))) From 02a12f9557aa6a587bed1175c0d4cebac219f412 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 25 Apr 2016 12:26:02 +0200 Subject: [PATCH 008/100] Improve layout with search and replace confusing Packages title --- dottydoc/js/src/html/Layout.scala | 35 +++++++++++++++++++++---------- dottydoc/js/static/index.css | 26 +++++++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala index 823090b1e5a6..6e1e59878b7e 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/js/src/html/Layout.scala @@ -4,6 +4,8 @@ package html import scalatags.JsDom.all._ import scalatags.JsDom.TypedTag +import org.scalajs.dom +import org.scalajs.dom.html.Div object IndexLayout { import model.Entities._ @@ -25,14 +27,20 @@ object IndexLayout { m.name ), nav( - cls := "mdl-navigation", - a(cls := "mdl-navigation__link", href := companionHref(m).map(_.path.last + ".html").getOrElse(""), "Companion " + m.name), + cls := "related mdl-navigation", + a( + cls := "mdl-navigation__link", + href := companionHref(m).map(_.path.last + ".html").getOrElse(""), + "Companion " + m.name + ), a(cls := "mdl-navigation__link", href := m.sourceUrl, "Source") ), span( cls := "mdl-layout-title", - "Packages" + id := "docs-title", + "Docs" ), + searchView, packageView ), main( @@ -57,13 +65,23 @@ object IndexLayout { ) ) + def searchView = div( + cls := "search-container", + div( + cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", + input(cls := "mdl-textfield__input", `type` := "text", id := "search"), + label(cls := "mdl-textfield__label", `for` := "search", "Search") + ) + ) + def packageView = nav( - cls := "mdl-navigation", + cls := "mdl-navigation packages", Index.packages.keys.flatMap { k => + a(cls := "mdl-navigation__link package", href := "#", k) :: Index.packages(k).children.sortBy(_.name).map { c => - a(cls := "mdl-navigation__link", href := "#", c.name) + a(cls := "mdl-navigation__link entity", href := "#", c.name) } - }.toList + }.toSeq ) def companionHref(m: Entity): Option[PackageMember] = { @@ -72,11 +90,6 @@ object IndexLayout { .flatMap(_.children.find(e => e.name == m.name && e.path.last != m.path.last)) } - - import org.scalajs.dom - import org.scalajs.dom.html.Div - - def member(m: Entity) = { def toggleBetween(short: Div, and: Div): Unit = if (and.style.display == "none") { diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css index c94c4187dab2..9ac1ec8ec23b 100644 --- a/dottydoc/js/static/index.css +++ b/dottydoc/js/static/index.css @@ -11,3 +11,29 @@ span.subtitle { div.member:hover { cursor: pointer; } + +nav.packages { + padding-top: 0 !important; +} + +nav.packages > a.entity { + padding: 0.2em 4em !important; +} + +div.search-container { + margin: 0 2em 0 2.8em; +} + +a.mdl-navigation__link { + padding-top: 0.2em !important; + padding-bottom: 0.2em !important; +} + +nav.related { + padding-top: 0 !important; +} + +span#docs-title { + line-height: normal; + padding-top: 2em; +} From 2de658d1a33a48ec8ef2a23674068970fb632664 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 25 Apr 2016 15:41:54 +0200 Subject: [PATCH 009/100] Add the scaladoc CLI args that make sense for dottydoc --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 9 ++- .../src/dotty/tools/dottydoc/Settings.scala | 58 +++++++++++++++++++ src/dotty/tools/dotc/config/Settings.scala | 4 +- src/dotty/tools/dotc/core/Contexts.scala | 2 +- 4 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 11957b01a527..394bd01959f4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -4,7 +4,7 @@ package dottydoc import core.Phases.DocPhase import dotc.config.CompilerCommand import dotc.config.Printers.dottydoc -import dotc.core.Contexts.{FreshContext, Context} +import dotc.core.Contexts._ import dotc.core.Phases.Phase import dotc.typer.FrontEnd import dotc.{Compiler, Driver} @@ -18,7 +18,9 @@ import dotc.{Compiler, Driver} * Example: * 1. Use the existing FrontEnd to typecheck the code being fed to dottydoc * 2. Create an AST that is serializable - * 3. Serialize to JSON + * 3. Serialize to JS-Object and write to file + * 4. Deserialize on client side with Scala.js + * 5. Serve content using Scala.js */ case object DottyDocCompiler extends Compiler { override def phases: List[List[Phase]] = @@ -28,6 +30,9 @@ case object DottyDocCompiler extends Compiler { } object DottyDoc extends Driver { + override protected def initCtx = + new InitialContext(new ContextBase, new DottyDocSettings) + override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { val ctx = rootCtx.fresh val summary = CompilerCommand.distill(args)(ctx) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala new file mode 100644 index 000000000000..ac614f62eea6 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala @@ -0,0 +1,58 @@ +package dotty.tools +package dottydoc + +import dotc.core.Contexts.Context +import dotc.config.{ScalaSettings, Settings} +import Settings._ + +class DottyDocSettings extends ScalaSettings { + /** A setting that defines the overall title of the documentation, typically the name of the library being + * documented. */ + val doctitle = StringSetting ( + "-doc-title", + "title", + "The overall name of the Scaladoc site", + "" + ) + + /** A setting that defines the overall version number of the documentation, typically the version of the library being + * documented. */ + val docversion = StringSetting ( + "-doc-version", + "version", + "An optional version number, to be appended to the title", + "" + ) + + val docfooter = StringSetting ( + "-doc-footer", + "footer", + "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.", + "" + ) + + val docUncompilable = StringSetting ( + "-doc-no-compile", + "path", + "A directory containing sources which should be parsed, no more (e.g. AnyRef.scala)", + "" + ) + + def uncompilableFiles(implicit ctx: Context) = docUncompilable.value match { + case "" => Nil + case path => io.Directory(path).deepFiles.filter(_ hasExtension "scala").toList + } + + val docExternalDoc = MultiStringSetting ( + "-doc-external-doc", + "external-doc", + "comma-separated list of classpath_entry_path#doc_URL pairs describing external dependencies." + ) + + val docAuthor = BooleanSetting("-author", "Include authors.", true) + + val docGroups = BooleanSetting ( + "-groups", + "Group similar functions together (based on the @group annotation)" + ) +} diff --git a/src/dotty/tools/dotc/config/Settings.scala b/src/dotty/tools/dotc/config/Settings.scala index f30cedaa008a..73df4e1ecafa 100644 --- a/src/dotty/tools/dotc/config/Settings.scala +++ b/src/dotty/tools/dotc/config/Settings.scala @@ -235,8 +235,8 @@ object Settings { setting } - def BooleanSetting(name: String, descr: String): Setting[Boolean] = - publish(Setting(name, descr, false)) + def BooleanSetting(name: String, descr: String, initialValue: Boolean = false): Setting[Boolean] = + publish(Setting(name, descr, initialValue)) def StringSetting(name: String, helpArg: String, descr: String, default: String): Setting[String] = publish(Setting(name, descr, default, helpArg)) diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 4a3f7c685221..d3ebe32fedf3 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -492,7 +492,7 @@ object Contexts { /** A class defining the initial context with given context base * and set of possible settings. */ - private class InitialContext(val base: ContextBase, settings: SettingGroup) extends FreshContext { + class InitialContext(val base: ContextBase, settings: SettingGroup) extends FreshContext { outer = NoContext period = InitialPeriod mode = Mode.None From 887759eb35f58a2b0ba3986322caa4939630da3b Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 26 Apr 2016 16:11:52 +0200 Subject: [PATCH 010/100] Add recursive CLI args, move other doc args --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 36 ++++++++++-- .../src/dotty/tools/dottydoc/Settings.scala | 58 ------------------- .../tools/dotc/config/ScalaSettings.scala | 50 ++++++++++++++++ 3 files changed, 81 insertions(+), 63 deletions(-) delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 394bd01959f4..61c49eaf0df9 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -7,7 +7,10 @@ import dotc.config.Printers.dottydoc import dotc.core.Contexts._ import dotc.core.Phases.Phase import dotc.typer.FrontEnd -import dotc.{Compiler, Driver} +import dotc.{Compiler, Driver, Run} +import io.PlainFile + +import scala.util.control.NonFatal /** Custom Compiler with phases for the documentation tool * @@ -27,17 +30,40 @@ case object DottyDocCompiler extends Compiler { List(new FrontEnd) :: List(new DocPhase) :: Nil + + override def newRun(implicit ctx: Context): Run = { + reset() + new DocRun(this)(rootContext) + } } -object DottyDoc extends Driver { - override protected def initCtx = - new InitialContext(new ContextBase, new DottyDocSettings) +class DocRun(comp: Compiler)(implicit ctx: Context) extends Run(comp)(ctx) { + def fromDirectory(f: String): List[String] = { + val file = new PlainFile(f) + + if (!file.isDirectory && f.endsWith(".scala")) List(f) + else if (!file.isDirectory) Nil + else file.iterator.flatMap { + case x if x.isDirectory => fromDirectory(x.canonicalPath) + case x => List(x.canonicalPath) + }.toList + } + /** If DocRecursive is set, then try to find all scala files! */ + override def compile(fileNames: List[String]): Unit = super.compile( + if (ctx.settings.DocRecursive.value) fileNames flatMap fromDirectory + else fileNames + ) +} + +object DottyDoc extends Driver { override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { - val ctx = rootCtx.fresh + val ctx = rootCtx.fresh val summary = CompilerCommand.distill(args)(ctx) + ctx.setSettings(summary.sstate) ctx.setSetting(ctx.settings.YkeepComments, true) + val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx) (fileNames, ctx) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala deleted file mode 100644 index ac614f62eea6..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/Settings.scala +++ /dev/null @@ -1,58 +0,0 @@ -package dotty.tools -package dottydoc - -import dotc.core.Contexts.Context -import dotc.config.{ScalaSettings, Settings} -import Settings._ - -class DottyDocSettings extends ScalaSettings { - /** A setting that defines the overall title of the documentation, typically the name of the library being - * documented. */ - val doctitle = StringSetting ( - "-doc-title", - "title", - "The overall name of the Scaladoc site", - "" - ) - - /** A setting that defines the overall version number of the documentation, typically the version of the library being - * documented. */ - val docversion = StringSetting ( - "-doc-version", - "version", - "An optional version number, to be appended to the title", - "" - ) - - val docfooter = StringSetting ( - "-doc-footer", - "footer", - "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.", - "" - ) - - val docUncompilable = StringSetting ( - "-doc-no-compile", - "path", - "A directory containing sources which should be parsed, no more (e.g. AnyRef.scala)", - "" - ) - - def uncompilableFiles(implicit ctx: Context) = docUncompilable.value match { - case "" => Nil - case path => io.Directory(path).deepFiles.filter(_ hasExtension "scala").toList - } - - val docExternalDoc = MultiStringSetting ( - "-doc-external-doc", - "external-doc", - "comma-separated list of classpath_entry_path#doc_URL pairs describing external dependencies." - ) - - val docAuthor = BooleanSetting("-author", "Include authors.", true) - - val docGroups = BooleanSetting ( - "-groups", - "Group similar functions together (based on the @group annotation)" - ) -} diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala index d0c4cc02cfe4..5af871189b0f 100644 --- a/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -196,4 +196,54 @@ class ScalaSettings extends Settings.SettingGroup { val YpresentationLog = StringSetting("-Ypresentation-log", "file", "Log presentation compiler events into file", "") val YpresentationReplay = StringSetting("-Ypresentation-replay", "file", "Replay presentation compiler events from file", "") val YpresentationDelay = IntSetting("-Ypresentation-delay", "Wait number of ms after typing before starting typechecking", 0, 0 to 999) + + /** Dottydoc specific settings */ + + val DocTitle = StringSetting ( + "-Ydoc-title", + "title", + "The overall name of the Scaladoc site", + "" + ) + + val DocVersion = StringSetting ( + "-Ydoc-version", + "version", + "An optional version number, to be appended to the title", + "" + ) + + val DocFooter = StringSetting ( + "-Ydoc-footer", + "footer", + "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.", + "" + ) + + val DocUncompilable = StringSetting ( + "-Ydoc-no-compile", + "path", + "A directory containing sources which should be parsed, no more (e.g. AnyRef.scala)", + "" + ) + + val DocRecursive = BooleanSetting("-Ydoc-recursive", "Get all files from supplied directory") + + //def DocUncompilableFiles(implicit ctx: Context) = DocUncompilable.value match { + // case "" => Nil + // case path => io.Directory(path).deepFiles.filter(_ hasExtension "scala").toList + //} + + val DocExternalDoc = MultiStringSetting ( + "-Ydoc-external-doc", + "external-doc", + "comma-separated list of classpath_entry_path#doc_URL pairs describing external dependencies." + ) + + val DocAuthor = BooleanSetting("-Ydoc-author", "Include authors.", true) + + val DocGroups = BooleanSetting ( + "-Ydoc:groups", + "Group similar functions together (based on the @group annotation)" + ) } From 46ac1bfe42d408dffd74a89bd2d9e3d13b68ee12 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 26 Apr 2016 16:13:34 +0200 Subject: [PATCH 011/100] Fix package list links --- dottydoc/js/src/html/Layout.scala | 34 ++++++++++++------- .../dottydoc/model/comment/BodyParsers.scala | 4 +-- .../tools/dottydoc/util/Traversing.scala | 4 +++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala index 6e1e59878b7e..cdd80586eb7e 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/js/src/html/Layout.scala @@ -5,7 +5,7 @@ package html import scalatags.JsDom.all._ import scalatags.JsDom.TypedTag import org.scalajs.dom -import org.scalajs.dom.html.Div +import org.scalajs.dom.html.{Anchor, Div} object IndexLayout { import model.Entities._ @@ -28,11 +28,7 @@ object IndexLayout { ), nav( cls := "related mdl-navigation", - a( - cls := "mdl-navigation__link", - href := companionHref(m).map(_.path.last + ".html").getOrElse(""), - "Companion " + m.name - ), + companion(m), a(cls := "mdl-navigation__link", href := m.sourceUrl, "Source") ), span( @@ -74,20 +70,34 @@ object IndexLayout { ) ) + private def relativePath(to: Entity) = + util.Traversing.relativePath(Index.currentEntity, to) + def packageView = nav( cls := "mdl-navigation packages", - Index.packages.keys.flatMap { k => - a(cls := "mdl-navigation__link package", href := "#", k) :: - Index.packages(k).children.sortBy(_.name).map { c => - a(cls := "mdl-navigation__link entity", href := "#", c.name) + { + val keys: Seq[String] = Index.packages.keys.toSeq.sorted + keys.flatMap { k => + val pack = Index.packages(k) + (a(cls := "mdl-navigation__link package", href := relativePath(pack), k) :: + pack.children.sortBy(_.name).map { c => + a(cls := "mdl-navigation__link entity", href := relativePath(c), c.name) + }) } - }.toSeq + } ) - def companionHref(m: Entity): Option[PackageMember] = { + def companion(m: Entity) = { val pack = m.path.dropRight(1).mkString(".") Index.packages.get(pack) .flatMap(_.children.find(e => e.name == m.name && e.path.last != m.path.last)) + .map { p => + a( + cls := "mdl-navigation__link", + href := p.path.last + ".html", + "Companion " + m.kind + ) + }.getOrElse(span()) } def member(m: Entity) = { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala index 3cfc34e41fec..b43440dd1341 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala @@ -37,9 +37,7 @@ object BodyParsers { } def relativePath(target: Entity) = - "../" * (origin.path.length - 1) + - target.path.mkString("/") + - ".html" + util.Traversing.relativePath(origin, target) def bodyToHtml(body: Body): String = (body.blocks map blockToHtml).mkString diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala index 1aa07dec1352..37c2f6e6b21f 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala @@ -10,4 +10,8 @@ object Traversing { e.members.map(mutateEntities(_)(trans)) case e: Entity => trans(e) } + + def relativePath(from: Entity, to: Entity) = + "../" * (from.path.length - 1) + + to.path.mkString("", "/", ".html") } From 32b4a9c331d9a078aa50db554667ca908eb8a344 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 27 Apr 2016 17:28:45 +0200 Subject: [PATCH 012/100] Add initial return values to members - to be updated This commit adds return values to defs and vals - but does not provide a link to these. This is to be continued --- dottydoc/js/src/html/Layout.scala | 122 ++++++------------ dottydoc/js/src/html/Member.scala | 76 +++++++++++ dottydoc/js/static/index.css | 11 +- .../dotty/tools/dottydoc/core/Phases.scala | 4 +- .../dotty/tools/dottydoc/model/Entity.scala | 2 + .../dottydoc/model/EntityFactories.scala | 4 + 6 files changed, 136 insertions(+), 83 deletions(-) create mode 100644 dottydoc/js/src/html/Member.scala diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala index cdd80586eb7e..77f4055765bf 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/js/src/html/Layout.scala @@ -10,56 +10,54 @@ import org.scalajs.dom.html.{Anchor, Div} object IndexLayout { import model.Entities._ import CustomTags._ + import MemberLayout._ - def layout(ent: Entity) = entity(ent) - - def entity(m: Entity) = + def layout(m: Entity) = div( + cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", div( - cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", - div( - cls := "mdl-layout__drawer", - span( - cls := "mdl-layout-title subtitle", - m.path.dropRight(1).mkString(".") - ), - span( - cls := "mdl-layout-title", - m.name - ), - nav( - cls := "related mdl-navigation", - companion(m), - a(cls := "mdl-navigation__link", href := m.sourceUrl, "Source") - ), - span( - cls := "mdl-layout-title", - id := "docs-title", - "Docs" - ), - searchView, - packageView + cls := "mdl-layout__drawer", + span( + cls := "mdl-layout-title subtitle", + m.path.dropRight(1).mkString(".") + ), + span( + cls := "mdl-layout-title", + m.name + ), + nav( + cls := "related mdl-navigation", + companion(m), + a(cls := "mdl-navigation__link", href := m.sourceUrl, "Source") ), - main( - cls := "mdl-layout__content", - div( - cls := "page-content", - div(raw(m.comment.fold("")(_.body))), - m match { - case e: Entity with Members => - Seq( - h5("Members"), - div( - cls := "mld-grid", - e.members - .collect { case x: Entity with Modifiers if !x.isPrivate => x} - .flatMap(member) - ) + span( + cls := "mdl-layout-title", + id := "docs-title", + "Docs" + ), + searchView, + packageView + ), + main( + cls := "mdl-layout__content", + div( + cls := "page-content", + div(raw(m.comment.fold("")(_.body))), + m match { + case e: Entity with Members => + Seq( + h5("Members"), + div( + cls := "mld-grid", + e.members + .collect { case x: Entity with Modifiers if !x.isPrivate => x} + .flatMap(member(_, m)) ) - case _ => () - } - ) + ) + case _ => () + } ) ) + ) def searchView = div( cls := "search-container", @@ -99,40 +97,4 @@ object IndexLayout { ) }.getOrElse(span()) } - - def member(m: Entity) = { - def toggleBetween(short: Div, and: Div): Unit = - if (and.style.display == "none") { - and.style.display = "block" - short.style.display = "none" - } else { - and.style.display = "none" - short.style.display = "block" - } - - m match { - case m: Entity with Modifiers => - val shortComment = div( - cls := "mdl-cell mdl-cell--12-col summary-comment", - raw(m.comment.fold("")(_.short)) - ).render - val fullComment = div( - cls := "mdl-cell mdl-cell--12-col full-comment", - style := "display: none;", - raw(m.comment.fold("")(_.body)) - ).render - val divs = div( - cls := "mdl-cell mdl-cell--12-col member", - onclick := { () => toggleBetween(shortComment, and = fullComment) }, - div( - cls := "mdl-cell mdl-cell--12-col", - h6(m.modifiers.mkString(" ") + " " + m.kind + " " + m.name) - ), - shortComment, - fullComment - ) - Seq(divs) - case _ => Nil - } - } } diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala new file mode 100644 index 000000000000..9dc5d4da2d09 --- /dev/null +++ b/dottydoc/js/src/html/Member.scala @@ -0,0 +1,76 @@ +package dotty.tools.dottydoc +package js +package html + +import scalatags.JsDom.all._ +import scalatags.JsDom.TypedTag +import org.scalajs.dom +import org.scalajs.dom.html.{Anchor, Div} + +object MemberLayout { + import model.Entities._ + import CustomTags._ + + def member(m: Entity, parent: Entity) = { + def toggleBetween(short: Div, and: Div): Unit = + if (and.style.display == "none") { + and.style.display = "block" + short.style.display = "none" + } else { + and.style.display = "none" + short.style.display = "block" + } + + m match { + case m: Entity with Modifiers => + val shortComment = div( + cls := "mdl-cell mdl-cell--12-col summary-comment", + raw(m.comment.fold("")(_.short)) + ).render + + val fullComment = div( + cls := "mdl-cell mdl-cell--12-col full-comment", + style := "display: none;", + raw(m.comment.fold("")(_.body)) + ).render + + + val hasLongerFullComment = m.comment.fold(false) { c => + c.short.length + 5 < c.body.length + } + + val divs = div( + cls := + s""" + mdl-cell mdl-cell--12-col member + ${if (hasLongerFullComment) "member-fullcomment" else ""} + """, + onclick := { () => toggleBetween(shortComment, and = fullComment) }, + div( + cls := "mdl-cell mdl-cell--12-col", + span(cls := "member-name", m.modifiers.mkString(" ") + " " + m.kind + " " + m.name), + returnValue(m, parent) + ), + shortComment, + fullComment + ) + Seq(divs) + case _ => Nil + } + } + + def returnValue(m: Entity with Modifiers, parent: Entity) = { + // shortens: "Option.this.A" => "A" + def shorten(s: String): String = s.split('.').toList match { + case x :: Nil => x + case x :: xs if x == parent.name => xs.last + case xs => s + } + + m match { + case v: Val => span(cls := "return-value", ": " + shorten(v.returnValue)) + case d: Def => span(cls := "return-value", ": " + shorten(d.returnValue)) + case _ => span() + } + } +} diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css index 9ac1ec8ec23b..7423198b9d62 100644 --- a/dottydoc/js/static/index.css +++ b/dottydoc/js/static/index.css @@ -8,7 +8,7 @@ span.subtitle { padding-top: 32px; } -div.member:hover { +div.member.member-fullcomment:hover { cursor: pointer; } @@ -37,3 +37,12 @@ span#docs-title { line-height: normal; padding-top: 2em; } + +span.member-name, span.return-value { + font-family: "Roboto","Helvetica","Arial",sans-serif; + font-weight: 400; + font-size: 16px; + margin: 24px 0 16px; + letter-spacing: .04em; + line-height: 24px; +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index b585c2745dd6..2d3496f6fa97 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -87,11 +87,11 @@ object Phases { /** def */ case d: DefDef => - Def(d.name.toString, flags(d), path(d)) + Def(d.name.toString, flags(d), path(d), returnType(d.tpt)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - Val(v.name.toString, flags(v), path(v)) + Val(v.name.toString, flags(v), path(v), returnType(v.tpt)) case x => { //dottydoc.println(s"Found unwanted entity: $x (${x.pos}, ${comment})\n${x.show}") diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala index 675bc8319fd2..5acdfee33cb7 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala @@ -99,6 +99,7 @@ object Entities { name: String, modifiers: List[String], path: List[String], + returnValue: String, var comment: Option[Comment] = None ) extends Entity with Modifiers { override val kind = "def" @@ -109,6 +110,7 @@ object Entities { name: String, modifiers: List[String], path: List[String], + returnValue: String, var comment: Option[Comment] = None ) extends Entity with Modifiers { override val kind = "val" diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala index 09510a1f80f7..9de1cf6ad81f 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala @@ -34,4 +34,8 @@ object EntityFactories { pathList(ref) } + + // TODO: should be updated to link to local entities + def returnType(t: Tree)(implicit ctx: Context): String = + t.show } From b480bd1dd2c1ae39a13e8bb3ac3b3c56e0d08c68 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 28 Apr 2016 18:25:36 +0200 Subject: [PATCH 013/100] Fix packages not ending up in `packages` map in Phases.scala --- dottydoc/js/src/html/Layout.scala | 11 ++- dottydoc/js/src/html/Member.scala | 2 +- .../src/dotty/tools/dottydoc/DottyDoc.scala | 8 +- .../dotty/tools/dottydoc/core/Phases.scala | 78 +++++++++---------- .../tools/dottydoc/util/IndexWriters.scala | 9 ++- .../dotty/tools/dottydoc/model/Entity.scala | 8 +- project/Build.scala | 7 +- 7 files changed, 63 insertions(+), 60 deletions(-) diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/js/src/html/Layout.scala index 77f4055765bf..868e5b71ac32 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/js/src/html/Layout.scala @@ -12,7 +12,12 @@ object IndexLayout { import CustomTags._ import MemberLayout._ - def layout(m: Entity) = div( + def layout(m: Entity) = m match { + case p: Package => h1(s"Package: ${p.name}") + case e => entity(e) + } + + def entity(m: Entity) = div( cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", div( cls := "mdl-layout__drawer", @@ -27,7 +32,7 @@ object IndexLayout { nav( cls := "related mdl-navigation", companion(m), - a(cls := "mdl-navigation__link", href := m.sourceUrl, "Source") + a(cls := "mdl-navigation__link", href := "#", "Source") ), span( cls := "mdl-layout-title", @@ -78,7 +83,7 @@ object IndexLayout { keys.flatMap { k => val pack = Index.packages(k) (a(cls := "mdl-navigation__link package", href := relativePath(pack), k) :: - pack.children.sortBy(_.name).map { c => + pack.children.sortBy(_.name).filter(_.kind == "package").map { c => a(cls := "mdl-navigation__link entity", href := relativePath(c), c.name) }) } diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 9dc5d4da2d09..57c66ea62724 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -55,7 +55,7 @@ object MemberLayout { fullComment ) Seq(divs) - case _ => Nil + case x => Seq(h1("ERROR: " + x.name)) } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 61c49eaf0df9..428bc17d8ec4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -25,7 +25,7 @@ import scala.util.control.NonFatal * 4. Deserialize on client side with Scala.js * 5. Serve content using Scala.js */ -case object DottyDocCompiler extends Compiler { +class DottyDocCompiler extends Compiler { override def phases: List[List[Phase]] = List(new FrontEnd) :: List(new DocPhase) :: @@ -56,7 +56,7 @@ class DocRun(comp: Compiler)(implicit ctx: Context) extends Run(comp)(ctx) { ) } -object DottyDoc extends Driver { +trait DottyDoc extends Driver { override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { val ctx = rootCtx.fresh val summary = CompilerCommand.distill(args)(ctx) @@ -68,5 +68,7 @@ object DottyDoc extends Driver { (fileNames, ctx) } - override def newCompiler(implicit ctx: Context): Compiler = DottyDocCompiler + override def newCompiler(implicit ctx: Context): Compiler = new DottyDocCompiler } + +object Main extends DottyDoc diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 2d3496f6fa97..cfbf67ecd39a 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -23,7 +23,7 @@ object Phases { def phaseName = "docphase" - private[this] var commentCache: Map[Entity, (Entity, Map[String, Package]) => Option[Comment]] = Map.empty + private[this] var commentCache: Map[String, (Entity, Map[String, Package]) => Option[Comment]] = Map.empty /** Saves the commentParser function for later evaluation, for when the AST has been filled */ def track(symbol: Symbol, ctx: Context)(op: => Entity) = { @@ -33,54 +33,45 @@ object Phases { wikiParser.parseHtml(symbol, entity, packs)(ctx) } - entity match { - case p: Package => - val path = p.path.mkString(".") - commentCache = commentCache + (packages.get(path).map { ex => - val children = (ex.children ::: p.children).distinct.sortBy(_.name) - Package(p.name, children, p.path, None) - }.getOrElse(p) -> commentParser) - case _ => - commentCache = commentCache + (entity -> commentParser) - } - - + commentCache = commentCache + (entity.path.mkString(".") -> commentParser) entity } /** Build documentation hierarchy from existing tree */ - def collect(tree: Tree)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { + def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { - def collectList(xs: List[Tree])(implicit ctx: Context): List[Entity] = - xs.map(collect).filter(_ != NonEntity) + def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = + xs.map(collect(_, ps)).filter(_ != NonEntity) - def collectPackageMembers(xs: List[Tree])(implicit ctx: Context): List[PackageMember] = - collectList(xs).asInstanceOf[List[PackageMember]] + def collectEntityMembers(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[EntityMember] = + collectList(xs, ps).asInstanceOf[List[EntityMember]] - def collectMembers(tree: Tree)(implicit ctx: Context): List[Entity] = tree match { - case t: Template => collectList(t.body) + def collectMembers(tree: Tree, ps: List[String] = prev)(implicit ctx: Context): List[Entity] = tree match { + case t: Template => collectList(t.body, ps) case _ => Nil } tree match { /** package */ - case p @ PackageDef(pid, st) => - val name = pid.name.toString - Package(name, collectPackageMembers(st), path(p)) + case pd @ PackageDef(pid, st) => + val newPath = prev :+ pid.name.toString + addEntity(Package(newPath.mkString("."), collectEntityMembers(st, newPath), newPath)) /** trait */ case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => val name = n.toString - Trait(name, collectMembers(rhs), flags(t), path(t)) + val newPath = prev :+ name + Trait(name, collectMembers(rhs), flags(t), newPath) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => val name = n.toString.dropRight(1) - Object(name, collectMembers(rhs), flags(o), path(o)) + Object(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$")) /** class / case class */ case c @ TypeDef(name, rhs) if c.symbol.isClass => - (name.toString, collectMembers(rhs), flags(c), path(c), None) match { + val newPath = prev :+ name.toString + (name.toString, collectMembers(rhs), flags(c), newPath, None) match { case x if c.symbol.is(Flags.CaseClass) => CaseClass.tupled(x) case x => Class.tupled(x) } @@ -94,7 +85,7 @@ object Phases { Val(v.name.toString, flags(v), path(v), returnType(v.tpt)) case x => { - //dottydoc.println(s"Found unwanted entity: $x (${x.pos}, ${comment})\n${x.show}") + //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") NonEntity } } @@ -102,19 +93,19 @@ object Phases { var packages: Map[String, Package] = Map.empty - def addEntity(p: Package): Unit = { - val path = p.path.mkString(".") - packages = packages + (path -> packages.get(path).map { ex => + def addEntity(p: Package): Package = { + val path = p.path.mkString(".") + val newPack = packages.get(path).map { ex => val children = (ex.children ::: p.children).distinct.sortBy(_.name) Package(p.name, children, p.path, None) - }.getOrElse(p)) + }.getOrElse(p) + + packages = packages + (path -> newPack) + newPack } override def run(implicit ctx: Context): Unit = - collect(ctx.compilationUnit.tpdTree) match { - case p: Package => addEntity(p) - case _ => () - } + collect(ctx.compilationUnit.tpdTree) // Will put packages in `packages` var override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { // (1) Create package structure for all `units`, this will give us a complete structure @@ -150,13 +141,13 @@ object Phases { // (3) Create documentation template from docstrings, with internal links packages.values.foreach { p => mutateEntities(p) { - case e: Package => e.comment = commentCache(e)(e, packages) - case e: Class => e.comment = commentCache(e)(e, packages) - case e: CaseClass => e.comment = commentCache(e)(e, packages) - case e: Object => e.comment = commentCache(e)(e, packages) - case e: Trait => e.comment = commentCache(e)(e, packages) - case e: Val => e.comment = commentCache(e)(e, packages) - case e: Def => e.comment = commentCache(e)(e, packages) + case e: Package => e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Class => e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: CaseClass => e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Object => e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Trait => e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Val => e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Def => e.comment = commentCache(e.path.mkString("."))(e, packages) case _ => () } } @@ -166,7 +157,8 @@ object Phases { // (5) Clear caches - commentCache = Map.empty + // TODO: enable me! + //commentCache = Map.empty // Return super's result compUnits diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index a911f05cad61..6346bee209a4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -7,14 +7,17 @@ object IndexWriters { import model.Html._ def writeJs(packs: Map[String, Package], outPath: String): Unit = { - for ((_, pack) <- packs) { + for (pack <- packs.values) { println(s"""Writing '${pack.path.mkString(".")}'""") writeFile( entityHtml(pack), - outPath + pack.path.tail.mkString("/", "/", "/"), + outPath + pack.path.mkString("/", "/", "/"), "index.html") - for (child <- pack.children) { + for { + child <- pack.children + if child.kind != "package" + } { println(s"""Writing '${child.path.mkString(".")}'""") writeFile( entityHtml(child), diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala index 5acdfee33cb7..f95190578fc5 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala @@ -6,7 +6,7 @@ import comment.Comment object Entities { import prickle._ - type PackageMember = Entity with Members with Modifiers + type EntityMember = Entity with Members sealed trait Entity { def name: String @@ -16,8 +16,6 @@ object Entities { def comment: Option[Comment] - def sourceUrl: String = "#" - def kind: String def parent: Option[Entity] @@ -47,8 +45,8 @@ object Entities { override val kind = "package" var parent: Option[Entity] = None - val children: List[PackageMember] = - members.collect { case x: PackageMember => x } + val children: List[EntityMember] = + members.collect { case x: EntityMember => x } } final case class Class( diff --git a/project/Build.scala b/project/Build.scala index b184d1f3b348..10f74fcb107f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -278,8 +278,11 @@ object DottyInjectedPlugin extends AutoPlugin { ) lazy val dottydocJVM = dottydoc.jvm.dependsOn(dotty).settings( - (resources in Compile) += (fastOptJS in (dottydocJS, Compile)).value.data, + resources in Compile += (fastOptJS in (dottydocJS, Compile)).value.data, scalaSource in Compile := baseDirectory.value / "src", + scalaSource in Test := baseDirectory.value / "test", + javaSource in Test := baseDirectory.value / "test", + libraryDependencies ++= Seq( "com.github.benhutchison" %% "prickle" % "1.1.10", "com.lihaoyi" %% "scalatags" % "0.5.4" @@ -288,7 +291,7 @@ object DottyInjectedPlugin extends AutoPlugin { // enable improved incremental compilation algorithm incOptions := incOptions.value.withNameHashing(true), - mainClass in (Compile, run) := Some("dotty.tools.dottydoc.DottyDoc"), + mainClass in (Compile, run) := Some("dotty.tools.dottydoc.Main"), fork in run := true, fork in Test := true, parallelExecution in Test := false, From cbc05e06b456fc9bc481b7a621aebc22be40fbfe Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 29 Apr 2016 16:46:43 +0200 Subject: [PATCH 014/100] Move dynamically generated content to JVM side --- dottydoc/js/src/DottyDoc.scala | 32 +- dottydoc/js/src/EntityIndex.scala | 28 + dottydoc/js/static/MaterialIcons-Regular.eot | Bin 0 -> 143258 bytes .../js/static/MaterialIcons-Regular.ijmap | 1 + dottydoc/js/static/MaterialIcons-Regular.svg | 2373 +++++++++++++++++ dottydoc/js/static/MaterialIcons-Regular.ttf | Bin 0 -> 128180 bytes dottydoc/js/static/MaterialIcons-Regular.woff | Bin 0 -> 78776 bytes .../js/static/MaterialIcons-Regular.woff2 | Bin 0 -> 42304 bytes dottydoc/js/static/codepoints | 932 +++++++ dottydoc/js/static/index.css | 2 +- dottydoc/js/static/material-icons.css | 38 + .../dotty/tools/dottydoc/core/Phases.scala | 35 +- .../tools/dottydoc}/html/CustomTags.scala | 7 +- .../tools/dottydoc/html/EntityLayout.scala} | 67 +- .../tools/dottydoc/{model => html}/Html.scala | 40 +- .../dotty/tools/dottydoc}/html/Member.scala | 11 +- .../tools/dottydoc/util/IndexWriters.scala | 11 +- project/Build.scala | 8 +- 18 files changed, 3481 insertions(+), 104 deletions(-) create mode 100644 dottydoc/js/src/EntityIndex.scala create mode 100755 dottydoc/js/static/MaterialIcons-Regular.eot create mode 100755 dottydoc/js/static/MaterialIcons-Regular.ijmap create mode 100755 dottydoc/js/static/MaterialIcons-Regular.svg create mode 100755 dottydoc/js/static/MaterialIcons-Regular.ttf create mode 100755 dottydoc/js/static/MaterialIcons-Regular.woff create mode 100755 dottydoc/js/static/MaterialIcons-Regular.woff2 create mode 100755 dottydoc/js/static/codepoints create mode 100755 dottydoc/js/static/material-icons.css rename dottydoc/{js/src => jvm/src/dotty/tools/dottydoc}/html/CustomTags.scala (51%) rename dottydoc/{js/src/html/Layout.scala => jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala} (54%) rename dottydoc/jvm/src/dotty/tools/dottydoc/{model => html}/Html.scala (54%) rename dottydoc/{js/src => jvm/src/dotty/tools/dottydoc}/html/Member.scala (91%) diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index 3bc6aa9652c5..9fdf007dcd34 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -7,37 +7,17 @@ import js.JSApp import js.annotation.{ JSExport, JSName } import org.scalajs.dom import model.Entities._ -import html.IndexLayout +import scala.concurrent.Future +import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue @JSExport object DottyDocJS { @JSExport def main(target: dom.html.Div) = { - global.document.title = "Dotty " + Index.currentEntity.path.mkString(".") - target.appendChild(IndexLayout.layout(Index.currentEntity).render) hljs.initHighlightingOnLoad() - } -} - -/** The unpickled AST available as scala classes */ -object Index { - import prickle._ - import model.Entities._ - - val packages: Map[String, Package] = Unpickle[Map[String, Package]] - .fromString(js.JSON.stringify(UnparsedIndex.packages)) - .toOption - .getOrElse(Map.empty) - val currentEntity: Entity = Unpickle[Entity] - .fromString(js.JSON.stringify(UnparsedIndex.currentEntity)) - .toOption - .getOrElse(NonEntity) -} - -/** Unparsed index stores the pickled AST generated by the dottydoc tool */ -@js.native object UnparsedIndex extends js.Object { - def packages: js.Any = js.native - - def currentEntity: js.Any = js.native + println("Started parsing...") + Future(EntityIndex.packages.keys).map(println) + println("after fututre") + } } /** Library wrapper for highlighting */ diff --git a/dottydoc/js/src/EntityIndex.scala b/dottydoc/js/src/EntityIndex.scala new file mode 100644 index 000000000000..e8e27dc88f6e --- /dev/null +++ b/dottydoc/js/src/EntityIndex.scala @@ -0,0 +1,28 @@ +package dotty.tools.dottydoc +package js + +import scala.scalajs.js +import js.Dynamic.global +import js.JSApp +import js.annotation.JSName + +/** The unpickled AST available as scala classes */ +object EntityIndex { + import microjson._ + import prickle._ + import model.Entities._ + + lazy val packages: Map[String, Package] = + //FIXME + //Unpickle[Map[String, Package]] + //.fromString(js.JSON.stringify(Unparsed.packages)) + //.from[js.Object](Unparsed.packages) + //.toOption + None + .getOrElse(Map.empty) + + /** Unparsed index stores the pickled AST generated by the dottydoc tool */ + @js.native @JSName("UnparsedIndex") private object Unparsed extends js.Object { + def packages: js.Object = js.native + } +} diff --git a/dottydoc/js/static/MaterialIcons-Regular.eot b/dottydoc/js/static/MaterialIcons-Regular.eot new file mode 100755 index 0000000000000000000000000000000000000000..70508ebabc9992e64f1314f866b2d7ab90438c58 GIT binary patch literal 143258 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 Hzx)3OGG_Ot literal 0 HcmV?d00001 diff --git a/dottydoc/js/static/MaterialIcons-Regular.ijmap b/dottydoc/js/static/MaterialIcons-Regular.ijmap new file mode 100755 index 000000000000..d9f1d259f3b1 --- /dev/null +++ b/dottydoc/js/static/MaterialIcons-Regular.ijmap @@ -0,0 +1 @@ +{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}} \ No newline at end of file diff --git a/dottydoc/js/static/MaterialIcons-Regular.svg b/dottydoc/js/static/MaterialIcons-Regular.svg new file mode 100755 index 000000000000..a449327e22c0 --- /dev/null +++ b/dottydoc/js/static/MaterialIcons-Regular.svg @@ -0,0 +1,2373 @@ + + + + + +Created by FontForge 20151118 at Mon Feb 8 11:58:02 2016 + By shyndman +Copyright 2015 Google, Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dottydoc/js/static/MaterialIcons-Regular.ttf b/dottydoc/js/static/MaterialIcons-Regular.ttf new file mode 100755 index 0000000000000000000000000000000000000000..7015564ad166a3e9d88c82f17829f0cc01ebe29a GIT binary patch literal 128180 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 ohyj3!`#ee%L;DTjx@8!5k5~VH0QmdE^#A|> literal 0 HcmV?d00001 diff --git a/dottydoc/js/static/MaterialIcons-Regular.woff b/dottydoc/js/static/MaterialIcons-Regular.woff new file mode 100755 index 0000000000000000000000000000000000000000..a0bfd17e73cdba0229cd143b2eb38550c58e1cd9 GIT binary patch literal 78776 zcmV)vK$X9DPew*hR8&s@0W-J&4FCWD0sja90RRgC000000000000000000000000( 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 `ZUVxvPc?;2naBlS+{8YhA^;>}E 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 literal 0 HcmV?d00001 diff --git a/dottydoc/js/static/codepoints b/dottydoc/js/static/codepoints new file mode 100755 index 000000000000..3c8b07507460 --- /dev/null +++ b/dottydoc/js/static/codepoints @@ -0,0 +1,932 @@ +3d_rotation e84d +ac_unit eb3b +access_alarm e190 +access_alarms e191 +access_time e192 +accessibility e84e +accessible e914 +account_balance e84f +account_balance_wallet e850 +account_box e851 +account_circle e853 +adb e60e +add e145 +add_a_photo e439 +add_alarm e193 +add_alert e003 +add_box e146 +add_circle e147 +add_circle_outline e148 +add_location e567 +add_shopping_cart e854 +add_to_photos e39d +add_to_queue e05c +adjust e39e +airline_seat_flat e630 +airline_seat_flat_angled e631 +airline_seat_individual_suite e632 +airline_seat_legroom_extra e633 +airline_seat_legroom_normal e634 +airline_seat_legroom_reduced e635 +airline_seat_recline_extra e636 +airline_seat_recline_normal e637 +airplanemode_active e195 +airplanemode_inactive e194 +airplay e055 +airport_shuttle eb3c +alarm e855 +alarm_add e856 +alarm_off e857 +alarm_on e858 +album e019 +all_inclusive eb3d +all_out e90b +android e859 +announcement e85a +apps e5c3 +archive e149 +arrow_back e5c4 +arrow_downward e5db +arrow_drop_down e5c5 +arrow_drop_down_circle e5c6 +arrow_drop_up e5c7 +arrow_forward e5c8 +arrow_upward e5d8 +art_track e060 +aspect_ratio e85b +assessment e85c +assignment e85d +assignment_ind e85e +assignment_late e85f +assignment_return e860 +assignment_returned e861 +assignment_turned_in e862 +assistant e39f +assistant_photo e3a0 +attach_file e226 +attach_money e227 +attachment e2bc +audiotrack e3a1 +autorenew e863 +av_timer e01b +backspace e14a +backup e864 +battery_alert e19c +battery_charging_full e1a3 +battery_full e1a4 +battery_std e1a5 +battery_unknown e1a6 +beach_access eb3e +beenhere e52d +block e14b +bluetooth e1a7 +bluetooth_audio e60f +bluetooth_connected e1a8 +bluetooth_disabled e1a9 +bluetooth_searching e1aa +blur_circular e3a2 +blur_linear e3a3 +blur_off e3a4 +blur_on e3a5 +book e865 +bookmark e866 +bookmark_border e867 +border_all e228 +border_bottom e229 +border_clear e22a +border_color e22b +border_horizontal e22c +border_inner e22d +border_left e22e +border_outer e22f +border_right e230 +border_style e231 +border_top e232 +border_vertical e233 +branding_watermark e06b +brightness_1 e3a6 +brightness_2 e3a7 +brightness_3 e3a8 +brightness_4 e3a9 +brightness_5 e3aa +brightness_6 e3ab +brightness_7 e3ac +brightness_auto e1ab +brightness_high e1ac +brightness_low e1ad +brightness_medium e1ae +broken_image e3ad +brush e3ae +bubble_chart e6dd +bug_report e868 +build e869 +burst_mode e43c +business e0af +business_center eb3f +cached e86a +cake e7e9 +call e0b0 +call_end e0b1 +call_made e0b2 +call_merge e0b3 +call_missed e0b4 +call_missed_outgoing e0e4 +call_received e0b5 +call_split e0b6 +call_to_action e06c +camera e3af +camera_alt e3b0 +camera_enhance e8fc +camera_front e3b1 +camera_rear e3b2 +camera_roll e3b3 +cancel e5c9 +card_giftcard e8f6 +card_membership e8f7 +card_travel e8f8 +casino eb40 +cast e307 +cast_connected e308 +center_focus_strong e3b4 +center_focus_weak e3b5 +change_history e86b +chat e0b7 +chat_bubble e0ca +chat_bubble_outline e0cb +check e5ca +check_box e834 +check_box_outline_blank e835 +check_circle e86c +chevron_left e5cb +chevron_right e5cc +child_care eb41 +child_friendly eb42 +chrome_reader_mode e86d +class e86e +clear e14c +clear_all e0b8 +close e5cd +closed_caption e01c +cloud e2bd +cloud_circle e2be +cloud_done e2bf +cloud_download e2c0 +cloud_off e2c1 +cloud_queue e2c2 +cloud_upload e2c3 +code e86f +collections e3b6 +collections_bookmark e431 +color_lens e3b7 +colorize e3b8 +comment e0b9 +compare e3b9 +compare_arrows e915 +computer e30a +confirmation_number e638 +contact_mail e0d0 +contact_phone e0cf +contacts e0ba +content_copy e14d +content_cut e14e +content_paste e14f +control_point e3ba +control_point_duplicate e3bb +copyright e90c +create e150 +create_new_folder e2cc +credit_card e870 +crop e3be +crop_16_9 e3bc +crop_3_2 e3bd +crop_5_4 e3bf +crop_7_5 e3c0 +crop_din e3c1 +crop_free e3c2 +crop_landscape e3c3 +crop_original e3c4 +crop_portrait e3c5 +crop_rotate e437 +crop_square e3c6 +dashboard e871 +data_usage e1af +date_range e916 +dehaze e3c7 +delete e872 +delete_forever e92b +delete_sweep e16c +description e873 +desktop_mac e30b +desktop_windows e30c +details e3c8 +developer_board e30d +developer_mode e1b0 +device_hub e335 +devices e1b1 +devices_other e337 +dialer_sip e0bb +dialpad e0bc +directions e52e +directions_bike e52f +directions_boat e532 +directions_bus e530 +directions_car e531 +directions_railway e534 +directions_run e566 +directions_subway e533 +directions_transit e535 +directions_walk e536 +disc_full e610 +dns e875 +do_not_disturb e612 +do_not_disturb_alt e611 +do_not_disturb_off e643 +do_not_disturb_on e644 +dock e30e +domain e7ee +done e876 +done_all e877 +donut_large e917 +donut_small e918 +drafts e151 +drag_handle e25d +drive_eta e613 +dvr e1b2 +edit e3c9 +edit_location e568 +eject e8fb +email e0be +enhanced_encryption e63f +equalizer e01d +error e000 +error_outline e001 +euro_symbol e926 +ev_station e56d +event e878 +event_available e614 +event_busy e615 +event_note e616 +event_seat e903 +exit_to_app e879 +expand_less e5ce +expand_more e5cf +explicit e01e +explore e87a +exposure e3ca +exposure_neg_1 e3cb +exposure_neg_2 e3cc +exposure_plus_1 e3cd +exposure_plus_2 e3ce +exposure_zero e3cf +extension e87b +face e87c +fast_forward e01f +fast_rewind e020 +favorite e87d +favorite_border e87e +featured_play_list e06d +featured_video e06e +feedback e87f +fiber_dvr e05d +fiber_manual_record e061 +fiber_new e05e +fiber_pin e06a +fiber_smart_record e062 +file_download e2c4 +file_upload e2c6 +filter e3d3 +filter_1 e3d0 +filter_2 e3d1 +filter_3 e3d2 +filter_4 e3d4 +filter_5 e3d5 +filter_6 e3d6 +filter_7 e3d7 +filter_8 e3d8 +filter_9 e3d9 +filter_9_plus e3da +filter_b_and_w e3db +filter_center_focus e3dc +filter_drama e3dd +filter_frames e3de +filter_hdr e3df +filter_list e152 +filter_none e3e0 +filter_tilt_shift e3e2 +filter_vintage e3e3 +find_in_page e880 +find_replace e881 +fingerprint e90d +first_page e5dc +fitness_center eb43 +flag e153 +flare e3e4 +flash_auto e3e5 +flash_off e3e6 +flash_on e3e7 +flight e539 +flight_land e904 +flight_takeoff e905 +flip e3e8 +flip_to_back e882 +flip_to_front e883 +folder e2c7 +folder_open e2c8 +folder_shared e2c9 +folder_special e617 +font_download e167 +format_align_center e234 +format_align_justify e235 +format_align_left e236 +format_align_right e237 +format_bold e238 +format_clear e239 +format_color_fill e23a +format_color_reset e23b +format_color_text e23c +format_indent_decrease e23d +format_indent_increase e23e +format_italic e23f +format_line_spacing e240 +format_list_bulleted e241 +format_list_numbered e242 +format_paint e243 +format_quote e244 +format_shapes e25e +format_size e245 +format_strikethrough e246 +format_textdirection_l_to_r e247 +format_textdirection_r_to_l e248 +format_underlined e249 +forum e0bf +forward e154 +forward_10 e056 +forward_30 e057 +forward_5 e058 +free_breakfast eb44 +fullscreen e5d0 +fullscreen_exit e5d1 +functions e24a +g_translate e927 +gamepad e30f +games e021 +gavel e90e +gesture e155 +get_app e884 +gif e908 +golf_course eb45 +gps_fixed e1b3 +gps_not_fixed e1b4 +gps_off e1b5 +grade e885 +gradient e3e9 +grain e3ea +graphic_eq e1b8 +grid_off e3eb +grid_on e3ec +group e7ef +group_add e7f0 +group_work e886 +hd e052 +hdr_off e3ed +hdr_on e3ee +hdr_strong e3f1 +hdr_weak e3f2 +headset e310 +headset_mic e311 +healing e3f3 +hearing e023 +help e887 +help_outline e8fd +high_quality e024 +highlight e25f +highlight_off e888 +history e889 +home e88a +hot_tub eb46 +hotel e53a +hourglass_empty e88b +hourglass_full e88c +http e902 +https e88d +image e3f4 +image_aspect_ratio e3f5 +import_contacts e0e0 +import_export e0c3 +important_devices e912 +inbox e156 +indeterminate_check_box e909 +info e88e +info_outline e88f +input e890 +insert_chart e24b +insert_comment e24c +insert_drive_file e24d +insert_emoticon e24e +insert_invitation e24f +insert_link e250 +insert_photo e251 +invert_colors e891 +invert_colors_off e0c4 +iso e3f6 +keyboard e312 +keyboard_arrow_down e313 +keyboard_arrow_left e314 +keyboard_arrow_right e315 +keyboard_arrow_up e316 +keyboard_backspace e317 +keyboard_capslock e318 +keyboard_hide e31a +keyboard_return e31b +keyboard_tab e31c +keyboard_voice e31d +kitchen eb47 +label e892 +label_outline e893 +landscape e3f7 +language e894 +laptop e31e +laptop_chromebook e31f +laptop_mac e320 +laptop_windows e321 +last_page e5dd +launch e895 +layers e53b +layers_clear e53c +leak_add e3f8 +leak_remove e3f9 +lens e3fa +library_add e02e +library_books e02f +library_music e030 +lightbulb_outline e90f +line_style e919 +line_weight e91a +linear_scale e260 +link e157 +linked_camera e438 +list e896 +live_help e0c6 +live_tv e639 +local_activity e53f +local_airport e53d +local_atm e53e +local_bar e540 +local_cafe e541 +local_car_wash e542 +local_convenience_store e543 +local_dining e556 +local_drink e544 +local_florist e545 +local_gas_station e546 +local_grocery_store e547 +local_hospital e548 +local_hotel e549 +local_laundry_service e54a +local_library e54b +local_mall e54c +local_movies e54d +local_offer e54e +local_parking e54f +local_pharmacy e550 +local_phone e551 +local_pizza e552 +local_play e553 +local_post_office e554 +local_printshop e555 +local_see e557 +local_shipping e558 +local_taxi e559 +location_city e7f1 +location_disabled e1b6 +location_off e0c7 +location_on e0c8 +location_searching e1b7 +lock e897 +lock_open e898 +lock_outline e899 +looks e3fc +looks_3 e3fb +looks_4 e3fd +looks_5 e3fe +looks_6 e3ff +looks_one e400 +looks_two e401 +loop e028 +loupe e402 +low_priority e16d +loyalty e89a +mail e158 +mail_outline e0e1 +map e55b +markunread e159 +markunread_mailbox e89b +memory e322 +menu e5d2 +merge_type e252 +message e0c9 +mic e029 +mic_none e02a +mic_off e02b +mms e618 +mode_comment e253 +mode_edit e254 +monetization_on e263 +money_off e25c +monochrome_photos e403 +mood e7f2 +mood_bad e7f3 +more e619 +more_horiz e5d3 +more_vert e5d4 +motorcycle e91b +mouse e323 +move_to_inbox e168 +movie e02c +movie_creation e404 +movie_filter e43a +multiline_chart e6df +music_note e405 +music_video e063 +my_location e55c +nature e406 +nature_people e407 +navigate_before e408 +navigate_next e409 +navigation e55d +near_me e569 +network_cell e1b9 +network_check e640 +network_locked e61a +network_wifi e1ba +new_releases e031 +next_week e16a +nfc e1bb +no_encryption e641 +no_sim e0cc +not_interested e033 +note e06f +note_add e89c +notifications e7f4 +notifications_active e7f7 +notifications_none e7f5 +notifications_off e7f6 +notifications_paused e7f8 +offline_pin e90a +ondemand_video e63a +opacity e91c +open_in_browser e89d +open_in_new e89e +open_with e89f +pages e7f9 +pageview e8a0 +palette e40a +pan_tool e925 +panorama e40b +panorama_fish_eye e40c +panorama_horizontal e40d +panorama_vertical e40e +panorama_wide_angle e40f +party_mode e7fa +pause e034 +pause_circle_filled e035 +pause_circle_outline e036 +payment e8a1 +people e7fb +people_outline e7fc +perm_camera_mic e8a2 +perm_contact_calendar e8a3 +perm_data_setting e8a4 +perm_device_information e8a5 +perm_identity e8a6 +perm_media e8a7 +perm_phone_msg e8a8 +perm_scan_wifi e8a9 +person e7fd +person_add e7fe +person_outline e7ff +person_pin e55a +person_pin_circle e56a +personal_video e63b +pets e91d +phone e0cd +phone_android e324 +phone_bluetooth_speaker e61b +phone_forwarded e61c +phone_in_talk e61d +phone_iphone e325 +phone_locked e61e +phone_missed e61f +phone_paused e620 +phonelink e326 +phonelink_erase e0db +phonelink_lock e0dc +phonelink_off e327 +phonelink_ring e0dd +phonelink_setup e0de +photo e410 +photo_album e411 +photo_camera e412 +photo_filter e43b +photo_library e413 +photo_size_select_actual e432 +photo_size_select_large e433 +photo_size_select_small e434 +picture_as_pdf e415 +picture_in_picture e8aa +picture_in_picture_alt e911 +pie_chart e6c4 +pie_chart_outlined e6c5 +pin_drop e55e +place e55f +play_arrow e037 +play_circle_filled e038 +play_circle_outline e039 +play_for_work e906 +playlist_add e03b +playlist_add_check e065 +playlist_play e05f +plus_one e800 +poll e801 +polymer e8ab +pool eb48 +portable_wifi_off e0ce +portrait e416 +power e63c +power_input e336 +power_settings_new e8ac +pregnant_woman e91e +present_to_all e0df +print e8ad +priority_high e645 +public e80b +publish e255 +query_builder e8ae +question_answer e8af +queue e03c +queue_music e03d +queue_play_next e066 +radio e03e +radio_button_checked e837 +radio_button_unchecked e836 +rate_review e560 +receipt e8b0 +recent_actors e03f +record_voice_over e91f +redeem e8b1 +redo e15a +refresh e5d5 +remove e15b +remove_circle e15c +remove_circle_outline e15d +remove_from_queue e067 +remove_red_eye e417 +remove_shopping_cart e928 +reorder e8fe +repeat e040 +repeat_one e041 +replay e042 +replay_10 e059 +replay_30 e05a +replay_5 e05b +reply e15e +reply_all e15f +report e160 +report_problem e8b2 +restaurant e56c +restaurant_menu e561 +restore e8b3 +restore_page e929 +ring_volume e0d1 +room e8b4 +room_service eb49 +rotate_90_degrees_ccw e418 +rotate_left e419 +rotate_right e41a +rounded_corner e920 +router e328 +rowing e921 +rss_feed e0e5 +rv_hookup e642 +satellite e562 +save e161 +scanner e329 +schedule e8b5 +school e80c +screen_lock_landscape e1be +screen_lock_portrait e1bf +screen_lock_rotation e1c0 +screen_rotation e1c1 +screen_share e0e2 +sd_card e623 +sd_storage e1c2 +search e8b6 +security e32a +select_all e162 +send e163 +sentiment_dissatisfied e811 +sentiment_neutral e812 +sentiment_satisfied e813 +sentiment_very_dissatisfied e814 +sentiment_very_satisfied e815 +settings e8b8 +settings_applications e8b9 +settings_backup_restore e8ba +settings_bluetooth e8bb +settings_brightness e8bd +settings_cell e8bc +settings_ethernet e8be +settings_input_antenna e8bf +settings_input_component e8c0 +settings_input_composite e8c1 +settings_input_hdmi e8c2 +settings_input_svideo e8c3 +settings_overscan e8c4 +settings_phone e8c5 +settings_power e8c6 +settings_remote e8c7 +settings_system_daydream e1c3 +settings_voice e8c8 +share e80d +shop e8c9 +shop_two e8ca +shopping_basket e8cb +shopping_cart e8cc +short_text e261 +show_chart e6e1 +shuffle e043 +signal_cellular_4_bar e1c8 +signal_cellular_connected_no_internet_4_bar e1cd +signal_cellular_no_sim e1ce +signal_cellular_null e1cf +signal_cellular_off e1d0 +signal_wifi_4_bar e1d8 +signal_wifi_4_bar_lock e1d9 +signal_wifi_off e1da +sim_card e32b +sim_card_alert e624 +skip_next e044 +skip_previous e045 +slideshow e41b +slow_motion_video e068 +smartphone e32c +smoke_free eb4a +smoking_rooms eb4b +sms e625 +sms_failed e626 +snooze e046 +sort e164 +sort_by_alpha e053 +spa eb4c +space_bar e256 +speaker e32d +speaker_group e32e +speaker_notes e8cd +speaker_notes_off e92a +speaker_phone e0d2 +spellcheck e8ce +star e838 +star_border e83a +star_half e839 +stars e8d0 +stay_current_landscape e0d3 +stay_current_portrait e0d4 +stay_primary_landscape e0d5 +stay_primary_portrait e0d6 +stop e047 +stop_screen_share e0e3 +storage e1db +store e8d1 +store_mall_directory e563 +straighten e41c +streetview e56e +strikethrough_s e257 +style e41d +subdirectory_arrow_left e5d9 +subdirectory_arrow_right e5da +subject e8d2 +subscriptions e064 +subtitles e048 +subway e56f +supervisor_account e8d3 +surround_sound e049 +swap_calls e0d7 +swap_horiz e8d4 +swap_vert e8d5 +swap_vertical_circle e8d6 +switch_camera e41e +switch_video e41f +sync e627 +sync_disabled e628 +sync_problem e629 +system_update e62a +system_update_alt e8d7 +tab e8d8 +tab_unselected e8d9 +tablet e32f +tablet_android e330 +tablet_mac e331 +tag_faces e420 +tap_and_play e62b +terrain e564 +text_fields e262 +text_format e165 +textsms e0d8 +texture e421 +theaters e8da +thumb_down e8db +thumb_up e8dc +thumbs_up_down e8dd +time_to_leave e62c +timelapse e422 +timeline e922 +timer e425 +timer_10 e423 +timer_3 e424 +timer_off e426 +title e264 +toc e8de +today e8df +toll e8e0 +tonality e427 +touch_app e913 +toys e332 +track_changes e8e1 +traffic e565 +train e570 +tram e571 +transfer_within_a_station e572 +transform e428 +translate e8e2 +trending_down e8e3 +trending_flat e8e4 +trending_up e8e5 +tune e429 +turned_in e8e6 +turned_in_not e8e7 +tv e333 +unarchive e169 +undo e166 +unfold_less e5d6 +unfold_more e5d7 +update e923 +usb e1e0 +verified_user e8e8 +vertical_align_bottom e258 +vertical_align_center e259 +vertical_align_top e25a +vibration e62d +video_call e070 +video_label e071 +video_library e04a +videocam e04b +videocam_off e04c +videogame_asset e338 +view_agenda e8e9 +view_array e8ea +view_carousel e8eb +view_column e8ec +view_comfy e42a +view_compact e42b +view_day e8ed +view_headline e8ee +view_list e8ef +view_module e8f0 +view_quilt e8f1 +view_stream e8f2 +view_week e8f3 +vignette e435 +visibility e8f4 +visibility_off e8f5 +voice_chat e62e +voicemail e0d9 +volume_down e04d +volume_mute e04e +volume_off e04f +volume_up e050 +vpn_key e0da +vpn_lock e62f +wallpaper e1bc +warning e002 +watch e334 +watch_later e924 +wb_auto e42c +wb_cloudy e42d +wb_incandescent e42e +wb_iridescent e436 +wb_sunny e430 +wc e63d +web e051 +web_asset e069 +weekend e16b +whatshot e80e +widgets e1bd +wifi e63e +wifi_lock e1e1 +wifi_tethering e1e2 +work e8f9 +wrap_text e25b +youtube_searched_for e8fa +zoom_in e8ff +zoom_out e900 +zoom_out_map e56b diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css index 7423198b9d62..e0fb19f939cc 100644 --- a/dottydoc/js/static/index.css +++ b/dottydoc/js/static/index.css @@ -21,7 +21,7 @@ nav.packages > a.entity { } div.search-container { - margin: 0 2em 0 2.8em; + margin: 0 2em 0 40px; } a.mdl-navigation__link { diff --git a/dottydoc/js/static/material-icons.css b/dottydoc/js/static/material-icons.css new file mode 100755 index 000000000000..43c889d6f23d --- /dev/null +++ b/dottydoc/js/static/material-icons.css @@ -0,0 +1,38 @@ +@font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url(MaterialIcons-Regular.eot); /* For IE6-8 */ + src: local('Material Icons'), + local('MaterialIcons-Regular'), + url(MaterialIcons-Regular.woff2) format('woff2'), + url(MaterialIcons-Regular.woff) format('woff'), + url(MaterialIcons-Regular.ttf) format('truetype'); +} + +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; /* Preferred icon size */ + display: inline-block; + width: 1em; + height: 1em; + line-height: 1; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + + /* Support for all WebKit browsers. */ + -webkit-font-smoothing: antialiased; + /* Support for Safari and Chrome. */ + text-rendering: optimizeLegibility; + + /* Support for Firefox. */ + -moz-osx-font-smoothing: grayscale; + + /* Support for IE. */ + font-feature-settings: 'liga'; +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index cfbf67ecd39a..a0235e7c6966 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -104,11 +104,18 @@ object Phases { newPack } - override def run(implicit ctx: Context): Unit = + private[this] var totalRuns = 0 + private[this] var currentRun = 0 + + override def run(implicit ctx: Context): Unit = { + currentRun += 1 + println(s"Generating schema for ($currentRun/$totalRuns): ${ctx.compilationUnit.source.file.name}") collect(ctx.compilationUnit.tpdTree) // Will put packages in `packages` var + } override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { // (1) Create package structure for all `units`, this will give us a complete structure + totalRuns = units.length val compUnits = super.runOn(units) // (2) Set parent of all package children @@ -133,6 +140,7 @@ object Phases { case _ => () } + println("Connecting parents to children...") for { parent <- packages.values child <- parent.children @@ -141,13 +149,20 @@ object Phases { // (3) Create documentation template from docstrings, with internal links packages.values.foreach { p => mutateEntities(p) { - case e: Package => e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Class => e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: CaseClass => e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Object => e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Trait => e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Val => e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Def => e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Package => + e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Class => + e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: CaseClass => + e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Object => + e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Trait => + e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Val => + e.comment = commentCache(e.path.mkString("."))(e, packages) + case e: Def => + e.comment = commentCache(e.path.mkString("."))(e, packages) case _ => () } } @@ -155,10 +170,8 @@ object Phases { // (4) Write the finished model to JSON util.IndexWriters.writeJs(packages, "../js/out") - // (5) Clear caches - // TODO: enable me! - //commentCache = Map.empty + commentCache = Map.empty // Return super's result compUnits diff --git a/dottydoc/js/src/html/CustomTags.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala similarity index 51% rename from dottydoc/js/src/html/CustomTags.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala index af1016f20639..766740c4a484 100644 --- a/dottydoc/js/src/html/CustomTags.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala @@ -1,13 +1,12 @@ package dotty.tools.dottydoc -package js package html -import scalatags.JsDom.all._ +import scalatags.Text.all._ import scalatags.generic import scalatags.generic.Util import org.scalajs.dom object CustomTags { - lazy val main = "main".tag[dom.html.Element] - lazy val nav = "nav".tag[dom.html.Element] + lazy val main = "main".tag + lazy val nav = "nav".tag } diff --git a/dottydoc/js/src/html/Layout.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala similarity index 54% rename from dottydoc/js/src/html/Layout.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala index 868e5b71ac32..e256919dad7c 100644 --- a/dottydoc/js/src/html/Layout.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala @@ -1,37 +1,33 @@ package dotty.tools.dottydoc -package js package html -import scalatags.JsDom.all._ -import scalatags.JsDom.TypedTag +import scalatags.Text.all._ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} +import model.Entities._ -object IndexLayout { - import model.Entities._ +case class EntityLayout(entity: Entity, packages: Map[String, Package]) { import CustomTags._ import MemberLayout._ - def layout(m: Entity) = m match { - case p: Package => h1(s"Package: ${p.name}") - case e => entity(e) - } - - def entity(m: Entity) = div( + def html = div( cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", div( cls := "mdl-layout__drawer", span( cls := "mdl-layout-title subtitle", - m.path.dropRight(1).mkString(".") + entity.path.dropRight(1).mkString(".") ), span( cls := "mdl-layout-title", - m.name + entity match { + case p: Package => p.name.split("\\.").last + case e => e.name + } ), nav( cls := "related mdl-navigation", - companion(m), + companion, a(cls := "mdl-navigation__link", href := "#", "Source") ), span( @@ -46,8 +42,8 @@ object IndexLayout { cls := "mdl-layout__content", div( cls := "page-content", - div(raw(m.comment.fold("")(_.body))), - m match { + div(raw(entity.comment.fold("")(_.body))), + entity match { case e: Entity with Members => Seq( h5("Members"), @@ -55,7 +51,7 @@ object IndexLayout { cls := "mld-grid", e.members .collect { case x: Entity with Modifiers if !x.isPrivate => x} - .flatMap(member(_, m)) + .flatMap(member(_, entity)) ) ) case _ => () @@ -74,31 +70,40 @@ object IndexLayout { ) private def relativePath(to: Entity) = - util.Traversing.relativePath(Index.currentEntity, to) + util.Traversing.relativePath(entity, to) + + private def filteredName(str: String) = + str.replaceAll("\\$colon", ":") def packageView = nav( cls := "mdl-navigation packages", { - val keys: Seq[String] = Index.packages.keys.toSeq.sorted + val keys: Seq[String] = packages.keys.toSeq.sorted keys.flatMap { k => - val pack = Index.packages(k) - (a(cls := "mdl-navigation__link package", href := relativePath(pack), k) :: - pack.children.sortBy(_.name).filter(_.kind == "package").map { c => - a(cls := "mdl-navigation__link entity", href := relativePath(c), c.name) - }) + val pack = packages(k) + val children = + pack.children.sortBy(_.name).filterNot(_.kind == "package").map { c => + a(cls := "mdl-navigation__link entity", href := relativePath(c), filteredName(c.name)) + } + + if (children.length > 0) + a(cls := "mdl-navigation__link package", href := relativePath(pack), filteredName(k)) :: children + else Nil } } ) - def companion(m: Entity) = { - val pack = m.path.dropRight(1).mkString(".") - Index.packages.get(pack) - .flatMap(_.children.find(e => e.name == m.name && e.path.last != m.path.last)) - .map { p => + def companion = { + val pack = entity.path.dropRight(1).mkString(".") + packages.get(pack) + .flatMap { p => + p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) + } + .map { c => a( cls := "mdl-navigation__link", - href := p.path.last + ".html", - "Companion " + m.kind + href := c.path.last + ".html", + "Companion " + c.kind ) }.getOrElse(span()) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala similarity index 54% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala index 016cc6669e41..7dc27ca8697c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/Html.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala @@ -1,37 +1,43 @@ package dotty.tools.dottydoc -package model +package html import scalatags.Text.all._ object Html { import prickle._ - import Entities._ + import model.Entities._ private def relPath(to: String, from: Entity) = "../" * from.path.length + to - def entityHtml(ent: Entity) = "" + html( + def entityHtml(entity: Entity, packages: Map[String, Package]) = "" + html( head( meta(charset := "utf-8"), meta(name := "viewport", content := "width=device-width, initial-scale=1, shrink-to-fit=no"), meta("http-equiv".attr := "x-ua-compatible", content := "ie=edge"), - script(`type` := "text/javascript", src := relPath("static/material.min.js", ent)), - script(`type` := "text/javascript", src := relPath("static/highlight.pack.js", ent)), - script(`type` := "text/javascript", src := relPath("index.js", ent)), - script(`type` := "text/javascript", src := relPath("target/scala-2.11/dottydoc-fastopt.js", ent)), - link(rel := "stylesheet", href := relPath("static/material.min.css", ent)), - link(rel := "stylesheet", href := relPath("static/github.css", ent)), - link(rel := "stylesheet", href := relPath("static/index.css", ent)), - link(rel := "stylesheet", href := "https://fonts.googleapis.com/icon?family=Material+Icons") + //title("Dotty - " + ent.path.mkString(".")), + script(`type` := "text/javascript", src := relPath("static/material.min.js", entity)), + script(`type` := "text/javascript", src := relPath("static/highlight.pack.js", entity)), + script(`type` := "text/javascript", src := relPath("index.js", entity)), + script(`type` := "text/javascript", src := relPath("target/scala-2.11/dottydoc-fastopt.js", entity)), + link(rel := "stylesheet", href := relPath("static/material-icons.css", entity)), + link(rel := "stylesheet", href := relPath("static/material.min.css", entity)), + link(rel := "stylesheet", href := relPath("static/github.css", entity)), + link(rel := "stylesheet", href := relPath("static/index.css", entity)) ), - body(div(id := "main-container")), - script(raw( - s"""|UnparsedIndex.currentEntity = ${Pickle.intoString(ent)}; - |dotty.tools.dottydoc.js.DottyDocJS() - | .main(document.getElementById("main-container")); - """.stripMargin)) + body( + div( + id := "main-container", + EntityLayout(entity, packages).html + ) + ), + script( + raw(s"""|dotty.tools.dottydoc.js.DottyDocJS() + | .main(document.getElementById("main-container")); + """.stripMargin) + ) ) } diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala similarity index 91% rename from dottydoc/js/src/html/Member.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala index 57c66ea62724..d04c76017210 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala @@ -1,9 +1,8 @@ package dotty.tools.dottydoc -package js package html -import scalatags.JsDom.all._ -import scalatags.JsDom.TypedTag +import scalatags.Text.all._ +import scalatags.Text.TypedTag import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} @@ -26,13 +25,13 @@ object MemberLayout { val shortComment = div( cls := "mdl-cell mdl-cell--12-col summary-comment", raw(m.comment.fold("")(_.short)) - ).render + ) val fullComment = div( cls := "mdl-cell mdl-cell--12-col full-comment", style := "display: none;", raw(m.comment.fold("")(_.body)) - ).render + ) val hasLongerFullComment = m.comment.fold(false) { c => @@ -45,7 +44,7 @@ object MemberLayout { mdl-cell mdl-cell--12-col member ${if (hasLongerFullComment) "member-fullcomment" else ""} """, - onclick := { () => toggleBetween(shortComment, and = fullComment) }, + //onclick := { () => toggleBetween(shortComment, and = fullComment) }, //FIXME! div( cls := "mdl-cell mdl-cell--12-col", span(cls := "member-name", m.modifiers.mkString(" ") + " " + m.kind + " " + m.name), diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index 6346bee209a4..6bd6a6e9fed7 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -4,15 +4,16 @@ package util object IndexWriters { import prickle._ import model.Entities._ - import model.Html._ + import html.Html._ def writeJs(packs: Map[String, Package], outPath: String): Unit = { for (pack <- packs.values) { println(s"""Writing '${pack.path.mkString(".")}'""") writeFile( - entityHtml(pack), - outPath + pack.path.mkString("/", "/", "/"), - "index.html") + entityHtml(pack, packs), + outPath + pack.path.dropRight(1).mkString("/", "/", "/"), + s"${pack.name.split("\\.").last}.html") + //s"index.html") for { child <- pack.children @@ -20,7 +21,7 @@ object IndexWriters { } { println(s"""Writing '${child.path.mkString(".")}'""") writeFile( - entityHtml(child), + entityHtml(child, packs), outPath + child.path.dropRight(1).mkString("/", "/", "/"), child.path.last + ".html") } diff --git a/project/Build.scala b/project/Build.scala index 10f74fcb107f..6b9939a34fb9 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -267,9 +267,10 @@ object DottyInjectedPlugin extends AutoPlugin { lazy val dottydoc = crossProject.in(file("dottydoc")) .jsSettings( libraryDependencies ++= Seq( - "org.scala-js" %%% "scalajs-dom" % "0.8.0", + "org.scala-js" %%% "scalajs-dom" % "0.9.0", + "com.github.benhutchison" %%% "microjson" % "1.3", "com.github.benhutchison" %%% "prickle" % "1.1.10", - "com.lihaoyi" %%% "scalatags" % "0.5.4" + "com.lihaoyi" %%% "scalatags" % "0.5.5" ) ) @@ -284,8 +285,9 @@ object DottyInjectedPlugin extends AutoPlugin { javaSource in Test := baseDirectory.value / "test", libraryDependencies ++= Seq( + "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0", "com.github.benhutchison" %% "prickle" % "1.1.10", - "com.lihaoyi" %% "scalatags" % "0.5.4" + "com.lihaoyi" %% "scalatags" % "0.5.5" ), // enable improved incremental compilation algorithm From 80a907708e970c9871d17184cfd8b022913e3bd6 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 29 Apr 2016 22:49:10 +0200 Subject: [PATCH 015/100] Move member rendering back to client (for event listeners) --- dottydoc/js/src/DottyDoc.scala | 9 +- dottydoc/js/src/EntityIndex.scala | 6 + dottydoc/js/src/html/EntityLayout.scala | 28 +++++ .../dottydoc => js/src}/html/Member.scala | 14 +-- .../tools/dottydoc/html/CustomTags.scala | 2 +- .../tools/dottydoc/html/EntityLayout.scala | 110 ------------------ .../src/dotty/tools/dottydoc/html/Html.scala | 96 +++++++++++++-- .../tools/dottydoc/util/IndexWriters.scala | 6 +- dottydoc/jvm/test/WhitelistedStdLib.scala | 21 ++++ 9 files changed, 157 insertions(+), 135 deletions(-) create mode 100644 dottydoc/js/src/html/EntityLayout.scala rename dottydoc/{jvm/src/dotty/tools/dottydoc => js/src}/html/Member.scala (90%) delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala create mode 100644 dottydoc/jvm/test/WhitelistedStdLib.scala diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index 9fdf007dcd34..b9ad1d891b71 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -7,16 +7,13 @@ import js.JSApp import js.annotation.{ JSExport, JSName } import org.scalajs.dom import model.Entities._ -import scala.concurrent.Future -import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue +import html.EntityLayout @JSExport object DottyDocJS { @JSExport def main(target: dom.html.Div) = { + global.document.title = "Dotty " + EntityIndex.currentEntity.path.mkString(".") + target.appendChild(EntityLayout(EntityIndex.currentEntity).html.render) hljs.initHighlightingOnLoad() - - println("Started parsing...") - Future(EntityIndex.packages.keys).map(println) - println("after fututre") } } diff --git a/dottydoc/js/src/EntityIndex.scala b/dottydoc/js/src/EntityIndex.scala index e8e27dc88f6e..69bda283f00d 100644 --- a/dottydoc/js/src/EntityIndex.scala +++ b/dottydoc/js/src/EntityIndex.scala @@ -21,8 +21,14 @@ object EntityIndex { None .getOrElse(Map.empty) + val currentEntity: Entity = Unpickle[Entity] + .fromString(js.JSON.stringify(Unparsed.currentEntity)) + .toOption + .get + /** Unparsed index stores the pickled AST generated by the dottydoc tool */ @js.native @JSName("UnparsedIndex") private object Unparsed extends js.Object { def packages: js.Object = js.native + def currentEntity: js.Object = js.native } } diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala new file mode 100644 index 000000000000..51fd000b7ffe --- /dev/null +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -0,0 +1,28 @@ +package dotty.tools.dottydoc +package js +package html + +import scalatags.JsDom.all._ +import org.scalajs.dom +import org.scalajs.dom.html.{Anchor, Div} +import model.Entities._ + +case class EntityLayout(entity: Entity) extends MemberLayout { + def html = div( + cls := "page-content", + div(raw(entity.comment.fold("")(_.body))), + entity match { + case e: Entity with Members => + Seq( + h5("Members"), + div( + cls := "mld-grid", + e.members + .collect { case x: Entity with Modifiers if !x.isPrivate => x} + .flatMap(member(_, entity)) + ) + ) + case _ => () + } + ) +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala b/dottydoc/js/src/html/Member.scala similarity index 90% rename from dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala rename to dottydoc/js/src/html/Member.scala index d04c76017210..065626a1c43a 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -1,14 +1,14 @@ package dotty.tools.dottydoc +package js package html -import scalatags.Text.all._ -import scalatags.Text.TypedTag +import scalatags.JsDom.all._ +import scalatags.JsDom.TypedTag import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} -object MemberLayout { +trait MemberLayout { import model.Entities._ - import CustomTags._ def member(m: Entity, parent: Entity) = { def toggleBetween(short: Div, and: Div): Unit = @@ -25,13 +25,13 @@ object MemberLayout { val shortComment = div( cls := "mdl-cell mdl-cell--12-col summary-comment", raw(m.comment.fold("")(_.short)) - ) + ).render val fullComment = div( cls := "mdl-cell mdl-cell--12-col full-comment", style := "display: none;", raw(m.comment.fold("")(_.body)) - ) + ).render val hasLongerFullComment = m.comment.fold(false) { c => @@ -44,7 +44,7 @@ object MemberLayout { mdl-cell mdl-cell--12-col member ${if (hasLongerFullComment) "member-fullcomment" else ""} """, - //onclick := { () => toggleBetween(shortComment, and = fullComment) }, //FIXME! + onclick := { () => toggleBetween(shortComment, and = fullComment) }, div( cls := "mdl-cell mdl-cell--12-col", span(cls := "member-name", m.modifiers.mkString(" ") + " " + m.kind + " " + m.name), diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala index 766740c4a484..ed462f21bea8 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala @@ -7,6 +7,6 @@ import scalatags.generic.Util import org.scalajs.dom object CustomTags { - lazy val main = "main".tag lazy val nav = "nav".tag + lazy val main = "main".tag } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala deleted file mode 100644 index e256919dad7c..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala +++ /dev/null @@ -1,110 +0,0 @@ -package dotty.tools.dottydoc -package html - -import scalatags.Text.all._ -import org.scalajs.dom -import org.scalajs.dom.html.{Anchor, Div} -import model.Entities._ - -case class EntityLayout(entity: Entity, packages: Map[String, Package]) { - import CustomTags._ - import MemberLayout._ - - def html = div( - cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", - div( - cls := "mdl-layout__drawer", - span( - cls := "mdl-layout-title subtitle", - entity.path.dropRight(1).mkString(".") - ), - span( - cls := "mdl-layout-title", - entity match { - case p: Package => p.name.split("\\.").last - case e => e.name - } - ), - nav( - cls := "related mdl-navigation", - companion, - a(cls := "mdl-navigation__link", href := "#", "Source") - ), - span( - cls := "mdl-layout-title", - id := "docs-title", - "Docs" - ), - searchView, - packageView - ), - main( - cls := "mdl-layout__content", - div( - cls := "page-content", - div(raw(entity.comment.fold("")(_.body))), - entity match { - case e: Entity with Members => - Seq( - h5("Members"), - div( - cls := "mld-grid", - e.members - .collect { case x: Entity with Modifiers if !x.isPrivate => x} - .flatMap(member(_, entity)) - ) - ) - case _ => () - } - ) - ) - ) - - def searchView = div( - cls := "search-container", - div( - cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", - input(cls := "mdl-textfield__input", `type` := "text", id := "search"), - label(cls := "mdl-textfield__label", `for` := "search", "Search") - ) - ) - - private def relativePath(to: Entity) = - util.Traversing.relativePath(entity, to) - - private def filteredName(str: String) = - str.replaceAll("\\$colon", ":") - - def packageView = nav( - cls := "mdl-navigation packages", - { - val keys: Seq[String] = packages.keys.toSeq.sorted - keys.flatMap { k => - val pack = packages(k) - val children = - pack.children.sortBy(_.name).filterNot(_.kind == "package").map { c => - a(cls := "mdl-navigation__link entity", href := relativePath(c), filteredName(c.name)) - } - - if (children.length > 0) - a(cls := "mdl-navigation__link package", href := relativePath(pack), filteredName(k)) :: children - else Nil - } - } - ) - - def companion = { - val pack = entity.path.dropRight(1).mkString(".") - packages.get(pack) - .flatMap { p => - p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) - } - .map { c => - a( - cls := "mdl-navigation__link", - href := c.path.last + ".html", - "Companion " + c.kind - ) - }.getOrElse(span()) - } -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala index 7dc27ca8697c..aef86ffd84aa 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala @@ -2,23 +2,22 @@ package dotty.tools.dottydoc package html import scalatags.Text.all._ +import model.Entities._ -object Html { +case class EntityPage(entity: Entity, packages: Map[String, Package]) { import prickle._ - import model.Entities._ + import CustomTags._ private def relPath(to: String, from: Entity) = "../" * from.path.length + to - def entityHtml(entity: Entity, packages: Map[String, Package]) = "" + html( + def render = "" + html( head( meta(charset := "utf-8"), meta(name := "viewport", content := "width=device-width, initial-scale=1, shrink-to-fit=no"), meta("http-equiv".attr := "x-ua-compatible", content := "ie=edge"), - //title("Dotty - " + ent.path.mkString(".")), - script(`type` := "text/javascript", src := relPath("static/material.min.js", entity)), script(`type` := "text/javascript", src := relPath("static/highlight.pack.js", entity)), script(`type` := "text/javascript", src := relPath("index.js", entity)), @@ -31,13 +30,94 @@ object Html { body( div( id := "main-container", - EntityLayout(entity, packages).html + div( + cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", + div( + cls := "mdl-layout__drawer", + span( + cls := "mdl-layout-title subtitle", + entity.path.dropRight(1).mkString(".") + ), + span( + cls := "mdl-layout-title", + entity match { + case p: Package => p.name.split("\\.").last + case e => e.name + } + ), + nav( + cls := "related mdl-navigation", + companion, + a(cls := "mdl-navigation__link", href := "#", "Source") + ), + span( + cls := "mdl-layout-title", + id := "docs-title", + "Docs" + ), + searchView, + packageView + ), + main( + id := "entity-container", + cls := "mdl-layout__content" + ) + ) ) ), script( - raw(s"""|dotty.tools.dottydoc.js.DottyDocJS() - | .main(document.getElementById("main-container")); + raw(s"""|UnparsedIndex.currentEntity = ${Pickle.intoString(entity)}; + |dotty.tools.dottydoc.js.DottyDocJS() + | .main(document.getElementById("entity-container")); """.stripMargin) ) ) + + private def filteredName(str: String) = + str.replaceAll("\\$colon", ":") + + private def relativePath(to: Entity) = + util.Traversing.relativePath(entity, to) + + def packageView = nav( + cls := "mdl-navigation packages", + { + val keys: Seq[String] = packages.keys.toSeq.sorted + keys.flatMap { k => + val pack = packages(k) + val children = + pack.children.sortBy(_.name).filterNot(_.kind == "package").map { c => + a(cls := "mdl-navigation__link entity", href := relativePath(c), filteredName(c.name)) + } + + if (children.length > 0) + a(cls := "mdl-navigation__link package", href := relativePath(pack), filteredName(k)) :: children + else Nil + } + } + ) + + def companion = { + val pack = entity.path.dropRight(1).mkString(".") + packages.get(pack) + .flatMap { p => + p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) + } + .map { c => + a( + cls := "mdl-navigation__link", + href := c.path.last + ".html", + "Companion " + c.kind + ) + }.getOrElse(span()) + } + + def searchView = div( + cls := "search-container", + div( + cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", + input(cls := "mdl-textfield__input", `type` := "text", id := "search"), + label(cls := "mdl-textfield__label", `for` := "search", "Search") + ) + ) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index 6bd6a6e9fed7..8ec62a7d4fd8 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -4,13 +4,13 @@ package util object IndexWriters { import prickle._ import model.Entities._ - import html.Html._ + import html.EntityPage def writeJs(packs: Map[String, Package], outPath: String): Unit = { for (pack <- packs.values) { println(s"""Writing '${pack.path.mkString(".")}'""") writeFile( - entityHtml(pack, packs), + EntityPage(pack, packs).render, outPath + pack.path.dropRight(1).mkString("/", "/", "/"), s"${pack.name.split("\\.").last}.html") //s"index.html") @@ -21,7 +21,7 @@ object IndexWriters { } { println(s"""Writing '${child.path.mkString(".")}'""") writeFile( - entityHtml(child, packs), + EntityPage(child, packs).render, outPath + child.path.dropRight(1).mkString("/", "/", "/"), child.path.last + ".html") } diff --git a/dottydoc/jvm/test/WhitelistedStdLib.scala b/dottydoc/jvm/test/WhitelistedStdLib.scala new file mode 100644 index 000000000000..8ba8f2b89a8d --- /dev/null +++ b/dottydoc/jvm/test/WhitelistedStdLib.scala @@ -0,0 +1,21 @@ +package dotty.tools +package dottydoc + +import scala.io.Source + +object WhitelistedStdLib extends DottyDoc { + override def main(args: Array[String]) = { + val whitelist = "../../test/dotc/scala-collections.whitelist" + val stdlibFiles = Source.fromFile(whitelist, "UTF8") + .getLines() + .map(_.trim) // allow identation + .filter(!_.startsWith("#")) // allow comment lines prefixed by # + .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line + .filter(_.nonEmpty) + .filterNot(_.endsWith("package.scala")) + .map("../." + _) + .toArray + + super.main("-language:Scala2" +: stdlibFiles) + } +} From db659dc0a199a77466088aeaf0ad50d4815e9308 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 3 May 2016 10:55:02 +0200 Subject: [PATCH 016/100] Split implementation to internal mutable and external interface --- dottydoc/js/src/DottyDoc.scala | 6 +- dottydoc/js/src/EntityIndex.scala | 3 +- dottydoc/js/src/html/EntityLayout.scala | 2 +- dottydoc/js/src/html/Member.scala | 2 +- .../dotty/tools/dottydoc/core/Phases.scala | 84 ++++------ .../src/dotty/tools/dottydoc/html/Html.scala | 21 ++- .../tools/dottydoc/model/CommentParsers.scala | 2 +- .../dottydoc/model/comment/BodyEntities.scala | 1 - .../dottydoc/model/comment/BodyParsers.scala | 3 +- .../model/comment/CommentParser.scala | 2 +- .../tools/dottydoc/util/IndexWriters.scala | 5 +- .../tools/dottydoc/util/MemberLookup.scala | 3 +- .../dotty/tools/dottydoc/util/mutate.scala | 39 +++++ .../dotty/tools/dottydoc/model/Entity.scala | 149 ------------------ .../dotty/tools/dottydoc/model/entities.scala | 91 +++++++++++ ...{EntityFactories.scala => factories.scala} | 2 +- .../dotty/tools/dottydoc/model/internal.scala | 69 ++++++++ .../dotty/tools/dottydoc/model/pickling.scala | 20 +++ .../tools/dottydoc/util/Traversing.scala | 4 +- 19 files changed, 280 insertions(+), 228 deletions(-) create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala delete mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala create mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala rename dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/{EntityFactories.scala => factories.scala} (97%) create mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala create mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index b9ad1d891b71..d08bd8cc8088 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -6,12 +6,14 @@ import js.Dynamic.global import js.JSApp import js.annotation.{ JSExport, JSName } import org.scalajs.dom -import model.Entities._ +import dom.document +import dom.webworkers.Worker +import model._ import html.EntityLayout @JSExport object DottyDocJS { @JSExport def main(target: dom.html.Div) = { - global.document.title = "Dotty " + EntityIndex.currentEntity.path.mkString(".") + document.title = "Dotty " + EntityIndex.currentEntity.path.mkString(".") target.appendChild(EntityLayout(EntityIndex.currentEntity).html.render) hljs.initHighlightingOnLoad() } diff --git a/dottydoc/js/src/EntityIndex.scala b/dottydoc/js/src/EntityIndex.scala index 69bda283f00d..e58cdf88e652 100644 --- a/dottydoc/js/src/EntityIndex.scala +++ b/dottydoc/js/src/EntityIndex.scala @@ -10,7 +10,8 @@ import js.annotation.JSName object EntityIndex { import microjson._ import prickle._ - import model.Entities._ + import model._ + import model.pickling._ lazy val packages: Map[String, Package] = //FIXME diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index 51fd000b7ffe..58ca3df49599 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -5,7 +5,7 @@ package html import scalatags.JsDom.all._ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} -import model.Entities._ +import model._ case class EntityLayout(entity: Entity) extends MemberLayout { def html = div( diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 065626a1c43a..a862ffea41bd 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -8,7 +8,7 @@ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} trait MemberLayout { - import model.Entities._ + import model._ def member(m: Entity, parent: Entity) = { def toggleBetween(short: Div, and: Div): Unit = diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index a0235e7c6966..1670313e17c3 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -15,11 +15,13 @@ object Phases { class DocPhase extends Phase { import model.comment.Comment import model.CommentParsers.wikiParser - import model.Entities._ - import model.EntityFactories._ + import model.factories._ + import model._ + import model.internal._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.ast.tpd._ - import util.Traversing._ + import util.traversing._ + import util.internal.setters._ def phaseName = "docphase" @@ -29,11 +31,13 @@ object Phases { def track(symbol: Symbol, ctx: Context)(op: => Entity) = { val entity = op - val commentParser = { (entity: Entity, packs: Map[String, Package]) => - wikiParser.parseHtml(symbol, entity, packs)(ctx) - } + if (entity != NonEntity) { + val commentParser = { (entity: Entity, packs: Map[String, Package]) => + wikiParser.parseHtml(symbol, entity, packs)(ctx) + } - commentCache = commentCache + (entity.path.mkString(".") -> commentParser) + commentCache = commentCache + (entity.path.mkString(".") -> commentParser) + } entity } @@ -43,8 +47,8 @@ object Phases { def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = xs.map(collect(_, ps)).filter(_ != NonEntity) - def collectEntityMembers(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[EntityMember] = - collectList(xs, ps).asInstanceOf[List[EntityMember]] + def collectEntityMembers(xs: List[Tree], ps: List[String])(implicit ctx: Context) = + collectList(xs, ps).asInstanceOf[List[Entity with Members]] def collectMembers(tree: Tree, ps: List[String] = prev)(implicit ctx: Context): List[Entity] = tree match { case t: Template => collectList(t.body, ps) @@ -55,34 +59,34 @@ object Phases { /** package */ case pd @ PackageDef(pid, st) => val newPath = prev :+ pid.name.toString - addEntity(Package(newPath.mkString("."), collectEntityMembers(st, newPath), newPath)) + addEntity(PackageImpl(newPath.mkString("."), collectEntityMembers(st, newPath), newPath)) /** trait */ case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => val name = n.toString val newPath = prev :+ name - Trait(name, collectMembers(rhs), flags(t), newPath) + TraitImpl(name, collectMembers(rhs), flags(t), newPath) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => val name = n.toString.dropRight(1) - Object(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$")) + ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$")) /** class / case class */ case c @ TypeDef(name, rhs) if c.symbol.isClass => val newPath = prev :+ name.toString (name.toString, collectMembers(rhs), flags(c), newPath, None) match { - case x if c.symbol.is(Flags.CaseClass) => CaseClass.tupled(x) - case x => Class.tupled(x) + case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) + case x => ClassImpl.tupled(x) } /** def */ case d: DefDef => - Def(d.name.toString, flags(d), path(d), returnType(d.tpt)) + DefImpl(d.name.toString, flags(d), path(d), returnType(d.tpt)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - Val(v.name.toString, flags(v), path(v), returnType(v.tpt)) + ValImpl(v.name.toString, flags(v), path(v), returnType(v.tpt)) case x => { //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") @@ -97,7 +101,7 @@ object Phases { val path = p.path.mkString(".") val newPack = packages.get(path).map { ex => val children = (ex.children ::: p.children).distinct.sortBy(_.name) - Package(p.name, children, p.path, None) + PackageImpl(p.name, children, p.path, None) }.getOrElse(p) packages = packages + (path -> newPack) @@ -119,52 +123,18 @@ object Phases { val compUnits = super.runOn(units) // (2) Set parent of all package children - def setParent(ent: Entity, to: Entity): Unit = - ent match { - case e: Class => - e.parent = Some(to) - e.members.foreach(setParent(_, e)) - case e: CaseClass => - e.parent = Some(to) - e.members.foreach(setParent(_, e)) - case e: Object => - e.parent = Some(to) - e.members.foreach(setParent(_, e)) - case e: Trait => - e.parent = Some(to) - e.members.foreach(setParent(_, e)) - case e: Val => - e.parent = Some(to) - case e: Def => - e.parent = Some(to) - case _ => () - } - - println("Connecting parents to children...") + println("Connecting parents to children, finding companions...") for { parent <- packages.values child <- parent.children } setParent(child, to = parent) // (3) Create documentation template from docstrings, with internal links - packages.values.foreach { p => - mutateEntities(p) { - case e: Package => - e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Class => - e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: CaseClass => - e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Object => - e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Trait => - e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Val => - e.comment = commentCache(e.path.mkString("."))(e, packages) - case e: Def => - e.comment = commentCache(e.path.mkString("."))(e, packages) - case _ => () - } + for { + pack <- packages.values + } mutateEntities(pack) { e => + val comment = commentCache(e.path.mkString("."))(e, packages) + setComment(e, to = comment) } // (4) Write the finished model to JSON diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala index aef86ffd84aa..91bf4d773358 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala @@ -2,11 +2,13 @@ package dotty.tools.dottydoc package html import scalatags.Text.all._ -import model.Entities._ +import model.internal._ +import model._ case class EntityPage(entity: Entity, packages: Map[String, Package]) { - import prickle._ import CustomTags._ + import model.pickling._ + import prickle._ private def relPath(to: String, from: Entity) = "../" * from.path.length + to @@ -77,7 +79,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { str.replaceAll("\\$colon", ":") private def relativePath(to: Entity) = - util.Traversing.relativePath(entity, to) + util.traversing.relativePath(entity, to) def packageView = nav( cls := "mdl-navigation packages", @@ -86,9 +88,16 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { keys.flatMap { k => val pack = packages(k) val children = - pack.children.sortBy(_.name).filterNot(_.kind == "package").map { c => - a(cls := "mdl-navigation__link entity", href := relativePath(c), filteredName(c.name)) - } + pack.children + .sortBy(_.name) + .filterNot(_.kind == "package") + .map { entity => + a( + cls := "mdl-navigation__link entity", + href := relativePath(entity), + filteredName(entity.name) + ) + } if (children.length > 0) a(cls := "mdl-navigation__link package", href := relativePath(pack), filteredName(k)) :: children diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala index e47a17f49fe1..e6adba977b55 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -8,7 +8,7 @@ import dotc.core.Contexts.Context object CommentParsers { import comment._ import BodyParsers._ - import Entities.{Entity, Package} + import model.internal._ sealed class WikiParser extends CommentCleaner with CommentParser with CommentExpander { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 9f06a7a9a9ae..f423cf8de99a 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -3,7 +3,6 @@ package model package comment import scala.collection._ -import Entities.Entity /** A body of text. A comment has a single body, which is composed of * at least one block. Inside every body is exactly one summary (see diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala index b43440dd1341..725d835578f2 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala @@ -3,7 +3,6 @@ package model package comment object BodyParsers { - import model.Entities.{Entity, Members} implicit class BodyToHtml(val body: Body) extends AnyVal { def toHtml(origin: Entity): String = { @@ -37,7 +36,7 @@ object BodyParsers { } def relativePath(target: Entity) = - util.Traversing.relativePath(origin, target) + util.traversing.relativePath(origin, target) def bodyToHtml(body: Body): String = (body.blocks map blockToHtml).mkString diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala index 3c5411c5cfc5..fb2119fc0ad4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala @@ -8,10 +8,10 @@ import dotty.tools.dotc.core.Contexts.Context import scala.collection.mutable import dotty.tools.dotc.config.Printers.dottydoc import scala.util.matching.Regex -import Entities.{Entity, Package} trait CommentParser extends util.MemberLookup { import Regexes._ + import model.internal._ /** Parses a raw comment string into a `Comment` object. * @param packages all packages parsed by Scaladoc tool, used for lookup diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index 8ec62a7d4fd8..70587e6b8993 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -2,9 +2,10 @@ package dotty.tools.dottydoc package util object IndexWriters { - import prickle._ - import model.Entities._ import html.EntityPage + import model.Package + import model.pickling._ + import prickle._ def writeJs(packs: Map[String, Package], outPath: String): Unit = { for (pack <- packs.values) { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala index 933ed682f26e..f95829caff8f 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala @@ -10,8 +10,9 @@ import dotc.core.Symbols._ import dotc.core.Types._ import dotc.core.Names._ import dotc.util.Positions._ +import model.internal._ import model.comment._ -import model.Entities._ +import model._ trait MemberLookup { /** Performs a lookup based on the provided (pruned) query string diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala new file mode 100644 index 000000000000..b491fb1612c2 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala @@ -0,0 +1,39 @@ +package dotty.tools.dottydoc +package util +package internal + +object setters { + import model._ + import model.comment.Comment + import model.internal._ + + def setComment(ent: Entity, to: Option[Comment]) = ent match { + case x: PackageImpl => x.comment = to + case x: ClassImpl => x.comment = to + case x: CaseClassImpl => x.comment = to + case x: TraitImpl => x.comment = to + case x: ObjectImpl => x.comment = to + case x: DefImpl => x.comment = to + case x: ValImpl => x.comment = to + } + + def setParent(ent: Entity, to: Entity): Unit = ent match { + case e: ClassImpl => + e.parent = to + e.members.foreach(setParent(_, e)) + case e: CaseClassImpl => + e.parent = to + e.members.foreach(setParent(_, e)) + case e: ObjectImpl => + e.parent = to + e.members.foreach(setParent(_, e)) + case e: TraitImpl => + e.parent = to + e.members.foreach(setParent(_, e)) + case e: ValImpl => + e.parent = to + case e: DefImpl => + e.parent = to + case _ => () + } +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala deleted file mode 100644 index f95190578fc5..000000000000 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/Entity.scala +++ /dev/null @@ -1,149 +0,0 @@ -package dotty.tools.dottydoc -package model - -import comment.Comment - -object Entities { - import prickle._ - - type EntityMember = Entity with Members - - sealed trait Entity { - def name: String - - /** Path from root, i.e. `scala.Option$` */ - def path: List[String] - - def comment: Option[Comment] - - def kind: String - - def parent: Option[Entity] - - /** All parents from package level i.e. Package to Object to Member etc */ - def parents: List[Entity] = - parent.map(p => p :: p.parents).getOrElse(Nil) - } - - sealed trait Members { - def members: List[Entity] - } - - sealed trait Modifiers { - def modifiers: List[String] - - val isPrivate: Boolean = - modifiers.contains("private") - } - - final case class Package( - name: String, - members: List[Entity], - path: List[String], - var comment: Option[Comment] = None - ) extends Entity with Members { - override val kind = "package" - - var parent: Option[Entity] = None - val children: List[EntityMember] = - members.collect { case x: EntityMember => x } - } - - final case class Class( - name: String, - members: List[Entity], - modifiers: List[String], - path: List[String], - var comment: Option[Comment] = None - ) extends Entity with Members with Modifiers { - override val kind = "class" - var parent: Option[Entity] = None - } - - final case class CaseClass( - name: String, - members: List[Entity], - modifiers: List[String], - path: List[String], - var comment: Option[Comment] = None - ) extends Entity with Members with Modifiers { - override val kind = "case class" - var parent: Option[Entity] = None - } - - final case class Trait( - name: String, - members: List[Entity], - modifiers: List[String], - path: List[String], - var comment: Option[Comment] = None - ) extends Entity with Members with Modifiers { - override val kind = "trait" - var parent: Option[Entity] = None - } - - final case class Object( - name: String, - members: List[Entity], - modifiers: List[String], - path: List[String], - var comment: Option[Comment] = None - ) extends Entity with Members with Modifiers { - override val kind = "object" - var parent: Option[Entity] = None - } - - final case class Def( - name: String, - modifiers: List[String], - path: List[String], - returnValue: String, - var comment: Option[Comment] = None - ) extends Entity with Modifiers { - override val kind = "def" - var parent: Option[Entity] = None - } - - final case class Val( - name: String, - modifiers: List[String], - path: List[String], - returnValue: String, - var comment: Option[Comment] = None - ) extends Entity with Modifiers { - override val kind = "val" - var parent: Option[Entity] = None - } - - /** This object is used to represent entities that are to be filtered out */ - final case object NonEntity extends Entity { - override val name = "" - override val comment = None - override val path = Nil - override val kind = "" - override val parent = None - } - - final case object RootEntity extends Entity { - override val name = "root" - override val comment = None - override val path = Nil - override val kind = "" - override val parent = None - } - - //implicit val pMPickler: PicklerPair[PackageMember] = CompositePickler[PackageMember] - // .concreteType[Class] - // .concreteType[CaseClass] - // .concreteType[Object] - // .concreteType[Trait] - - implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity] - .concreteType[Val] - .concreteType[Def] - .concreteType[Class] - .concreteType[CaseClass] - .concreteType[Object] - .concreteType[Trait] - .concreteType[Package] -} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala new file mode 100644 index 000000000000..e62b8573a4e9 --- /dev/null +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala @@ -0,0 +1,91 @@ +package dotty.tools.dottydoc +package model + +import comment.Comment + +trait Entity { + def name: String + + /** Path from root, i.e. `scala.Option$` */ + def path: List[String] + + def comment: Option[Comment] + + def kind: String + + def parent: Entity + + /** All parents from package level i.e. Package to Object to Member etc */ + def parents: List[Entity] = parent match { + case NonEntity => Nil + case e => e :: e.parents + } + + /** Applies `f` to entity if != `NonEntity` */ + def fold[A](nonEntity: A)(f: Entity => A) = this match { + case NonEntity => nonEntity + case x => f(x) + } +} + +trait Members { + def members: List[Entity] +} + +trait Modifiers { + def modifiers: List[String] + + val isPrivate: Boolean = + modifiers.contains("private") +} + +trait ReturnValue { + def returnValue: String +} + +trait Package extends Entity with Members { + override val kind = "package" + + def children: List[Entity with Members] +} + +trait Class extends Entity with Members with Modifiers { + override val kind = "class" +} + +trait CaseClass extends Class { + override val kind = "case class" +} + +trait Trait extends Class { + override val kind = "trait" +} + +trait Object extends Class { + override val kind = "object" +} + +trait Def extends Entity with Modifiers with ReturnValue { + override val kind = "def" +} + +trait Val extends Def { + override val kind = "val" +} + +trait Var extends Def { + override val kind = "var" +} + +trait NonEntity extends Entity { + override val name = "" + override val comment = None + override val path = Nil + override val kind = "" + override val parent = NonEntity +} + +final case object NonEntity extends NonEntity +final case object RootEntity extends NonEntity { + override val name = "root" +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala similarity index 97% rename from dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala rename to dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 9de1cf6ad81f..14289502158a 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/EntityFactories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -9,7 +9,7 @@ import dotc.core.{ Flags => DottyFlags } import dotc.ast.Trees._ import DottyFlags.FlagSet -object EntityFactories { +object factories { import dotty.tools.dotc.ast.tpd._ import DottyFlags._ diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala new file mode 100644 index 000000000000..f8707f69217d --- /dev/null +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -0,0 +1,69 @@ +package dotty.tools.dottydoc +package model + +import comment.Comment + +object internal { + + trait Impl { + var parent: Entity = NonEntity + } + + final case class PackageImpl( + name: String, + members: List[Entity], + path: List[String], + var comment: Option[Comment] = None + ) extends Package with Impl { + val children: List[Entity with Members] = + members.collect { case x: Entity with Members => x } + } + + final case class ClassImpl( + name: String, + members: List[Entity], + modifiers: List[String], + path: List[String], + var comment: Option[Comment] = None + ) extends Class with Impl + + final case class CaseClassImpl( + name: String, + members: List[Entity], + modifiers: List[String], + path: List[String], + var comment: Option[Comment] = None + ) extends CaseClass with Impl + + final case class TraitImpl( + name: String, + members: List[Entity], + modifiers: List[String], + path: List[String], + var comment: Option[Comment] = None + ) extends Trait with Impl + + final case class ObjectImpl( + name: String, + members: List[Entity], + modifiers: List[String], + path: List[String], + var comment: Option[Comment] = None + ) extends Object with Impl + + final case class DefImpl( + name: String, + modifiers: List[String], + path: List[String], + returnValue: String, + var comment: Option[Comment] = None + ) extends Def with Impl + + final case class ValImpl( + name: String, + modifiers: List[String], + path: List[String], + returnValue: String, + var comment: Option[Comment] = None + ) extends Val with Impl +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala new file mode 100644 index 000000000000..ea33a05fd0ee --- /dev/null +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala @@ -0,0 +1,20 @@ +package dotty.tools.dottydoc +package model + +object pickling { + import internal._ + import prickle._ + + implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity] + .concreteType[NonEntity.type] + .concreteType[ValImpl] + .concreteType[DefImpl] + .concreteType[ClassImpl] + .concreteType[CaseClassImpl] + .concreteType[ObjectImpl] + .concreteType[TraitImpl] + .concreteType[PackageImpl] + + implicit val packagePickler: PicklerPair[Package] = CompositePickler[Package] + .concreteType[PackageImpl] +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala index 37c2f6e6b21f..aca5f41ea358 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala @@ -1,8 +1,8 @@ package dotty.tools.dottydoc package util -object Traversing { - import model.Entities._ +object traversing { + import model._ def mutateEntities(e: Entity)(trans: Entity => Unit): Unit = e match { case e: Entity with Members => From 0fb1058cafc8c8a72c9d97e3aa1ff7584a28ec82 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 3 May 2016 11:40:56 +0200 Subject: [PATCH 017/100] Filter out companion objects from package-view --- .../src/dotty/tools/dottydoc/html/Html.scala | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala index 91bf4d773358..216794ac7f91 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala @@ -49,7 +49,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ), nav( cls := "related mdl-navigation", - companion, + companionAnchor, a(cls := "mdl-navigation__link", href := "#", "Source") ), span( @@ -90,7 +90,9 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { val children = pack.children .sortBy(_.name) - .filterNot(_.kind == "package") + .filterNot { ent => + ent.kind == "package" || (ent.kind == "object" && companion(ent).isDefined) + } .map { entity => a( cls := "mdl-navigation__link entity", @@ -106,19 +108,22 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { } ) - def companion = { + def companion(entity: Entity) = { val pack = entity.path.dropRight(1).mkString(".") - packages.get(pack) - .flatMap { p => - p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) - } - .map { c => - a( - cls := "mdl-navigation__link", - href := c.path.last + ".html", - "Companion " + c.kind - ) - }.getOrElse(span()) + (for { + p <- packages.get(pack) + child <- p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) + } yield child) + } + + def companionAnchor = { + companion(entity).map { c => + a( + cls := "mdl-navigation__link", + href := c.path.last + ".html", + "Companion " + c.kind + ) + }.getOrElse(span()) } def searchView = div( From 86f816d430ce61a751c7b8a5b787b0fcabcee3e6 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 3 May 2016 15:35:09 +0200 Subject: [PATCH 018/100] Add companions to package view w ability to choose between them --- dottydoc/js/static/index.css | 58 ++++++++++++++++++- .../html/{Html.scala => EntityPage.scala} | 26 ++++++--- 2 files changed, 74 insertions(+), 10 deletions(-) rename dottydoc/jvm/src/dotty/tools/dottydoc/html/{Html.scala => EntityPage.scala} (81%) diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css index e0fb19f939cc..cdf4b0206ec5 100644 --- a/dottydoc/js/static/index.css +++ b/dottydoc/js/static/index.css @@ -12,12 +12,64 @@ div.member.member-fullcomment:hover { cursor: pointer; } -nav.packages { +ul.packages { padding-top: 0 !important; } -nav.packages > a.entity { - padding: 0.2em 4em !important; +ul.packages > li.entity { + padding: 0; + transition: 0.3s; +} + +ul.packages > li.entity.one { + margin-left: -48px; +} + +ul.packages > li.entity.two { + margin-left: -96px; +} + +ul.packages > li.entity:hover { + background-color: #efefef; + margin-left: 0px; +} + +li.entity > a.entity-button { + float: left; + display: inline; + background-color: green; + height: 48px; + width: 48px; + line-height: 48px; + vertical-align: middle; + text-align: center; + text-decoration: none; + color: #fff; + +} + +li.entity > a.entity-name { + padding-left: 2em; + font-size: 14px; +} + +li.entity > a.entity-button.object { + background-color: rgb(44, 108, 141); +} + +li.entity > a.entity-button.class, +li.entity > a.entity-button.caseclass { + background-color: rgb(68, 173, 125); +} + +li.entity > a.entity-button.trait { + background-color: rgb(25, 170, 207); +} + +li.entity > a.entity-button.shadowed { + -webkit-box-shadow: inset -2px 0px 5px -3px rgba(0,0,0,0.25); + -moz-box-shadow: inset -2px 0px 5px -3px rgba(0,0,0,0.25); + box-shadow: inset -2px 0px 5px -3px rgba(0,0,0,0.25); } div.search-container { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala similarity index 81% rename from dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 216794ac7f91..26e25ab67993 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -81,8 +81,8 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { private def relativePath(to: Entity) = util.traversing.relativePath(entity, to) - def packageView = nav( - cls := "mdl-navigation packages", + def packageView = ul( + cls := "mdl-list packages", { val keys: Seq[String] = packages.keys.toSeq.sorted keys.flatMap { k => @@ -94,15 +94,27 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ent.kind == "package" || (ent.kind == "object" && companion(ent).isDefined) } .map { entity => - a( - cls := "mdl-navigation__link entity", - href := relativePath(entity), - filteredName(entity.name) + val comp = companion(entity) + val entityUrl = relativePath(entity) + val compUrl = comp.map(relativePath).getOrElse("#") + li( + cls := s"""mdl-list__item entity ${ if (comp.isDefined) "two" else "one" }""", + comp.map { _ => a(cls := "entity-button object", href := compUrl, "O") }.getOrElse(()), + a( + cls := s"""entity-button shadowed ${entity.kind.replaceAll(" ", "")}""", + href := entityUrl, + entity.kind(0).toUpper.toString + ), + a( + cls := "entity-name", + href := entityUrl, + filteredName(entity.name) + ) ) } if (children.length > 0) - a(cls := "mdl-navigation__link package", href := relativePath(pack), filteredName(k)) :: children + li(cls := "mdl-list__item package", href := relativePath(pack), filteredName(k)) :: children else Nil } } From 53fc2c03b0b9cf998be8f037c59b42503df3fe17 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 3 May 2016 18:09:12 +0200 Subject: [PATCH 019/100] Adjust font configuration for finalized package view --- dottydoc/js/static/index.css | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css index cdf4b0206ec5..8bc0c539a0f3 100644 --- a/dottydoc/js/static/index.css +++ b/dottydoc/js/static/index.css @@ -16,17 +16,25 @@ ul.packages { padding-top: 0 !important; } +ul.packages > li.package { + padding-bottom: 0; + padding-left: 40px; + font-size: 14px; +} + ul.packages > li.entity { padding: 0; transition: 0.3s; + min-height: 36px !important; + max-height: 36px !important; } ul.packages > li.entity.one { - margin-left: -48px; + margin-left: -36px; } ul.packages > li.entity.two { - margin-left: -96px; + margin-left: -72px; } ul.packages > li.entity:hover { @@ -38,19 +46,23 @@ li.entity > a.entity-button { float: left; display: inline; background-color: green; - height: 48px; - width: 48px; - line-height: 48px; + height: 36px; + width: 36px; + line-height: 36px; vertical-align: middle; text-align: center; text-decoration: none; color: #fff; - } li.entity > a.entity-name { - padding-left: 2em; + text-decoration: none; + font-weight: normal; + color: #757575; + padding-left: 48px; font-size: 14px; + font-family: "Helvetica","Arial",sans-serif; + letter-spacing: 0; } li.entity > a.entity-button.object { From cb42a04bfcd7548261cda15c489671b8ca09cd7e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 4 May 2016 09:46:13 +0200 Subject: [PATCH 020/100] Filter out ProductX when X > 3 in package view --- .../jvm/src/dotty/tools/dottydoc/html/EntityPage.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 26e25ab67993..b3f5b5d53dd9 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -85,13 +85,19 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { cls := "mdl-list packages", { val keys: Seq[String] = packages.keys.toSeq.sorted + val productReg = """^Product[0-9]+$""".r keys.flatMap { k => val pack = packages(k) val children = pack.children .sortBy(_.name) .filterNot { ent => - ent.kind == "package" || (ent.kind == "object" && companion(ent).isDefined) + // Filter out ProductX where X > 3 + productReg.findFirstIn(ent.name).map(_.slice(7, 99).toInt > 3).getOrElse(false) || + // Filter out packages + ent.kind == "package" || + // Filter out objects that have companions + (ent.kind == "object" && companion(ent).isDefined) } .map { entity => val comp = companion(entity) From 80b027f88ac86539ba0a51558564c6694cbfac9a Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 4 May 2016 09:56:32 +0200 Subject: [PATCH 021/100] Break out commentCache to CommentParser --- .../dotty/tools/dottydoc/core/Phases.scala | 40 +++++++++---------- .../tools/dottydoc/model/CommentParsers.scala | 39 +++++++++++++++--- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 1670313e17c3..7d97fab5e537 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -13,11 +13,11 @@ import dotc.core.Symbols.Symbol object Phases { class DocPhase extends Phase { - import model.comment.Comment - import model.CommentParsers.wikiParser - import model.factories._ + import model.CommentParsers.WikiParser import model._ + import model.factories._ import model.internal._ + import model.comment.Comment import dotty.tools.dotc.core.Flags import dotty.tools.dotc.ast.tpd._ import util.traversing._ @@ -25,19 +25,15 @@ object Phases { def phaseName = "docphase" - private[this] var commentCache: Map[String, (Entity, Map[String, Package]) => Option[Comment]] = Map.empty + private[this] val commentParser = new WikiParser /** Saves the commentParser function for later evaluation, for when the AST has been filled */ def track(symbol: Symbol, ctx: Context)(op: => Entity) = { val entity = op - if (entity != NonEntity) { - val commentParser = { (entity: Entity, packs: Map[String, Package]) => - wikiParser.parseHtml(symbol, entity, packs)(ctx) - } + if (entity != NonEntity) + commentParser += (entity, symbol, ctx) - commentCache = commentCache + (entity.path.mkString(".") -> commentParser) - } entity } @@ -113,7 +109,7 @@ object Phases { override def run(implicit ctx: Context): Unit = { currentRun += 1 - println(s"Generating schema for ($currentRun/$totalRuns): ${ctx.compilationUnit.source.file.name}") + println(s"Compiling ($currentRun/$totalRuns): ${ctx.compilationUnit.source.file.name}") collect(ctx.compilationUnit.tpdTree) // Will put packages in `packages` var } @@ -123,17 +119,19 @@ object Phases { val compUnits = super.runOn(units) // (2) Set parent of all package children - println("Connecting parents to children, finding companions...") - for { - parent <- packages.values - child <- parent.children - } setParent(child, to = parent) + // + // This step is unnecessary for now - member `parent` is not being used + // + //println("Connecting parents to children, finding companions...") + //for { + // parent <- packages.values + // child <- parent.children + //} setParent(child, to = parent) // (3) Create documentation template from docstrings, with internal links - for { - pack <- packages.values - } mutateEntities(pack) { e => - val comment = commentCache(e.path.mkString("."))(e, packages) + println("Creating documentation...") + for (pack <- packages.values) mutateEntities(pack) { e => + val comment = commentParser.parse(e, packages) setComment(e, to = comment) } @@ -141,7 +139,7 @@ object Phases { util.IndexWriters.writeJs(packages, "../js/out") // (5) Clear caches - commentCache = Map.empty + commentParser.clear() // Return super's result compUnits diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala index e6adba977b55..029e6a9d66f4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -10,19 +10,46 @@ object CommentParsers { import BodyParsers._ import model.internal._ - sealed class WikiParser - extends CommentCleaner with CommentParser with CommentExpander { - def parseHtml(sym: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): Option[Comment] = - ctx.base.docstring(sym).map { d => + class WikiParser extends CommentCleaner with CommentParser with CommentExpander { + private[this] var commentCache: Map[String, (Entity, Map[String, Package]) => Option[Comment]] = Map.empty + + /** Parses comment and returns the path to the entity with an optional comment + * + * The idea here is to use this fact to create `Future[Seq[(String, Option[Comment]]]` + * which can then be awaited near the end of the run - before the pickling. + */ + def parseHtml(sym: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): (String, Option[Comment]) = { + val cmt = ctx.base.docstring(sym).map { d => val expanded = expand(sym) val body = parse(entity, packages, clean(expanded), expanded, d.pos) val summary = body.summary.map(_.toHtml(entity)).getOrElse("") - body.toHtml(entity) match { + body.toHtml(entity) match { case "" => None case x => Some(Comment(x, summary)) } }.flatten + + (entity.path.mkString("."), cmt) } - val wikiParser = new WikiParser + + def add(entity: Entity, symbol: Symbol, ctx: Context): Unit = { + val commentParser = { (entity: Entity, packs: Map[String, Package]) => + parseHtml(symbol, entity, packs)(ctx)._2 + } + + val path = entity.path.mkString(".") + if (!commentCache.contains(path) || ctx.base.docstring(symbol).isDefined) + commentCache = commentCache + (path -> commentParser) + } + + def +=(entity: Entity, symbol: Symbol, ctx: Context) = add(entity, symbol, ctx) + + def parse(entity: Entity, packs: Map[String, Package]): Option[Comment] = + commentCache(entity.path.mkString("."))(entity, packs) + + def clear(): Unit = commentCache = Map.empty + + def size: Int = commentCache.size + } } From 60b5dc30f65dfe6dcd6d69b3673d645ea512003f Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 4 May 2016 13:09:22 +0200 Subject: [PATCH 022/100] Better prints while documenting packages --- .../jvm/src/dotty/tools/dottydoc/core/Phases.scala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 7d97fab5e537..a6a61b0d1ac6 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -130,9 +130,16 @@ object Phases { // (3) Create documentation template from docstrings, with internal links println("Creating documentation...") - for (pack <- packages.values) mutateEntities(pack) { e => - val comment = commentParser.parse(e, packages) - setComment(e, to = comment) + val totalPackages = packages.size + var currentPackage = 0 + for (pack <- packages.values) { + currentPackage += 1 + println(s"Documenting package ($currentPackage/$totalPackages): ${pack.name}") + + mutateEntities(pack) { e => + val comment = commentParser.parse(e, packages) + setComment(e, to = comment) + } } // (4) Write the finished model to JSON From 5c5d54aee133620e7f697aeb65c011f95ac9ab4e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 4 May 2016 20:43:19 +0200 Subject: [PATCH 023/100] Parse comments only from root packages (which contain all entities subsequently) --- .../dotty/tools/dottydoc/core/Phases.scala | 29 +++-------------- .../tools/dottydoc/model/CommentParsers.scala | 32 +++++++++++++++++-- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index a6a61b0d1ac6..4650b21d8960 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -118,34 +118,13 @@ object Phases { totalRuns = units.length val compUnits = super.runOn(units) - // (2) Set parent of all package children - // - // This step is unnecessary for now - member `parent` is not being used - // - //println("Connecting parents to children, finding companions...") - //for { - // parent <- packages.values - // child <- parent.children - //} setParent(child, to = parent) - - // (3) Create documentation template from docstrings, with internal links - println("Creating documentation...") - val totalPackages = packages.size - var currentPackage = 0 - for (pack <- packages.values) { - currentPackage += 1 - println(s"Documenting package ($currentPackage/$totalPackages): ${pack.name}") - - mutateEntities(pack) { e => - val comment = commentParser.parse(e, packages) - setComment(e, to = comment) - } - } + // (2) Create documentation template from docstrings, with internal links + commentParser.parse(packages) - // (4) Write the finished model to JSON + // (3) Write the finished model to JSON util.IndexWriters.writeJs(packages, "../js/out") - // (5) Clear caches + // (4) Clear caches commentParser.clear() // Return super's result diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala index 029e6a9d66f4..bd9eb87f9055 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -9,6 +9,8 @@ object CommentParsers { import comment._ import BodyParsers._ import model.internal._ + import util.traversing._ + import util.internal.setters._ class WikiParser extends CommentCleaner with CommentParser with CommentExpander { private[this] var commentCache: Map[String, (Entity, Map[String, Package]) => Option[Comment]] = Map.empty @@ -45,11 +47,35 @@ object CommentParsers { def +=(entity: Entity, symbol: Symbol, ctx: Context) = add(entity, symbol, ctx) - def parse(entity: Entity, packs: Map[String, Package]): Option[Comment] = + def size: Int = commentCache.size + + private def parse(entity: Entity, packs: Map[String, Package]): Option[Comment] = commentCache(entity.path.mkString("."))(entity, packs) - def clear(): Unit = commentCache = Map.empty + def parse(packs: Map[String, Package]): Unit = { + def rootPackages: List[String] = { + var currentDepth = Int.MaxValue + var packages: List[String] = Nil - def size: Int = commentCache.size + for (key <- packs.keys) { + val keyDepth = key.split(".").length + packages = + if (keyDepth < currentDepth) key :: Nil + else if (keyDepth == currentDepth) key :: packages + else packages + } + + packages + } + + for (pack <- rootPackages) { + mutateEntities(packs(pack)) { e => + val comment = parse(e, packs) + setComment(e, to = comment) + } + } + } + + def clear(): Unit = commentCache = Map.empty } } From b4622aabd0ebd6929639c9cfcd3c7845a250598f Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 09:33:43 +0200 Subject: [PATCH 024/100] Fix root-package finding in comment-parser --- .../dotty/tools/dottydoc/model/CommentParsers.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala index bd9eb87f9055..9320bb5fee9c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala @@ -58,11 +58,14 @@ object CommentParsers { var packages: List[String] = Nil for (key <- packs.keys) { - val keyDepth = key.split(".").length + val keyDepth = key.split("\\.").length packages = - if (keyDepth < currentDepth) key :: Nil - else if (keyDepth == currentDepth) key :: packages - else packages + if (keyDepth < currentDepth) { + currentDepth = keyDepth + key :: Nil + } else if (keyDepth == currentDepth) { + key :: packages + } else packages } packages From 29cf43bca7e478f290e7c39a05ce7e8bcb218d3d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 11:28:51 +0200 Subject: [PATCH 025/100] Add JUnit test structure for testing the DocPhase --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 8 ++-- dottydoc/jvm/test/CompilerTest.scala | 47 +++++++++++++++++++ dottydoc/jvm/test/TestCommentParsing.scala | 9 ++++ dottydoc/jvm/test/WhitelistedStdLib.scala | 12 +++-- project/Build.scala | 4 +- project/plugins.sbt | 2 + 6 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 dottydoc/jvm/test/CompilerTest.scala create mode 100644 dottydoc/jvm/test/TestCommentParsing.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 428bc17d8ec4..1fb93d961ea8 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -31,10 +31,10 @@ class DottyDocCompiler extends Compiler { List(new DocPhase) :: Nil - override def newRun(implicit ctx: Context): Run = { - reset() - new DocRun(this)(rootContext) - } + override def newRun(implicit ctx: Context): Run = { + reset() + new DocRun(this)(rootContext) + } } class DocRun(comp: Compiler)(implicit ctx: Context) extends Run(comp)(ctx) { diff --git a/dottydoc/jvm/test/CompilerTest.scala b/dottydoc/jvm/test/CompilerTest.scala new file mode 100644 index 000000000000..4cafc72e0b6b --- /dev/null +++ b/dottydoc/jvm/test/CompilerTest.scala @@ -0,0 +1,47 @@ +package dotty.tools +package dottydoc + +import dotc.core.Contexts +import Contexts.{ Context, ContextBase } +import dotc.core.Phases.Phase +import dotc.typer.FrontEnd +import dottydoc.core.Phases.DocPhase + +trait DottyTest { + dotty.tools.dotc.parsing.Scanners // initialize keywords + + implicit var ctx: Contexts.Context = { + val base = new ContextBase + import base.settings._ + val ctx = base.initialCtx.fresh + ctx.setSetting(ctx.settings.YkeepComments, true) + base.initialize()(ctx) + ctx + } + + private def compilerWithChecker(assertion: DocPhase => Unit) = new DottyDocCompiler { + val docPhase = new DocPhase + override def phases = + List(new FrontEnd) :: + List(docPhase) :: + List(new Phase { + def phaseName = "assertionPhase" + override def run(implicit ctx: Context): Unit = assertion(docPhase) + }) :: + Nil + } + + def checkCompile(source: String)(assertion: DocPhase => Unit): Unit = { + val c = compilerWithChecker(assertion) + c.rootContext(ctx) + val run = c.newRun + run.compile(source) + } + + def checkCompile(sources:List[String])(assertion: DocPhase => Unit): Unit = { + val c = compilerWithChecker(assertion) + c.rootContext(ctx) + val run = c.newRun + run.compile(sources) + } +} diff --git a/dottydoc/jvm/test/TestCommentParsing.scala b/dottydoc/jvm/test/TestCommentParsing.scala new file mode 100644 index 000000000000..16e8559574a6 --- /dev/null +++ b/dottydoc/jvm/test/TestCommentParsing.scala @@ -0,0 +1,9 @@ +package dotty.tools +package dottydoc + +import org.junit.Test +import org.junit.Assert._ + +class TestWhitelistedCollections extends DottyTest { + @Test def test = assert(false) +} diff --git a/dottydoc/jvm/test/WhitelistedStdLib.scala b/dottydoc/jvm/test/WhitelistedStdLib.scala index 8ba8f2b89a8d..2ab8328705cd 100644 --- a/dottydoc/jvm/test/WhitelistedStdLib.scala +++ b/dottydoc/jvm/test/WhitelistedStdLib.scala @@ -3,10 +3,11 @@ package dottydoc import scala.io.Source -object WhitelistedStdLib extends DottyDoc { - override def main(args: Array[String]) = { +object WhitelistedStandardLib extends DottyDoc { + val files: Array[String] = { val whitelist = "../../test/dotc/scala-collections.whitelist" - val stdlibFiles = Source.fromFile(whitelist, "UTF8") + + Source.fromFile(whitelist, "UTF8") .getLines() .map(_.trim) // allow identation .filter(!_.startsWith("#")) // allow comment lines prefixed by # @@ -15,7 +16,8 @@ object WhitelistedStdLib extends DottyDoc { .filterNot(_.endsWith("package.scala")) .map("../." + _) .toArray - - super.main("-language:Scala2" +: stdlibFiles) } + + override def main(args: Array[String]) = + super.main("-language:Scala2" +: files) } diff --git a/project/Build.scala b/project/Build.scala index 6b9939a34fb9..add3ebecbe06 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -268,7 +268,6 @@ object DottyInjectedPlugin extends AutoPlugin { .jsSettings( libraryDependencies ++= Seq( "org.scala-js" %%% "scalajs-dom" % "0.9.0", - "com.github.benhutchison" %%% "microjson" % "1.3", "com.github.benhutchison" %%% "prickle" % "1.1.10", "com.lihaoyi" %%% "scalatags" % "0.5.5" ) @@ -287,7 +286,8 @@ object DottyInjectedPlugin extends AutoPlugin { libraryDependencies ++= Seq( "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0", "com.github.benhutchison" %% "prickle" % "1.1.10", - "com.lihaoyi" %% "scalatags" % "0.5.5" + "com.lihaoyi" %% "scalatags" % "0.5.5", + "com.novocode" % "junit-interface" % "0.11" % "test" ), // enable improved incremental compilation algorithm diff --git a/project/plugins.sbt b/project/plugins.sbt index 57bd465815b4..8ac4d69bf1b7 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -8,3 +8,5 @@ addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.8") + +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5") From 00203025abbb16a0fc45ababa02550dcb4b20671 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 12:03:48 +0200 Subject: [PATCH 026/100] Add test for checking if Array has documentation after compiling std lib --- .../jvm/src/dotty/tools/dottydoc/core/Phases.scala | 3 ++- dottydoc/jvm/test/CompilerTest.scala | 11 +++++++---- dottydoc/jvm/test/TestCommentParsing.scala | 11 ++++++++++- dottydoc/jvm/test/WhitelistedStdLib.scala | 6 +++--- src/dotty/tools/dotc/config/ScalaSettings.scala | 1 + 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 4650b21d8960..e3aff1d71763 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -119,10 +119,11 @@ object Phases { val compUnits = super.runOn(units) // (2) Create documentation template from docstrings, with internal links + println("Generating documentation, this might take a while...") commentParser.parse(packages) // (3) Write the finished model to JSON - util.IndexWriters.writeJs(packages, "../js/out") + if (!ctx.settings.YDocNoWrite.value) util.IndexWriters.writeJs(packages, "../js/out") // (4) Clear caches commentParser.clear() diff --git a/dottydoc/jvm/test/CompilerTest.scala b/dottydoc/jvm/test/CompilerTest.scala index 4cafc72e0b6b..001e4d42271d 100644 --- a/dottydoc/jvm/test/CompilerTest.scala +++ b/dottydoc/jvm/test/CompilerTest.scala @@ -2,7 +2,7 @@ package dotty.tools package dottydoc import dotc.core.Contexts -import Contexts.{ Context, ContextBase } +import Contexts.{ Context, ContextBase, FreshContext } import dotc.core.Phases.Phase import dotc.typer.FrontEnd import dottydoc.core.Phases.DocPhase @@ -10,17 +10,20 @@ import dottydoc.core.Phases.DocPhase trait DottyTest { dotty.tools.dotc.parsing.Scanners // initialize keywords - implicit var ctx: Contexts.Context = { + implicit var ctx: FreshContext = { val base = new ContextBase import base.settings._ val ctx = base.initialCtx.fresh + ctx.setSetting(ctx.settings.language, List("Scala2")) ctx.setSetting(ctx.settings.YkeepComments, true) + ctx.setSetting(ctx.settings.YDocNoWrite, true) base.initialize()(ctx) ctx } private def compilerWithChecker(assertion: DocPhase => Unit) = new DottyDocCompiler { - val docPhase = new DocPhase + private[this] val docPhase = new DocPhase + override def phases = List(new FrontEnd) :: List(docPhase) :: @@ -38,7 +41,7 @@ trait DottyTest { run.compile(source) } - def checkCompile(sources:List[String])(assertion: DocPhase => Unit): Unit = { + def checkCompile(sources: List[String])(assertion: DocPhase => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun diff --git a/dottydoc/jvm/test/TestCommentParsing.scala b/dottydoc/jvm/test/TestCommentParsing.scala index 16e8559574a6..12f60f6a61cf 100644 --- a/dottydoc/jvm/test/TestCommentParsing.scala +++ b/dottydoc/jvm/test/TestCommentParsing.scala @@ -5,5 +5,14 @@ import org.junit.Test import org.junit.Assert._ class TestWhitelistedCollections extends DottyTest { - @Test def test = assert(false) + @Test def arrayHasDocumentation = + checkCompile(WhitelistedStandardLib.files) { doc => + val array = doc + .packages("scala") + .children + .find(_.path.mkString(".") == "scala.Array") + .get + + assert(array.comment.get.body.length > 0) + } } diff --git a/dottydoc/jvm/test/WhitelistedStdLib.scala b/dottydoc/jvm/test/WhitelistedStdLib.scala index 2ab8328705cd..f4a2f9dc649c 100644 --- a/dottydoc/jvm/test/WhitelistedStdLib.scala +++ b/dottydoc/jvm/test/WhitelistedStdLib.scala @@ -4,7 +4,7 @@ package dottydoc import scala.io.Source object WhitelistedStandardLib extends DottyDoc { - val files: Array[String] = { + val files: List[String] = { val whitelist = "../../test/dotc/scala-collections.whitelist" Source.fromFile(whitelist, "UTF8") @@ -15,9 +15,9 @@ object WhitelistedStandardLib extends DottyDoc { .filter(_.nonEmpty) .filterNot(_.endsWith("package.scala")) .map("../." + _) - .toArray + .toList } override def main(args: Array[String]) = - super.main("-language:Scala2" +: files) + super.main("-language:Scala2" +: files.toArray) } diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala index 5af871189b0f..0cc08d3cddc2 100644 --- a/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -198,6 +198,7 @@ class ScalaSettings extends Settings.SettingGroup { val YpresentationDelay = IntSetting("-Ypresentation-delay", "Wait number of ms after typing before starting typechecking", 0, 0 to 999) /** Dottydoc specific settings */ + val YDocNoWrite = BooleanSetting("-Ydoc-nowrite", "Doesn't write HTML files if set", false) val DocTitle = StringSetting ( "-Ydoc-title", From bc594c81c6ce8c696dde2f7668132952e83b383a Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 12:22:53 +0200 Subject: [PATCH 027/100] Add test for simple comment --- dottydoc/jvm/test/TestSimpleComments.scala | 29 +++++++++++++++++++ ...sing.scala => TestWhitelistedStdLib.scala} | 3 +- 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 dottydoc/jvm/test/TestSimpleComments.scala rename dottydoc/jvm/test/{TestCommentParsing.scala => TestWhitelistedStdLib.scala} (83%) diff --git a/dottydoc/jvm/test/TestSimpleComments.scala b/dottydoc/jvm/test/TestSimpleComments.scala new file mode 100644 index 000000000000..48cdecec08a8 --- /dev/null +++ b/dottydoc/jvm/test/TestSimpleComments.scala @@ -0,0 +1,29 @@ +package dotty.tools +package dottydoc + +import org.junit.Test +import org.junit.Assert._ + +class TestSimpleComments extends DottyTest { + + @Test def simpleComment = { + val source = + """ + |package scala + | + |/** Hello, world! */ + |trait HelloWorld + """.stripMargin + + checkCompile(source) { doc => + val traitCmt = doc + .packages("scala") + .children.find(_.path.mkString(".") == "scala.HelloWorld") + .flatMap(_.comment.map(_.body)) + .get + + assertEquals(traitCmt, "

    Hello, world!

    ") + } + } + +} diff --git a/dottydoc/jvm/test/TestCommentParsing.scala b/dottydoc/jvm/test/TestWhitelistedStdLib.scala similarity index 83% rename from dottydoc/jvm/test/TestCommentParsing.scala rename to dottydoc/jvm/test/TestWhitelistedStdLib.scala index 12f60f6a61cf..763f41370ed6 100644 --- a/dottydoc/jvm/test/TestCommentParsing.scala +++ b/dottydoc/jvm/test/TestWhitelistedStdLib.scala @@ -9,8 +9,7 @@ class TestWhitelistedCollections extends DottyTest { checkCompile(WhitelistedStandardLib.files) { doc => val array = doc .packages("scala") - .children - .find(_.path.mkString(".") == "scala.Array") + .children.find(_.path.mkString(".") == "scala.Array") .get assert(array.comment.get.body.length > 0) From 8e39b71b29afd7951745dbaf957eade0e9f51434 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 15:22:29 +0200 Subject: [PATCH 028/100] Fix repeated traversal of packages when generating docs (5x speedup) --- .../dotty/tools/dottydoc/core/Phases.scala | 18 +++- .../{CompilerTest.scala => BaseTest.scala} | 12 ++- dottydoc/jvm/test/PackageStructure.scala | 89 +++++++++++++++++++ ...pleComments.scala => SimpleComments.scala} | 2 +- dottydoc/jvm/test/TestWhitelistedStdLib.scala | 17 ---- dottydoc/jvm/test/WhitelistedStdLib.scala | 28 +++--- dottydoc/jvm/test/WhitelistedStdLibMain.scala | 23 +++++ .../dotty/tools/dottydoc/model/internal.scala | 4 +- 8 files changed, 151 insertions(+), 42 deletions(-) rename dottydoc/jvm/test/{CompilerTest.scala => BaseTest.scala} (75%) create mode 100644 dottydoc/jvm/test/PackageStructure.scala rename dottydoc/jvm/test/{TestSimpleComments.scala => SimpleComments.scala} (94%) delete mode 100644 dottydoc/jvm/test/TestWhitelistedStdLib.scala create mode 100644 dottydoc/jvm/test/WhitelistedStdLibMain.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index e3aff1d71763..d2a1320a2bc5 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -94,10 +94,22 @@ object Phases { var packages: Map[String, Package] = Map.empty def addEntity(p: Package): Package = { + def mergedChildren(x1s: List[Entity], x2s: List[Entity]): List[Entity] = { + val (packs1, others1) = x1s.partition(_.kind == "package") + val (packs2, others2) = x2s.partition(_.kind == "package") + + val others = others1 ::: others2 + val packs = (packs1 ::: packs2).groupBy(_.path).map(_._2.head) + + (others ++ packs).sortBy(_.name) + } + val path = p.path.mkString(".") - val newPack = packages.get(path).map { ex => - val children = (ex.children ::: p.children).distinct.sortBy(_.name) - PackageImpl(p.name, children, p.path, None) + val newPack = packages.get(path).map { + case ex: PackageImpl => + if (!ex.comment.isDefined) ex.comment = p.comment + ex.members = mergedChildren(ex.members, p.members) + ex }.getOrElse(p) packages = packages + (path -> newPack) diff --git a/dottydoc/jvm/test/CompilerTest.scala b/dottydoc/jvm/test/BaseTest.scala similarity index 75% rename from dottydoc/jvm/test/CompilerTest.scala rename to dottydoc/jvm/test/BaseTest.scala index 001e4d42271d..2703f816973e 100644 --- a/dottydoc/jvm/test/CompilerTest.scala +++ b/dottydoc/jvm/test/BaseTest.scala @@ -3,6 +3,7 @@ package dottydoc import dotc.core.Contexts import Contexts.{ Context, ContextBase, FreshContext } +import dotc.util.SourceFile import dotc.core.Phases.Phase import dotc.typer.FrontEnd import dottydoc.core.Phases.DocPhase @@ -34,17 +35,24 @@ trait DottyTest { Nil } - def checkCompile(source: String)(assertion: DocPhase => Unit): Unit = { + def checkSource(source: String)(assertion: DocPhase => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun run.compile(source) } - def checkCompile(sources: List[String])(assertion: DocPhase => Unit): Unit = { + def checkFiles(sources: List[String])(assertion: DocPhase => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun run.compile(sources) } + + def checkSources(sourceFiles: List[SourceFile])(assertion: DocPhase => Unit): Unit = { + val c = compilerWithChecker(assertion) + c.rootContext(ctx) + val run = c.newRun + run.compileSources(sourceFiles) + } } diff --git a/dottydoc/jvm/test/PackageStructure.scala b/dottydoc/jvm/test/PackageStructure.scala new file mode 100644 index 000000000000..af6e52184e8b --- /dev/null +++ b/dottydoc/jvm/test/PackageStructure.scala @@ -0,0 +1,89 @@ +package dotty.tools +package dottydoc + +import org.junit.Test +import org.junit.Assert._ + +import dotc.util.SourceFile +import model.internal._ + +class PackageStructure extends DottyTest { + @Test def multipleCompilationUnits = { + val source1 = new SourceFile( + "", + """ + |package scala + | + |trait A + """.stripMargin + ) + + val source2 = new SourceFile( + "", + """ + |package scala + | + |trait B + """.stripMargin + ) + + checkSources(source1 :: source2 :: Nil) { doc => + doc.packages("scala") match { + case PackageImpl(_, List(tA, tB), _, _) => + assert( + tA.name == "A" && tB.name == "B", + s"trait A had name '${tA.name}' and trait B had name '${tB.name}'" + ) + case _ => fail("Incorrect package structure after run") + } + } + } + + + @Test def multiplePackages = { + val source1 = new SourceFile( + "", + """ + |package scala + |package collection + | + |trait A + """.stripMargin) + + val source2 = new SourceFile( + "", + """ + |package scala + |package collection + | + |trait B + """.stripMargin) + + checkSources(source1 :: source2 :: Nil) { doc => + doc.packages("scala") match { + case PackageImpl( + "scala", + List(PackageImpl("scala.collection", List(tA, tB), _, _)), + _, _ + ) => + assert( + tA.name == "A" && tB.name == "B", + s"trait A had name '${tA.name}' and trait B had name '${tB.name}'" + ) + + case _ => + fail(s"""Incorrect package structure for 'scala' package: ${doc.packages("scala")}""") + } + + doc.packages("scala.collection") match { + case PackageImpl("scala.collection", List(tA, tB), _, _) => + assert( + tA.name == "A" && tB.name == "B", + s"trait A had name '${tA.name}' and trait B had name '${tB.name}'" + ) + + case _ => fail("Incorrect package structure for 'scala.collection' package") + } + } + } +} diff --git a/dottydoc/jvm/test/TestSimpleComments.scala b/dottydoc/jvm/test/SimpleComments.scala similarity index 94% rename from dottydoc/jvm/test/TestSimpleComments.scala rename to dottydoc/jvm/test/SimpleComments.scala index 48cdecec08a8..ad9b7b1a6962 100644 --- a/dottydoc/jvm/test/TestSimpleComments.scala +++ b/dottydoc/jvm/test/SimpleComments.scala @@ -15,7 +15,7 @@ class TestSimpleComments extends DottyTest { |trait HelloWorld """.stripMargin - checkCompile(source) { doc => + checkSource(source) { doc => val traitCmt = doc .packages("scala") .children.find(_.path.mkString(".") == "scala.HelloWorld") diff --git a/dottydoc/jvm/test/TestWhitelistedStdLib.scala b/dottydoc/jvm/test/TestWhitelistedStdLib.scala deleted file mode 100644 index 763f41370ed6..000000000000 --- a/dottydoc/jvm/test/TestWhitelistedStdLib.scala +++ /dev/null @@ -1,17 +0,0 @@ -package dotty.tools -package dottydoc - -import org.junit.Test -import org.junit.Assert._ - -class TestWhitelistedCollections extends DottyTest { - @Test def arrayHasDocumentation = - checkCompile(WhitelistedStandardLib.files) { doc => - val array = doc - .packages("scala") - .children.find(_.path.mkString(".") == "scala.Array") - .get - - assert(array.comment.get.body.length > 0) - } -} diff --git a/dottydoc/jvm/test/WhitelistedStdLib.scala b/dottydoc/jvm/test/WhitelistedStdLib.scala index f4a2f9dc649c..bbf0b4c6bc56 100644 --- a/dottydoc/jvm/test/WhitelistedStdLib.scala +++ b/dottydoc/jvm/test/WhitelistedStdLib.scala @@ -1,23 +1,17 @@ package dotty.tools package dottydoc -import scala.io.Source +import org.junit.Test +import org.junit.Assert._ -object WhitelistedStandardLib extends DottyDoc { - val files: List[String] = { - val whitelist = "../../test/dotc/scala-collections.whitelist" +class TestWhitelistedCollections extends DottyTest { + @Test def arrayHasDocumentation = + checkFiles(WhitelistedStandardLib.files) { doc => + val array = doc + .packages("scala") + .children.find(_.path.mkString(".") == "scala.Array") + .get - Source.fromFile(whitelist, "UTF8") - .getLines() - .map(_.trim) // allow identation - .filter(!_.startsWith("#")) // allow comment lines prefixed by # - .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line - .filter(_.nonEmpty) - .filterNot(_.endsWith("package.scala")) - .map("../." + _) - .toList - } - - override def main(args: Array[String]) = - super.main("-language:Scala2" +: files.toArray) + assert(array.comment.get.body.length > 0) + } } diff --git a/dottydoc/jvm/test/WhitelistedStdLibMain.scala b/dottydoc/jvm/test/WhitelistedStdLibMain.scala new file mode 100644 index 000000000000..f4a2f9dc649c --- /dev/null +++ b/dottydoc/jvm/test/WhitelistedStdLibMain.scala @@ -0,0 +1,23 @@ +package dotty.tools +package dottydoc + +import scala.io.Source + +object WhitelistedStandardLib extends DottyDoc { + val files: List[String] = { + val whitelist = "../../test/dotc/scala-collections.whitelist" + + Source.fromFile(whitelist, "UTF8") + .getLines() + .map(_.trim) // allow identation + .filter(!_.startsWith("#")) // allow comment lines prefixed by # + .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line + .filter(_.nonEmpty) + .filterNot(_.endsWith("package.scala")) + .map("../." + _) + .toList + } + + override def main(args: Array[String]) = + super.main("-language:Scala2" +: files.toArray) +} diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala index f8707f69217d..147523662711 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -11,11 +11,11 @@ object internal { final case class PackageImpl( name: String, - members: List[Entity], + var members: List[Entity], path: List[String], var comment: Option[Comment] = None ) extends Package with Impl { - val children: List[Entity with Members] = + def children: List[Entity with Members] = members.collect { case x: Entity with Members => x } } From 07e4ae210b34e64a84731133f6ea4761baa19057 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 15:36:12 +0200 Subject: [PATCH 029/100] Replace "$plus" with "+" in webview --- .../dotty/tools/dottydoc/html/EntityPage.scala | 5 +++-- dottydoc/jvm/test/WhitelistedStdLib.scala | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index b3f5b5d53dd9..8bbc73db8ccb 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -75,8 +75,9 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ) ) - private def filteredName(str: String) = - str.replaceAll("\\$colon", ":") + private def filteredName(str: String) = str + .replaceAll("\\$colon", ":") + .replaceAll("\\$plus", "+") private def relativePath(to: Entity) = util.traversing.relativePath(entity, to) diff --git a/dottydoc/jvm/test/WhitelistedStdLib.scala b/dottydoc/jvm/test/WhitelistedStdLib.scala index bbf0b4c6bc56..88dc67e995e7 100644 --- a/dottydoc/jvm/test/WhitelistedStdLib.scala +++ b/dottydoc/jvm/test/WhitelistedStdLib.scala @@ -14,4 +14,19 @@ class TestWhitelistedCollections extends DottyTest { assert(array.comment.get.body.length > 0) } + + @Test def traitImmutableHasDocumentation = + checkFiles(WhitelistedStandardLib.files) { doc => + val imm = doc + .packages("scala") + .children.find(_.path.mkString(".") == "scala.Immutable") + .get + + assert( + imm.kind == "trait" && imm.name == "Immutable", + "Found wrong `Immutable`") + assert( + imm.comment.map(_.body).get.length > 0, + "Imm did not have a comment with length > 0") + } } From 3ecc86c00d0df6a2a2693ba8461c47ca0ff43737 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 15:48:41 +0200 Subject: [PATCH 030/100] Fix linking (do not remove parent linking!) --- .../jvm/src/dotty/tools/dottydoc/core/Phases.scala | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index d2a1320a2bc5..8fec012156e8 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -130,14 +130,20 @@ object Phases { totalRuns = units.length val compUnits = super.runOn(units) - // (2) Create documentation template from docstrings, with internal links + // (2) Set parents of entities, needed for linking + for { + parent <- packages.values + child <- parent.children + } setParent(child, to = parent) + + // (3) Create documentation template from docstrings, with internal links println("Generating documentation, this might take a while...") commentParser.parse(packages) - // (3) Write the finished model to JSON + // (4) Write the finished model to JSON if (!ctx.settings.YDocNoWrite.value) util.IndexWriters.writeJs(packages, "../js/out") - // (4) Clear caches + // (5) Clear caches commentParser.clear() // Return super's result From 73bfb73bbf72dc790c8e5595b7c3e58bca281015 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 15:48:55 +0200 Subject: [PATCH 031/100] Cosmetic updates --- dottydoc/js/static/index.css | 4 ++++ .../jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala | 1 - .../main/scala/dotty/tools/dottydoc/model/factories.scala | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dottydoc/js/static/index.css b/dottydoc/js/static/index.css index 8bc0c539a0f3..2be323ae709e 100644 --- a/dottydoc/js/static/index.css +++ b/dottydoc/js/static/index.css @@ -8,6 +8,10 @@ span.subtitle { padding-top: 32px; } +div.member { + min-height: 70px; +} + div.member.member-fullcomment:hover { cursor: pointer; } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index 70587e6b8993..1d9631e75dbd 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -14,7 +14,6 @@ object IndexWriters { EntityPage(pack, packs).render, outPath + pack.path.dropRight(1).mkString("/", "/", "/"), s"${pack.name.split("\\.").last}.html") - //s"index.html") for { child <- pack.children diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 14289502158a..8e6a0b6cea41 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -14,7 +14,10 @@ object factories { import DottyFlags._ def flags(t: Tree)(implicit ctx: Context): List[String] = - (t.symbol.flags & SourceModifierFlags).flagStrings.toList + (t.symbol.flags & SourceModifierFlags) + .flagStrings.toList + .filter(_ != "") + .filter(_ != "interface") def path(t: Tree)(implicit ctx: Context): List[String] = { def pathList(tpe: Type): List[String] = tpe match { From cb4d93c73f006fd3537f0fcdbd287e38ad180257 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 5 May 2016 15:50:04 +0200 Subject: [PATCH 032/100] Filter out `AnyValCompanion` trait --- dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 8bbc73db8ccb..07966b3f56d8 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -98,7 +98,8 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { // Filter out packages ent.kind == "package" || // Filter out objects that have companions - (ent.kind == "object" && companion(ent).isDefined) + (ent.kind == "object" && companion(ent).isDefined) || + ent.name == "AnyValCompanion" } .map { entity => val comp = companion(entity) From 2010a932329075ea1b2a0779fb96e442bc53232f Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 6 May 2016 09:59:35 +0200 Subject: [PATCH 033/100] Move name filtering to AST build in Phase.scala --- .../src/dotty/tools/dottydoc/core/Phases.scala | 15 ++++++++------- .../dotty/tools/dottydoc/html/EntityPage.scala | 8 ++------ .../dotty/tools/dottydoc/model/factories.scala | 4 ++++ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 8fec012156e8..745c8302f331 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -59,30 +59,31 @@ object Phases { /** trait */ case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => - val name = n.toString + val name = filteredName(n.toString) val newPath = prev :+ name TraitImpl(name, collectMembers(rhs), flags(t), newPath) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => - val name = n.toString.dropRight(1) + val name = filteredName(n.toString.dropRight(1)) ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$")) /** class / case class */ - case c @ TypeDef(name, rhs) if c.symbol.isClass => - val newPath = prev :+ name.toString - (name.toString, collectMembers(rhs), flags(c), newPath, None) match { + case c @ TypeDef(n, rhs) if c.symbol.isClass => + val name = filteredName(n.toString) + val newPath = prev :+ name + (name, collectMembers(rhs), flags(c), newPath, None) match { case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) case x => ClassImpl.tupled(x) } /** def */ case d: DefDef => - DefImpl(d.name.toString, flags(d), path(d), returnType(d.tpt)) + DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d.tpt)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - ValImpl(v.name.toString, flags(v), path(v), returnType(v.tpt)) + ValImpl(filteredName(v.name.toString), flags(v), path(v), returnType(v.tpt)) case x => { //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 07966b3f56d8..29d7aef5a199 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -75,10 +75,6 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ) ) - private def filteredName(str: String) = str - .replaceAll("\\$colon", ":") - .replaceAll("\\$plus", "+") - private def relativePath(to: Entity) = util.traversing.relativePath(entity, to) @@ -116,13 +112,13 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { a( cls := "entity-name", href := entityUrl, - filteredName(entity.name) + entity.name ) ) } if (children.length > 0) - li(cls := "mdl-list__item package", href := relativePath(pack), filteredName(k)) :: children + li(cls := "mdl-list__item package", href := relativePath(pack), k) :: children else Nil } } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 8e6a0b6cea41..f151722c93df 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -41,4 +41,8 @@ object factories { // TODO: should be updated to link to local entities def returnType(t: Tree)(implicit ctx: Context): String = t.show + + def filteredName(str: String) = str + .replaceAll("\\$colon", ":") + .replaceAll("\\$plus", "+") } From f084357c79d9c1ee9783ca07b9cfb84fb725328a Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 6 May 2016 10:29:46 +0200 Subject: [PATCH 034/100] Add implicit method `flat` to `Entity` This method can be used when pickling the `currentEntity` on each page --- .../tools/dottydoc/html/EntityPage.scala | 3 ++- .../dotty/tools/dottydoc/util/mutate.scala | 25 +++++++++++++++++++ .../tools/dottydoc/model/factories.scala | 1 - 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 29d7aef5a199..f74e904eabba 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -9,6 +9,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { import CustomTags._ import model.pickling._ import prickle._ + import util.internal.setters._ private def relPath(to: String, from: Entity) = "../" * from.path.length + to @@ -68,7 +69,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ) ), script( - raw(s"""|UnparsedIndex.currentEntity = ${Pickle.intoString(entity)}; + raw(s"""|UnparsedIndex.currentEntity = ${Pickle.intoString(entity.flat)}; |dotty.tools.dottydoc.js.DottyDocJS() | .main(document.getElementById("entity-container")); """.stripMargin) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala index b491fb1612c2..798d54041ffa 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala @@ -36,4 +36,29 @@ object setters { e.parent = to case _ => () } + + implicit class FlattenedEntity(val ent: Entity) extends AnyVal { + /** Returns a flat copy if anything was changed (Entity with Members) else + * the identity + */ + def flat: Entity = { + def flattenMember: Entity => Entity = { + case e: PackageImpl => e.copy(members = Nil) + case e: ObjectImpl => e.copy(members = Nil) + case e: CaseClassImpl => e.copy(members = Nil) + case e: ClassImpl => e.copy(members = Nil) + case e: TraitImpl => e.copy(members = Nil) + case other => other + } + + ent match { + case e: PackageImpl => e.copy(members = e.members.map(flattenMember)) + case e: ObjectImpl => e.copy(members = e.members.map(flattenMember)) + case e: CaseClassImpl => e.copy(members = e.members.map(flattenMember)) + case e: ClassImpl => e.copy(members = e.members.map(flattenMember)) + case e: TraitImpl => e.copy(members = e.members.map(flattenMember)) + case other => other + } + } + } } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index f151722c93df..4707fccff617 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -7,7 +7,6 @@ import dotc.core.Contexts.Context import dotc.core.Symbols.Symbol import dotc.core.{ Flags => DottyFlags } import dotc.ast.Trees._ -import DottyFlags.FlagSet object factories { import dotty.tools.dotc.ast.tpd._ From 0bfdc911b7f0c505d470f31091e7efb066849ff5 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 10 May 2016 11:59:44 +0200 Subject: [PATCH 035/100] Fix #7, "immutable" package mistaken for "Immutable" trait --- dottydoc/js/src/html/EntityLayout.scala | 2 +- .../tools/dottydoc/html/EntityPage.scala | 19 +++++++++++++++---- .../tools/dottydoc/util/IndexWriters.scala | 4 ++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index 58ca3df49599..fcb0cd5e0c8b 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -12,7 +12,7 @@ case class EntityLayout(entity: Entity) extends MemberLayout { cls := "page-content", div(raw(entity.comment.fold("")(_.body))), entity match { - case e: Entity with Members => + case e: Entity with Members if e.members.nonEmpty => Seq( h5("Members"), div( diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index f74e904eabba..cfac8333df06 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -11,8 +11,14 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { import prickle._ import util.internal.setters._ - private def relPath(to: String, from: Entity) = - "../" * from.path.length + to + private def relPath(to: String, from: Entity) = { + val len = from.path.length + (from match { + case _: Package => 1 + case _ => 0 + }) + + "../" * len + to + } def render = "" + html( head( @@ -76,8 +82,13 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ) ) - private def relativePath(to: Entity) = - util.traversing.relativePath(entity, to) + private def relativePath(to: Entity) = { + val prefix = entity match { + case _: Package => "../" + case _ => "" + } + prefix + util.traversing.relativePath(entity, to) + } def packageView = ul( cls := "mdl-list packages", diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index 1d9631e75dbd..65ed70773325 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -12,8 +12,8 @@ object IndexWriters { println(s"""Writing '${pack.path.mkString(".")}'""") writeFile( EntityPage(pack, packs).render, - outPath + pack.path.dropRight(1).mkString("/", "/", "/"), - s"${pack.name.split("\\.").last}.html") + outPath + pack.path.mkString("/", "/", "/"), + "index.html") for { child <- pack.children From bcc75851c42b1e412767dc77465a145e3fb4b5d5 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 10 May 2016 13:29:56 +0200 Subject: [PATCH 036/100] Add setting for output dir --- dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala | 8 +++++++- dottydoc/jvm/test/WhitelistedStdLibMain.scala | 2 +- src/dotty/tools/dotc/config/ScalaSettings.scala | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 745c8302f331..e569a706a701 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -142,7 +142,13 @@ object Phases { commentParser.parse(packages) // (4) Write the finished model to JSON - if (!ctx.settings.YDocNoWrite.value) util.IndexWriters.writeJs(packages, "../js/out") + val outputDir = { + val out = ctx.settings.DocOutput.value + if (out.last == '/') out.dropRight(1) + else out + } + assert(outputDir == "../js/out") + if (!ctx.settings.YDocNoWrite.value) util.IndexWriters.writeJs(packages, outputDir) // (5) Clear caches commentParser.clear() diff --git a/dottydoc/jvm/test/WhitelistedStdLibMain.scala b/dottydoc/jvm/test/WhitelistedStdLibMain.scala index f4a2f9dc649c..d4c8206a9ef5 100644 --- a/dottydoc/jvm/test/WhitelistedStdLibMain.scala +++ b/dottydoc/jvm/test/WhitelistedStdLibMain.scala @@ -19,5 +19,5 @@ object WhitelistedStandardLib extends DottyDoc { } override def main(args: Array[String]) = - super.main("-language:Scala2" +: files.toArray) + super.main("-language:Scala2" +: "-Ydoc-output" +: "../js/out" +: files.toArray) } diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala index 0cc08d3cddc2..fa4059a9634d 100644 --- a/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -214,6 +214,13 @@ class ScalaSettings extends Settings.SettingGroup { "" ) + val DocOutput = StringSetting ( + "-Ydoc-output", + "outdir", + "The output directory in which to place the documentation", + "." + ) + val DocFooter = StringSetting ( "-Ydoc-footer", "footer", From 926a81c358b58ea09de86f8d55519cc38bc97034 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 11 May 2016 15:57:56 +0200 Subject: [PATCH 037/100] Add option `-Ydoc-output` for specifying output dir --- .gitignore | 1 + .../resources}/MaterialIcons-Regular.eot | Bin .../resources}/MaterialIcons-Regular.ijmap | 0 .../resources}/MaterialIcons-Regular.svg | 0 .../resources}/MaterialIcons-Regular.ttf | Bin .../resources}/MaterialIcons-Regular.woff | Bin .../resources}/MaterialIcons-Regular.woff2 | Bin .../{js/static => jvm/resources}/codepoints | 0 .../{js/static => jvm/resources}/github.css | 0 .../resources}/highlight.pack.js | 0 .../{js/static => jvm/resources}/index.css | 0 .../resources}/material-icons.css | 0 .../static => jvm/resources}/material.min.css | 0 .../static => jvm/resources}/material.min.js | 0 .../dotty/tools/dottydoc/core/Phases.scala | 3 +- .../tools/dottydoc/html/EntityPage.scala | 4 +- .../tools/dottydoc/util/IndexWriters.scala | 47 --------- .../tools/dottydoc/util/OutputWriter.scala | 90 ++++++++++++++++++ dottydoc/jvm/test/WhitelistedStdLibMain.scala | 2 +- project/Build.scala | 9 +- 20 files changed, 100 insertions(+), 56 deletions(-) rename dottydoc/{js/static => jvm/resources}/MaterialIcons-Regular.eot (100%) rename dottydoc/{js/static => jvm/resources}/MaterialIcons-Regular.ijmap (100%) rename dottydoc/{js/static => jvm/resources}/MaterialIcons-Regular.svg (100%) rename dottydoc/{js/static => jvm/resources}/MaterialIcons-Regular.ttf (100%) rename dottydoc/{js/static => jvm/resources}/MaterialIcons-Regular.woff (100%) rename dottydoc/{js/static => jvm/resources}/MaterialIcons-Regular.woff2 (100%) rename dottydoc/{js/static => jvm/resources}/codepoints (100%) rename dottydoc/{js/static => jvm/resources}/github.css (100%) rename dottydoc/{js/static => jvm/resources}/highlight.pack.js (100%) rename dottydoc/{js/static => jvm/resources}/index.css (100%) rename dottydoc/{js/static => jvm/resources}/material-icons.css (100%) rename dottydoc/{js/static => jvm/resources}/material.min.css (100%) rename dottydoc/{js/static => jvm/resources}/material.min.js (100%) delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala diff --git a/.gitignore b/.gitignore index 05f8019612f5..17eba04681ba 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ scala-scala # Ignore output files but keep the directory out/ +build/ !out/.keep # Ignore build-file diff --git a/dottydoc/js/static/MaterialIcons-Regular.eot b/dottydoc/jvm/resources/MaterialIcons-Regular.eot similarity index 100% rename from dottydoc/js/static/MaterialIcons-Regular.eot rename to dottydoc/jvm/resources/MaterialIcons-Regular.eot diff --git a/dottydoc/js/static/MaterialIcons-Regular.ijmap b/dottydoc/jvm/resources/MaterialIcons-Regular.ijmap similarity index 100% rename from dottydoc/js/static/MaterialIcons-Regular.ijmap rename to dottydoc/jvm/resources/MaterialIcons-Regular.ijmap diff --git a/dottydoc/js/static/MaterialIcons-Regular.svg b/dottydoc/jvm/resources/MaterialIcons-Regular.svg similarity index 100% rename from dottydoc/js/static/MaterialIcons-Regular.svg rename to dottydoc/jvm/resources/MaterialIcons-Regular.svg diff --git a/dottydoc/js/static/MaterialIcons-Regular.ttf b/dottydoc/jvm/resources/MaterialIcons-Regular.ttf similarity index 100% rename from dottydoc/js/static/MaterialIcons-Regular.ttf rename to dottydoc/jvm/resources/MaterialIcons-Regular.ttf diff --git a/dottydoc/js/static/MaterialIcons-Regular.woff b/dottydoc/jvm/resources/MaterialIcons-Regular.woff similarity index 100% rename from dottydoc/js/static/MaterialIcons-Regular.woff rename to dottydoc/jvm/resources/MaterialIcons-Regular.woff diff --git a/dottydoc/js/static/MaterialIcons-Regular.woff2 b/dottydoc/jvm/resources/MaterialIcons-Regular.woff2 similarity index 100% rename from dottydoc/js/static/MaterialIcons-Regular.woff2 rename to dottydoc/jvm/resources/MaterialIcons-Regular.woff2 diff --git a/dottydoc/js/static/codepoints b/dottydoc/jvm/resources/codepoints similarity index 100% rename from dottydoc/js/static/codepoints rename to dottydoc/jvm/resources/codepoints diff --git a/dottydoc/js/static/github.css b/dottydoc/jvm/resources/github.css similarity index 100% rename from dottydoc/js/static/github.css rename to dottydoc/jvm/resources/github.css diff --git a/dottydoc/js/static/highlight.pack.js b/dottydoc/jvm/resources/highlight.pack.js similarity index 100% rename from dottydoc/js/static/highlight.pack.js rename to dottydoc/jvm/resources/highlight.pack.js diff --git a/dottydoc/js/static/index.css b/dottydoc/jvm/resources/index.css similarity index 100% rename from dottydoc/js/static/index.css rename to dottydoc/jvm/resources/index.css diff --git a/dottydoc/js/static/material-icons.css b/dottydoc/jvm/resources/material-icons.css similarity index 100% rename from dottydoc/js/static/material-icons.css rename to dottydoc/jvm/resources/material-icons.css diff --git a/dottydoc/js/static/material.min.css b/dottydoc/jvm/resources/material.min.css similarity index 100% rename from dottydoc/js/static/material.min.css rename to dottydoc/jvm/resources/material.min.css diff --git a/dottydoc/js/static/material.min.js b/dottydoc/jvm/resources/material.min.js similarity index 100% rename from dottydoc/js/static/material.min.js rename to dottydoc/jvm/resources/material.min.js diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index e569a706a701..81dc21bbc955 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -147,8 +147,7 @@ object Phases { if (out.last == '/') out.dropRight(1) else out } - assert(outputDir == "../js/out") - if (!ctx.settings.YDocNoWrite.value) util.IndexWriters.writeJs(packages, outputDir) + if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) // (5) Clear caches commentParser.clear() diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index cfac8333df06..84630f214a44 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -12,7 +12,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { import util.internal.setters._ private def relPath(to: String, from: Entity) = { - val len = from.path.length + (from match { + val len = (from.path.length - 1) + (from match { case _: Package => 1 case _ => 0 }) @@ -30,7 +30,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { script(`type` := "text/javascript", src := relPath("static/material.min.js", entity)), script(`type` := "text/javascript", src := relPath("static/highlight.pack.js", entity)), script(`type` := "text/javascript", src := relPath("index.js", entity)), - script(`type` := "text/javascript", src := relPath("target/scala-2.11/dottydoc-fastopt.js", entity)), + script(`type` := "text/javascript", src := relPath("static/dottydoc-fastopt.js", entity)), link(rel := "stylesheet", href := relPath("static/material-icons.css", entity)), link(rel := "stylesheet", href := relPath("static/material.min.css", entity)), link(rel := "stylesheet", href := relPath("static/github.css", entity)), diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala deleted file mode 100644 index 65ed70773325..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ /dev/null @@ -1,47 +0,0 @@ -package dotty.tools.dottydoc -package util - -object IndexWriters { - import html.EntityPage - import model.Package - import model.pickling._ - import prickle._ - - def writeJs(packs: Map[String, Package], outPath: String): Unit = { - for (pack <- packs.values) { - println(s"""Writing '${pack.path.mkString(".")}'""") - writeFile( - EntityPage(pack, packs).render, - outPath + pack.path.mkString("/", "/", "/"), - "index.html") - - for { - child <- pack.children - if child.kind != "package" - } { - println(s"""Writing '${child.path.mkString(".")}'""") - writeFile( - EntityPage(child, packs).render, - outPath + child.path.dropRight(1).mkString("/", "/", "/"), - child.path.last + ".html") - } - } - - val pickled = Pickle.intoString(packs) - val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + pickled + ";" - println("Writing index.js...") - writeFile(js, outPath + "/../", "index.js") - println("Done writing static material, building js-app") - - } - - def writeFile(str: String, path: String, file: String): Unit = { - def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) { - val p = new java.io.PrintWriter(f) - try { op(p) } finally { p.close() } - } - - new java.io.File(path).mkdirs() - printToFile(new java.io.File(path + file))(_.println(str)) - } -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala new file mode 100644 index 000000000000..f2a6c7e95d74 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -0,0 +1,90 @@ +package dotty.tools.dottydoc +package util + + +class OutputWriter { + import java.io.{File => JFile, BufferedInputStream, FileInputStream, FileOutputStream, BufferedOutputStream} + import html.EntityPage + import model.Package + import model.pickling._ + import prickle._ + + def write(packs: Map[String, Package], outPath: String): Unit = { + // Write all packages to `outPath` + for (pack <- packs.values) { + println(s"""Writing '${pack.path.mkString(".")}'""") + writeFile( + EntityPage(pack, packs).render, + outPath + pack.path.mkString("/", "/", "/"), + "index.html") + + // Write all package children to outPath + for { + child <- pack.children + if child.kind != "package" + } { + println(s"""Writing '${child.path.mkString(".")}'""") + writeFile( + EntityPage(child, packs).render, + outPath + child.path.dropRight(1).mkString("/", "/", "/"), + child.path.last + ".html") + } + } + + // Write full index to outPath + val pickled = Pickle.intoString(packs) + val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + pickled + ";" + println("Writing index.js...") + writeFile(js, outPath + "/", "index.js") + + // Write resources to outPath + println("Copying CSS/JS resources to destination...") + assert(resources.nonEmpty) + resources.map(copy(_, outPath)) + + println("Done writing static material, building js-app") + } + + def writeFile(str: String, path: String, file: String): Unit = + writeFile(str.map(_.toByte).toArray, path, file) + + def writeFile(bytes: Array[Byte], path: String, file: String): Unit = { + def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) = { + val bos = new BufferedOutputStream(new FileOutputStream(f)) + try { + Stream.continually(bos.write(bytes)) + } finally bos.close() + } + + new java.io.File(path).mkdirs() + printToFile(new java.io.File(path + file))(printer => bytes.foreach(printer.print)) + } + + def copy(src: JFile, path: String): Unit = { + val reader = new BufferedInputStream(new FileInputStream(src)) + try { + val bytes = Stream.continually(reader.read).takeWhile(-1 != _).map(_.toByte) + writeFile(bytes.toArray, path + "/static/", src.getName) + } finally reader.close() + } + + /** All static resources */ + private val resources: Iterable[JFile] = List( + "/MaterialIcons-Regular.eot", + "/MaterialIcons-Regular.ijmap", + "/MaterialIcons-Regular.svg", + "/MaterialIcons-Regular.ttf", + "/MaterialIcons-Regular.woff", + "/MaterialIcons-Regular.woff2", + "/codepoints", + "/github.css", + "/highlight.pack.js", + "/index.css", + "/material-icons.css", + "/material.min.css", + "/material.min.js", + "/dottydoc-fastopt.js" + ).map { f => + new JFile(this.getClass.getResource(f).toURI) + } +} diff --git a/dottydoc/jvm/test/WhitelistedStdLibMain.scala b/dottydoc/jvm/test/WhitelistedStdLibMain.scala index d4c8206a9ef5..49e8f4fc59b8 100644 --- a/dottydoc/jvm/test/WhitelistedStdLibMain.scala +++ b/dottydoc/jvm/test/WhitelistedStdLibMain.scala @@ -19,5 +19,5 @@ object WhitelistedStandardLib extends DottyDoc { } override def main(args: Array[String]) = - super.main("-language:Scala2" +: "-Ydoc-output" +: "../js/out" +: files.toArray) + super.main("-language:Scala2" +: "-Ydoc-output" +: "../../build/dottydoc" +: files.toArray) } diff --git a/project/Build.scala b/project/Build.scala index add3ebecbe06..e0edd571e8ee 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -278,10 +278,11 @@ object DottyInjectedPlugin extends AutoPlugin { ) lazy val dottydocJVM = dottydoc.jvm.dependsOn(dotty).settings( - resources in Compile += (fastOptJS in (dottydocJS, Compile)).value.data, - scalaSource in Compile := baseDirectory.value / "src", - scalaSource in Test := baseDirectory.value / "test", - javaSource in Test := baseDirectory.value / "test", + resources in Compile += (fastOptJS in (dottydocJS, Compile)).value.data, + resourceDirectory in Compile := baseDirectory.value / "resources", + scalaSource in Compile := baseDirectory.value / "src", + scalaSource in Test := baseDirectory.value / "test", + javaSource in Test := baseDirectory.value / "test", libraryDependencies ++= Seq( "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0", From 59055f28c7f6f3b01216ccbbd701e138101912d3 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 30 May 2016 17:45:32 +0200 Subject: [PATCH 038/100] Add basic member-lookup for result types --- dottydoc/js/src/html/Member.scala | 11 ++- .../dotty/tools/dottydoc/core/Phases.scala | 11 ++- .../dottydoc/model/comment/BodyParsers.scala | 68 ++++++++++--------- .../{CommentParsers.scala => parsers.scala} | 22 +++++- .../tools/dottydoc/util/MemberLookup.scala | 19 ++++-- .../dotty/tools/dottydoc/util/mutate.scala | 11 ++- .../dottydoc/model/comment/BodyEntities.scala | 11 ++- .../dotty/tools/dottydoc/model/entities.scala | 4 +- .../tools/dottydoc/model/factories.scala | 22 +++++- .../dotty/tools/dottydoc/model/internal.scala | 6 +- .../dotty/tools/dottydoc/model/pickling.scala | 16 +++++ .../tools/dottydoc/util/Traversing.scala | 10 ++- 12 files changed, 155 insertions(+), 56 deletions(-) rename dottydoc/jvm/src/dotty/tools/dottydoc/model/{CommentParsers.scala => parsers.scala} (75%) rename dottydoc/{jvm/src => shared/src/main/scala}/dotty/tools/dottydoc/model/comment/BodyEntities.scala (91%) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index a862ffea41bd..ff16631c5362 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -9,6 +9,7 @@ import org.scalajs.dom.html.{Anchor, Div} trait MemberLayout { import model._ + import comment._ def member(m: Entity, parent: Entity) = { def toggleBetween(short: Div, and: Div): Unit = @@ -66,9 +67,15 @@ trait MemberLayout { case xs => s } + def link(rv: MaterializableLink) = rv match { + case ml: MaterializedLink => + span(cls := "return-value", ": ", raw(ml.target)) + case un: UnsetLink => + span(cls := "return-value", ": " + shorten(un.query)) + } + m match { - case v: Val => span(cls := "return-value", ": " + shorten(v.returnValue)) - case d: Def => span(cls := "return-value", ": " + shorten(d.returnValue)) + case rv: ReturnValue => link(rv.returnValue) case _ => span() } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 81dc21bbc955..e4da0a971329 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -13,7 +13,7 @@ import dotc.core.Symbols.Symbol object Phases { class DocPhase extends Phase { - import model.CommentParsers.WikiParser + import model.parsers.{ WikiParser, ReturnTypeParser } import model._ import model.factories._ import model.internal._ @@ -26,6 +26,7 @@ object Phases { def phaseName = "docphase" private[this] val commentParser = new WikiParser + private[this] val returnLinker = new ReturnTypeParser /** Saves the commentParser function for later evaluation, for when the AST has been filled */ def track(symbol: Symbol, ctx: Context)(op: => Entity) = { @@ -79,11 +80,11 @@ object Phases { /** def */ case d: DefDef => - DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d.tpt)) + DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d, d.tpt)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - ValImpl(filteredName(v.name.toString), flags(v), path(v), returnType(v.tpt)) + ValImpl(filteredName(v.name.toString), flags(v), path(v), returnType(v, v.tpt)) case x => { //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") @@ -137,6 +138,10 @@ object Phases { child <- parent.children } setParent(child, to = parent) + + // (3) Set returntypes to correct entities + returnLinker.link(packages) + // (3) Create documentation template from docstrings, with internal links println("Generating documentation, this might take a while...") commentParser.parse(packages) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala index 725d835578f2..8c1fa8d49162 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala @@ -6,37 +6,7 @@ object BodyParsers { implicit class BodyToHtml(val body: Body) extends AnyVal { def toHtml(origin: Entity): String = { - def inlineToHtml(inl: Inline): String = inl match { - case Chain(items) => (items map inlineToHtml).mkString - case Italic(in) => s"${inlineToHtml(in)}" - case Bold(in) => s"${inlineToHtml(in)}" - case Underline(in) => s"${inlineToHtml(in)}" - case Superscript(in) => s"${inlineToHtml(in)}" - case Subscript(in) => s"${inlineToHtml(in) }" - case Link(raw, title) => s"""${inlineToHtml(title)}""" - case Monospace(in) => s"${inlineToHtml(in)}" - case Text(text) => text - case Summary(in) => inlineToHtml(in) - case HtmlTag(tag) => tag - case EntityLink(target, link) => enityLinkToHtml(target, link) - } - - def enityLinkToHtml(target: Inline, link: LinkTo) = link match { - case Tooltip(_) => inlineToHtml(target) - case LinkToExternal(n, url) => s"""$n""" - case LinkToEntity(t: Entity) => t match { - // Entity is a package member - case e: Entity with Members => - s"""${inlineToHtml(target)}""" - // Entity is a Val / Def - case x => x.parent.fold(inlineToHtml(target)) { xpar => - s"""${inlineToHtml(target)}""" - } - } - } - - def relativePath(target: Entity) = - util.traversing.relativePath(origin, target) + val inlineToHtml = InlineToHtml(origin) def bodyToHtml(body: Body): String = (body.blocks map blockToHtml).mkString @@ -73,4 +43,40 @@ object BodyParsers { bodyToHtml(body) } } + + case class InlineToHtml(origin: Entity) { + def apply(inline: Inline) = toHtml(inline) + + def relativePath(target: Entity) = + util.traversing.relativePath(origin, target) + + def toHtml(inline: Inline): String = inline match { + case Chain(items) => (items map toHtml).mkString + case Italic(in) => s"${toHtml(in)}" + case Bold(in) => s"${toHtml(in)}" + case Underline(in) => s"${toHtml(in)}" + case Superscript(in) => s"${toHtml(in)}" + case Subscript(in) => s"${toHtml(in) }" + case Link(raw, title) => s"""${toHtml(title)}""" + case Monospace(in) => s"${toHtml(in)}" + case Text(text) => text + case Summary(in) => toHtml(in) + case HtmlTag(tag) => tag + case EntityLink(target, link) => enityLinkToHtml(target, link) + } + + def enityLinkToHtml(target: Inline, link: LinkTo) = link match { + case Tooltip(_) => toHtml(target) + case LinkToExternal(n, url) => s"""$n""" + case LinkToEntity(t: Entity) => t match { + // Entity is a package member + case e: Entity with Members => + s"""${toHtml(target)}""" + // Entity is a Val / Def + case x => x.parent.fold(toHtml(target)) { xpar => + s"""${toHtml(target)}""" + } + } + } + } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala similarity index 75% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index 9320bb5fee9c..8d5eb3467049 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -4,11 +4,13 @@ package model import dotc.core.Symbols.Symbol import dotc.core.Contexts.Context +import dotc.util.Positions.NoPosition -object CommentParsers { +object parsers { import comment._ import BodyParsers._ import model.internal._ + import util.MemberLookup import util.traversing._ import util.internal.setters._ @@ -81,4 +83,22 @@ object CommentParsers { def clear(): Unit = commentCache = Map.empty } + + class ReturnTypeParser extends MemberLookup { + def link(packs: Map[String, Package]): Unit = + for (pack <- packs.values) mutateEntities(pack) { ent => + if (ent.isInstanceOf[ReturnValue]) + setReturnValue(ent, returnValue(ent, ent.asInstanceOf[ReturnValue], packs)) + } + + private def returnValue(ent: Entity, rv: ReturnValue, packs: Map[String, Package]): MaterializableLink = { + if (rv.returnValue.isInstanceOf[UnsetLink]) { + val unset = rv.returnValue.asInstanceOf[UnsetLink] + val el = makeEntityLink(ent, packs, unset.title, NoPosition, unset.query) + val inlineToHtml = InlineToHtml(ent) + + MaterializedLink(inlineToHtml(unset.title), inlineToHtml(el)) + } else rv.returnValue + } + } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala index f95829caff8f..d8abb0319bcc 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala @@ -30,7 +30,12 @@ trait MemberLookup { /** Looks for the specified entity among `ent`'s members */ def localLookup(ent: Entity with Members, searchStr: String): LinkTo = - ent.members.find(_.name == searchStr).fold(notFound)(e => LinkToEntity(e)) + ent + .members + .collect { case x if x.name == searchStr => x } + .sortBy(_.path.last) + .headOption + .fold(notFound)(e => LinkToEntity(e)) /** Looks for an entity down in the structure, if the search list is Nil, * the search stops @@ -43,8 +48,8 @@ trait MemberLookup { case x :: xs => ent .members - .collect { case e: Entity with Members => e } - .find(_.name == x) + .collect { case e: Entity with Members if e.name == x => e } + .headOption .fold(notFound)(e => downwardLookup(e, xs)) } @@ -71,8 +76,10 @@ trait MemberLookup { localLookup(e, x) case (x :: _, e: Entity with Members) if x == entity.name => downwardLookup(e, querys) - case _ => - globalLookup + case (x :: xs, _) => + if (xs.nonEmpty) + globalLookup + else lookup(entity, packages, "scala." + query, pos) } } @@ -82,5 +89,5 @@ trait MemberLookup { title: Inline, pos: Position, query: String - ): Inline = EntityLink(title, lookup(entity, packages, query, pos)) + ): EntityLink = EntityLink(title, lookup(entity, packages, query, pos)) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala index 798d54041ffa..bbef32474513 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala @@ -4,8 +4,8 @@ package internal object setters { import model._ - import model.comment.Comment - import model.internal._ + import comment.{ Comment, MaterializableLink } + import internal._ def setComment(ent: Entity, to: Option[Comment]) = ent match { case x: PackageImpl => x.comment = to @@ -17,6 +17,13 @@ object setters { case x: ValImpl => x.comment = to } + + def setReturnValue(ent: Entity, to: MaterializableLink) = ent match { + case x: DefImpl => x.returnValue = to + case x: ValImpl => x.returnValue = to + case _ => () + } + def setParent(ent: Entity, to: Entity): Unit = ent match { case e: ClassImpl => e.parent = to diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala similarity index 91% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala rename to dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index f423cf8de99a..c22d7a82f093 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -87,6 +87,15 @@ final case class HtmlTag(data: String) extends Inline { final case class Summary(text: Inline) extends Inline sealed trait LinkTo -final case class LinkToEntity(entity: Entity) extends LinkTo final case class LinkToExternal(name: String, url: String) extends LinkTo final case class Tooltip(name: String) extends LinkTo + +/** Linking directly to entities is not picklable because of cyclic references */ +final case class LinkToEntity(entity: Entity) extends LinkTo + +/** Use MaterializableLink for entities that need be picklable */ +sealed trait MaterializableLink { + def title: Any +} +final case class UnsetLink(title: Inline, query: String) extends MaterializableLink +final case class MaterializedLink(title: String, target: String) extends MaterializableLink diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala index e62b8573a4e9..0ecfd04be7da 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala @@ -1,7 +1,7 @@ package dotty.tools.dottydoc package model -import comment.Comment +import comment.{ Comment, MaterializableLink } trait Entity { def name: String @@ -40,7 +40,7 @@ trait Modifiers { } trait ReturnValue { - def returnValue: String + def returnValue: MaterializableLink } trait Package extends Entity with Members { diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 4707fccff617..ab6ff86d10fd 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -1,6 +1,7 @@ package dotty.tools.dottydoc package model +import comment._ import dotty.tools.dotc import dotc.core.Types._ import dotc.core.Contexts.Context @@ -8,10 +9,13 @@ import dotc.core.Symbols.Symbol import dotc.core.{ Flags => DottyFlags } import dotc.ast.Trees._ + object factories { import dotty.tools.dotc.ast.tpd._ import DottyFlags._ + type TypeTree = dotty.tools.dotc.ast.Trees.Tree[Type] + def flags(t: Tree)(implicit ctx: Context): List[String] = (t.symbol.flags & SourceModifierFlags) .flagStrings.toList @@ -37,11 +41,23 @@ object factories { pathList(ref) } - // TODO: should be updated to link to local entities - def returnType(t: Tree)(implicit ctx: Context): String = - t.show + def returnType(t: Tree, tpt: TypeTree)(implicit ctx: Context): MaterializableLink = { + def cleanTitle(title: String): String = title match { + case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last + case _ => title + } + + def cleanQuery(query: String): String = query match { + case x if x matches "[^\\[]+\\[[^\\]]+\\]" => x.takeWhile(_ != '[') + case _ => query + } + + UnsetLink(Text(cleanTitle(tpt.show)), cleanQuery(tpt.show)) + } def filteredName(str: String) = str .replaceAll("\\$colon", ":") .replaceAll("\\$plus", "+") + .replaceAll("\\$less", "<") + .replaceAll("\\$eq", "=") } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala index 147523662711..7535504b6acd 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -1,7 +1,7 @@ package dotty.tools.dottydoc package model -import comment.Comment +import comment.{ Comment, MaterializableLink } object internal { @@ -55,7 +55,7 @@ object internal { name: String, modifiers: List[String], path: List[String], - returnValue: String, + var returnValue: MaterializableLink, var comment: Option[Comment] = None ) extends Def with Impl @@ -63,7 +63,7 @@ object internal { name: String, modifiers: List[String], path: List[String], - returnValue: String, + var returnValue: MaterializableLink, var comment: Option[Comment] = None ) extends Val with Impl } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala index ea33a05fd0ee..75741bb6b704 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala @@ -4,6 +4,22 @@ package model object pickling { import internal._ import prickle._ + import comment._ + + implicit val inlinePickler: PicklerPair[Inline] = CompositePickler[Inline] + .concreteType[Chain] + .concreteType[Italic] + .concreteType[Bold] + .concreteType[Underline] + .concreteType[Superscript] + .concreteType[Subscript] + .concreteType[Link] + .concreteType[Monospace] + .concreteType[Text] + + implicit val entityLinkPicker: PicklerPair[MaterializableLink] = CompositePickler[MaterializableLink] + .concreteType[UnsetLink] + .concreteType[MaterializedLink] implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity] .concreteType[NonEntity.type] diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala index aca5f41ea358..2ac8eae4f7ce 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala @@ -11,7 +11,13 @@ object traversing { case e: Entity => trans(e) } - def relativePath(from: Entity, to: Entity) = - "../" * (from.path.length - 1) + + def relativePath(from: Entity, to: Entity) = { + val offset = from match { + case _: Val | _: Def => 2 + case _ => 1 + } + + "../" * (from.path.length - offset) + to.path.mkString("", "/", ".html") + } } From 23465a357a84c024ba71f671e08ffc67586a662e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 31 May 2016 09:54:11 +0200 Subject: [PATCH 039/100] Improve return value filtering --- .../src/main/scala/dotty/tools/dottydoc/model/factories.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index ab6ff86d10fd..3e5745a18730 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -44,6 +44,9 @@ object factories { def returnType(t: Tree, tpt: TypeTree)(implicit ctx: Context): MaterializableLink = { def cleanTitle(title: String): String = title match { case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last + case x if x matches "[^\\[]+\\[[^\\]]+\\]" => + val Array(tpe, params) = x.dropRight(1).split("\\[") + s"""$tpe[${params.split(",").map(x => cleanTitle(x.trim)).mkString(", ")}]""" case _ => title } From 4b99e29b7de0bb5725d9e63a2c44f9e633685a6e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 31 May 2016 11:12:40 +0200 Subject: [PATCH 040/100] Change package serialization to go straight to JSON We'll write a facade in Scala.js to handle the unparsed JS-object --- .../src/dotty/tools/dottydoc/model/json.scala | 61 +++++++++++++++++++ .../tools/dottydoc/util/OutputWriter.scala | 14 ++--- project/Build.scala | 1 + 3 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala new file mode 100644 index 000000000000..02d4ecf02119 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -0,0 +1,61 @@ +package dotty.tools.dottydoc +package model + +import spray.json._ + +/** This object provides a protocol for serializing the package AST to JSON, + * this is supposed to be one-way for performance reasons + */ +object json extends DefaultJsonProtocol { + import model._ + import model.comment._ + import model.internal._ + + implicit val commentFormat = jsonFormat2(Comment.apply) + implicit val textFormat: JsonFormat[Text] = lazyFormat(jsonFormat(Text, "text")) + implicit object InlineJsonFormat extends RootJsonFormat[Inline] { + def write(i: Inline) = i match { + case i: Text => i.toJson + case _ => JsString("could not serialize") + } + def read(json: JsValue) = ??? // The json serialization is supposed to be one way + } + + implicit val matLinkFormat = lazyFormat(jsonFormat(MaterializedLink, "title", "target")) + implicit val unsLinkFormat = lazyFormat(jsonFormat(UnsetLink, "title", "query")) + + implicit object MaterializableLinkFormat extends RootJsonFormat[MaterializableLink] { + def write(obj: MaterializableLink) = obj match { + case obj: MaterializedLink => obj.toJson + case obj: UnsetLink => obj.toJson + } + def read(json: JsValue) = ??? // The json serialization is supposed to be one way + } + + implicit object EntityJsonFormat extends RootJsonFormat[Entity] { + def write(e: Entity) = e match { + case e: PackageImpl => e.toJson + case e: ClassImpl => e.toJson + case e: CaseClassImpl => e.toJson + case e: TraitImpl => e.toJson + case e: ObjectImpl => e.toJson + case e: DefImpl => e.toJson + case e: ValImpl => e.toJson + } + def read(json: JsValue) = ??? // The json serialization is supposed to be one way + } + + implicit object PackageFormat extends RootJsonFormat[Package] { + def write(obj: Package) = obj match { case obj: PackageImpl => obj.toJson } + def read(json: JsValue) = ??? // The json serialization is supposed to be one way + } + + implicit val valFormat: JsonFormat[ValImpl] = lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment")) + implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "comment")) + implicit val objFormat: JsonFormat[ObjectImpl] = lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "comment")) + implicit val traitormat: JsonFormat[TraitImpl] = lazyFormat(jsonFormat(TraitImpl, "name", "members", "modifiers", "path", "comment")) + implicit val cclassFormat: JsonFormat[CaseClassImpl] = lazyFormat(jsonFormat(CaseClassImpl, "name", "members", "modifiers", "path", "comment")) + implicit val classFormat: JsonFormat[ClassImpl] = lazyFormat(jsonFormat(ClassImpl, "name", "members", "modifiers", "path", "comment")) + implicit val packageFormat: JsonFormat[PackageImpl] = lazyFormat(jsonFormat(PackageImpl, "name", "members", "path", "comment")) +} + diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala index f2a6c7e95d74..b036a2d3abc7 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -1,14 +1,13 @@ package dotty.tools.dottydoc package util +import java.io.{File => JFile, BufferedInputStream, FileInputStream, FileOutputStream, BufferedOutputStream} +import html.EntityPage +import model.Package +import spray.json._ +import model.json._ class OutputWriter { - import java.io.{File => JFile, BufferedInputStream, FileInputStream, FileOutputStream, BufferedOutputStream} - import html.EntityPage - import model.Package - import model.pickling._ - import prickle._ - def write(packs: Map[String, Package], outPath: String): Unit = { // Write all packages to `outPath` for (pack <- packs.values) { @@ -32,7 +31,8 @@ class OutputWriter { } // Write full index to outPath - val pickled = Pickle.intoString(packs) + //val pickled = Pickle.intoString(packs) + val pickled = packs.toJson val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + pickled + ";" println("Writing index.js...") writeFile(js, outPath + "/", "index.js") diff --git a/project/Build.scala b/project/Build.scala index e0edd571e8ee..48bdd987aa12 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -287,6 +287,7 @@ object DottyInjectedPlugin extends AutoPlugin { libraryDependencies ++= Seq( "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0", "com.github.benhutchison" %% "prickle" % "1.1.10", + "io.spray" %% "spray-json" % "1.3.2", "com.lihaoyi" %% "scalatags" % "0.5.5", "com.novocode" % "junit-interface" % "0.11" % "test" ), From 79133f9454bf56521bb07a4402d3f0a29ab22e81 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 31 May 2016 15:17:02 +0200 Subject: [PATCH 041/100] Add interface for interacting with serialized case classes on frontend --- dottydoc/js/src/DottyDoc.scala | 12 ++-- dottydoc/js/src/EntityIndex.scala | 35 ++++----- dottydoc/js/src/model/entities.scala | 71 +++++++++++++++++++ .../src/dotty/tools/dottydoc/model/json.scala | 19 +++-- 4 files changed, 104 insertions(+), 33 deletions(-) create mode 100644 dottydoc/js/src/model/entities.scala diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index d08bd8cc8088..48989b66c3c2 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -1,10 +1,10 @@ package dotty.tools.dottydoc package js -import scala.scalajs.js -import js.Dynamic.global -import js.JSApp -import js.annotation.{ JSExport, JSName } +import scala.scalajs.{ js => sjs } +import sjs.Dynamic.global +import sjs.JSApp +import sjs.annotation.{ JSExport, JSName } import org.scalajs.dom import dom.document import dom.webworkers.Worker @@ -20,6 +20,6 @@ import html.EntityLayout } /** Library wrapper for highlighting */ -@js.native object hljs extends js.Object { - def initHighlightingOnLoad(): js.Any = js.native +@sjs.native object hljs extends sjs.Object { + def initHighlightingOnLoad(): sjs.Any = sjs.native } diff --git a/dottydoc/js/src/EntityIndex.scala b/dottydoc/js/src/EntityIndex.scala index e58cdf88e652..b6fe1842f3ff 100644 --- a/dottydoc/js/src/EntityIndex.scala +++ b/dottydoc/js/src/EntityIndex.scala @@ -1,35 +1,30 @@ -package dotty.tools.dottydoc +package dotty.tools +package dottydoc package js -import scala.scalajs.js -import js.Dynamic.global -import js.JSApp -import js.annotation.JSName +import scala.scalajs.{ js => sjs } +import sjs.JSConverters._ +import sjs.Dynamic.global +import sjs.JSApp +import sjs.annotation.JSName /** The unpickled AST available as scala classes */ object EntityIndex { - import microjson._ import prickle._ - import model._ - import model.pickling._ + import dottydoc.model.pickling._ + import js.model._ lazy val packages: Map[String, Package] = - //FIXME - //Unpickle[Map[String, Package]] - //.fromString(js.JSON.stringify(Unparsed.packages)) - //.from[js.Object](Unparsed.packages) - //.toOption - None - .getOrElse(Map.empty) + Unparsed.packages.toMap[String, Package] - val currentEntity: Entity = Unpickle[Entity] - .fromString(js.JSON.stringify(Unparsed.currentEntity)) + val currentEntity: dottydoc.model.Entity = Unpickle[dottydoc.model.Entity] + .fromString(sjs.JSON.stringify(Unparsed.currentEntity)) .toOption .get /** Unparsed index stores the pickled AST generated by the dottydoc tool */ - @js.native @JSName("UnparsedIndex") private object Unparsed extends js.Object { - def packages: js.Object = js.native - def currentEntity: js.Object = js.native + @sjs.native @JSName("UnparsedIndex") private object Unparsed extends sjs.Object { + def packages: sjs.Dictionary[Package] = sjs.native + def currentEntity: sjs.Object = sjs.native } } diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala new file mode 100644 index 000000000000..27db4ec0a768 --- /dev/null +++ b/dottydoc/js/src/model/entities.scala @@ -0,0 +1,71 @@ +package dotty.tools +package dottydoc +package js +package model + +import scala.scalajs.{ js => sjs } + +/** This file defines the interface for which to interact with the searchable + * index. To use the normal operations available on the traits on the JVM: + * + * {{{ + * import dotty.tools.dottydoc.js.model.ops._ + * val x: Package = ... + * }}} + * + * Please note that some of the actual fields have not been added to this + * interface, this is simply due to the fact that they're not necessary for + * search - YET. They could be added, for instance `comment` is missing. + */ +@sjs.native +trait Entity extends sjs.Any { + val kind: String = sjs.native + + val name: String = sjs.native + + val path: sjs.Array[String] = sjs.native + + val parent: Entity = sjs.native +} + +@sjs.native +trait Members extends sjs.Any { + val members: sjs.Array[Entity] = sjs.native +} + +@sjs.native +trait Package extends Entity with Members + +@sjs.native +trait Class extends Entity with Members + +@sjs.native +trait CaseClass extends Entity with Members + +@sjs.native +trait Object extends Class + +@sjs.native +trait Trait extends Class + +@sjs.native +trait Def extends Entity + +@sjs.native +trait Val extends Def + +@sjs.native +trait Var extends Def + +object ops { + val EntitiesWithMembers = + "package" :: "case class" :: "class" :: "object" :: "trait" :: Nil + + implicit class PackageOps(val p: Package) { + def children: sjs.Array[Entity with Members] = + p.members.collect { + case x if EntitiesWithMembers contains x.kind => + x.asInstanceOf[Entity with Members] + } + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 02d4ecf02119..ba1438c7a704 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -33,14 +33,19 @@ object json extends DefaultJsonProtocol { } implicit object EntityJsonFormat extends RootJsonFormat[Entity] { + private def addKind(json: JsValue, kind: String): JsValue = json match { + case json: JsObject => JsObject(json.fields + ("kind" -> JsString(kind))) + case other => other + } + def write(e: Entity) = e match { - case e: PackageImpl => e.toJson - case e: ClassImpl => e.toJson - case e: CaseClassImpl => e.toJson - case e: TraitImpl => e.toJson - case e: ObjectImpl => e.toJson - case e: DefImpl => e.toJson - case e: ValImpl => e.toJson + case e: PackageImpl => addKind(e.toJson, "package") + case e: ClassImpl => addKind(e.toJson, "class") + case e: CaseClassImpl => addKind(e.toJson, "case class") + case e: TraitImpl => addKind(e.toJson, "trait") + case e: ObjectImpl => addKind(e.toJson, "object") + case e: DefImpl => addKind(e.toJson, "def") + case e: ValImpl => addKind(e.toJson, "val") } def read(json: JsValue) = ??? // The json serialization is supposed to be one way } From dccfb5bab0047b348b7b0168aec221e3f7939977 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 31 May 2016 15:25:13 +0200 Subject: [PATCH 042/100] Remove parent from fields since it is not serialized --- dottydoc/js/src/model/entities.scala | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 27db4ec0a768..2710a5392817 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -24,8 +24,6 @@ trait Entity extends sjs.Any { val name: String = sjs.native val path: sjs.Array[String] = sjs.native - - val parent: Entity = sjs.native } @sjs.native @@ -33,23 +31,28 @@ trait Members extends sjs.Any { val members: sjs.Array[Entity] = sjs.native } +@sjs.native +trait Modifiers extends sjs.Any { + val modifiers: sjs.Array[String] = sjs.native +} + @sjs.native trait Package extends Entity with Members @sjs.native -trait Class extends Entity with Members +trait Class extends Entity with Members with Modifiers @sjs.native -trait CaseClass extends Entity with Members +trait CaseClass extends Entity with Members with Modifiers @sjs.native -trait Object extends Class +trait Object extends Class with Modifiers @sjs.native trait Trait extends Class @sjs.native -trait Def extends Entity +trait Def extends Entity with Modifiers @sjs.native trait Val extends Def From 756861ed32207b5e1ab7964bcfdbe4165b68723e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 31 May 2016 21:09:51 +0200 Subject: [PATCH 043/100] Add first steps to implementing search --- dottydoc/js/src/DottyDoc.scala | 3 +++ dottydoc/js/src/Search.scala | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 dottydoc/js/src/Search.scala diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index 48989b66c3c2..5773e6a192d8 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -16,6 +16,9 @@ import html.EntityLayout document.title = "Dotty " + EntityIndex.currentEntity.path.mkString(".") target.appendChild(EntityLayout(EntityIndex.currentEntity).html.render) hljs.initHighlightingOnLoad() + + val searchInput = document.getElementById("search").asInstanceOf[dom.html.Input] + searchInput.onkeyup = Search(searchInput) } } diff --git a/dottydoc/js/src/Search.scala b/dottydoc/js/src/Search.scala new file mode 100644 index 000000000000..0683c5d95b5d --- /dev/null +++ b/dottydoc/js/src/Search.scala @@ -0,0 +1,34 @@ +package dotty.tools.dottydoc +package js + +import scala.scalajs.{ js => sjs } +import sjs.timers._ +import org.scalajs.dom + +object Search { + private var isSearching = false + + def apply(input: dom.html.Input) = considerSearch(input) + + def considerSearch(input: dom.html.Input): dom.Event => Unit = { e => + val query = input.value + if (query.length > 2) setTimeout(200) { + if (!isSearching) { + isSearching = true + performSearch(query) + } + } + } + + def performSearch(query: String): Unit = { + println(s"searching for $query...") + + val matchingPackages = EntityIndex.packages.values.collect { + case x if x.name.startsWith(query) => x + } + + println("Found matching packages: ") + matchingPackages.map(_.name).foreach(println) + isSearching = false + } +} From a099344f81ddb0463bbc6da99c376df9f70667df Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 1 Jun 2016 17:23:37 +0200 Subject: [PATCH 044/100] Add basic implementation of toplevel entity search --- dottydoc/js/src/DottyDoc.scala | 2 +- dottydoc/js/src/Search.scala | 115 +++++++++++++++--- dottydoc/js/src/html/EntityLayout.scala | 2 +- dottydoc/js/src/html/Member.scala | 4 +- dottydoc/js/src/model/entities.scala | 50 ++++---- dottydoc/jvm/resources/index.css | 49 ++++++-- .../tools/dottydoc/html/EntityPage.scala | 4 + .../src/dotty/tools/dottydoc/model/json.scala | 11 +- .../tools/dottydoc/util/OutputWriter.scala | 1 - 9 files changed, 181 insertions(+), 57 deletions(-) diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index 5773e6a192d8..d33648e4900b 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -18,7 +18,7 @@ import html.EntityLayout hljs.initHighlightingOnLoad() val searchInput = document.getElementById("search").asInstanceOf[dom.html.Input] - searchInput.onkeyup = Search(searchInput) + searchInput.onkeyup = new Search(searchInput).search() } } diff --git a/dottydoc/js/src/Search.scala b/dottydoc/js/src/Search.scala index 0683c5d95b5d..6625e3c78949 100644 --- a/dottydoc/js/src/Search.scala +++ b/dottydoc/js/src/Search.scala @@ -2,33 +2,120 @@ package dotty.tools.dottydoc package js import scala.scalajs.{ js => sjs } -import sjs.timers._ -import org.scalajs.dom +import sjs.timers.setTimeout +import scalatags.JsDom.all._ +import org.scalajs.dom.html.{ Input, Div } +import org.scalajs.dom.{ document, Event } +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future -object Search { +import js.model._ +import js.model.ops._ + +class Search(val input: Input) { private var isSearching = false - def apply(input: dom.html.Input) = considerSearch(input) + private val mainDiv = document + .getElementById("entity-container") + .asInstanceOf[Div] + private val resultsDiv = document + .getElementById("search-results") + .asInstanceOf[Div] + + /** Search result ADTs */ + private case class PackageResults(matching: Stream[Package], nonMatching: Stream[Package]) + private object PackageResults { + def empty = PackageResults(Stream.empty, Stream.empty) + } - def considerSearch(input: dom.html.Input): dom.Event => Unit = { e => - val query = input.value + /** Entry point into search, will consider whether to start searching or not, + * then call `performSearch` + */ + def search(): Event => Unit = { e => + val query = input.value.trim if (query.length > 2) setTimeout(200) { if (!isSearching) { isSearching = true - performSearch(query) + performSearch(query.toLowerCase).map { _ => isSearching = false } } } + else if (query.length == 0) + hideSearchDiv() } - def performSearch(query: String): Unit = { - println(s"searching for $query...") + private def performSearch(query: String): Future[Unit] = + for (PackageResults(matching, nonMatching) <- searchPackages(query)) yield { + // Clear old results, add new result categories add close button + resultsDiv.innerHTML = "" + val toplevelRes = div(id := "toplevel-results").render + val methodRes = div(id := "method-results").render + val closeButton = button( + id := "close-button", + onclick := { _: Event => + resetInput() + hideSearchDiv() + }, + cls := "mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored", + i(cls := "material-icons", "clear") + ).render + + resultsDiv.appendChild(toplevelRes) + resultsDiv.appendChild(methodRes) + resultsDiv.appendChild(closeButton) + + // Add all matching toplevel entities + matching + .toStream + .sortBy(_.name) + .map(createPackageCard) + .foreach(toplevelRes.appendChild) + + // Hide entity and show results instead + showSearchDiv() + } + + private def searchPackages(query: String): Future[PackageResults] = Future { + EntityIndex.packages.values.foldLeft(PackageResults.empty) { (acc, p) => + val matchingMembers = p.members.collect { + case x if (x.name.toLowerCase.contains(query) && x.kind != "package") => x + } + + println("We found all matching members maybe") + sjs.Dynamic.global.console.log(p) - val matchingPackages = EntityIndex.packages.values.collect { - case x if x.name.startsWith(query) => x + if (p.name.toLowerCase.contains(query) || matchingMembers.nonEmpty) + acc.copy(matching = p.withMembers(matchingMembers) #:: acc.matching) + else acc } + } + + private def createPackageCard(pack: Package): Div = div( + cls := "mdl-card mdl-shadow--2dp package-result", + div(cls := "mdl-card__title", h2(cls := "mdl-card__title-text", pack.name)), + ul(pack.members.map(createEntityLi).toList) + ).render + + private def createEntityLi(e: Entity) = li( + a( + href := toRoot + e.path.mkString("", "/", ".html"), + e.kind + " " + e.name + ) + ) + + private def toRoot = "../" * (EntityIndex.currentEntity.path.length - 1) + + private def resetInput() = { + input.value = "" + input.parentElement.className = input.parentElement.className.replaceAll("is-dirty", "") + } + + private def showSearchDiv() = { + mainDiv.style.display = "none" + resultsDiv.style.display = "block" + } - println("Found matching packages: ") - matchingPackages.map(_.name).foreach(println) - isSearching = false + private def hideSearchDiv() = { + resultsDiv.style.display = "none" + mainDiv.style.display = "block" } } diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index fcb0cd5e0c8b..9a1076a16872 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -5,7 +5,7 @@ package html import scalatags.JsDom.all._ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} -import model._ +import dotty.tools.dottydoc.model._ case class EntityLayout(entity: Entity) extends MemberLayout { def html = div( diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index ff16631c5362..c4989e762b6a 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -8,8 +8,8 @@ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} trait MemberLayout { - import model._ - import comment._ + import dotty.tools.dottydoc.model._ + import dotty.tools.dottydoc.model.comment._ def member(m: Entity, parent: Entity) = { def toggleBetween(short: Div, and: Div): Unit = diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 2710a5392817..4a4984a349f9 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -4,6 +4,7 @@ package js package model import scala.scalajs.{ js => sjs } +import sjs.annotation.ScalaJSDefined /** This file defines the interface for which to interact with the searchable * index. To use the normal operations available on the traits on the JVM: @@ -17,47 +18,47 @@ import scala.scalajs.{ js => sjs } * interface, this is simply due to the fact that they're not necessary for * search - YET. They could be added, for instance `comment` is missing. */ -@sjs.native -trait Entity extends sjs.Any { - val kind: String = sjs.native +@ScalaJSDefined +trait Entity extends sjs.Object { + val kind: String - val name: String = sjs.native + val name: String - val path: sjs.Array[String] = sjs.native + val path: sjs.Array[String] } -@sjs.native -trait Members extends sjs.Any { - val members: sjs.Array[Entity] = sjs.native +@ScalaJSDefined +trait Members extends sjs.Object { + val members: sjs.Array[Entity] } -@sjs.native -trait Modifiers extends sjs.Any { - val modifiers: sjs.Array[String] = sjs.native +@ScalaJSDefined +trait Modifiers extends sjs.Object { + val modifiers: sjs.Array[String] } -@sjs.native +@ScalaJSDefined trait Package extends Entity with Members -@sjs.native +@ScalaJSDefined trait Class extends Entity with Members with Modifiers -@sjs.native -trait CaseClass extends Entity with Members with Modifiers +@ScalaJSDefined +trait CaseClass extends Class -@sjs.native -trait Object extends Class with Modifiers +@ScalaJSDefined +trait Object extends Class -@sjs.native +@ScalaJSDefined trait Trait extends Class -@sjs.native +@ScalaJSDefined trait Def extends Entity with Modifiers -@sjs.native +@ScalaJSDefined trait Val extends Def -@sjs.native +@ScalaJSDefined trait Var extends Def object ops { @@ -70,5 +71,12 @@ object ops { case x if EntitiesWithMembers contains x.kind => x.asInstanceOf[Entity with Members] } + + def withMembers(mbrs: sjs.Array[Entity]): Package = new Package { + val kind = p.kind + val name = p.name + val path = p.path + val members = mbrs + } } } diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index 2be323ae709e..c7292a1a4d4e 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -1,21 +1,10 @@ -main > div.page-content { - padding: 30px 60px; -} - +/* Sidebar ------------------------------------------------------------------ */ span.subtitle { font-size: 12px; line-height: 0 !important; padding-top: 32px; } -div.member { - min-height: 70px; -} - -div.member.member-fullcomment:hover { - cursor: pointer; -} - ul.packages { padding-top: 0 !important; } @@ -106,6 +95,11 @@ span#docs-title { padding-top: 2em; } +/* Entity ------------------------------------------------------------------- */ +main > div.page-content { + padding: 30px 60px; +} + span.member-name, span.return-value { font-family: "Roboto","Helvetica","Arial",sans-serif; font-weight: 400; @@ -114,3 +108,34 @@ span.member-name, span.return-value { letter-spacing: .04em; line-height: 24px; } + +div.member { + min-height: 70px; +} + +div.member.member-fullcomment:hover { + cursor: pointer; +} + +/* Search results ----------------------------------------------------------- */ +main#search-results { + display: none; +} + +/* +main#search-results > div#toplevel-results { + float: left; + width: 50%; +} +*/ + +main#search-results > div#toplevel-results > div.mdl-card.package-result { + margin: 20px auto; + width: 80%; +} + +main#search-results > button#close-button { + position: fixed; + top: 1em; + right: 1em; +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 84630f214a44..8496a11b8510 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -70,6 +70,10 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { main( id := "entity-container", cls := "mdl-layout__content" + ), + main( + id := "search-results", + cls := "mdl-layout__content" ) ) ) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index ba1438c7a704..fef880351f2f 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -33,10 +33,6 @@ object json extends DefaultJsonProtocol { } implicit object EntityJsonFormat extends RootJsonFormat[Entity] { - private def addKind(json: JsValue, kind: String): JsValue = json match { - case json: JsObject => JsObject(json.fields + ("kind" -> JsString(kind))) - case other => other - } def write(e: Entity) = e match { case e: PackageImpl => addKind(e.toJson, "package") @@ -51,10 +47,15 @@ object json extends DefaultJsonProtocol { } implicit object PackageFormat extends RootJsonFormat[Package] { - def write(obj: Package) = obj match { case obj: PackageImpl => obj.toJson } + def write(obj: Package) = obj match { case obj: PackageImpl => addKind(obj.toJson, "package") } def read(json: JsValue) = ??? // The json serialization is supposed to be one way } + private def addKind(json: JsValue, kind: String): JsValue = json match { + case json: JsObject => JsObject(json.fields + ("kind" -> JsString(kind))) + case other => other + } + implicit val valFormat: JsonFormat[ValImpl] = lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment")) implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "comment")) implicit val objFormat: JsonFormat[ObjectImpl] = lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "comment")) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala index b036a2d3abc7..7febb520c63b 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -31,7 +31,6 @@ class OutputWriter { } // Write full index to outPath - //val pickled = Pickle.intoString(packs) val pickled = packs.toJson val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + pickled + ";" println("Writing index.js...") From 091272744ac958e847b408cd30b3bc9978136d0e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 10 Jun 2016 18:17:59 +0200 Subject: [PATCH 045/100] Add type parameters to rendered entity --- dottydoc/js/src/html/Member.scala | 10 ++++++- dottydoc/js/src/model/entities.scala | 17 ++++++++---- .../dotty/tools/dottydoc/core/Phases.scala | 2 +- .../src/dotty/tools/dottydoc/model/json.scala | 2 +- .../dotty/tools/dottydoc/model/entities.scala | 26 ++++++++++--------- .../tools/dottydoc/model/factories.scala | 7 +++++ .../dotty/tools/dottydoc/model/internal.scala | 2 ++ 7 files changed, 46 insertions(+), 20 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index c4989e762b6a..8b6a85e599b5 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -48,7 +48,10 @@ trait MemberLayout { onclick := { () => toggleBetween(shortComment, and = fullComment) }, div( cls := "mdl-cell mdl-cell--12-col", - span(cls := "member-name", m.modifiers.mkString(" ") + " " + m.kind + " " + m.name), + span( + cls := "member-name", + m.modifiers.mkString(" ") + " " + m.kind + " " + m.name + typeParams(m) + ), returnValue(m, parent) ), shortComment, @@ -59,6 +62,11 @@ trait MemberLayout { } } + def typeParams(m: Entity): String = m match { + case d: Def if d.typeParams.nonEmpty => d.typeParams.mkString("[", ", ", "]") + case _ => "" + } + def returnValue(m: Entity with Modifiers, parent: Entity) = { // shortens: "Option.this.A" => "A" def shorten(s: String): String = s.split('.').toList match { diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 4a4984a349f9..1d8c00b2c674 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -21,9 +21,7 @@ import sjs.annotation.ScalaJSDefined @ScalaJSDefined trait Entity extends sjs.Object { val kind: String - val name: String - val path: sjs.Array[String] } @@ -53,13 +51,15 @@ trait Object extends Class trait Trait extends Class @ScalaJSDefined -trait Def extends Entity with Modifiers +trait Def extends Entity with Modifiers { + val typeParams: sjs.Array[String] +} @ScalaJSDefined -trait Val extends Def +trait Val extends Entity with Modifiers @ScalaJSDefined -trait Var extends Def +trait Var extends Entity with Modifiers object ops { val EntitiesWithMembers = @@ -79,4 +79,11 @@ object ops { val members = mbrs } } + + implicit class EntityOps(val ent: Entity) { + def typeParams: sjs.Array[String] = + if (ent.kind == "def") + ent.asInstanceOf[Def].typeParams + else sjs.Array() + } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index e4da0a971329..f620c53c8368 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -80,7 +80,7 @@ object Phases { /** def */ case d: DefDef => - DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d, d.tpt)) + DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d, d.tpt), typeParams(d), paramLists(d)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index fef880351f2f..4a33e57739df 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -57,7 +57,7 @@ object json extends DefaultJsonProtocol { } implicit val valFormat: JsonFormat[ValImpl] = lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment")) - implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "comment")) + implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "paramTypes", "paramLists", "comment")) implicit val objFormat: JsonFormat[ObjectImpl] = lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "comment")) implicit val traitormat: JsonFormat[TraitImpl] = lazyFormat(jsonFormat(TraitImpl, "name", "members", "modifiers", "path", "comment")) implicit val cclassFormat: JsonFormat[CaseClassImpl] = lazyFormat(jsonFormat(CaseClassImpl, "name", "members", "modifiers", "path", "comment")) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala index 0ecfd04be7da..f2f4d9eefbcf 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala @@ -44,13 +44,13 @@ trait ReturnValue { } trait Package extends Entity with Members { - override val kind = "package" + val kind = "package" def children: List[Entity with Members] } trait Class extends Entity with Members with Modifiers { - override val kind = "class" + val kind = "class" } trait CaseClass extends Class { @@ -66,23 +66,25 @@ trait Object extends Class { } trait Def extends Entity with Modifiers with ReturnValue { - override val kind = "def" + def typeParams: List[String] + def paramLists: List[List[(String, MaterializableLink)]] + val kind = "def" } -trait Val extends Def { - override val kind = "val" +trait Val extends Entity with Modifiers with ReturnValue { + val kind = "val" } -trait Var extends Def { - override val kind = "var" +trait Var extends Entity with Modifiers with ReturnValue { + val kind = "var" } trait NonEntity extends Entity { - override val name = "" - override val comment = None - override val path = Nil - override val kind = "" - override val parent = NonEntity + val name = "" + val comment = None + val path = Nil + val kind = "" + val parent = NonEntity } final case object NonEntity extends NonEntity diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 3e5745a18730..a97ee2bb53e5 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -58,6 +58,13 @@ object factories { UnsetLink(Text(cleanTitle(tpt.show)), cleanQuery(tpt.show)) } + def typeParams(t: DefDef)(implicit ctx: Context): List[String] = + t.tparams.map(_.symbol.name.toString) + + def paramLists(t: DefDef)(implicit ctx: Context): List[List[(String, MaterializableLink)]] = { + Nil + } + def filteredName(str: String) = str .replaceAll("\\$colon", ":") .replaceAll("\\$plus", "+") diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala index 7535504b6acd..5d431782e6e1 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -56,6 +56,8 @@ object internal { modifiers: List[String], path: List[String], var returnValue: MaterializableLink, + var typeParams: List[String] = Nil, + var paramLists: List[List[(String, MaterializableLink)]] = Nil, var comment: Option[Comment] = None ) extends Def with Impl From 34590e7b62b58ef0ccbda58dcb4dea69ff492d25 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 13 Jun 2016 11:16:13 +0200 Subject: [PATCH 046/100] Add parameter-lists (text-only) --- dottydoc/js/src/html/Member.scala | 10 ++++++++-- dottydoc/js/src/model/entities.scala | 1 + dottydoc/jvm/resources/index.css | 13 ++++++++++--- .../dotty/tools/dottydoc/model/factories.scala | 6 +++++- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 8b6a85e599b5..d0d2c456057a 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -47,10 +47,10 @@ trait MemberLayout { """, onclick := { () => toggleBetween(shortComment, and = fullComment) }, div( - cls := "mdl-cell mdl-cell--12-col", + cls := "mdl-cell mdl-cell--12-col member-definition", span( cls := "member-name", - m.modifiers.mkString(" ") + " " + m.kind + " " + m.name + typeParams(m) + s"""${m.modifiers.mkString(" ")} ${m.kind} ${m.name}${typeParams(m)}${paramList(m)}""" ), returnValue(m, parent) ), @@ -62,6 +62,12 @@ trait MemberLayout { } } + def paramList(m: Entity): String = m match { + case d: Def if d.paramLists.nonEmpty => + d.paramLists.map(xs => xs map { case (x, y: UnsetLink) => s"$x: ${y.query}" } mkString ("(", ", ", ")")).mkString("") + case _ => "" + } + def typeParams(m: Entity): String = m match { case d: Def if d.typeParams.nonEmpty => d.typeParams.mkString("[", ", ", "]") case _ => "" diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 1d8c00b2c674..a50a0427173c 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -53,6 +53,7 @@ trait Trait extends Class @ScalaJSDefined trait Def extends Entity with Modifiers { val typeParams: sjs.Array[String] + //val paramLists: sjs.Array[sjs.Array[(String, _)]] } @ScalaJSDefined diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index c7292a1a4d4e..4217eb286c26 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -1,3 +1,6 @@ +/* Fonts -------------------------------------------------------------------- */ +@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro); + /* Sidebar ------------------------------------------------------------------ */ span.subtitle { font-size: 12px; @@ -100,12 +103,11 @@ main > div.page-content { padding: 30px 60px; } -span.member-name, span.return-value { - font-family: "Roboto","Helvetica","Arial",sans-serif; +div.member-definition { + font-family: "Source Code Pro", sans-serif; font-weight: 400; font-size: 16px; margin: 24px 0 16px; - letter-spacing: .04em; line-height: 24px; } @@ -117,6 +119,11 @@ div.member.member-fullcomment:hover { cursor: pointer; } +div.full-comment, +div.summary-comment { + margin-left: 0; +} + /* Search results ----------------------------------------------------------- */ main#search-results { display: none; diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index a97ee2bb53e5..2dfc98c4262b 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -62,7 +62,11 @@ object factories { t.tparams.map(_.symbol.name.toString) def paramLists(t: DefDef)(implicit ctx: Context): List[List[(String, MaterializableLink)]] = { - Nil + def getParams(xs: List[ValDef]): List[(String, MaterializableLink)] = xs map { vd => + (vd.name.toString, UnsetLink(Text(vd.tpt.show), vd.tpt.show)) + } + + t.vparamss.map(getParams) } def filteredName(str: String) = str From ffcf17ab0a8d842a2556ae131fbc707306808d63 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 13 Jun 2016 11:58:50 +0200 Subject: [PATCH 047/100] Change function definition to be span based for better granularity --- dottydoc/js/src/html/Member.scala | 27 +++++++++++++++++++++------ dottydoc/jvm/resources/index.css | 15 ++++++++++++++- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index d0d2c456057a..487b7d0c9979 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -48,10 +48,16 @@ trait MemberLayout { onclick := { () => toggleBetween(shortComment, and = fullComment) }, div( cls := "mdl-cell mdl-cell--12-col member-definition", + span( + cls := "member-modifiers-kind", + m.modifiers.mkString(" ") + " " + m.kind + ), span( cls := "member-name", - s"""${m.modifiers.mkString(" ")} ${m.kind} ${m.name}${typeParams(m)}${paramList(m)}""" + m.name ), + spanWith("member-type-params no-left-margin", typeParams(m)), + spanWith("member-param-list no-left-margin", paramList(m)), returnValue(m, parent) ), shortComment, @@ -62,9 +68,18 @@ trait MemberLayout { } } + def spanWith(clazz: String, contents: String) = contents match { + case "" => None + case _ => Some(span(cls := clazz, contents)) + } + def paramList(m: Entity): String = m match { case d: Def if d.paramLists.nonEmpty => - d.paramLists.map(xs => xs map { case (x, y: UnsetLink) => s"$x: ${y.query}" } mkString ("(", ", ", ")")).mkString("") + d.paramLists.map { xs => + xs.map { + case (x, y: UnsetLink) => s"$x: ${y.query}" + }.mkString ("(", ", ", ")") + }.mkString("") case _ => "" } @@ -83,14 +98,14 @@ trait MemberLayout { def link(rv: MaterializableLink) = rv match { case ml: MaterializedLink => - span(cls := "return-value", ": ", raw(ml.target)) + span(cls := "member-return-value no-left-margin", ": ", raw(ml.target)) case un: UnsetLink => - span(cls := "return-value", ": " + shorten(un.query)) + span(cls := "member-return-value no-left-margin", ": " + shorten(un.query)) } m match { - case rv: ReturnValue => link(rv.returnValue) - case _ => span() + case rv: ReturnValue => Some(link(rv.returnValue)) + case _ => None } } } diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index 4217eb286c26..c9622173e989 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -1,5 +1,5 @@ /* Fonts -------------------------------------------------------------------- */ -@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro); +@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700,600); /* Sidebar ------------------------------------------------------------------ */ span.subtitle { @@ -111,6 +111,19 @@ div.member-definition { line-height: 24px; } +div.member-definition > span+span { + margin-left: 10px; +} + +div.member-definition > span.no-left-margin { + margin-left: 0; +} + +div.member-definition > span.member-name { + color: #458; + font-weight: 600; +} + div.member { min-height: 70px; } From 8294dd082088effda892db3e7c63379596e66a29 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 13 Jun 2016 13:44:14 +0200 Subject: [PATCH 048/100] Add type parameters to classes --- dottydoc/js/src/html/EntityLayout.scala | 22 +++++++++++++++++++ dottydoc/jvm/resources/index.css | 22 +++++++++++++++---- .../dotty/tools/dottydoc/core/Phases.scala | 4 ++-- .../src/dotty/tools/dottydoc/model/json.scala | 8 +++---- .../dotty/tools/dottydoc/model/entities.scala | 15 ++++++++----- .../tools/dottydoc/model/factories.scala | 13 +++++++++-- .../dotty/tools/dottydoc/model/internal.scala | 3 +++ 7 files changed, 69 insertions(+), 18 deletions(-) diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index 9a1076a16872..ddd7bd2efd12 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -10,6 +10,7 @@ import dotty.tools.dottydoc.model._ case class EntityLayout(entity: Entity) extends MemberLayout { def html = div( cls := "page-content", + div(cls := "entity-title", entityTitle), div(raw(entity.comment.fold("")(_.body))), entity match { case e: Entity with Members if e.members.nonEmpty => @@ -25,4 +26,25 @@ case class EntityLayout(entity: Entity) extends MemberLayout { case _ => () } ) + + def entityTitle = { + val modifiers = entity match { + case m: Modifiers if m.modifiers.nonEmpty => + Some(span(cls := "entity-modifiers", m.modifiers.mkString(" "))) + case _ => None + } + + val typeParams = entity match { + case t: TypeParams => + Some(span(cls := "entity-type-params no-left-margin", t.typeParams.mkString("[", ", ", "]"))) + case _ => None + } + + modifiers :: + Some(span(cls := "entity-kind", entity.kind)) :: + Some(span(cls := "entity-name", entity.name)) :: + typeParams :: + Nil + + }.flatten } diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index c9622173e989..6d3a06bdd5dd 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -103,6 +103,19 @@ main > div.page-content { padding: 30px 60px; } +div.entity-title { + color: #34495e; + margin: 1.5em 0 1.5em; +} + +div.entity-title > span { + font-size: 2.0em; +} + +div.entity-title > span+span { + margin-left: 9px; +} + div.member-definition { font-family: "Source Code Pro", sans-serif; font-weight: 400; @@ -115,10 +128,6 @@ div.member-definition > span+span { margin-left: 10px; } -div.member-definition > span.no-left-margin { - margin-left: 0; -} - div.member-definition > span.member-name { color: #458; font-weight: 600; @@ -159,3 +168,8 @@ main#search-results > button#close-button { top: 1em; right: 1em; } + +/* Helper classes ----------------------------------------------------------- */ +.no-left-margin { + margin-left: 0 !important; +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index f620c53c8368..64c3319c1d94 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -62,7 +62,7 @@ object Phases { case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => val name = filteredName(n.toString) val newPath = prev :+ name - TraitImpl(name, collectMembers(rhs), flags(t), newPath) + TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t)) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => @@ -73,7 +73,7 @@ object Phases { case c @ TypeDef(n, rhs) if c.symbol.isClass => val name = filteredName(n.toString) val newPath = prev :+ name - (name, collectMembers(rhs), flags(c), newPath, None) match { + (name, collectMembers(rhs), flags(c), newPath, typeParams(c), None) match { case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) case x => ClassImpl.tupled(x) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 4a33e57739df..714d0ef96fc6 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -57,11 +57,11 @@ object json extends DefaultJsonProtocol { } implicit val valFormat: JsonFormat[ValImpl] = lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment")) - implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "paramTypes", "paramLists", "comment")) + implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "typeParams", "paramLists", "comment")) implicit val objFormat: JsonFormat[ObjectImpl] = lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "comment")) - implicit val traitormat: JsonFormat[TraitImpl] = lazyFormat(jsonFormat(TraitImpl, "name", "members", "modifiers", "path", "comment")) - implicit val cclassFormat: JsonFormat[CaseClassImpl] = lazyFormat(jsonFormat(CaseClassImpl, "name", "members", "modifiers", "path", "comment")) - implicit val classFormat: JsonFormat[ClassImpl] = lazyFormat(jsonFormat(ClassImpl, "name", "members", "modifiers", "path", "comment")) + implicit val traitormat: JsonFormat[TraitImpl] = lazyFormat(jsonFormat(TraitImpl, "name", "members", "modifiers", "path", "typeParams", "comment")) + implicit val cclassFormat: JsonFormat[CaseClassImpl] = lazyFormat(jsonFormat(CaseClassImpl, "name", "members", "modifiers", "path", "typeParams", "comment")) + implicit val classFormat: JsonFormat[ClassImpl] = lazyFormat(jsonFormat(ClassImpl, "name", "members", "modifiers", "path", "typeParams", "comment")) implicit val packageFormat: JsonFormat[PackageImpl] = lazyFormat(jsonFormat(PackageImpl, "name", "members", "path", "comment")) } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala index f2f4d9eefbcf..183a7374bda0 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala @@ -39,6 +39,10 @@ trait Modifiers { modifiers.contains("private") } +trait TypeParams { + def typeParams: List[String] +} + trait ReturnValue { def returnValue: MaterializableLink } @@ -49,24 +53,23 @@ trait Package extends Entity with Members { def children: List[Entity with Members] } -trait Class extends Entity with Members with Modifiers { +trait Class extends Entity with Modifiers with TypeParams with Members { val kind = "class" } -trait CaseClass extends Class { +trait CaseClass extends Entity with Modifiers with TypeParams with Members { override val kind = "case class" } -trait Trait extends Class { +trait Trait extends Entity with Modifiers with TypeParams with Members { override val kind = "trait" } -trait Object extends Class { +trait Object extends Entity with Modifiers with Members { override val kind = "object" } -trait Def extends Entity with Modifiers with ReturnValue { - def typeParams: List[String] +trait Def extends Entity with Modifiers with TypeParams with ReturnValue { def paramLists: List[List[(String, MaterializableLink)]] val kind = "def" } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 2dfc98c4262b..0fc66916c35b 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -58,8 +58,17 @@ object factories { UnsetLink(Text(cleanTitle(tpt.show)), cleanQuery(tpt.show)) } - def typeParams(t: DefDef)(implicit ctx: Context): List[String] = - t.tparams.map(_.symbol.name.toString) + def typeParams(t: Tree)(implicit ctx: Context): List[String] = t match { + case t: DefDef => + def variance(s: Symbol) = + if (s is Covariant) "+" + else if (s is Contravariant) "-" + else "" + t.tparams.map(p => variance(p.symbol) + p.show) + case t: TypeDef if t.rhs.isInstanceOf[Template] => + // Get the names from the constructor method `DefDef` + typeParams(t.rhs.asInstanceOf[Template].constr) + } def paramLists(t: DefDef)(implicit ctx: Context): List[List[(String, MaterializableLink)]] = { def getParams(xs: List[ValDef]): List[(String, MaterializableLink)] = xs map { vd => diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala index 5d431782e6e1..f66439c8652b 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -24,6 +24,7 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], + var typeParams: List[String] = Nil, var comment: Option[Comment] = None ) extends Class with Impl @@ -32,6 +33,7 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], + var typeParams: List[String] = Nil, var comment: Option[Comment] = None ) extends CaseClass with Impl @@ -40,6 +42,7 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], + var typeParams: List[String] = Nil, var comment: Option[Comment] = None ) extends Trait with Impl From 76bbb8de91990e5bf2344fbf2f06918c860c4c0e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 13 Jun 2016 17:34:14 +0200 Subject: [PATCH 049/100] Add supertypes to class, cc, obj and trait --- dottydoc/js/src/html/EntityLayout.scala | 14 +++++- .../dotty/tools/dottydoc/core/Phases.scala | 6 +-- .../src/dotty/tools/dottydoc/model/json.scala | 21 +++++--- .../dotty/tools/dottydoc/model/entities.scala | 12 +++-- .../tools/dottydoc/model/factories.scala | 50 +++++++++++++++---- .../dotty/tools/dottydoc/model/internal.scala | 4 ++ 6 files changed, 81 insertions(+), 26 deletions(-) diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index ddd7bd2efd12..3e4777714db7 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -6,6 +6,7 @@ import scalatags.JsDom.all._ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} import dotty.tools.dottydoc.model._ +import dotty.tools.dottydoc.model.comment.{ UnsetLink, Text } case class EntityLayout(entity: Entity) extends MemberLayout { def html = div( @@ -35,15 +36,26 @@ case class EntityLayout(entity: Entity) extends MemberLayout { } val typeParams = entity match { - case t: TypeParams => + case t: TypeParams if t.typeParams.nonEmpty => Some(span(cls := "entity-type-params no-left-margin", t.typeParams.mkString("[", ", ", "]"))) case _ => None } + val superTypes = entity match { + case st: SuperTypes => Some(span( + cls := "entity-super-types", + st.superTypes.collect { + case unset: UnsetLink => unset.title.asInstanceOf[Text].text + }.mkString(" extends ", " with ", "") + )) + case _ => None + } + modifiers :: Some(span(cls := "entity-kind", entity.kind)) :: Some(span(cls := "entity-name", entity.name)) :: typeParams :: + superTypes :: Nil }.flatten diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 64c3319c1d94..d60700acc777 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -62,18 +62,18 @@ object Phases { case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => val name = filteredName(n.toString) val newPath = prev :+ name - TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t)) + TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t), superTypes(t)) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => val name = filteredName(n.toString.dropRight(1)) - ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$")) + ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o)) /** class / case class */ case c @ TypeDef(n, rhs) if c.symbol.isClass => val name = filteredName(n.toString) val newPath = prev :+ name - (name, collectMembers(rhs), flags(c), newPath, typeParams(c), None) match { + (name, collectMembers(rhs), flags(c), newPath, typeParams(c), superTypes(c), None) match { case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) case x => ClassImpl.tupled(x) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 714d0ef96fc6..c355c50cf27c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -56,12 +56,19 @@ object json extends DefaultJsonProtocol { case other => other } - implicit val valFormat: JsonFormat[ValImpl] = lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment")) - implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "typeParams", "paramLists", "comment")) - implicit val objFormat: JsonFormat[ObjectImpl] = lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "comment")) - implicit val traitormat: JsonFormat[TraitImpl] = lazyFormat(jsonFormat(TraitImpl, "name", "members", "modifiers", "path", "typeParams", "comment")) - implicit val cclassFormat: JsonFormat[CaseClassImpl] = lazyFormat(jsonFormat(CaseClassImpl, "name", "members", "modifiers", "path", "typeParams", "comment")) - implicit val classFormat: JsonFormat[ClassImpl] = lazyFormat(jsonFormat(ClassImpl, "name", "members", "modifiers", "path", "typeParams", "comment")) - implicit val packageFormat: JsonFormat[PackageImpl] = lazyFormat(jsonFormat(PackageImpl, "name", "members", "path", "comment")) + implicit val valFormat: JsonFormat[ValImpl] = + lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment")) + implicit val defFormat: JsonFormat[DefImpl] = + lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "typeParams", "paramLists", "comment")) + implicit val objFormat: JsonFormat[ObjectImpl] = + lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "superTypes", "comment")) + implicit val traitormat: JsonFormat[TraitImpl] = + lazyFormat(jsonFormat(TraitImpl, "name", "members", "modifiers", "path", "typeParams", "superTypes", "comment")) + implicit val cclassFormat: JsonFormat[CaseClassImpl] = + lazyFormat(jsonFormat(CaseClassImpl, "name", "members", "modifiers", "path", "typeParams", "superTypes", "comment")) + implicit val classFormat: JsonFormat[ClassImpl] = + lazyFormat(jsonFormat(ClassImpl, "name", "members", "modifiers", "path", "typeParams", "superTypes", "comment")) + implicit val packageFormat: JsonFormat[PackageImpl] = + lazyFormat(jsonFormat(PackageImpl, "name", "members", "path", "comment")) } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala index 183a7374bda0..482c3b755cf1 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala @@ -28,6 +28,10 @@ trait Entity { } } +trait SuperTypes { + def superTypes: List[MaterializableLink] +} + trait Members { def members: List[Entity] } @@ -53,19 +57,19 @@ trait Package extends Entity with Members { def children: List[Entity with Members] } -trait Class extends Entity with Modifiers with TypeParams with Members { +trait Class extends Entity with Modifiers with TypeParams with SuperTypes with Members { val kind = "class" } -trait CaseClass extends Entity with Modifiers with TypeParams with Members { +trait CaseClass extends Entity with Modifiers with TypeParams with SuperTypes with Members { override val kind = "case class" } -trait Trait extends Entity with Modifiers with TypeParams with Members { +trait Trait extends Entity with Modifiers with TypeParams with SuperTypes with Members { override val kind = "trait" } -trait Object extends Entity with Modifiers with Members { +trait Object extends Entity with Modifiers with SuperTypes with Members { override val kind = "object" } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 0fc66916c35b..ff4cc52fe971 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -6,6 +6,8 @@ import dotty.tools.dotc import dotc.core.Types._ import dotc.core.Contexts.Context import dotc.core.Symbols.Symbol +import dotty.tools.dotc.core.SymDenotations._ +import dotty.tools.dotc.core.Names.TypeName import dotc.core.{ Flags => DottyFlags } import dotc.ast.Trees._ @@ -22,18 +24,18 @@ object factories { .filter(_ != "") .filter(_ != "interface") - def path(t: Tree)(implicit ctx: Context): List[String] = { - def pathList(tpe: Type): List[String] = tpe match { - case t: ThisType => - pathList(t.tref) - case t: NamedType if t.prefix == NoPrefix && t.name.toString == "" => - Nil - case t: NamedType if t.prefix == NoPrefix => - t.name.toString :: Nil - case t: NamedType => - pathList(t.prefix) :+ t.name.toString - } + private def pathList(tpe: Type): List[String] = tpe match { + case t: ThisType => + pathList(t.tref) + case t: NamedType if t.prefix == NoPrefix && t.name.toString == "" => + Nil + case t: NamedType if t.prefix == NoPrefix => + t.name.toString :: Nil + case t: NamedType => + pathList(t.prefix) :+ t.name.toString + } + def path(t: Tree)(implicit ctx: Context): List[String] = { val ref = if (t.symbol.isTerm) t.symbol.termRef else t.symbol.typeRef @@ -70,6 +72,32 @@ object factories { typeParams(t.rhs.asInstanceOf[Template].constr) } + val product = """Product[1-9][0-9]*""".r + + def superTypes(t: Tree)(implicit ctx: Context): List[MaterializableLink] = t.symbol.denot match { + case cd: ClassDenotation => + def isJavaLangObject(prefix: Type): Boolean = + prefix match { + case TypeRef(ThisType(TypeRef(NoPrefix, outerName)), innerName) => + outerName.toString == "lang" && innerName.toString == "Object" + case _ => false + } + + def isProductWithArity(prefix: Type): Boolean = prefix match { + case TypeRef(TermRef(TermRef(NoPrefix, root), scala), prod) => + root.toString == "_root_" && + scala.toString == "scala" && + product.findFirstIn(prod.toString).isDefined + case _ => false + } + + cd.classParents.collect { + case t: TypeRef if !isJavaLangObject(t) && !isProductWithArity(t) => + UnsetLink(Text(t.name.toString), pathList(t).mkString(".")) + } + case _ => Nil + } + def paramLists(t: DefDef)(implicit ctx: Context): List[List[(String, MaterializableLink)]] = { def getParams(xs: List[ValDef]): List[(String, MaterializableLink)] = xs map { vd => (vd.name.toString, UnsetLink(Text(vd.tpt.show), vd.tpt.show)) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala index f66439c8652b..78fbcec7eecc 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -25,6 +25,7 @@ object internal { modifiers: List[String], path: List[String], var typeParams: List[String] = Nil, + var superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Class with Impl @@ -34,6 +35,7 @@ object internal { modifiers: List[String], path: List[String], var typeParams: List[String] = Nil, + var superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends CaseClass with Impl @@ -43,6 +45,7 @@ object internal { modifiers: List[String], path: List[String], var typeParams: List[String] = Nil, + var superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Trait with Impl @@ -51,6 +54,7 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], + var superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Object with Impl From 82752b2075f4e68c99a6588eacb11d6fdaa03207 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 13 Jun 2016 17:35:01 +0200 Subject: [PATCH 050/100] Fix value classes not being documented --- dottydoc/js/src/html/EntityLayout.scala | 2 +- dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala | 9 +++++++-- .../scala/dotty/tools/dottydoc/model/factories.scala | 6 ++++++ src/dotty/tools/dotc/typer/FrontEnd.scala | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index 3e4777714db7..37a72c73df04 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -46,7 +46,7 @@ case class EntityLayout(entity: Entity) extends MemberLayout { cls := "entity-super-types", st.superTypes.collect { case unset: UnsetLink => unset.title.asInstanceOf[Text].text - }.mkString(" extends ", " with ", "") + }.mkString("extends ", " with ", "") )) case _ => None } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 1fb93d961ea8..8b4dc5525f00 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -7,7 +7,7 @@ import dotc.config.Printers.dottydoc import dotc.core.Contexts._ import dotc.core.Phases.Phase import dotc.typer.FrontEnd -import dotc.{Compiler, Driver, Run} +import dotc.{ CompilationUnit, Compiler, Driver, Run } import io.PlainFile import scala.util.control.NonFatal @@ -27,7 +27,7 @@ import scala.util.control.NonFatal */ class DottyDocCompiler extends Compiler { override def phases: List[List[Phase]] = - List(new FrontEnd) :: + List(new DocFrontEnd) :: List(new DocPhase) :: Nil @@ -37,6 +37,11 @@ class DottyDocCompiler extends Compiler { } } +class DocFrontEnd extends FrontEnd { + override protected def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) = + unit.isJava +} + class DocRun(comp: Compiler)(implicit ctx: Context) extends Run(comp)(ctx) { def fromDirectory(f: String): List[String] = { val file = new PlainFile(f) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index ff4cc52fe971..b95b0637cd21 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -109,6 +109,12 @@ object factories { def filteredName(str: String) = str .replaceAll("\\$colon", ":") .replaceAll("\\$plus", "+") + .replaceAll("\\$minus", "-") .replaceAll("\\$less", "<") + .replaceAll("\\$greater", ">") .replaceAll("\\$eq", "=") + .replaceAll("\\$bang", "!") + .replaceAll("\\$amp", "&") + .replaceAll("\\$bar", "|") + .replaceAll("\\$up", "^") } diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala index c5c6aec3cd4d..e193b126a09f 100644 --- a/src/dotty/tools/dotc/typer/FrontEnd.scala +++ b/src/dotty/tools/dotc/typer/FrontEnd.scala @@ -57,7 +57,7 @@ class FrontEnd extends Phase { case _ => NoSymbol } - private def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) = + protected def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) = unit.isJava || firstTopLevelDef(unit.tpdTree :: Nil).isPrimitiveValueClass override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { From fdb82c9c90316b171570d15fac1f1b4958874187 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 13 Jun 2016 18:20:12 +0200 Subject: [PATCH 051/100] Remove `filteredName` method in favor for `decode` --- .../dotty/tools/dottydoc/core/Phases.scala | 10 ++-- .../tools/dottydoc/model/factories.scala | 55 +++++++------------ 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index d60700acc777..6cdc851fb6e4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -60,18 +60,18 @@ object Phases { /** trait */ case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => - val name = filteredName(n.toString) + val name = n.decode.toString val newPath = prev :+ name TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t), superTypes(t)) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => - val name = filteredName(n.toString.dropRight(1)) + val name = n.decode.toString.dropRight(1) ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o)) /** class / case class */ case c @ TypeDef(n, rhs) if c.symbol.isClass => - val name = filteredName(n.toString) + val name = n.decode.toString val newPath = prev :+ name (name, collectMembers(rhs), flags(c), newPath, typeParams(c), superTypes(c), None) match { case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) @@ -80,11 +80,11 @@ object Phases { /** def */ case d: DefDef => - DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d, d.tpt), typeParams(d), paramLists(d)) + DefImpl(d.name.decode.toString, flags(d), path(d), returnType(d, d.tpt), typeParams(d), paramLists(d)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - ValImpl(filteredName(v.name.toString), flags(v), path(v), returnType(v, v.tpt)) + ValImpl(v.name.decode.toString, flags(v), path(v), returnType(v, v.tpt)) case x => { //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index b95b0637cd21..82a2204cc17f 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -43,22 +43,23 @@ object factories { pathList(ref) } - def returnType(t: Tree, tpt: TypeTree)(implicit ctx: Context): MaterializableLink = { - def cleanTitle(title: String): String = title match { - case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last - case x if x matches "[^\\[]+\\[[^\\]]+\\]" => - val Array(tpe, params) = x.dropRight(1).split("\\[") - s"""$tpe[${params.split(",").map(x => cleanTitle(x.trim)).mkString(", ")}]""" - case _ => title - } + private val product = """Product[1-9][0-9]*""".r + + private def cleanTitle(title: String): String = title match { + case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last + case x if x matches "[^\\[]+\\[[^\\]]+\\]" => + val Array(tpe, params) = x.dropRight(1).split("\\[") + s"""$tpe[${params.split(",").map(x => cleanTitle(x.trim)).mkString(", ")}]""" + case _ => title + } - def cleanQuery(query: String): String = query match { - case x if x matches "[^\\[]+\\[[^\\]]+\\]" => x.takeWhile(_ != '[') - case _ => query - } + private def cleanQuery(query: String): String = query match { + case x if x matches "[^\\[]+\\[[^\\]]+\\]" => x.takeWhile(_ != '[') + case _ => query + } + def returnType(t: Tree, tpt: TypeTree)(implicit ctx: Context): MaterializableLink = UnsetLink(Text(cleanTitle(tpt.show)), cleanQuery(tpt.show)) - } def typeParams(t: Tree)(implicit ctx: Context): List[String] = t match { case t: DefDef => @@ -72,7 +73,13 @@ object factories { typeParams(t.rhs.asInstanceOf[Template].constr) } - val product = """Product[1-9][0-9]*""".r + def paramLists(t: DefDef)(implicit ctx: Context): List[List[(String, MaterializableLink)]] = { + def getParams(xs: List[ValDef]): List[(String, MaterializableLink)] = xs map { vd => + (vd.name.toString, UnsetLink(Text(vd.tpt.show), vd.tpt.show)) + } + + t.vparamss.map(getParams) + } def superTypes(t: Tree)(implicit ctx: Context): List[MaterializableLink] = t.symbol.denot match { case cd: ClassDenotation => @@ -97,24 +104,4 @@ object factories { } case _ => Nil } - - def paramLists(t: DefDef)(implicit ctx: Context): List[List[(String, MaterializableLink)]] = { - def getParams(xs: List[ValDef]): List[(String, MaterializableLink)] = xs map { vd => - (vd.name.toString, UnsetLink(Text(vd.tpt.show), vd.tpt.show)) - } - - t.vparamss.map(getParams) - } - - def filteredName(str: String) = str - .replaceAll("\\$colon", ":") - .replaceAll("\\$plus", "+") - .replaceAll("\\$minus", "-") - .replaceAll("\\$less", "<") - .replaceAll("\\$greater", ">") - .replaceAll("\\$eq", "=") - .replaceAll("\\$bang", "!") - .replaceAll("\\$amp", "&") - .replaceAll("\\$bar", "|") - .replaceAll("\\$up", "^") } From c6a744681dc729009e8081f51ed0c62d9bcfc18c Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 14 Jun 2016 21:07:20 +0200 Subject: [PATCH 052/100] Implement structure allowing lookup of higher-kinded types --- dottydoc/js/src/html/Member.scala | 48 +++++++++++++++---- .../dotty/tools/dottydoc/core/Phases.scala | 4 +- .../src/dotty/tools/dottydoc/model/json.scala | 17 +++++++ .../dotty/tools/dottydoc/model/parsers.scala | 37 +++++++++----- .../dotty/tools/dottydoc/util/mutate.scala | 8 ++-- .../dottydoc/model/comment/BodyEntities.scala | 11 +++-- .../dotty/tools/dottydoc/model/entities.scala | 6 +-- .../tools/dottydoc/model/factories.scala | 33 +++++++++++-- .../dotty/tools/dottydoc/model/internal.scala | 8 ++-- .../dotty/tools/dottydoc/model/pickling.scala | 7 +++ 10 files changed, 138 insertions(+), 41 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 487b7d0c9979..92c758caf7d1 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -5,7 +5,7 @@ package html import scalatags.JsDom.all._ import scalatags.JsDom.TypedTag import org.scalajs.dom -import org.scalajs.dom.html.{Anchor, Div} +import org.scalajs.dom.html.{Anchor, Div, Span} trait MemberLayout { import dotty.tools.dottydoc.model._ @@ -76,13 +76,22 @@ trait MemberLayout { def paramList(m: Entity): String = m match { case d: Def if d.paramLists.nonEmpty => d.paramLists.map { xs => - xs.map { - case (x, y: UnsetLink) => s"$x: ${y.query}" + xs.map { tr => + // FIXME: should not cast like this - it won't be guaranteed to be a + // TypeReference after Or/Types for paramlists have been implemented + tr.title + ": " + decodeLink(tr.ref.asInstanceOf[TypeReference].tpeLink) }.mkString ("(", ", ", ")") }.mkString("") case _ => "" } + def decodeLink: MaterializableLink => String = { + case MaterializedLink(t, _) => t + case NoLink(t, _) => t + //FIXME: there should be no UnsetLinks - either MaterializedLink or NoLink + case UnsetLink(_, q) => q + } + def typeParams(m: Entity): String = m match { case d: Def if d.typeParams.nonEmpty => d.typeParams.mkString("[", ", ", "]") case _ => "" @@ -96,15 +105,36 @@ trait MemberLayout { case xs => s } - def link(rv: MaterializableLink) = rv match { - case ml: MaterializedLink => - span(cls := "member-return-value no-left-margin", ": ", raw(ml.target)) - case un: UnsetLink => - span(cls := "member-return-value no-left-margin", ": " + shorten(un.query)) + def link(rv: Reference): Span = { + def decodeTpeLink: MaterializableLink => Span = { + case ml: MaterializedLink => + println(s"received tpeLink: $ml") + span(cls := "member-return-value", a(href := ml.target, ml.title)).render + case un: UnsetLink => + span(cls := "member-return-value", shorten(un.query)).render + case no: NoLink => + span(cls := "member-return-value", shorten(no.title)).render + } + + rv match { + case rv: TypeReference => + val returnValue = decodeTpeLink(rv.tpeLink) + + if (rv.paramLinks.nonEmpty) span( + returnValue, + "[", rv.paramLinks.map(decodeTpeLink), "]" //FIXME: does not get spacing and commas + ).render + else returnValue + case _ => ??? /** TODO: should not happen currently, but when + * `returnValue` in factories is changes - this will get + * triggered + */ + } + } m match { - case rv: ReturnValue => Some(link(rv.returnValue)) + case rv: ReturnValue => Some(span(cls := "no-left-margin", ": ", link(rv.returnValue))) case _ => None } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 6cdc851fb6e4..659c23cc3176 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -80,11 +80,11 @@ object Phases { /** def */ case d: DefDef => - DefImpl(d.name.decode.toString, flags(d), path(d), returnType(d, d.tpt), typeParams(d), paramLists(d)) + DefImpl(d.name.decode.toString, flags(d), path(d), returnType(d.tpt), typeParams(d), paramLists(d)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - ValImpl(v.name.decode.toString, flags(v), path(v), returnType(v, v.tpt)) + ValImpl(v.name.decode.toString, flags(v), path(v), returnType(v.tpt)) case x => { //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index c355c50cf27c..bcb51b3d9cb2 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -22,16 +22,33 @@ object json extends DefaultJsonProtocol { } implicit val matLinkFormat = lazyFormat(jsonFormat(MaterializedLink, "title", "target")) + implicit val noLinkFormat = lazyFormat(jsonFormat(NoLink, "title", "target")) implicit val unsLinkFormat = lazyFormat(jsonFormat(UnsetLink, "title", "query")) implicit object MaterializableLinkFormat extends RootJsonFormat[MaterializableLink] { def write(obj: MaterializableLink) = obj match { case obj: MaterializedLink => obj.toJson case obj: UnsetLink => obj.toJson + case obj: NoLink => obj.toJson } def read(json: JsValue) = ??? // The json serialization is supposed to be one way } + implicit object ReferenceFormat extends RootJsonFormat[Reference] { + def write(obj: Reference) = obj match { + case obj: AndTypeReference => obj.toJson + case obj: OrTypeReference => obj.toJson + case obj: TypeReference => obj.toJson + case obj: NamedReference => obj.toJson + } + def read(json: JsValue) = ??? // The json serialization is supposed to be one way + } + + implicit val tpeRefFormat = lazyFormat(jsonFormat(TypeReference, "title", "tpeLink", "paramLinks")) + implicit val orRefFormat = lazyFormat(jsonFormat(OrTypeReference, "left", "right")) + implicit val andRefFormat = lazyFormat(jsonFormat(AndTypeReference, "left", "right")) + implicit val namedRefFormat = lazyFormat(jsonFormat(NamedReference, "title", "ref")) + implicit object EntityJsonFormat extends RootJsonFormat[Entity] { def write(e: Entity) = e match { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index 8d5eb3467049..d73f8fe9f2bd 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -86,19 +86,34 @@ object parsers { class ReturnTypeParser extends MemberLookup { def link(packs: Map[String, Package]): Unit = - for (pack <- packs.values) mutateEntities(pack) { ent => - if (ent.isInstanceOf[ReturnValue]) - setReturnValue(ent, returnValue(ent, ent.asInstanceOf[ReturnValue], packs)) + for (pack <- packs.values) mutateEntities(pack) { + case ent: ReturnValue => + setReturnValue(ent, returnValue(ent, ent, packs)) + case _ => () } - private def returnValue(ent: Entity, rv: ReturnValue, packs: Map[String, Package]): MaterializableLink = { - if (rv.returnValue.isInstanceOf[UnsetLink]) { - val unset = rv.returnValue.asInstanceOf[UnsetLink] - val el = makeEntityLink(ent, packs, unset.title, NoPosition, unset.query) - val inlineToHtml = InlineToHtml(ent) + private def returnValue(ent: Entity, rv: ReturnValue, packs: Map[String, Package]): Reference = + rv.returnValue match { + case rv @ TypeReference(_, UnsetLink(t, query), tps) => + val inlineToHtml = InlineToHtml(ent) + val title = inlineToHtml(t) - MaterializedLink(inlineToHtml(unset.title), inlineToHtml(el)) - } else rv.returnValue - } + def handleEntityLink(title: String, lt: LinkTo): MaterializableLink = lt match { + case Tooltip(str) => NoLink(title, str) + case LinkToExternal(_, url) => MaterializedLink(title, url) + case LinkToEntity(target) => MaterializedLink(title, util.traversing.relativePath(ent, target)) + } + + val target = handleEntityLink(title, makeEntityLink(ent, packs, t, NoPosition, query).link) + + val tpTargets = tps.map { + case UnsetLink(t, query) => + handleEntityLink(inlineToHtml(t), makeEntityLink(ent, packs, t, NoPosition, query).link) + case x => x + } + + rv.copy(tpeLink = target, paramLinks = tpTargets) + case _ => rv.returnValue + } } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala index bbef32474513..e6f1e6245064 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala @@ -4,7 +4,7 @@ package internal object setters { import model._ - import comment.{ Comment, MaterializableLink } + import comment.{ Comment, MaterializableLink, Reference } import internal._ def setComment(ent: Entity, to: Option[Comment]) = ent match { @@ -18,9 +18,9 @@ object setters { } - def setReturnValue(ent: Entity, to: MaterializableLink) = ent match { - case x: DefImpl => x.returnValue = to - case x: ValImpl => x.returnValue = to + def setReturnValue(ent: Entity, ref: Reference) = ent match { + case x: DefImpl => x.returnValue = ref + case x: ValImpl => x.returnValue = ref case _ => () } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index c22d7a82f093..bd082ef1e3b3 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -94,8 +94,13 @@ final case class Tooltip(name: String) extends LinkTo final case class LinkToEntity(entity: Entity) extends LinkTo /** Use MaterializableLink for entities that need be picklable */ -sealed trait MaterializableLink { - def title: Any -} +sealed trait MaterializableLink { def title: Any } final case class UnsetLink(title: Inline, query: String) extends MaterializableLink final case class MaterializedLink(title: String, target: String) extends MaterializableLink +final case class NoLink(title: String, target: String) extends MaterializableLink + +sealed trait Reference +final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[MaterializableLink]) extends Reference +final case class OrTypeReference(left: Reference, right: Reference) extends Reference +final case class AndTypeReference(left: Reference, right: Reference) extends Reference +final case class NamedReference(title: String, ref: Reference) extends Reference diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala index 482c3b755cf1..6f6f1e0b7b12 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala @@ -1,7 +1,7 @@ package dotty.tools.dottydoc package model -import comment.{ Comment, MaterializableLink } +import comment.{ Comment, MaterializableLink, Reference, NamedReference } trait Entity { def name: String @@ -48,7 +48,7 @@ trait TypeParams { } trait ReturnValue { - def returnValue: MaterializableLink + def returnValue: Reference } trait Package extends Entity with Members { @@ -74,7 +74,7 @@ trait Object extends Entity with Modifiers with SuperTypes with Members { } trait Def extends Entity with Modifiers with TypeParams with ReturnValue { - def paramLists: List[List[(String, MaterializableLink)]] + def paramLists: List[List[NamedReference]] val kind = "def" } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 82a2204cc17f..c665768960f4 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -46,7 +46,9 @@ object factories { private val product = """Product[1-9][0-9]*""".r private def cleanTitle(title: String): String = title match { + // matches Entity.this.Something case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last + // Matches Entity[P, ...] case x if x matches "[^\\[]+\\[[^\\]]+\\]" => val Array(tpe, params) = x.dropRight(1).split("\\[") s"""$tpe[${params.split(",").map(x => cleanTitle(x.trim)).mkString(", ")}]""" @@ -58,8 +60,26 @@ object factories { case _ => query } - def returnType(t: Tree, tpt: TypeTree)(implicit ctx: Context): MaterializableLink = - UnsetLink(Text(cleanTitle(tpt.show)), cleanQuery(tpt.show)) + def returnType(t: TypeTree)(implicit ctx: Context): Reference = { + def tpeWithParamTpes(t: Type): List[String] = t match { + case ref @ RefinedType(parent, rn) => + val name = ref.refinedInfo match { + case ta: TypeAlias => ta.alias.asInstanceOf[NamedType].name.decode.toString + case _ => rn.decode.toString.split("\\$").last + } + tpeWithParamTpes(parent) ++ (name :: Nil) + case TypeRef(_, name) => name.decode.toString :: Nil + case OrType(left, right) => "ortype" :: Nil + case AndType(left, right) => "andtype" :: Nil + case AnnotatedType(tpe, _) => tpeWithParamTpes(tpe) + case c: ConstantType => c.show :: Nil + } + + val List(retTpe, params @ _*) = tpeWithParamTpes(t.tpe) + + //TODO: should not be a TypeReference but a Reference because of Or/And-types + TypeReference(retTpe, UnsetLink(Text(retTpe), retTpe), params.map(x => UnsetLink(Text(x), x)).toList) + } def typeParams(t: Tree)(implicit ctx: Context): List[String] = t match { case t: DefDef => @@ -73,9 +93,12 @@ object factories { typeParams(t.rhs.asInstanceOf[Template].constr) } - def paramLists(t: DefDef)(implicit ctx: Context): List[List[(String, MaterializableLink)]] = { - def getParams(xs: List[ValDef]): List[(String, MaterializableLink)] = xs map { vd => - (vd.name.toString, UnsetLink(Text(vd.tpt.show), vd.tpt.show)) + def paramLists(t: DefDef)(implicit ctx: Context): List[List[NamedReference]] = { + def getParams(xs: List[ValDef]): List[NamedReference] = xs map { vd => + val name = vd.name.decode.toString + //TODO: should not be a TypeReference but a Reference since the argument can be an Or/And-types + val ref = TypeReference(name, UnsetLink(Text(vd.tpt.show), vd.tpt.show), Nil) + NamedReference(name, ref) } t.vparamss.map(getParams) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala index 78fbcec7eecc..0c204c06691b 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -1,7 +1,7 @@ package dotty.tools.dottydoc package model -import comment.{ Comment, MaterializableLink } +import comment.{ Comment, MaterializableLink, Reference, NamedReference } object internal { @@ -62,9 +62,9 @@ object internal { name: String, modifiers: List[String], path: List[String], - var returnValue: MaterializableLink, + var returnValue: Reference, var typeParams: List[String] = Nil, - var paramLists: List[List[(String, MaterializableLink)]] = Nil, + var paramLists: List[List[NamedReference]] = Nil, var comment: Option[Comment] = None ) extends Def with Impl @@ -72,7 +72,7 @@ object internal { name: String, modifiers: List[String], path: List[String], - var returnValue: MaterializableLink, + var returnValue: Reference, var comment: Option[Comment] = None ) extends Val with Impl } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala index 75741bb6b704..3ef4ab4a92be 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala @@ -19,8 +19,15 @@ object pickling { implicit val entityLinkPicker: PicklerPair[MaterializableLink] = CompositePickler[MaterializableLink] .concreteType[UnsetLink] + .concreteType[NoLink] .concreteType[MaterializedLink] + implicit val referencePicker: PicklerPair[Reference] = CompositePickler[Reference] + .concreteType[TypeReference] + .concreteType[OrTypeReference] + .concreteType[AndTypeReference] + .concreteType[NamedReference] + implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity] .concreteType[NonEntity.type] .concreteType[ValImpl] From cedbb785ebe615c26d60b3660a6b098be8f78e16 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 22 Jun 2016 11:09:49 +0200 Subject: [PATCH 053/100] Complete proper structure for return types Return types now consist of: - TypeReference (containing all type information) - OrTypeReference/AndTypeReference - ConstantReference Instead of being simply a TypeReference --- dottydoc/js/src/html/Member.scala | 27 +++++++++--- dottydoc/jvm/resources/index.css | 5 +++ .../src/dotty/tools/dottydoc/model/json.scala | 10 +++-- .../dottydoc/model/comment/BodyEntities.scala | 1 + .../tools/dottydoc/model/factories.scala | 43 ++++++++++++------- .../dotty/tools/dottydoc/model/pickling.scala | 1 + 6 files changed, 62 insertions(+), 25 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 92c758caf7d1..4ab214fdb7fe 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -122,15 +122,30 @@ trait MemberLayout { if (rv.paramLinks.nonEmpty) span( returnValue, - "[", rv.paramLinks.map(decodeTpeLink), "]" //FIXME: does not get spacing and commas + "[", + rv.paramLinks + .map(decodeTpeLink) + .flatMap { sp => + Seq(sp, span(cls := "type-separator no-left-margin", ",").render) + } + .dropRight(1), + "]" ).render else returnValue - case _ => ??? /** TODO: should not happen currently, but when - * `returnValue` in factories is changes - this will get - * triggered - */ - } + case OrTypeReference(left, right) => span( + cls := "member-return-value or-type", + link(left), + span(cls := "type-separator", "|"), + link(right) + ).render + case AndTypeReference(left, right) => span( + cls := "member-return-value and-type", + link(left), + span(cls := "type-separator", "&"), + link(right) + ).render + } } m match { diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index 6d3a06bdd5dd..e68cf5ac5527 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -146,6 +146,11 @@ div.summary-comment { margin-left: 0; } +span.member-return-value > span.type-separator { + margin: 0 10px; +} + + /* Search results ----------------------------------------------------------- */ main#search-results { display: none; diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index bcb51b3d9cb2..71ed12cecdb8 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -36,10 +36,11 @@ object json extends DefaultJsonProtocol { implicit object ReferenceFormat extends RootJsonFormat[Reference] { def write(obj: Reference) = obj match { - case obj: AndTypeReference => obj.toJson - case obj: OrTypeReference => obj.toJson - case obj: TypeReference => obj.toJson - case obj: NamedReference => obj.toJson + case obj: AndTypeReference => obj.toJson + case obj: OrTypeReference => obj.toJson + case obj: TypeReference => obj.toJson + case obj: NamedReference => obj.toJson + case obj: ConstantReference => obj.toJson } def read(json: JsValue) = ??? // The json serialization is supposed to be one way } @@ -48,6 +49,7 @@ object json extends DefaultJsonProtocol { implicit val orRefFormat = lazyFormat(jsonFormat(OrTypeReference, "left", "right")) implicit val andRefFormat = lazyFormat(jsonFormat(AndTypeReference, "left", "right")) implicit val namedRefFormat = lazyFormat(jsonFormat(NamedReference, "title", "ref")) + implicit val constRefFormat = lazyFormat(jsonFormat(ConstantReference, "title")) implicit object EntityJsonFormat extends RootJsonFormat[Entity] { diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index bd082ef1e3b3..37f1b05feb9a 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -104,3 +104,4 @@ final case class TypeReference(title: String, tpeLink: MaterializableLink, param final case class OrTypeReference(left: Reference, right: Reference) extends Reference final case class AndTypeReference(left: Reference, right: Reference) extends Reference final case class NamedReference(title: String, ref: Reference) extends Reference +final case class ConstantReference(title: String) extends Reference diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index c665768960f4..e6a548b0fa54 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -61,24 +61,37 @@ object factories { } def returnType(t: TypeTree)(implicit ctx: Context): Reference = { - def tpeWithParamTpes(t: Type): List[String] = t match { - case ref @ RefinedType(parent, rn) => - val name = ref.refinedInfo match { - case ta: TypeAlias => ta.alias.asInstanceOf[NamedType].name.decode.toString - case _ => rn.decode.toString.split("\\$").last + def typeRef(name: String, params: List[MaterializableLink]) = + TypeReference(name, UnsetLink(Text(name), name), params) + + def expandTpe(t: Type, params: List[MaterializableLink] = Nil): Reference = t match { + case ref @ RefinedType(parent, rn) => { + val paramName = ref.refinedInfo match { + case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => + ta.alias.asInstanceOf[NamedType].name.decode.toString + case _ => + rn.decode.toString.split("\\$").last } - tpeWithParamTpes(parent) ++ (name :: Nil) - case TypeRef(_, name) => name.decode.toString :: Nil - case OrType(left, right) => "ortype" :: Nil - case AndType(left, right) => "andtype" :: Nil - case AnnotatedType(tpe, _) => tpeWithParamTpes(tpe) - case c: ConstantType => c.show :: Nil + val param = UnsetLink(Text(paramName), paramName) + expandTpe(parent, param :: params) + } + case TypeRef(_, name) => + typeRef(name.decode.toString, params) + case OrType(left, right) => + OrTypeReference(expandTpe(left), expandTpe(right)) + case AndType(left, right) => + AndTypeReference(expandTpe(left), expandTpe(right)) + case AnnotatedType(tpe, _) => + expandTpe(tpe) + case ExprType(tpe) => + expandTpe(tpe) + case c: ConstantType => + ConstantReference(c.show) + case tt: ThisType => + expandTpe(tt.underlying) } - val List(retTpe, params @ _*) = tpeWithParamTpes(t.tpe) - - //TODO: should not be a TypeReference but a Reference because of Or/And-types - TypeReference(retTpe, UnsetLink(Text(retTpe), retTpe), params.map(x => UnsetLink(Text(x), x)).toList) + expandTpe(t.tpe) } def typeParams(t: Tree)(implicit ctx: Context): List[String] = t match { diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala index 3ef4ab4a92be..76a2effa6a42 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala @@ -27,6 +27,7 @@ object pickling { .concreteType[OrTypeReference] .concreteType[AndTypeReference] .concreteType[NamedReference] + .concreteType[ConstantReference] implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity] .concreteType[NonEntity.type] From a72763749ac8b7869619ec3a7d2c8e5095229309 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 22 Jun 2016 11:48:27 +0200 Subject: [PATCH 054/100] Fix proper structure for paramlist links (clientside) --- dottydoc/js/src/html/Member.scala | 70 +++++++++++++++---- dottydoc/jvm/resources/index.css | 2 +- .../tools/dottydoc/model/factories.scala | 8 +-- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 4ab214fdb7fe..a8da9d126227 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -57,7 +57,7 @@ trait MemberLayout { m.name ), spanWith("member-type-params no-left-margin", typeParams(m)), - spanWith("member-param-list no-left-margin", paramList(m)), + span(cls := "member-param-list no-left-margin", paramList(m)), returnValue(m, parent) ), shortComment, @@ -73,23 +73,63 @@ trait MemberLayout { case _ => Some(span(cls := clazz, contents)) } - def paramList(m: Entity): String = m match { + def paramList(m: Entity): Span = m match { case d: Def if d.paramLists.nonEmpty => - d.paramLists.map { xs => - xs.map { tr => - // FIXME: should not cast like this - it won't be guaranteed to be a - // TypeReference after Or/Types for paramlists have been implemented - tr.title + ": " + decodeLink(tr.ref.asInstanceOf[TypeReference].tpeLink) - }.mkString ("(", ", ", ")") - }.mkString("") - case _ => "" + span( + cls := "member-param-lists", + d.paramLists.map { xs => + span( + cls := "param-list", + "(", + xs.flatMap { tr => + Seq( + span(cls := "param-name", tr.title).render, + span(cls := "type-separator no-left-margin", ":").render, + span(referenceToLinks(tr.ref)).render, + span(cls := "type-separator no-left-margin", ",").render + ) + }.dropRight(1), + ")" + ).render + } + ).render + case _ => span().render } - def decodeLink: MaterializableLink => String = { - case MaterializedLink(t, _) => t - case NoLink(t, _) => t - //FIXME: there should be no UnsetLinks - either MaterializedLink or NoLink - case UnsetLink(_, q) => q + def referenceToLinks(ref: Reference): Span = { + def linkToAnchor(link: MaterializableLink) = link match { + case MaterializedLink(t, url) => a(href := url, t).render + case NoLink(t, _) => span(t).render + + //FIXME: there should be no UnsetLinks - either MaterializedLink or NoLink + case UnsetLink(_, q) => span(q).render + } + + ref match { + case ref: TypeReference if ref.paramLinks.nonEmpty => span( + linkToAnchor(ref.tpeLink), + "[", + ref + .paramLinks + .map(linkToAnchor) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)) + .dropRight(1), + "]" + ).render + case ref: TypeReference => span(linkToAnchor(ref.tpeLink)).render + + case OrTypeReference(left, right) => span( + referenceToLinks(left), + span(cls := "type-separator", "|"), + referenceToLinks(right) + ).render + + case AndTypeReference(left, right) => span( + referenceToLinks(left), + span(cls := "type-separator", "&"), + referenceToLinks(right) + ).render + } } def typeParams(m: Entity): String = m match { diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index e68cf5ac5527..47e0ea7173d4 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -146,7 +146,7 @@ div.summary-comment { margin-left: 0; } -span.member-return-value > span.type-separator { +span.type-separator { margin: 0 10px; } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index e6a548b0fa54..e8d453842059 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -107,12 +107,8 @@ object factories { } def paramLists(t: DefDef)(implicit ctx: Context): List[List[NamedReference]] = { - def getParams(xs: List[ValDef]): List[NamedReference] = xs map { vd => - val name = vd.name.decode.toString - //TODO: should not be a TypeReference but a Reference since the argument can be an Or/And-types - val ref = TypeReference(name, UnsetLink(Text(vd.tpt.show), vd.tpt.show), Nil) - NamedReference(name, ref) - } + def getParams(xs: List[ValDef]): List[NamedReference] = + xs.map(vd => NamedReference(vd.name.decode.toString, returnType(vd.tpt))) t.vparamss.map(getParams) } From d451f903ef2b858118c61990b582b0927b12f71d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 23 Jun 2016 18:21:13 +0200 Subject: [PATCH 055/100] Add implicitly added methods to entity documentation --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 17 +- .../dottydoc/core/AddImplicitsPhase.scala | 30 +++ .../dotty/tools/dottydoc/core/DocPhase.scala | 185 ++++++++++++++++++ .../dotty/tools/dottydoc/core/Phases.scala | 165 ---------------- dottydoc/jvm/test/BaseTest.scala | 2 +- .../tools/dottydoc/model/factories.scala | 58 +++--- 6 files changed, 257 insertions(+), 200 deletions(-) create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 8b4dc5525f00..db2a394beea1 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -1,7 +1,7 @@ package dotty.tools package dottydoc -import core.Phases.DocPhase +import core.{ AddImplicitsPhase, DocPhase } import dotc.config.CompilerCommand import dotc.config.Printers.dottydoc import dotc.core.Contexts._ @@ -28,6 +28,7 @@ import scala.util.control.NonFatal class DottyDocCompiler extends Compiler { override def phases: List[List[Phase]] = List(new DocFrontEnd) :: + List(new AddImplicitsPhase) :: List(new DocPhase) :: Nil @@ -37,6 +38,20 @@ class DottyDocCompiler extends Compiler { } } +/** TODO: this object is only temporary, should be factored out, just wanted it to demo dottydoc */ +object ImplicitlyAdded { + import dotc.core.Symbols.Symbol + import dotc.ast.tpd.DefDef + import scala.collection.mutable + + private var _defs: Map[Symbol, Set[Symbol]] = Map.empty + def defs(sym: Symbol): Set[Symbol] = _defs.get(sym).getOrElse(Set.empty) + + def addDef(s: Symbol, d: Symbol): Unit = _defs = (_defs + { + s -> _defs.get(s).map(xs => xs + d).getOrElse(Set(d)) + }) +} + class DocFrontEnd extends FrontEnd { override protected def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) = unit.isJava diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala new file mode 100644 index 000000000000..3ee6082b69b0 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala @@ -0,0 +1,30 @@ +package dotty.tools +package dottydoc +package core + +import dotty.tools.dotc.transform.TreeTransforms.{ MiniPhaseTransform, TransformerInfo } +import dotty.tools.dotc.core.Flags +import dotc.core.Contexts.Context + +class AddImplicitsPhase extends MiniPhaseTransform { thisTransformer => + import dotty.tools.dotc.ast.tpd._ + + def phaseName = "addImplicitsPhase" + + override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = { + if ( + tree.symbol.is(Flags.Implicit) && // has to have an implicit flag + tree.symbol.owner.isStaticOwner && // owner has to be static (e.g. top-level `object`) + tree.vparamss.length > 0 && + tree.vparamss(0).length == 1 // should only take one arg, since it has to be a transformation + ) { + val convertee = tree.vparamss(0)(0).symbol.info.widenDealias.finalResultType.typeSymbol//denot.typeRef // the pimped type (i.e. `class`) + println(s"Adding methods from ${tree.symbol.info.widenDealias.finalResultType.typeSymbol} to ${convertee}") + //println(s" ${tree.denot.info} ${tree.vparamss(0)(0).denot.info}") + //ImplicitlyAdded.addDef(convertee, tree) + ImplicitlyAdded.addDef(convertee, tree.symbol.info.widenDealias.finalResultType.typeSymbol) + } + + tree + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala new file mode 100644 index 000000000000..b5386be96f7b --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala @@ -0,0 +1,185 @@ +package dotty.tools +package dottydoc +package core + +/** Dotty and Dottydoc imports */ +import dotc.ast.Trees._ +import dotc.CompilationUnit +import dotc.config.Printers.dottydoc +import dotc.core.Contexts.Context +import dotc.core.Phases.Phase +import dotc.core.Symbols.Symbol + +class DocPhase extends Phase { + import model.parsers.{ WikiParser, ReturnTypeParser } + import model._ + import model.factories._ + import model.internal._ + import model.comment.Comment + import dotty.tools.dotc.core.Flags + import dotty.tools.dotc.ast.tpd._ + import util.traversing._ + import util.internal.setters._ + + def phaseName = "docphase" + + private[this] val commentParser = new WikiParser + private[this] val returnLinker = new ReturnTypeParser + + /** Saves the commentParser function for later evaluation, for when the AST has been filled */ + def track(symbol: Symbol, ctx: Context)(op: => Entity) = { + val entity = op + + if (entity != NonEntity) + commentParser += (entity, symbol, ctx) + + entity + } + + /** Build documentation hierarchy from existing tree */ + def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { + val implicitlyAddedMembers = ImplicitlyAdded.defs(tree.symbol)//denot.info) + + def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = + xs.map(collect(_, ps)).filter(_ != NonEntity) + + def collectEntityMembers(xs: List[Tree], ps: List[String])(implicit ctx: Context) = + collectList(xs, ps).asInstanceOf[List[Entity with Members]] + + /** TODO: should be a set, not a uniqued list */ + def collectMembers(tree: Tree, ps: List[String] = prev)(implicit ctx: Context): List[Entity] = { + val defs = (tree match { + case t: Template => collectList(t.body, ps) + case _ => Nil + }) ++ implicitlyAddedMembers.flatMap(defFromSymbol) + + defs + } + + def defFromSymbol(sym: Symbol): List[Entity] = { + val defs = sym.info.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => + track(sym, ctx) { + println(meth.show) + DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), Nil/*paramLists(???)*/) + } + }.toList + + println(s"Implicitly added to ${tree.symbol.show}:") + defs.foreach(println) + println("-------") + defs + } + + + tree match { + /** package */ + case pd @ PackageDef(pid, st) => + val newPath = prev :+ pid.name.toString + addEntity(PackageImpl(newPath.mkString("."), collectEntityMembers(st, newPath), newPath)) + + /** trait */ + case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => + val name = n.decode.toString + val newPath = prev :+ name + //TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well + TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), superTypes(t)) + + /** objects, on the format "Object$" so drop the last letter */ + case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => + val name = n.decode.toString.dropRight(1) + //TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well + ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o)) + + /** class / case class */ + case c @ TypeDef(n, rhs) if c.symbol.isClass => + val name = n.decode.toString + val newPath = prev :+ name + //TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well + (name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), superTypes(c), None) match { + case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) + case x => ClassImpl.tupled(x) + } + + /** def */ + case d: DefDef => + DefImpl(d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d)) + + /** val */ + case v: ValDef if !v.symbol.is(Flags.ModuleVal) => + ValImpl(v.name.decode.toString, flags(v), path(v.symbol), returnType(v.tpt.tpe)) + + case x => { + //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") + NonEntity + } + } + } + + var packages: Map[String, Package] = Map.empty + + def addEntity(p: Package): Package = { + def mergedChildren(x1s: List[Entity], x2s: List[Entity]): List[Entity] = { + val (packs1, others1) = x1s.partition(_.kind == "package") + val (packs2, others2) = x2s.partition(_.kind == "package") + + val others = others1 ::: others2 + val packs = (packs1 ::: packs2).groupBy(_.path).map(_._2.head) + + (others ++ packs).sortBy(_.name) + } + + val path = p.path.mkString(".") + val newPack = packages.get(path).map { + case ex: PackageImpl => + if (!ex.comment.isDefined) ex.comment = p.comment + ex.members = mergedChildren(ex.members, p.members) + ex + }.getOrElse(p) + + packages = packages + (path -> newPack) + newPack + } + + private[this] var totalRuns = 0 + private[this] var currentRun = 0 + + override def run(implicit ctx: Context): Unit = { + currentRun += 1 + println(s"Compiling ($currentRun/$totalRuns): ${ctx.compilationUnit.source.file.name}") + collect(ctx.compilationUnit.tpdTree) // Will put packages in `packages` var + } + + override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { + // (1) Create package structure for all `units`, this will give us a complete structure + totalRuns = units.length + val compUnits = super.runOn(units) + + // (2) Set parents of entities, needed for linking + for { + parent <- packages.values + child <- parent.children + } setParent(child, to = parent) + + + // (3) Set returntypes to correct entities + returnLinker.link(packages) + + // (3) Create documentation template from docstrings, with internal links + println("Generating documentation, this might take a while...") + commentParser.parse(packages) + + // (4) Write the finished model to JSON + val outputDir = { + val out = ctx.settings.DocOutput.value + if (out.last == '/') out.dropRight(1) + else out + } + if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) + + // (5) Clear caches + commentParser.clear() + + // Return super's result + compUnits + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala deleted file mode 100644 index 659c23cc3176..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ /dev/null @@ -1,165 +0,0 @@ -package dotty.tools -package dottydoc -package core - -/** Dotty and Dottydoc imports */ -import dotc.ast.Trees._ -import dotc.CompilationUnit -import dotc.config.Printers.dottydoc -import dotc.core.Contexts.Context -import dotc.core.Phases.Phase -import dotc.core.Symbols.Symbol - -object Phases { - - class DocPhase extends Phase { - import model.parsers.{ WikiParser, ReturnTypeParser } - import model._ - import model.factories._ - import model.internal._ - import model.comment.Comment - import dotty.tools.dotc.core.Flags - import dotty.tools.dotc.ast.tpd._ - import util.traversing._ - import util.internal.setters._ - - def phaseName = "docphase" - - private[this] val commentParser = new WikiParser - private[this] val returnLinker = new ReturnTypeParser - - /** Saves the commentParser function for later evaluation, for when the AST has been filled */ - def track(symbol: Symbol, ctx: Context)(op: => Entity) = { - val entity = op - - if (entity != NonEntity) - commentParser += (entity, symbol, ctx) - - entity - } - - /** Build documentation hierarchy from existing tree */ - def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { - - def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = - xs.map(collect(_, ps)).filter(_ != NonEntity) - - def collectEntityMembers(xs: List[Tree], ps: List[String])(implicit ctx: Context) = - collectList(xs, ps).asInstanceOf[List[Entity with Members]] - - def collectMembers(tree: Tree, ps: List[String] = prev)(implicit ctx: Context): List[Entity] = tree match { - case t: Template => collectList(t.body, ps) - case _ => Nil - } - - tree match { - /** package */ - case pd @ PackageDef(pid, st) => - val newPath = prev :+ pid.name.toString - addEntity(PackageImpl(newPath.mkString("."), collectEntityMembers(st, newPath), newPath)) - - /** trait */ - case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) => - val name = n.decode.toString - val newPath = prev :+ name - TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t), superTypes(t)) - - /** objects, on the format "Object$" so drop the last letter */ - case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => - val name = n.decode.toString.dropRight(1) - ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o)) - - /** class / case class */ - case c @ TypeDef(n, rhs) if c.symbol.isClass => - val name = n.decode.toString - val newPath = prev :+ name - (name, collectMembers(rhs), flags(c), newPath, typeParams(c), superTypes(c), None) match { - case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) - case x => ClassImpl.tupled(x) - } - - /** def */ - case d: DefDef => - DefImpl(d.name.decode.toString, flags(d), path(d), returnType(d.tpt), typeParams(d), paramLists(d)) - - /** val */ - case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - ValImpl(v.name.decode.toString, flags(v), path(v), returnType(v.tpt)) - - case x => { - //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") - NonEntity - } - } - } - - var packages: Map[String, Package] = Map.empty - - def addEntity(p: Package): Package = { - def mergedChildren(x1s: List[Entity], x2s: List[Entity]): List[Entity] = { - val (packs1, others1) = x1s.partition(_.kind == "package") - val (packs2, others2) = x2s.partition(_.kind == "package") - - val others = others1 ::: others2 - val packs = (packs1 ::: packs2).groupBy(_.path).map(_._2.head) - - (others ++ packs).sortBy(_.name) - } - - val path = p.path.mkString(".") - val newPack = packages.get(path).map { - case ex: PackageImpl => - if (!ex.comment.isDefined) ex.comment = p.comment - ex.members = mergedChildren(ex.members, p.members) - ex - }.getOrElse(p) - - packages = packages + (path -> newPack) - newPack - } - - private[this] var totalRuns = 0 - private[this] var currentRun = 0 - - override def run(implicit ctx: Context): Unit = { - currentRun += 1 - println(s"Compiling ($currentRun/$totalRuns): ${ctx.compilationUnit.source.file.name}") - collect(ctx.compilationUnit.tpdTree) // Will put packages in `packages` var - } - - override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { - // (1) Create package structure for all `units`, this will give us a complete structure - totalRuns = units.length - val compUnits = super.runOn(units) - - // (2) Set parents of entities, needed for linking - for { - parent <- packages.values - child <- parent.children - } setParent(child, to = parent) - - - // (3) Set returntypes to correct entities - returnLinker.link(packages) - - // (3) Create documentation template from docstrings, with internal links - println("Generating documentation, this might take a while...") - commentParser.parse(packages) - - // (4) Write the finished model to JSON - val outputDir = { - val out = ctx.settings.DocOutput.value - if (out.last == '/') out.dropRight(1) - else out - } - if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) - - // (5) Clear caches - commentParser.clear() - - // Return super's result - compUnits - } - } - -} diff --git a/dottydoc/jvm/test/BaseTest.scala b/dottydoc/jvm/test/BaseTest.scala index 2703f816973e..1a2fb25cf0de 100644 --- a/dottydoc/jvm/test/BaseTest.scala +++ b/dottydoc/jvm/test/BaseTest.scala @@ -6,7 +6,7 @@ import Contexts.{ Context, ContextBase, FreshContext } import dotc.util.SourceFile import dotc.core.Phases.Phase import dotc.typer.FrontEnd -import dottydoc.core.Phases.DocPhase +import dottydoc.core.DocPhase trait DottyTest { dotty.tools.dotc.parsing.Scanners // initialize keywords diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index e8d453842059..bb415aed7029 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -4,6 +4,7 @@ package model import comment._ import dotty.tools.dotc import dotc.core.Types._ +import dotc.core.Flags import dotc.core.Contexts.Context import dotc.core.Symbols.Symbol import dotty.tools.dotc.core.SymDenotations._ @@ -24,27 +25,14 @@ object factories { .filter(_ != "") .filter(_ != "interface") - private def pathList(tpe: Type): List[String] = tpe match { - case t: ThisType => - pathList(t.tref) - case t: NamedType if t.prefix == NoPrefix && t.name.toString == "" => - Nil - case t: NamedType if t.prefix == NoPrefix => - t.name.toString :: Nil - case t: NamedType => - pathList(t.prefix) :+ t.name.toString + def path(sym: Symbol)(implicit ctx: Context): List[String] = sym match { + case sym if sym.name.decode.toString == "" => Nil + case sym if sym is Flags.Module => path(sym.owner) :+ sym.name.decode.toString.dropRight(1) + case sym => path(sym.owner) :+ sym.name.decode.toString } - def path(t: Tree)(implicit ctx: Context): List[String] = { - val ref = - if (t.symbol.isTerm) t.symbol.termRef - else t.symbol.typeRef - - pathList(ref) - } private val product = """Product[1-9][0-9]*""".r - private def cleanTitle(title: String): String = title match { // matches Entity.this.Something case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last @@ -60,8 +48,8 @@ object factories { case _ => query } - def returnType(t: TypeTree)(implicit ctx: Context): Reference = { - def typeRef(name: String, params: List[MaterializableLink]) = + def returnType(t: Type)(implicit ctx: Context): Reference = { + def typeRef(name: String, params: List[MaterializableLink] = Nil) = TypeReference(name, UnsetLink(Text(name), name), params) def expandTpe(t: Type, params: List[MaterializableLink] = Nil): Reference = t match { @@ -89,26 +77,30 @@ object factories { ConstantReference(c.show) case tt: ThisType => expandTpe(tt.underlying) + case ci: ClassInfo => + typeRef(ci.cls.show) + case ta: TypeAlias => + expandTpe(ta.alias.widenDealias) + case mt: MethodType => + expandTpe(mt.resultType) + case pt: PolyType => + expandTpe(pt.resultType) + case pp: PolyParam => + typeRef(pp.paramName.decode.toString) } - expandTpe(t.tpe) + expandTpe(t) } - def typeParams(t: Tree)(implicit ctx: Context): List[String] = t match { - case t: DefDef => - def variance(s: Symbol) = - if (s is Covariant) "+" - else if (s is Contravariant) "-" - else "" - t.tparams.map(p => variance(p.symbol) + p.show) - case t: TypeDef if t.rhs.isInstanceOf[Template] => - // Get the names from the constructor method `DefDef` - typeParams(t.rhs.asInstanceOf[Template].constr) - } + def typeParams(sym: Symbol)(implicit ctx: Context): List[String] = + sym.denot.info match { + case pt: PolyType => pt.paramNames.map(_.decode.toString) + case _ => Nil + } def paramLists(t: DefDef)(implicit ctx: Context): List[List[NamedReference]] = { def getParams(xs: List[ValDef]): List[NamedReference] = - xs.map(vd => NamedReference(vd.name.decode.toString, returnType(vd.tpt))) + xs.map(vd => NamedReference(vd.name.decode.toString, returnType(vd.tpt.tpe))) t.vparamss.map(getParams) } @@ -132,7 +124,7 @@ object factories { cd.classParents.collect { case t: TypeRef if !isJavaLangObject(t) && !isProductWithArity(t) => - UnsetLink(Text(t.name.toString), pathList(t).mkString(".")) + UnsetLink(Text(t.name.toString), path(t.symbol).mkString(".")) } case _ => Nil } From f1c88d7aac3df093b2912f6905b5fa852cf50e7d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 23 Jun 2016 18:25:00 +0200 Subject: [PATCH 056/100] Add implicitly added values as well --- .../src/dotty/tools/dottydoc/core/DocPhase.scala | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala index b5386be96f7b..2c07befc9bd4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala @@ -51,23 +51,25 @@ class DocPhase extends Phase { val defs = (tree match { case t: Template => collectList(t.body, ps) case _ => Nil - }) ++ implicitlyAddedMembers.flatMap(defFromSymbol) + }) ++ implicitlyAddedMembers.flatMap(addedFromSymbol) defs } - def defFromSymbol(sym: Symbol): List[Entity] = { + def addedFromSymbol(sym: Symbol): List[Entity] = { val defs = sym.info.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => track(sym, ctx) { - println(meth.show) DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), Nil/*paramLists(???)*/) } }.toList - println(s"Implicitly added to ${tree.symbol.show}:") - defs.foreach(println) - println("-------") - defs + val vals = sym.info.fields.map { value => + track(sym, ctx) { + ValImpl(value.symbol.name.decode.toString, Nil, path(value.symbol), returnType(value.info)) + } + } + + defs ++ vals } From 76413f003945140e5b502e6ad7b8fb058e6e6ade Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 24 Jun 2016 11:32:09 +0200 Subject: [PATCH 057/100] Cleanup return types and type parameters from dollar signs --- .../dottydoc/core/AddImplicitsPhase.scala | 3 -- .../dotty/tools/dottydoc/core/DocPhase.scala | 4 +-- .../tools/dottydoc/model/factories.scala | 31 ++++++++++++------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala index 3ee6082b69b0..15994ee28749 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala @@ -19,9 +19,6 @@ class AddImplicitsPhase extends MiniPhaseTransform { thisTransformer => tree.vparamss(0).length == 1 // should only take one arg, since it has to be a transformation ) { val convertee = tree.vparamss(0)(0).symbol.info.widenDealias.finalResultType.typeSymbol//denot.typeRef // the pimped type (i.e. `class`) - println(s"Adding methods from ${tree.symbol.info.widenDealias.finalResultType.typeSymbol} to ${convertee}") - //println(s" ${tree.denot.info} ${tree.vparamss(0)(0).denot.info}") - //ImplicitlyAdded.addDef(convertee, tree) ImplicitlyAdded.addDef(convertee, tree.symbol.info.widenDealias.finalResultType.typeSymbol) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala index 2c07befc9bd4..71d33950e845 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala @@ -58,13 +58,13 @@ class DocPhase extends Phase { def addedFromSymbol(sym: Symbol): List[Entity] = { val defs = sym.info.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => - track(sym, ctx) { + track(meth.symbol, ctx) { DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), Nil/*paramLists(???)*/) } }.toList val vals = sym.info.fields.map { value => - track(sym, ctx) { + track(value.symbol, ctx) { ValImpl(value.symbol.name.decode.toString, Nil, path(value.symbol), returnType(value.info)) } } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index bb415aed7029..eb0f54480475 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -49,22 +49,24 @@ object factories { } def returnType(t: Type)(implicit ctx: Context): Reference = { - def typeRef(name: String, params: List[MaterializableLink] = Nil) = - TypeReference(name, UnsetLink(Text(name), name), params) + def typeRef(name: String, query: String = "", params: List[MaterializableLink] = Nil) = { + val realQuery = if (query != "") query else name + TypeReference(name, UnsetLink(Text(name), realQuery), params) + } def expandTpe(t: Type, params: List[MaterializableLink] = Nil): Reference = t match { case ref @ RefinedType(parent, rn) => { - val paramName = ref.refinedInfo match { + val paramName = (ref.refinedInfo match { case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => - ta.alias.asInstanceOf[NamedType].name.decode.toString - case _ => - rn.decode.toString.split("\\$").last - } + ta.alias.asInstanceOf[NamedType].name.show + case _ => rn.show + }).split("\\$").last val param = UnsetLink(Text(paramName), paramName) expandTpe(parent, param :: params) } - case TypeRef(_, name) => - typeRef(name.decode.toString, params) + case TypeRef(_, n) => + val name = n.decode.toString.split("\\$").last + typeRef(name, params = params) case OrType(left, right) => OrTypeReference(expandTpe(left), expandTpe(right)) case AndType(left, right) => @@ -86,7 +88,13 @@ object factories { case pt: PolyType => expandTpe(pt.resultType) case pp: PolyParam => - typeRef(pp.paramName.decode.toString) + val paramName = pp.paramName.show + val name = + if (paramName.contains('$')) + paramName.split("\\$\\$").last + else paramName + + typeRef(name) } expandTpe(t) @@ -94,7 +102,8 @@ object factories { def typeParams(sym: Symbol)(implicit ctx: Context): List[String] = sym.denot.info match { - case pt: PolyType => pt.paramNames.map(_.decode.toString) + case pt: PolyType => + pt.paramNames.map(_.show.split("\\$").last) case _ => Nil } From 81a86be75dd45f6e3eae4bb5fdd016058738c497 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Sat, 25 Jun 2016 11:24:32 +0200 Subject: [PATCH 058/100] Materialize parameter list references --- .../dotty/tools/dottydoc/core/DocPhase.scala | 15 ++++--- .../dotty/tools/dottydoc/model/parsers.scala | 45 ++++++++++++++----- .../dotty/tools/dottydoc/util/mutate.scala | 7 ++- .../tools/dottydoc/model/factories.scala | 17 ++++--- 4 files changed, 61 insertions(+), 23 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala index 71d33950e845..522b224d12c1 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala @@ -11,7 +11,7 @@ import dotc.core.Phases.Phase import dotc.core.Symbols.Symbol class DocPhase extends Phase { - import model.parsers.{ WikiParser, ReturnTypeParser } + import model.parsers.{ WikiParser, ReturnTypeLinker, ParamListLinker } import model._ import model.factories._ import model.internal._ @@ -24,7 +24,10 @@ class DocPhase extends Phase { def phaseName = "docphase" private[this] val commentParser = new WikiParser - private[this] val returnLinker = new ReturnTypeParser + private[this] val linkers = + new ReturnTypeLinker :: + new ParamListLinker :: + Nil /** Saves the commentParser function for later evaluation, for when the AST has been filled */ def track(symbol: Symbol, ctx: Context)(op: => Entity) = { @@ -59,11 +62,11 @@ class DocPhase extends Phase { def addedFromSymbol(sym: Symbol): List[Entity] = { val defs = sym.info.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => track(meth.symbol, ctx) { - DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), Nil/*paramLists(???)*/) + DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), paramLists(meth.info)) } }.toList - val vals = sym.info.fields.map { value => + val vals = sym.info.fields.filterNot(_.symbol.is(Flags.Private | Flags.Synthetic)).map { value => track(value.symbol, ctx) { ValImpl(value.symbol.name.decode.toString, Nil, path(value.symbol), returnType(value.info)) } @@ -104,7 +107,7 @@ class DocPhase extends Phase { /** def */ case d: DefDef => - DefImpl(d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d)) + DefImpl(d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d.symbol.info)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => @@ -164,7 +167,7 @@ class DocPhase extends Phase { // (3) Set returntypes to correct entities - returnLinker.link(packages) + for (linker <- linkers) linker.link(packages) // (3) Create documentation template from docstrings, with internal links println("Generating documentation, this might take a while...") diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index d73f8fe9f2bd..2c163b1e626d 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -84,16 +84,9 @@ object parsers { def clear(): Unit = commentCache = Map.empty } - class ReturnTypeParser extends MemberLookup { - def link(packs: Map[String, Package]): Unit = - for (pack <- packs.values) mutateEntities(pack) { - case ent: ReturnValue => - setReturnValue(ent, returnValue(ent, ent, packs)) - case _ => () - } - - private def returnValue(ent: Entity, rv: ReturnValue, packs: Map[String, Package]): Reference = - rv.returnValue match { + sealed trait TypeLinker extends MemberLookup { + protected def linkReference(ent: Entity, rv: Reference, packs: Map[String, Package]): Reference = + rv match { case rv @ TypeReference(_, UnsetLink(t, query), tps) => val inlineToHtml = InlineToHtml(ent) val title = inlineToHtml(t) @@ -113,7 +106,37 @@ object parsers { } rv.copy(tpeLink = target, paramLinks = tpTargets) - case _ => rv.returnValue + case rv @ OrTypeReference(left, right) => + rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) + case rv @ AndTypeReference(left, right) => + rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) + case rv @ NamedReference(_, ref) => rv.copy(ref = linkReference(ent, ref, packs)) + case _ => rv + } + + def link(packs: Map[String, Package]): Unit + } + + class ReturnTypeLinker extends TypeLinker { + def link(packs: Map[String, Package]): Unit = + for (pack <- packs.values) mutateEntities(pack) { + case ent: ReturnValue => + setReturnValue(ent, linkReference(ent, ent.returnValue, packs)) + case _ => () + } + } + + class ParamListLinker extends TypeLinker { + def link(packs: Map[String, Package]): Unit = + for (pack <- packs.values) mutateEntities(pack) { + case ent: Def => + val newParamLists = for { + list <- ent.paramLists + newList = list.map(linkReference(ent, _, packs)) + } yield newList.asInstanceOf[List[NamedReference]] + + setParamLists(ent, newParamLists) + case _ => () } } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala index e6f1e6245064..4ce94459de44 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala @@ -4,7 +4,7 @@ package internal object setters { import model._ - import comment.{ Comment, MaterializableLink, Reference } + import comment.{ Comment, MaterializableLink, Reference, NamedReference } import internal._ def setComment(ent: Entity, to: Option[Comment]) = ent match { @@ -24,6 +24,11 @@ object setters { case _ => () } + def setParamLists(ent: Entity, refs: List[List[NamedReference]]) = ent match { + case x: DefImpl => x.paramLists = refs + case _ => () + } + def setParent(ent: Entity, to: Entity): Unit = ent match { case e: ClassImpl => e.parent = to diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index eb0f54480475..c2c7f9940d93 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -107,11 +107,18 @@ object factories { case _ => Nil } - def paramLists(t: DefDef)(implicit ctx: Context): List[List[NamedReference]] = { - def getParams(xs: List[ValDef]): List[NamedReference] = - xs.map(vd => NamedReference(vd.name.decode.toString, returnType(vd.tpt.tpe))) - - t.vparamss.map(getParams) + def paramLists(tpe: Type)(implicit ctx: Context): List[List[NamedReference]] = tpe match { + case pt: PolyType => + paramLists(pt.resultType) + + case mt: MethodType => + mt.paramNames.zip(mt.paramTypes).map { case (name, tpe) => + NamedReference(name.decode.toString, returnType(tpe)) + } :: paramLists(mt.resultType) + + case annot: AnnotatedType => paramLists(annot.tpe) + case (_: PolyParam | _: RefinedType | _: TypeRef | _: ThisType | + _: ExprType | _: OrType | _: AndType) => Nil // return types should not be in the paramlist } def superTypes(t: Tree)(implicit ctx: Context): List[MaterializableLink] = t.symbol.denot match { From c80af6a29b816d2ba7863b25b5c508efc4362b73 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 28 Jun 2016 18:04:31 +0200 Subject: [PATCH 059/100] Introduce DocMiniPhase concept, fused phases Like dotty, dottydoc can now also enjoy the modularity of having fused mini-phases. By extending `DocMiniPhase` and overriding the appropriate methods, one can alter the DocAST easily. ping: @DarkDimius --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 32 +-- .../dottydoc/core/AddImplicitsPhase.scala | 2 +- .../{DocPhase.scala => DocASTPhase.scala} | 27 +-- .../dottydoc/core/MiniPhaseTransform.scala | 189 ++++++++++++++++++ .../tools/dottydoc/core/PrintPhase.scala | 30 +++ .../dottydoc/core/TypeLinkerPhases.scala | 69 +++++++ .../dotty/tools/dottydoc/model/parsers.scala | 56 ------ dottydoc/jvm/test/BaseTest.scala | 12 +- src/dotty/tools/dotc/core/Contexts.scala | 13 +- 9 files changed, 324 insertions(+), 106 deletions(-) rename dottydoc/jvm/src/dotty/tools/dottydoc/core/{DocPhase.scala => DocASTPhase.scala} (90%) create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkerPhases.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index db2a394beea1..5eead13c0896 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -1,7 +1,8 @@ package dotty.tools package dottydoc -import core.{ AddImplicitsPhase, DocPhase } +import core._ +import core.transform._ import dotc.config.CompilerCommand import dotc.config.Printers.dottydoc import dotc.core.Contexts._ @@ -10,8 +11,6 @@ import dotc.typer.FrontEnd import dotc.{ CompilationUnit, Compiler, Driver, Run } import io.PlainFile -import scala.util.control.NonFatal - /** Custom Compiler with phases for the documentation tool * * The idea here is to structure `dottydoc` around the new infrastructure. As @@ -26,11 +25,14 @@ import scala.util.control.NonFatal * 5. Serve content using Scala.js */ class DottyDocCompiler extends Compiler { - override def phases: List[List[Phase]] = - List(new DocFrontEnd) :: - List(new AddImplicitsPhase) :: - List(new DocPhase) :: - Nil + override def phases: List[List[Phase]] = List( + List(new DocFrontEnd), + List(new AddImplicitsPhase), + List(new DocASTPhase), + List(DocMiniTransformations(new ReturnTypeLinker, + new ParamListTypeLinker)), + List(new PrintPhase) + ) override def newRun(implicit ctx: Context): Run = { reset() @@ -38,20 +40,6 @@ class DottyDocCompiler extends Compiler { } } -/** TODO: this object is only temporary, should be factored out, just wanted it to demo dottydoc */ -object ImplicitlyAdded { - import dotc.core.Symbols.Symbol - import dotc.ast.tpd.DefDef - import scala.collection.mutable - - private var _defs: Map[Symbol, Set[Symbol]] = Map.empty - def defs(sym: Symbol): Set[Symbol] = _defs.get(sym).getOrElse(Set.empty) - - def addDef(s: Symbol, d: Symbol): Unit = _defs = (_defs + { - s -> _defs.get(s).map(xs => xs + d).getOrElse(Set(d)) - }) -} - class DocFrontEnd extends FrontEnd { override protected def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) = unit.isJava diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala index 15994ee28749..3b1f2b26ad7a 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala @@ -19,7 +19,7 @@ class AddImplicitsPhase extends MiniPhaseTransform { thisTransformer => tree.vparamss(0).length == 1 // should only take one arg, since it has to be a transformation ) { val convertee = tree.vparamss(0)(0).symbol.info.widenDealias.finalResultType.typeSymbol//denot.typeRef // the pimped type (i.e. `class`) - ImplicitlyAdded.addDef(convertee, tree.symbol.info.widenDealias.finalResultType.typeSymbol) + ctx.base.addDef(convertee, tree.symbol.info.widenDealias.finalResultType.typeSymbol) } tree diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala similarity index 90% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala index 522b224d12c1..72e679565e5a 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -10,11 +10,11 @@ import dotc.core.Contexts.Context import dotc.core.Phases.Phase import dotc.core.Symbols.Symbol -class DocPhase extends Phase { - import model.parsers.{ WikiParser, ReturnTypeLinker, ParamListLinker } +class DocASTPhase extends Phase { import model._ import model.factories._ import model.internal._ + import model.parsers.WikiParser import model.comment.Comment import dotty.tools.dotc.core.Flags import dotty.tools.dotc.ast.tpd._ @@ -24,10 +24,6 @@ class DocPhase extends Phase { def phaseName = "docphase" private[this] val commentParser = new WikiParser - private[this] val linkers = - new ReturnTypeLinker :: - new ParamListLinker :: - Nil /** Saves the commentParser function for later evaluation, for when the AST has been filled */ def track(symbol: Symbol, ctx: Context)(op: => Entity) = { @@ -41,7 +37,7 @@ class DocPhase extends Phase { /** Build documentation hierarchy from existing tree */ def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { - val implicitlyAddedMembers = ImplicitlyAdded.defs(tree.symbol)//denot.info) + val implicitlyAddedMembers = ctx.base.defs(tree.symbol) def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = xs.map(collect(_, ps)).filter(_ != NonEntity) @@ -165,25 +161,16 @@ class DocPhase extends Phase { child <- parent.children } setParent(child, to = parent) - - // (3) Set returntypes to correct entities - for (linker <- linkers) linker.link(packages) - // (3) Create documentation template from docstrings, with internal links println("Generating documentation, this might take a while...") commentParser.parse(packages) - // (4) Write the finished model to JSON - val outputDir = { - val out = ctx.settings.DocOutput.value - if (out.last == '/') out.dropRight(1) - else out - } - if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) - - // (5) Clear caches + // (4) Clear caches commentParser.clear() + // (5) Update Doc AST in ctx.base + for (kv <- packages) ctx.base.packages += kv + // Return super's result compUnits } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala new file mode 100644 index 000000000000..ba7ea040a6e4 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala @@ -0,0 +1,189 @@ +package dotty.tools +package dottydoc +package core + +import dotc.CompilationUnit +import dotc.core.Contexts.Context +import dotc.core.Phases.Phase +import model._ +import model.internal._ + +object transform { + /** + * The idea behind DocMiniTransformations is to fuse transformations to the + * doc AST, much like `MiniPhaseTransform` in dotty core - but in a much more + * simple implementation + * + * Usage + * ----- + * + * Create a `DocMiniPhase` which overrides the relevant method: + * + * {{{ + * override def transformDef(implicit ctx: Context) = { + * case x if shouldTransform(x) => x.copy(newValue = ...) + * } + * }}} + * + * On each node in the AST, the appropriate method in `DocMiniPhase` will be + * called in the order that they are supplied in + * `DocMiniphaseTransformations`. + * + * There won't be a match-error as `transformX` is composed with an + * `identity` function. + * + * The transformations in `DocMiniTransformations` will apply transformations + * to all nodes - this means that you do _not_ need to transform children in + * `transformPackage`, because `transformX` will be called for the relevant + * children. If you want to add children to `Package` you need to do that in + * `transformPackage`, these additions will be persisted. + */ + abstract class DocMiniTransformations(transformations: List[DocMiniPhase]) extends Phase { + + override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { + for { + rootName <- rootPackages + pack = ctx.base.packages[Package](rootName) + transformed = performPackageTransform(pack) + } yield ctx.base.packages(rootName) = transformed + super.runOn(units) + } + + private def rootPackages(implicit ctx: Context): List[String] = { + var currentDepth = Int.MaxValue + var packs = List.empty[String] + + for (key <- ctx.base.packages.keys) { + val keyDepth = key.split("\\.").length + packs = + if (keyDepth < currentDepth) { + currentDepth = keyDepth + key :: Nil + } else if (keyDepth == currentDepth) { + key :: packs + } else packs + } + packs + } + + private def performPackageTransform(pack: Package)(implicit ctx: Context): Package = { + def transformEntity[E <: Entity](e: E, f: DocMiniPhase => E => E)(createNew: E => E): E = { + val transformedEntity = transformations.foldLeft(e) { case (oldE, transf) => + f(transf)(oldE) + } + createNew(transformedEntity) + } + + def traverse(ent: Entity): Entity = ent match { + case p: Package => transformEntity(p, _.packageTransformation) { p => + PackageImpl( + p.name, + p.members.map(traverse), + p.path, + p.comment + ) + } + case c: Class => transformEntity(c, _.classTransformation) { newClass => + ClassImpl( + newClass.name, + newClass.members.map(traverse), + newClass.modifiers, + newClass.path, + newClass.typeParams, + newClass.superTypes, + newClass.comment + ) + } + case cc: CaseClass => transformEntity(cc, _.cclassTransformation) { cc => + CaseClassImpl( + cc.name, + cc.members.map(traverse), + cc.modifiers, + cc.path, + cc.typeParams, + cc.superTypes, + cc.comment + ) + } + case trt: Trait => transformEntity(trt, _.traitTransformation) { trt => + TraitImpl( + trt.name, + trt.members.map(traverse), + trt.modifiers, + trt.path, + trt.typeParams, + trt.superTypes, + trt.comment + ) + } + case obj: Object => transformEntity(obj, _.objectTransformation) { obj => + ObjectImpl( + obj.name, + obj.members.map(traverse), + obj.modifiers, + obj.path, + obj.superTypes, + obj.comment + ) + } + case df: Def => transformEntity(df, _.defTransformation) { df => + DefImpl( + df.name, + df.modifiers, + df.path, + df.returnValue, + df.typeParams, + df.paramLists, + df.comment + ) + } + case vl: Val => transformEntity(vl, _.valTransformation) { vl => + ValImpl( + vl.name, + vl.modifiers, + vl.path, + vl.returnValue, + vl.comment + ) + } + } + + traverse(pack).asInstanceOf[Package] + } + + override def run(implicit ctx: Context): Unit = () + } + + object DocMiniTransformations { + private var previousPhase = 0 + def apply(transformations: DocMiniPhase*) = + new DocMiniTransformations(transformations.toList) { + val packages = Map.empty[String, Package] + + def phaseName = s"MiniTransformation${ previousPhase += 1 }" + } + } + + trait DocMiniPhase { phase => + private def identity[E]: PartialFunction[E, E] = { + case id => id + } + + // Partial functions instead???? + def transformPackage(implicit ctx: Context): PartialFunction[Package, Package] = identity + def transformClass(implicit ctx: Context): PartialFunction[Class, Class] = identity + def transformCaseClass(implicit ctx: Context): PartialFunction[CaseClass, CaseClass] = identity + def transformTrait(implicit ctx: Context): PartialFunction[Trait, Trait] = identity + def transformObject(implicit ctx: Context): PartialFunction[Object, Object] = identity + def transformDef(implicit ctx: Context): PartialFunction[Def, Def] = identity + def transformVal(implicit ctx: Context): PartialFunction[Val, Val] = identity + + private[transform] def packageTransformation(p: Package)(implicit ctx: Context) = (transformPackage orElse identity)(p) + private[transform] def classTransformation(cls: Class)(implicit ctx: Context) = (transformClass orElse identity)(cls) + private[transform] def cclassTransformation(cc: CaseClass)(implicit ctx: Context) = (transformCaseClass orElse identity)(cc) + private[transform] def traitTransformation(trt: Trait)(implicit ctx: Context) = (transformTrait orElse identity)(trt) + private[transform] def objectTransformation(obj: Object)(implicit ctx: Context) = (transformObject orElse identity)(obj) + private[transform] def defTransformation(df: Def)(implicit ctx: Context) = (transformDef orElse identity)(df) + private[transform] def valTransformation(vl: Val)(implicit ctx: Context) = (transformVal orElse identity)(vl) + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala new file mode 100644 index 000000000000..9c9070d24999 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala @@ -0,0 +1,30 @@ +package dotty.tools +package dottydoc +package core + +import dotc.CompilationUnit +import dotc.core.Contexts.Context +import dotc.core.Phases.Phase +import model.{Package, Entity} + +/** TODO: re-write to `DocMiniPhase` */ +class PrintPhase extends Phase { + def phaseName = "docPrintPhase" + + var currentRun = 0 + override def run(implicit ctx: Context): Unit = () + + override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { + val compUnits = super.runOn(units) + val packages = ctx.base.packages[Package].toMap + + val outputDir = { + val out = ctx.settings.DocOutput.value + if (out.last == '/') out.dropRight(1) + else out + } + if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) + + compUnits + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkerPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkerPhases.scala new file mode 100644 index 000000000000..5339844ba843 --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkerPhases.scala @@ -0,0 +1,69 @@ +package dotty.tools +package dottydoc +package core + +import dotc.core.Contexts.Context +import dotc.util.Positions.NoPosition + +import transform.DocMiniPhase +import model._ +import comment._ +import BodyParsers._ +import model.internal._ +import util.MemberLookup +import util.traversing._ +import util.internal.setters._ + +class ReturnTypeLinker extends DocMiniPhase with TypeLinker { + override def transformDef(implicit ctx: Context) = { case df: DefImpl => + val returnValue = linkReference(df, df.returnValue, ctx.base.packages[Package].toMap) + df.copy(returnValue = returnValue) + } + + override def transformVal(implicit ctx: Context) = { case vl: ValImpl => + val returnValue = linkReference(vl, vl.returnValue, ctx.base.packages[Package].toMap) + vl.copy(returnValue = returnValue) + } +} + +class ParamListTypeLinker extends DocMiniPhase with TypeLinker { + override def transformDef(implicit ctx: Context) = { case df: DefImpl => + val newParamLists = for { + list <- df.paramLists + newList = list.map(linkReference(df, _, ctx.base.packages[Package].toMap)) + } yield newList.asInstanceOf[List[NamedReference]] + + df.copy(paramLists = newParamLists) + } +} + +trait TypeLinker extends MemberLookup { + def linkReference(ent: Entity, rv: Reference, packs: Map[String, Package]): Reference = + rv match { + case rv @ TypeReference(_, UnsetLink(t, query), tps) => + val inlineToHtml = InlineToHtml(ent) + val title = inlineToHtml(t) + + def handleEntityLink(title: String, lt: LinkTo): MaterializableLink = lt match { + case Tooltip(str) => NoLink(title, str) + case LinkToExternal(_, url) => MaterializedLink(title, url) + case LinkToEntity(target) => MaterializedLink(title, util.traversing.relativePath(ent, target)) + } + + val target = handleEntityLink(title, makeEntityLink(ent, packs, t, NoPosition, query).link) + + val tpTargets = tps.map { + case UnsetLink(t, query) => + handleEntityLink(inlineToHtml(t), makeEntityLink(ent, packs, t, NoPosition, query).link) + case x => x + } + + rv.copy(tpeLink = target, paramLinks = tpTargets) + case rv @ OrTypeReference(left, right) => + rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) + case rv @ AndTypeReference(left, right) => + rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) + case rv @ NamedReference(_, ref) => rv.copy(ref = linkReference(ent, ref, packs)) + case _ => rv + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index 2c163b1e626d..3b2f2df4379e 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -83,60 +83,4 @@ object parsers { def clear(): Unit = commentCache = Map.empty } - - sealed trait TypeLinker extends MemberLookup { - protected def linkReference(ent: Entity, rv: Reference, packs: Map[String, Package]): Reference = - rv match { - case rv @ TypeReference(_, UnsetLink(t, query), tps) => - val inlineToHtml = InlineToHtml(ent) - val title = inlineToHtml(t) - - def handleEntityLink(title: String, lt: LinkTo): MaterializableLink = lt match { - case Tooltip(str) => NoLink(title, str) - case LinkToExternal(_, url) => MaterializedLink(title, url) - case LinkToEntity(target) => MaterializedLink(title, util.traversing.relativePath(ent, target)) - } - - val target = handleEntityLink(title, makeEntityLink(ent, packs, t, NoPosition, query).link) - - val tpTargets = tps.map { - case UnsetLink(t, query) => - handleEntityLink(inlineToHtml(t), makeEntityLink(ent, packs, t, NoPosition, query).link) - case x => x - } - - rv.copy(tpeLink = target, paramLinks = tpTargets) - case rv @ OrTypeReference(left, right) => - rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) - case rv @ AndTypeReference(left, right) => - rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) - case rv @ NamedReference(_, ref) => rv.copy(ref = linkReference(ent, ref, packs)) - case _ => rv - } - - def link(packs: Map[String, Package]): Unit - } - - class ReturnTypeLinker extends TypeLinker { - def link(packs: Map[String, Package]): Unit = - for (pack <- packs.values) mutateEntities(pack) { - case ent: ReturnValue => - setReturnValue(ent, linkReference(ent, ent.returnValue, packs)) - case _ => () - } - } - - class ParamListLinker extends TypeLinker { - def link(packs: Map[String, Package]): Unit = - for (pack <- packs.values) mutateEntities(pack) { - case ent: Def => - val newParamLists = for { - list <- ent.paramLists - newList = list.map(linkReference(ent, _, packs)) - } yield newList.asInstanceOf[List[NamedReference]] - - setParamLists(ent, newParamLists) - case _ => () - } - } } diff --git a/dottydoc/jvm/test/BaseTest.scala b/dottydoc/jvm/test/BaseTest.scala index 1a2fb25cf0de..0c6fad1c8e21 100644 --- a/dottydoc/jvm/test/BaseTest.scala +++ b/dottydoc/jvm/test/BaseTest.scala @@ -6,7 +6,7 @@ import Contexts.{ Context, ContextBase, FreshContext } import dotc.util.SourceFile import dotc.core.Phases.Phase import dotc.typer.FrontEnd -import dottydoc.core.DocPhase +import dottydoc.core.DocASTPhase trait DottyTest { dotty.tools.dotc.parsing.Scanners // initialize keywords @@ -22,8 +22,8 @@ trait DottyTest { ctx } - private def compilerWithChecker(assertion: DocPhase => Unit) = new DottyDocCompiler { - private[this] val docPhase = new DocPhase + private def compilerWithChecker(assertion: DocASTPhase => Unit) = new DottyDocCompiler { + private[this] val docPhase = new DocASTPhase override def phases = List(new FrontEnd) :: @@ -35,21 +35,21 @@ trait DottyTest { Nil } - def checkSource(source: String)(assertion: DocPhase => Unit): Unit = { + def checkSource(source: String)(assertion: DocASTPhase => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun run.compile(source) } - def checkFiles(sources: List[String])(assertion: DocPhase => Unit): Unit = { + def checkFiles(sources: List[String])(assertion: DocASTPhase => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun run.compile(sources) } - def checkSources(sourceFiles: List[SourceFile])(assertion: DocPhase => Unit): Unit = { + def checkSources(sourceFiles: List[SourceFile])(assertion: DocASTPhase => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index d3ebe32fedf3..7490a62cc6cc 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -492,7 +492,7 @@ object Contexts { /** A class defining the initial context with given context base * and set of possible settings. */ - class InitialContext(val base: ContextBase, settings: SettingGroup) extends FreshContext { + private class InitialContext(val base: ContextBase, settings: SettingGroup) extends FreshContext { outer = NoContext period = InitialPeriod mode = Mode.None @@ -576,6 +576,17 @@ object Contexts { def addDocstring(sym: Symbol, doc: Option[Comment]): Unit = doc.map(d => _docstrings += (sym -> d)) + + private[this] val _packages: mutable.Map[String, AnyRef] = mutable.Map.empty + def packages[A]: mutable.Map[String, A] = _packages.asInstanceOf[mutable.Map[String, A]] + + /** Should perhaps factorize this into caches that get flushed */ + private var _defs: Map[Symbol, Set[Symbol]] = Map.empty + def defs(sym: Symbol): Set[Symbol] = _defs.get(sym).getOrElse(Set.empty) + + def addDef(s: Symbol, d: Symbol): Unit = _defs = (_defs + { + s -> _defs.get(s).map(xs => xs + d).getOrElse(Set(d)) + }) } /** The essential mutable state of a context base, collected into a common class */ From 7fbda931e9181be668d6d2bb087f37ce4ea4863f Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 28 Jun 2016 18:21:23 +0200 Subject: [PATCH 060/100] Rename AddImplicitsPhase to DocImplicitsPhase --- dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala | 2 +- .../core/{AddImplicitsPhase.scala => DocImplicitsPhase.scala} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename dottydoc/jvm/src/dotty/tools/dottydoc/core/{AddImplicitsPhase.scala => DocImplicitsPhase.scala} (93%) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 5eead13c0896..557fc8fecdf2 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -27,7 +27,7 @@ import io.PlainFile class DottyDocCompiler extends Compiler { override def phases: List[List[Phase]] = List( List(new DocFrontEnd), - List(new AddImplicitsPhase), + List(new DocImplicitsPhase), List(new DocASTPhase), List(DocMiniTransformations(new ReturnTypeLinker, new ParamListTypeLinker)), diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala similarity index 93% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala index 3b1f2b26ad7a..0847648568c4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/AddImplicitsPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala @@ -6,7 +6,7 @@ import dotty.tools.dotc.transform.TreeTransforms.{ MiniPhaseTransform, Transform import dotty.tools.dotc.core.Flags import dotc.core.Contexts.Context -class AddImplicitsPhase extends MiniPhaseTransform { thisTransformer => +class DocImplicitsPhase extends MiniPhaseTransform { thisTransformer => import dotty.tools.dotc.ast.tpd._ def phaseName = "addImplicitsPhase" From 8615072f182ce5123b653bce3819202f35096112 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 28 Jun 2016 18:21:43 +0200 Subject: [PATCH 061/100] Rename `XTypeLinkers` to `LinkXTypes` - because the amount of linker is too d*mn high! --- dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala | 4 ++-- .../core/{TypeLinkerPhases.scala => TypeLinkingPhases.scala} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename dottydoc/jvm/src/dotty/tools/dottydoc/core/{TypeLinkerPhases.scala => TypeLinkingPhases.scala} (95%) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 557fc8fecdf2..8fd51aeea3b5 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -29,8 +29,8 @@ class DottyDocCompiler extends Compiler { List(new DocFrontEnd), List(new DocImplicitsPhase), List(new DocASTPhase), - List(DocMiniTransformations(new ReturnTypeLinker, - new ParamListTypeLinker)), + List(DocMiniTransformations(new LinkReturnTypes, + new LinkParamListTypes)), List(new PrintPhase) ) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkerPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala similarity index 95% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkerPhases.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 5339844ba843..6d8e85d87aee 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkerPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -14,7 +14,7 @@ import util.MemberLookup import util.traversing._ import util.internal.setters._ -class ReturnTypeLinker extends DocMiniPhase with TypeLinker { +class LinkReturnTypes extends DocMiniPhase with TypeLinker { override def transformDef(implicit ctx: Context) = { case df: DefImpl => val returnValue = linkReference(df, df.returnValue, ctx.base.packages[Package].toMap) df.copy(returnValue = returnValue) @@ -26,7 +26,7 @@ class ReturnTypeLinker extends DocMiniPhase with TypeLinker { } } -class ParamListTypeLinker extends DocMiniPhase with TypeLinker { +class LinkParamListTypes extends DocMiniPhase with TypeLinker { override def transformDef(implicit ctx: Context) = { case df: DefImpl => val newParamLists = for { list <- df.paramLists From 8e5159f74c7c8db2461b0ec8c30115d71855af6a Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 28 Jun 2016 18:24:11 +0200 Subject: [PATCH 062/100] Rename `cclassTransformation` to `caseClassTransformation` --- .../src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala index ba7ea040a6e4..b12ceeb95622 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala @@ -94,7 +94,7 @@ object transform { newClass.comment ) } - case cc: CaseClass => transformEntity(cc, _.cclassTransformation) { cc => + case cc: CaseClass => transformEntity(cc, _.caseClassTransformation) { cc => CaseClassImpl( cc.name, cc.members.map(traverse), @@ -180,7 +180,7 @@ object transform { private[transform] def packageTransformation(p: Package)(implicit ctx: Context) = (transformPackage orElse identity)(p) private[transform] def classTransformation(cls: Class)(implicit ctx: Context) = (transformClass orElse identity)(cls) - private[transform] def cclassTransformation(cc: CaseClass)(implicit ctx: Context) = (transformCaseClass orElse identity)(cc) + private[transform] def caseClassTransformation(cc: CaseClass)(implicit ctx: Context) = (transformCaseClass orElse identity)(cc) private[transform] def traitTransformation(trt: Trait)(implicit ctx: Context) = (transformTrait orElse identity)(trt) private[transform] def objectTransformation(obj: Object)(implicit ctx: Context) = (transformObject orElse identity)(obj) private[transform] def defTransformation(df: Def)(implicit ctx: Context) = (transformDef orElse identity)(df) From d5b00141315e61f2f0f994872fdcf5a93f7b7aae Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 29 Jun 2016 15:16:59 +0200 Subject: [PATCH 063/100] =?UTF-8?q?Remove=20dependency=20on=20pickling=20l?= =?UTF-8?q?ibrary,=20make=20frontend=20use=20fa=C3=A7ade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dottydoc/js/src/EntityIndex.scala | 9 +- dottydoc/js/src/html/EntityLayout.scala | 59 ++++-- dottydoc/js/src/html/Member.scala | 188 ++++++++++-------- dottydoc/js/src/model/entities.scala | 52 ++++- dottydoc/js/src/model/references.scala | 65 ++++++ .../dottydoc/core/TypeLinkingPhases.scala | 6 +- .../tools/dottydoc/html/EntityPage.scala | 7 +- .../src/dotty/tools/dottydoc/model/json.scala | 16 +- .../dottydoc/model/comment/BodyEntities.scala | 4 +- .../tools/dottydoc/model/factories.scala | 6 +- .../dotty/tools/dottydoc/model/pickling.scala | 44 ---- project/Build.scala | 2 - 12 files changed, 279 insertions(+), 179 deletions(-) create mode 100644 dottydoc/js/src/model/references.scala delete mode 100644 dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala diff --git a/dottydoc/js/src/EntityIndex.scala b/dottydoc/js/src/EntityIndex.scala index b6fe1842f3ff..358298ca0b81 100644 --- a/dottydoc/js/src/EntityIndex.scala +++ b/dottydoc/js/src/EntityIndex.scala @@ -10,21 +10,16 @@ import sjs.annotation.JSName /** The unpickled AST available as scala classes */ object EntityIndex { - import prickle._ - import dottydoc.model.pickling._ import js.model._ lazy val packages: Map[String, Package] = Unparsed.packages.toMap[String, Package] - val currentEntity: dottydoc.model.Entity = Unpickle[dottydoc.model.Entity] - .fromString(sjs.JSON.stringify(Unparsed.currentEntity)) - .toOption - .get + val currentEntity: Entity = Unparsed.currentEntity /** Unparsed index stores the pickled AST generated by the dottydoc tool */ @sjs.native @JSName("UnparsedIndex") private object Unparsed extends sjs.Object { def packages: sjs.Dictionary[Package] = sjs.native - def currentEntity: sjs.Object = sjs.native + def currentEntity: Entity = sjs.native } } diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index 37a72c73df04..e08425c244ce 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -5,8 +5,8 @@ package html import scalatags.JsDom.all._ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div} -import dotty.tools.dottydoc.model._ -import dotty.tools.dottydoc.model.comment.{ UnsetLink, Text } +import js.model._ +import js.model.ops._ case class EntityLayout(entity: Entity) extends MemberLayout { def html = div( @@ -14,40 +14,55 @@ case class EntityLayout(entity: Entity) extends MemberLayout { div(cls := "entity-title", entityTitle), div(raw(entity.comment.fold("")(_.body))), entity match { - case e: Entity with Members if e.members.nonEmpty => - Seq( - h5("Members"), - div( - cls := "mld-grid", - e.members - .collect { case x: Entity with Modifiers if !x.isPrivate => x} - .flatMap(member(_, entity)) + case x if x.hasMembers => + val e = x.asInstanceOf[Entity with Members] + if (e.members.nonEmpty) + Seq( + h5("Members"), + div( + cls := "mld-grid", + e.members + .collect { + case x if x.hasModifiers && !x.isPrivate => x + } + .flatMap(member(_, entity)).toList + ) ) - ) case _ => () } ) def entityTitle = { - val modifiers = entity match { - case m: Modifiers if m.modifiers.nonEmpty => - Some(span(cls := "entity-modifiers", m.modifiers.mkString(" "))) + val modifiers = entity.kind match { + case "Modifiers" => + val m = entity.asInstanceOf[Modifiers] + if (m.modifiers.nonEmpty) + Some(span(cls := "entity-modifiers", m.modifiers.mkString(" "))) + else + None case _ => None } val typeParams = entity match { - case t: TypeParams if t.typeParams.nonEmpty => - Some(span(cls := "entity-type-params no-left-margin", t.typeParams.mkString("[", ", ", "]"))) + case x if x.hasTypeParams => + val t = entity.asInstanceOf[TypeParams] + if (t.typeParams.nonEmpty) + Some(span(cls := "entity-type-params no-left-margin", t.typeParams.mkString("[", ", ", "]"))) + else None case _ => None } val superTypes = entity match { - case st: SuperTypes => Some(span( - cls := "entity-super-types", - st.superTypes.collect { - case unset: UnsetLink => unset.title.asInstanceOf[Text].text - }.mkString("extends ", " with ", "") - )) + case x if x.hasSuperTypes => + val st = entity.asInstanceOf[SuperTypes] + if (st.superTypes.nonEmpty) + Some(span( + cls := "entity-super-types", + st.superTypes.collect { + case x => x.title + }.mkString("extends ", " with ", "") + )) + else None case _ => None } diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index a8da9d126227..1786f745a5a1 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -8,8 +8,7 @@ import org.scalajs.dom import org.scalajs.dom.html.{Anchor, Div, Span} trait MemberLayout { - import dotty.tools.dottydoc.model._ - import dotty.tools.dottydoc.model.comment._ + import js.model._ def member(m: Entity, parent: Entity) = { def toggleBetween(short: Div, and: Div): Unit = @@ -21,8 +20,9 @@ trait MemberLayout { short.style.display = "block" } - m match { - case m: Entity with Modifiers => + m.kind match { + case "class" | "case class" | "object" | "trait" | "def" | "val" => + val entity = m.asInstanceOf[Entity with Modifiers] val shortComment = div( cls := "mdl-cell mdl-cell--12-col summary-comment", raw(m.comment.fold("")(_.short)) @@ -50,7 +50,7 @@ trait MemberLayout { cls := "mdl-cell mdl-cell--12-col member-definition", span( cls := "member-modifiers-kind", - m.modifiers.mkString(" ") + " " + m.kind + entity.modifiers.mkString(" ") + " " + m.kind ), span( cls := "member-name", @@ -58,13 +58,13 @@ trait MemberLayout { ), spanWith("member-type-params no-left-margin", typeParams(m)), span(cls := "member-param-list no-left-margin", paramList(m)), - returnValue(m, parent) + returnValue(entity, parent) ), shortComment, fullComment ) Seq(divs) - case x => Seq(h1("ERROR: " + x.name)) + case _ => Seq(h1("ERROR: " + m.name)) } } @@ -73,67 +73,82 @@ trait MemberLayout { case _ => Some(span(cls := clazz, contents)) } - def paramList(m: Entity): Span = m match { - case d: Def if d.paramLists.nonEmpty => - span( - cls := "member-param-lists", - d.paramLists.map { xs => - span( - cls := "param-list", - "(", - xs.flatMap { tr => - Seq( - span(cls := "param-name", tr.title).render, - span(cls := "type-separator no-left-margin", ":").render, - span(referenceToLinks(tr.ref)).render, - span(cls := "type-separator no-left-margin", ",").render - ) - }.dropRight(1), - ")" - ).render - } - ).render + def paramList(m: Entity): Span = m.kind match { + case "def" => + val d = m.asInstanceOf[Def] + if (d.paramLists.nonEmpty) + span( + cls := "member-param-lists", + d.paramLists.map { xs => + span( + cls := "param-list", + "(", + xs.flatMap { tr => + Seq( + span(cls := "param-name", tr.title).render, + span(cls := "type-separator no-left-margin", ":").render, + span(referenceToLinks(tr.ref)).render, + span(cls := "type-separator no-left-margin", ",").render + ) + }.toList.dropRight(1), + ")" + ).render + }.toList + ).render + else span().render case _ => span().render } def referenceToLinks(ref: Reference): Span = { - def linkToAnchor(link: MaterializableLink) = link match { - case MaterializedLink(t, url) => a(href := url, t).render - case NoLink(t, _) => span(t).render + def linkToAnchor(link: MaterializableLink) = link.kind match { + case "MaterializedLink" => + val (t, url) = (link.asInstanceOf[MaterializedLink].title, link.asInstanceOf[MaterializedLink].target) + a(href := url, t).render + case "NoLink" => span(link.title).render //FIXME: there should be no UnsetLinks - either MaterializedLink or NoLink - case UnsetLink(_, q) => span(q).render + case "UnsetLink" => span(link.title).render } - ref match { - case ref: TypeReference if ref.paramLinks.nonEmpty => span( - linkToAnchor(ref.tpeLink), - "[", - ref - .paramLinks - .map(linkToAnchor) - .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)) - .dropRight(1), - "]" - ).render - case ref: TypeReference => span(linkToAnchor(ref.tpeLink)).render - - case OrTypeReference(left, right) => span( - referenceToLinks(left), - span(cls := "type-separator", "|"), - referenceToLinks(right) - ).render - - case AndTypeReference(left, right) => span( - referenceToLinks(left), - span(cls := "type-separator", "&"), - referenceToLinks(right) - ).render + ref.kind match { + case "TypeReference" => + val tref = ref.asInstanceOf[TypeReference] + if (tref.paramLinks.nonEmpty) span( + linkToAnchor(tref.tpeLink), + "[", + tref + .paramLinks + .map(linkToAnchor) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)) + .toList.dropRight(1), + "]" + ).render + else span(linkToAnchor(tref.tpeLink)).render + + case "OrTypeReference" => + val (left, right) = (ref.asInstanceOf[OrTypeReference].left, ref.asInstanceOf[OrTypeReference].right) + span( + referenceToLinks(left), + span(cls := "type-separator", "|"), + referenceToLinks(right) + ).render + + case "AndTypeReference" => + val (left, right) = (ref.asInstanceOf[AndTypeReference].left, ref.asInstanceOf[AndTypeReference].right) + span( + referenceToLinks(left), + span(cls := "type-separator", "&"), + referenceToLinks(right) + ).render } } - def typeParams(m: Entity): String = m match { - case d: Def if d.typeParams.nonEmpty => d.typeParams.mkString("[", ", ", "]") + def typeParams(m: Entity): String = m.kind match { + case "def" => + val d = m.asInstanceOf[Def] + if (d.typeParams.nonEmpty) + d.typeParams.mkString("[", ", ", "]") + else "" case _ => "" } @@ -146,50 +161,59 @@ trait MemberLayout { } def link(rv: Reference): Span = { - def decodeTpeLink: MaterializableLink => Span = { - case ml: MaterializedLink => - println(s"received tpeLink: $ml") + def decodeTpeLink(link: MaterializableLink): Span = link.kind match { + case "MaterializedLink" => + val ml = link.asInstanceOf[MaterializedLink] span(cls := "member-return-value", a(href := ml.target, ml.title)).render - case un: UnsetLink => + case "UnsetLink" => + val un = link.asInstanceOf[UnsetLink] span(cls := "member-return-value", shorten(un.query)).render - case no: NoLink => + case "NoLink" => + val no = link.asInstanceOf[NoLink] span(cls := "member-return-value", shorten(no.title)).render } - rv match { - case rv: TypeReference => - val returnValue = decodeTpeLink(rv.tpeLink) + rv.kind match { + case "TypeReference" => + val trv = rv.asInstanceOf[TypeReference] + val returnValue = decodeTpeLink(trv.tpeLink) - if (rv.paramLinks.nonEmpty) span( + if (trv.paramLinks.nonEmpty) span( returnValue, "[", - rv.paramLinks + trv.paramLinks .map(decodeTpeLink) .flatMap { sp => Seq(sp, span(cls := "type-separator no-left-margin", ",").render) } - .dropRight(1), + .toList.dropRight(1), "]" ).render else returnValue - case OrTypeReference(left, right) => span( - cls := "member-return-value or-type", - link(left), - span(cls := "type-separator", "|"), - link(right) - ).render - case AndTypeReference(left, right) => span( - cls := "member-return-value and-type", - link(left), - span(cls := "type-separator", "&"), - link(right) - ).render + case "OrTypeReference" => + val (left, right) = (rv.asInstanceOf[OrTypeReference].left, rv.asInstanceOf[OrTypeReference].right) + span( + cls := "member-return-value or-type", + link(left), + span(cls := "type-separator", "|"), + link(right) + ).render + case "AndTypeReference" => + val (left, right) = (rv.asInstanceOf[AndTypeReference].left, rv.asInstanceOf[AndTypeReference].right) + span( + cls := "member-return-value and-type", + link(left), + span(cls := "type-separator", "&"), + link(right) + ).render } } - m match { - case rv: ReturnValue => Some(span(cls := "no-left-margin", ": ", link(rv.returnValue))) + m.kind match { + case "def" => + val rv = m.asInstanceOf[ReturnValue] + Some(span(cls := "no-left-margin", ": ", link(rv.returnValue))) case _ => None } } diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index a50a0427173c..adf7bc4ca921 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -23,6 +23,13 @@ trait Entity extends sjs.Object { val kind: String val name: String val path: sjs.Array[String] + val comment: sjs.UndefOr[Comment] +} + +@ScalaJSDefined +trait Comment extends sjs.Object { + val body: String + val short: String } @ScalaJSDefined @@ -35,6 +42,21 @@ trait Modifiers extends sjs.Object { val modifiers: sjs.Array[String] } +@ScalaJSDefined +trait ReturnValue extends sjs.Object { + val returnValue: Reference +} + +@ScalaJSDefined +trait TypeParams extends sjs.Object { + val typeParams: sjs.Array[String] +} + +@ScalaJSDefined +trait SuperTypes extends sjs.Object { + val superTypes: sjs.Array[MaterializableLink] +} + @ScalaJSDefined trait Package extends Entity with Members @@ -51,9 +73,9 @@ trait Object extends Class trait Trait extends Class @ScalaJSDefined -trait Def extends Entity with Modifiers { +trait Def extends Entity with Modifiers with ReturnValue { val typeParams: sjs.Array[String] - //val paramLists: sjs.Array[sjs.Array[(String, _)]] + val paramLists: sjs.Array[sjs.Array[NamedReference]] } @ScalaJSDefined @@ -63,9 +85,18 @@ trait Val extends Entity with Modifiers trait Var extends Entity with Modifiers object ops { + val EntitiesWithModifiers = + "case class" :: "class" :: "object" :: "trait" :: "def" :: "val" :: Nil + val EntitiesWithMembers = "package" :: "case class" :: "class" :: "object" :: "trait" :: Nil + val EntitiesWithTypeParams = + "case class" :: "class" :: "trait" :: "def" :: Nil + + val EntitiesWithSuperTypes = + "case class" :: "class" :: "trait" :: "object" :: Nil + implicit class PackageOps(val p: Package) { def children: sjs.Array[Entity with Members] = p.members.collect { @@ -78,6 +109,7 @@ object ops { val name = p.name val path = p.path val members = mbrs + val comment = p.comment } } @@ -86,5 +118,21 @@ object ops { if (ent.kind == "def") ent.asInstanceOf[Def].typeParams else sjs.Array() + + def hasMembers: Boolean = + EntitiesWithMembers contains ent.kind + + def hasModifiers: Boolean = + EntitiesWithModifiers contains ent.kind + + def hasTypeParams: Boolean = + EntitiesWithTypeParams contains ent.kind + + def hasSuperTypes: Boolean = + EntitiesWithSuperTypes contains ent.kind + + def isPrivate: Boolean = + hasModifiers && + ent.asInstanceOf[Modifiers].modifiers.contains("private") } } diff --git a/dottydoc/js/src/model/references.scala b/dottydoc/js/src/model/references.scala new file mode 100644 index 000000000000..8e725b5d9a67 --- /dev/null +++ b/dottydoc/js/src/model/references.scala @@ -0,0 +1,65 @@ +package dotty.tools +package dottydoc +package js +package model + +import scala.scalajs.{ js => sjs } +import sjs.annotation.ScalaJSDefined + +/** Type References */ +@ScalaJSDefined +sealed trait Reference extends sjs.Object { + val kind: String +} + +@ScalaJSDefined +trait TypeReference extends Reference { + val title: String + val tpeLink: MaterializableLink + val paramLinks: sjs.Array[MaterializableLink] +} + +@ScalaJSDefined +trait OrTypeReference extends Reference { + val left: Reference + val right: Reference +} + +@ScalaJSDefined +trait AndTypeReference extends Reference { + val left: Reference + val right: Reference +} + +@ScalaJSDefined +trait NamedReference extends Reference { + val title: String + val ref: Reference +} + +@ScalaJSDefined +trait ConstantReference extends Reference { + val title: String +} + +/** Materializable links */ +@ScalaJSDefined +sealed trait MaterializableLink extends sjs.Object { + val kind: String + val title: String +} + +@ScalaJSDefined +trait UnsetLink extends MaterializableLink { + val query: String +} + +@ScalaJSDefined +trait MaterializedLink extends MaterializableLink { + val target: String +} + +@ScalaJSDefined +trait NoLink extends MaterializableLink { + val target: String +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 6d8e85d87aee..105aeaef6c6c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -42,7 +42,7 @@ trait TypeLinker extends MemberLookup { rv match { case rv @ TypeReference(_, UnsetLink(t, query), tps) => val inlineToHtml = InlineToHtml(ent) - val title = inlineToHtml(t) + val title = t def handleEntityLink(title: String, lt: LinkTo): MaterializableLink = lt match { case Tooltip(str) => NoLink(title, str) @@ -50,11 +50,11 @@ trait TypeLinker extends MemberLookup { case LinkToEntity(target) => MaterializedLink(title, util.traversing.relativePath(ent, target)) } - val target = handleEntityLink(title, makeEntityLink(ent, packs, t, NoPosition, query).link) + val target = handleEntityLink(title, makeEntityLink(ent, packs, Text(t), NoPosition, query).link) val tpTargets = tps.map { case UnsetLink(t, query) => - handleEntityLink(inlineToHtml(t), makeEntityLink(ent, packs, t, NoPosition, query).link) + handleEntityLink(t, makeEntityLink(ent, packs, Text(t), NoPosition, query).link) case x => x } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 8496a11b8510..f1abafc8be57 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -2,13 +2,12 @@ package dotty.tools.dottydoc package html import scalatags.Text.all._ -import model.internal._ import model._ case class EntityPage(entity: Entity, packages: Map[String, Package]) { import CustomTags._ - import model.pickling._ - import prickle._ + import spray.json._ + import model.json._ import util.internal.setters._ private def relPath(to: String, from: Entity) = { @@ -79,7 +78,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ) ), script( - raw(s"""|UnparsedIndex.currentEntity = ${Pickle.intoString(entity.flat)}; + raw(s"""|UnparsedIndex.currentEntity = ${entity.flat.toJson}; |dotty.tools.dottydoc.js.DottyDocJS() | .main(document.getElementById("entity-container")); """.stripMargin) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 71ed12cecdb8..0b6c00a84aa7 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -27,20 +27,20 @@ object json extends DefaultJsonProtocol { implicit object MaterializableLinkFormat extends RootJsonFormat[MaterializableLink] { def write(obj: MaterializableLink) = obj match { - case obj: MaterializedLink => obj.toJson - case obj: UnsetLink => obj.toJson - case obj: NoLink => obj.toJson + case obj: MaterializedLink => addKind(obj.toJson, "MaterializedLink") + case obj: UnsetLink => addKind(obj.toJson, "UnsetLink") + case obj: NoLink => addKind(obj.toJson, "NoLink") } def read(json: JsValue) = ??? // The json serialization is supposed to be one way } implicit object ReferenceFormat extends RootJsonFormat[Reference] { def write(obj: Reference) = obj match { - case obj: AndTypeReference => obj.toJson - case obj: OrTypeReference => obj.toJson - case obj: TypeReference => obj.toJson - case obj: NamedReference => obj.toJson - case obj: ConstantReference => obj.toJson + case obj: AndTypeReference => addKind(obj.toJson, "AndTypeReference") + case obj: OrTypeReference => addKind(obj.toJson, "OrTypeReference") + case obj: TypeReference => addKind(obj.toJson, "TypeReference") + case obj: NamedReference => addKind(obj.toJson, "NamedReference") + case obj: ConstantReference => addKind(obj.toJson, "ConstantReference") } def read(json: JsValue) = ??? // The json serialization is supposed to be one way } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 37f1b05feb9a..526eff50cefe 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -94,8 +94,8 @@ final case class Tooltip(name: String) extends LinkTo final case class LinkToEntity(entity: Entity) extends LinkTo /** Use MaterializableLink for entities that need be picklable */ -sealed trait MaterializableLink { def title: Any } -final case class UnsetLink(title: Inline, query: String) extends MaterializableLink +sealed trait MaterializableLink { def title: String } +final case class UnsetLink(title: String, query: String) extends MaterializableLink final case class MaterializedLink(title: String, target: String) extends MaterializableLink final case class NoLink(title: String, target: String) extends MaterializableLink diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index c2c7f9940d93..452c1a3b4496 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -51,7 +51,7 @@ object factories { def returnType(t: Type)(implicit ctx: Context): Reference = { def typeRef(name: String, query: String = "", params: List[MaterializableLink] = Nil) = { val realQuery = if (query != "") query else name - TypeReference(name, UnsetLink(Text(name), realQuery), params) + TypeReference(name, UnsetLink(name, realQuery), params) } def expandTpe(t: Type, params: List[MaterializableLink] = Nil): Reference = t match { @@ -61,7 +61,7 @@ object factories { ta.alias.asInstanceOf[NamedType].name.show case _ => rn.show }).split("\\$").last - val param = UnsetLink(Text(paramName), paramName) + val param = UnsetLink(paramName, paramName) expandTpe(parent, param :: params) } case TypeRef(_, n) => @@ -140,7 +140,7 @@ object factories { cd.classParents.collect { case t: TypeRef if !isJavaLangObject(t) && !isProductWithArity(t) => - UnsetLink(Text(t.name.toString), path(t.symbol).mkString(".")) + UnsetLink(t.name.toString, path(t.symbol).mkString(".")) } case _ => Nil } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala deleted file mode 100644 index 76a2effa6a42..000000000000 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala +++ /dev/null @@ -1,44 +0,0 @@ -package dotty.tools.dottydoc -package model - -object pickling { - import internal._ - import prickle._ - import comment._ - - implicit val inlinePickler: PicklerPair[Inline] = CompositePickler[Inline] - .concreteType[Chain] - .concreteType[Italic] - .concreteType[Bold] - .concreteType[Underline] - .concreteType[Superscript] - .concreteType[Subscript] - .concreteType[Link] - .concreteType[Monospace] - .concreteType[Text] - - implicit val entityLinkPicker: PicklerPair[MaterializableLink] = CompositePickler[MaterializableLink] - .concreteType[UnsetLink] - .concreteType[NoLink] - .concreteType[MaterializedLink] - - implicit val referencePicker: PicklerPair[Reference] = CompositePickler[Reference] - .concreteType[TypeReference] - .concreteType[OrTypeReference] - .concreteType[AndTypeReference] - .concreteType[NamedReference] - .concreteType[ConstantReference] - - implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity] - .concreteType[NonEntity.type] - .concreteType[ValImpl] - .concreteType[DefImpl] - .concreteType[ClassImpl] - .concreteType[CaseClassImpl] - .concreteType[ObjectImpl] - .concreteType[TraitImpl] - .concreteType[PackageImpl] - - implicit val packagePickler: PicklerPair[Package] = CompositePickler[Package] - .concreteType[PackageImpl] -} diff --git a/project/Build.scala b/project/Build.scala index 48bdd987aa12..09f465d49ee0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -268,7 +268,6 @@ object DottyInjectedPlugin extends AutoPlugin { .jsSettings( libraryDependencies ++= Seq( "org.scala-js" %%% "scalajs-dom" % "0.9.0", - "com.github.benhutchison" %%% "prickle" % "1.1.10", "com.lihaoyi" %%% "scalatags" % "0.5.5" ) ) @@ -286,7 +285,6 @@ object DottyInjectedPlugin extends AutoPlugin { libraryDependencies ++= Seq( "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0", - "com.github.benhutchison" %% "prickle" % "1.1.10", "io.spray" %% "spray-json" % "1.3.2", "com.lihaoyi" %% "scalatags" % "0.5.5", "com.novocode" % "junit-interface" % "0.11" % "test" From 9bd61015d1b686f94424022f51fa25537d420808 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 4 Jul 2016 16:14:15 +0200 Subject: [PATCH 064/100] Remove spray-json dependency --- .../tools/dottydoc/html/EntityPage.scala | 3 +- .../src/dotty/tools/dottydoc/model/json.scala | 129 ++++++++---------- .../tools/dottydoc/util/OutputWriter.scala | 4 +- project/Build.scala | 1 - 4 files changed, 58 insertions(+), 79 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index f1abafc8be57..3ace813f0b45 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -6,7 +6,6 @@ import model._ case class EntityPage(entity: Entity, packages: Map[String, Package]) { import CustomTags._ - import spray.json._ import model.json._ import util.internal.setters._ @@ -78,7 +77,7 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { ) ), script( - raw(s"""|UnparsedIndex.currentEntity = ${entity.flat.toJson}; + raw(s"""|UnparsedIndex.currentEntity = ${entity.flat.json}; |dotty.tools.dottydoc.js.DottyDocJS() | .main(document.getElementById("entity-container")); """.stripMargin) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 0b6c00a84aa7..da6e4d909199 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -1,93 +1,76 @@ package dotty.tools.dottydoc package model -import spray.json._ +import model.comment._ -/** This object provides a protocol for serializing the package AST to JSON, - * this is supposed to be one-way for performance reasons +/** This object provides a protocol for serializing the package AST to JSON + * + * TODO: It might be a good ideat to represent the JSON better than just + * serializing a big string-blob in the future. */ -object json extends DefaultJsonProtocol { - import model._ - import model.comment._ - import model.internal._ +object json { + implicit class JsonString(val str: String) extends AnyVal { + def json: String = { + val cleanedString = str + .replaceAll("\\\\","\\\\\\\\") + .replaceAll("\\\"", "\\\\\"") + .replaceAll("\n", "\\\\n") - implicit val commentFormat = jsonFormat2(Comment.apply) - implicit val textFormat: JsonFormat[Text] = lazyFormat(jsonFormat(Text, "text")) - implicit object InlineJsonFormat extends RootJsonFormat[Inline] { - def write(i: Inline) = i match { - case i: Text => i.toJson - case _ => JsString("could not serialize") + s""""$cleanedString"""" } - def read(json: JsValue) = ??? // The json serialization is supposed to be one way } - implicit val matLinkFormat = lazyFormat(jsonFormat(MaterializedLink, "title", "target")) - implicit val noLinkFormat = lazyFormat(jsonFormat(NoLink, "title", "target")) - implicit val unsLinkFormat = lazyFormat(jsonFormat(UnsetLink, "title", "query")) - - implicit object MaterializableLinkFormat extends RootJsonFormat[MaterializableLink] { - def write(obj: MaterializableLink) = obj match { - case obj: MaterializedLink => addKind(obj.toJson, "MaterializedLink") - case obj: UnsetLink => addKind(obj.toJson, "UnsetLink") - case obj: NoLink => addKind(obj.toJson, "NoLink") - } - def read(json: JsValue) = ??? // The json serialization is supposed to be one way + implicit class JsonComment(val cmt: Comment) extends AnyVal { + def json: String = s"""{"body":${cmt.body.json},"short":${cmt.short.json}}""" } - implicit object ReferenceFormat extends RootJsonFormat[Reference] { - def write(obj: Reference) = obj match { - case obj: AndTypeReference => addKind(obj.toJson, "AndTypeReference") - case obj: OrTypeReference => addKind(obj.toJson, "OrTypeReference") - case obj: TypeReference => addKind(obj.toJson, "TypeReference") - case obj: NamedReference => addKind(obj.toJson, "NamedReference") - case obj: ConstantReference => addKind(obj.toJson, "ConstantReference") + implicit class LinkJson(val link: MaterializableLink) extends AnyVal { + def json: String = { + val (secondTitle, secondValue, kind) = link match { + case ul: UnsetLink => ("query".json, ul.query.json, "UnsetLink".json) + case ml: MaterializedLink => ("target", ml.target.json, "MaterializedLink".json) + case nl: NoLink => ("target".json, nl.target.json, "NoLink".json) + } + s"""{"title":${link.title.json},$secondTitle:${secondValue},"kind":$kind}""" } - def read(json: JsValue) = ??? // The json serialization is supposed to be one way } - implicit val tpeRefFormat = lazyFormat(jsonFormat(TypeReference, "title", "tpeLink", "paramLinks")) - implicit val orRefFormat = lazyFormat(jsonFormat(OrTypeReference, "left", "right")) - implicit val andRefFormat = lazyFormat(jsonFormat(AndTypeReference, "left", "right")) - implicit val namedRefFormat = lazyFormat(jsonFormat(NamedReference, "title", "ref")) - implicit val constRefFormat = lazyFormat(jsonFormat(ConstantReference, "title")) - - implicit object EntityJsonFormat extends RootJsonFormat[Entity] { - - def write(e: Entity) = e match { - case e: PackageImpl => addKind(e.toJson, "package") - case e: ClassImpl => addKind(e.toJson, "class") - case e: CaseClassImpl => addKind(e.toJson, "case class") - case e: TraitImpl => addKind(e.toJson, "trait") - case e: ObjectImpl => addKind(e.toJson, "object") - case e: DefImpl => addKind(e.toJson, "def") - case e: ValImpl => addKind(e.toJson, "val") - } - def read(json: JsValue) = ??? // The json serialization is supposed to be one way + private def refToJson(ref: Reference): String = ref match { + case ref: TypeReference => + s"""{"title":${ref.title.json},"tpeLink":${ref.tpeLink.json},"paramLinks":${ref.paramLinks.map(_.json).mkString("[",",","]")},"kind":"TypeReference"}""" + case ref: AndTypeReference => + s"""{"left":${refToJson(ref.left)},"right":${refToJson(ref.right)},"kind":"AndTypeReference"}""" + case ref: OrTypeReference => + s"""{"left":${refToJson(ref.left)},"right":${refToJson(ref.right)},"kind":"OrTypeReference"}""" + case ref: NamedReference => + s"""{"title":${ref.title.json},"ref":${refToJson(ref.ref)},"kind":"NamedReference"}""" + case ref: ConstantReference => + s"""{"title":${ref.title.json},"kind": "ConstantReference"}""" } + implicit class ReferenceJson(val ref: Reference) extends AnyVal { def json: String = refToJson(ref) } - implicit object PackageFormat extends RootJsonFormat[Package] { - def write(obj: Package) = obj match { case obj: PackageImpl => addKind(obj.toJson, "package") } - def read(json: JsValue) = ??? // The json serialization is supposed to be one way + private def entToJson(ent: Entity): String = ent match { + case ent: Package => + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"package"}""" + case ent: Class => + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}""" + case ent: CaseClass => + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}""" + case ent: Trait => + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}""" + case ent: Object => + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" + case ent: Def => + s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"paramLists":${ent.paramLists.map{ xs =>xs.map(_.json).mkString("[",",","]")}.mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"def"}""" + case ent: Val => + s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"val"}""" } + implicit class EntityJson(val ent: Entity) extends AnyVal { def json: String = entToJson(ent) } + implicit class PackageJson(val pack: Package) extends AnyVal { def json: String = (pack: Entity).json } - private def addKind(json: JsValue, kind: String): JsValue = json match { - case json: JsObject => JsObject(json.fields + ("kind" -> JsString(kind))) - case other => other + implicit class PackMapJson(val packs: Map[String, Package]) extends AnyVal { + def json: String = packs + .map { case (k, v) => s"${k.json}: ${v.json}" } + .mkString("{",",","}") } - - implicit val valFormat: JsonFormat[ValImpl] = - lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment")) - implicit val defFormat: JsonFormat[DefImpl] = - lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "typeParams", "paramLists", "comment")) - implicit val objFormat: JsonFormat[ObjectImpl] = - lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "superTypes", "comment")) - implicit val traitormat: JsonFormat[TraitImpl] = - lazyFormat(jsonFormat(TraitImpl, "name", "members", "modifiers", "path", "typeParams", "superTypes", "comment")) - implicit val cclassFormat: JsonFormat[CaseClassImpl] = - lazyFormat(jsonFormat(CaseClassImpl, "name", "members", "modifiers", "path", "typeParams", "superTypes", "comment")) - implicit val classFormat: JsonFormat[ClassImpl] = - lazyFormat(jsonFormat(ClassImpl, "name", "members", "modifiers", "path", "typeParams", "superTypes", "comment")) - implicit val packageFormat: JsonFormat[PackageImpl] = - lazyFormat(jsonFormat(PackageImpl, "name", "members", "path", "comment")) } - diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala index 7febb520c63b..fdbcd49cb953 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -4,7 +4,6 @@ package util import java.io.{File => JFile, BufferedInputStream, FileInputStream, FileOutputStream, BufferedOutputStream} import html.EntityPage import model.Package -import spray.json._ import model.json._ class OutputWriter { @@ -31,8 +30,7 @@ class OutputWriter { } // Write full index to outPath - val pickled = packs.toJson - val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + pickled + ";" + val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + packs.json + ";" println("Writing index.js...") writeFile(js, outPath + "/", "index.js") diff --git a/project/Build.scala b/project/Build.scala index 09f465d49ee0..ca79167013f4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -285,7 +285,6 @@ object DottyInjectedPlugin extends AutoPlugin { libraryDependencies ++= Seq( "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0", - "io.spray" %% "spray-json" % "1.3.2", "com.lihaoyi" %% "scalatags" % "0.5.5", "com.novocode" % "junit-interface" % "0.11" % "test" ), From 5e88fe39ac7ac1422a13af39428143215297d23f Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 4 Jul 2016 16:51:07 +0200 Subject: [PATCH 065/100] Move frontend code to JS project - only kicker left in JVM project --- .../dottydoc => js/src}/html/CustomTags.scala | 3 +- dottydoc/js/src/html/EntityLayout.scala | 169 +++++++++++++++--- .../tools/dottydoc/html/EntityPage.scala | 127 +------------ 3 files changed, 153 insertions(+), 146 deletions(-) rename dottydoc/{jvm/src/dotty/tools/dottydoc => js/src}/html/CustomTags.scala (83%) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala b/dottydoc/js/src/html/CustomTags.scala similarity index 83% rename from dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala rename to dottydoc/js/src/html/CustomTags.scala index ed462f21bea8..af3667f11d0e 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala +++ b/dottydoc/js/src/html/CustomTags.scala @@ -1,7 +1,8 @@ package dotty.tools.dottydoc +package js package html -import scalatags.Text.all._ +import scalatags.JsDom.all._ import scalatags.generic import scalatags.generic.Util import org.scalajs.dom diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index e08425c244ce..251644075c61 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -9,29 +9,131 @@ import js.model._ import js.model.ops._ case class EntityLayout(entity: Entity) extends MemberLayout { - def html = div( - cls := "page-content", - div(cls := "entity-title", entityTitle), - div(raw(entity.comment.fold("")(_.body))), - entity match { - case x if x.hasMembers => - val e = x.asInstanceOf[Entity with Members] - if (e.members.nonEmpty) - Seq( - h5("Members"), - div( - cls := "mld-grid", - e.members - .collect { - case x if x.hasModifiers && !x.isPrivate => x - } - .flatMap(member(_, entity)).toList - ) - ) - case _ => () + import CustomTags._ + import EntityIndex.packages + + private def relativePath(to: Entity) = { + val offset = entity.kind match { + case "val" | "def" => 2 + case _ => 1 + } + + val prefix = entity.kind match { + case "package" => "../" + case _ => "" + } + + prefix + { + "../" * (entity.path.length - offset) + to.path.mkString("","/",".html") + } + } + + def html = + div( + cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", + div( + cls := "mdl-layout__drawer", + span( + cls := "mdl-layout-title subtitle", + entity.path.dropRight(1).mkString(".") + ), + span( + cls := "mdl-layout-title", + if (entity.kind == "package") entity.name.split("\\.").last + else entity.name + ), + nav( + cls := "related mdl-navigation", + companionAnchor, + a(cls := "mdl-navigation__link", href := "#", "Source") + ), + span( + cls := "mdl-layout-title", + id := "docs-title", + "Docs" + ), + searchView, + packageView + ), + main( + id := "entity-container", + cls := "mdl-layout__content", + div( + cls := "page-content", + div(cls := "entity-title", entityTitle), + div(raw(entity.comment.fold("")(_.body))), + entity match { + case x if x.hasMembers => + val e = x.asInstanceOf[Entity with Members] + if (e.members.nonEmpty) + Seq( + h5("Members"), + div( + cls := "mld-grid", + e.members + .collect { + case x if x.hasModifiers && !x.isPrivate => x + } + .flatMap(member(_, entity)).toList + ) + ) + case _ => () + } + ) + ), + main( + id := "search-results", + cls := "mdl-layout__content" + ) + ) + + def packageView = ul( + cls := "mdl-list packages", + { + val keys: Seq[String] = packages.keys.toSeq.sorted + val productReg = """^Product[0-9]+$""".r + keys.flatMap { k => + val pack = packages(k) + val children = + pack.children + .sortBy(_.name) + .filterNot { ent => + // Filter out ProductX where X > 3 + productReg.findFirstIn(ent.name).map(_.slice(7, 99).toInt > 3).getOrElse(false) || + // Filter out packages + ent.kind == "package" || + // Filter out objects that have companions + (ent.kind == "object" && companion(ent).isDefined) || + ent.name == "AnyValCompanion" + } + .map { entity => + val comp = companion(entity) + val entityUrl = relativePath(entity) + val compUrl = comp.map(relativePath).getOrElse("#") + li( + cls := s"""mdl-list__item entity ${ if (comp.isDefined) "two" else "one" }""", + comp.map { _ => a(cls := "entity-button object", href := compUrl, "O") }.getOrElse(()), + a( + cls := s"""entity-button shadowed ${entity.kind.replaceAll(" ", "")}""", + href := entityUrl, + entity.kind(0).toUpper.toString + ), + a( + cls := "entity-name", + href := entityUrl, + entity.name + ) + ) + } + + if (children.length > 0) + li(cls := "mdl-list__item package", href := relativePath(pack), k) :: children.toList + else Nil + } } ) + def entityTitle = { val modifiers = entity.kind match { case "Modifiers" => @@ -74,4 +176,31 @@ case class EntityLayout(entity: Entity) extends MemberLayout { Nil }.flatten + + def companion(entity: Entity) = { + val pack = entity.path.dropRight(1).mkString(".") + for { + p <- packages.get(pack) + child <- p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) + } yield child + } + + def companionAnchor = + companion(entity).map { c => + a( + cls := "mdl-navigation__link", + href := c.path.last + ".html", + "Companion " + c.kind + ) + }.getOrElse(span()) + + def searchView = + div( + cls := "search-container", + div( + cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", + input(cls := "mdl-textfield__input", `type` := "text", id := "search"), + label(cls := "mdl-textfield__label", `for` := "search", "Search") + ) + ) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala index 3ace813f0b45..6eee9abf9403 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala @@ -5,7 +5,6 @@ import scalatags.Text.all._ import model._ case class EntityPage(entity: Entity, packages: Map[String, Package]) { - import CustomTags._ import model.json._ import util.internal.setters._ @@ -34,134 +33,12 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) { link(rel := "stylesheet", href := relPath("static/github.css", entity)), link(rel := "stylesheet", href := relPath("static/index.css", entity)) ), - body( - div( - id := "main-container", - div( - cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", - div( - cls := "mdl-layout__drawer", - span( - cls := "mdl-layout-title subtitle", - entity.path.dropRight(1).mkString(".") - ), - span( - cls := "mdl-layout-title", - entity match { - case p: Package => p.name.split("\\.").last - case e => e.name - } - ), - nav( - cls := "related mdl-navigation", - companionAnchor, - a(cls := "mdl-navigation__link", href := "#", "Source") - ), - span( - cls := "mdl-layout-title", - id := "docs-title", - "Docs" - ), - searchView, - packageView - ), - main( - id := "entity-container", - cls := "mdl-layout__content" - ), - main( - id := "search-results", - cls := "mdl-layout__content" - ) - ) - ) - ), + body(div(id := "main-container")), script( raw(s"""|UnparsedIndex.currentEntity = ${entity.flat.json}; |dotty.tools.dottydoc.js.DottyDocJS() - | .main(document.getElementById("entity-container")); + | .main(document.getElementById("main-container")); """.stripMargin) ) ) - - private def relativePath(to: Entity) = { - val prefix = entity match { - case _: Package => "../" - case _ => "" - } - prefix + util.traversing.relativePath(entity, to) - } - - def packageView = ul( - cls := "mdl-list packages", - { - val keys: Seq[String] = packages.keys.toSeq.sorted - val productReg = """^Product[0-9]+$""".r - keys.flatMap { k => - val pack = packages(k) - val children = - pack.children - .sortBy(_.name) - .filterNot { ent => - // Filter out ProductX where X > 3 - productReg.findFirstIn(ent.name).map(_.slice(7, 99).toInt > 3).getOrElse(false) || - // Filter out packages - ent.kind == "package" || - // Filter out objects that have companions - (ent.kind == "object" && companion(ent).isDefined) || - ent.name == "AnyValCompanion" - } - .map { entity => - val comp = companion(entity) - val entityUrl = relativePath(entity) - val compUrl = comp.map(relativePath).getOrElse("#") - li( - cls := s"""mdl-list__item entity ${ if (comp.isDefined) "two" else "one" }""", - comp.map { _ => a(cls := "entity-button object", href := compUrl, "O") }.getOrElse(()), - a( - cls := s"""entity-button shadowed ${entity.kind.replaceAll(" ", "")}""", - href := entityUrl, - entity.kind(0).toUpper.toString - ), - a( - cls := "entity-name", - href := entityUrl, - entity.name - ) - ) - } - - if (children.length > 0) - li(cls := "mdl-list__item package", href := relativePath(pack), k) :: children - else Nil - } - } - ) - - def companion(entity: Entity) = { - val pack = entity.path.dropRight(1).mkString(".") - (for { - p <- packages.get(pack) - child <- p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) - } yield child) - } - - def companionAnchor = { - companion(entity).map { c => - a( - cls := "mdl-navigation__link", - href := c.path.last + ".html", - "Companion " + c.kind - ) - }.getOrElse(span()) - } - - def searchView = div( - cls := "search-container", - div( - cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", - input(cls := "mdl-textfield__input", `type` := "text", id := "search"), - label(cls := "mdl-textfield__label", `for` := "search", "Search") - ) - ) } From 7d8dadeffe73ebe6bbf094c7e2ca3ee9d18528fd Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 11 Jul 2016 13:30:53 +0200 Subject: [PATCH 066/100] Implement by name in parameter lists --- dottydoc/js/src/html/Member.scala | 2 +- dottydoc/js/src/model/references.scala | 1 + .../src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala | 2 +- dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala | 6 +++++- .../dotty/tools/dottydoc/model/comment/BodyEntities.scala | 2 +- .../main/scala/dotty/tools/dottydoc/model/factories.scala | 2 +- 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 1786f745a5a1..772a1ed23dec 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -86,7 +86,7 @@ trait MemberLayout { xs.flatMap { tr => Seq( span(cls := "param-name", tr.title).render, - span(cls := "type-separator no-left-margin", ":").render, + span(cls := "type-separator no-left-margin", if (tr.isByName) ": =>" else ":").render, span(referenceToLinks(tr.ref)).render, span(cls := "type-separator no-left-margin", ",").render ) diff --git a/dottydoc/js/src/model/references.scala b/dottydoc/js/src/model/references.scala index 8e725b5d9a67..3fab228af1a0 100644 --- a/dottydoc/js/src/model/references.scala +++ b/dottydoc/js/src/model/references.scala @@ -35,6 +35,7 @@ trait AndTypeReference extends Reference { trait NamedReference extends Reference { val title: String val ref: Reference + val isByName: Boolean } @ScalaJSDefined diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 105aeaef6c6c..c1ad520fff60 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -63,7 +63,7 @@ trait TypeLinker extends MemberLookup { rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) case rv @ AndTypeReference(left, right) => rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) - case rv @ NamedReference(_, ref) => rv.copy(ref = linkReference(ent, ref, packs)) + case rv @ NamedReference(_, ref, _) => rv.copy(ref = linkReference(ent, ref, packs)) case _ => rv } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index da6e4d909199..621ab08686a3 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -20,6 +20,10 @@ object json { } } + implicit class JsonBoolean(val boo: Boolean) extends AnyVal { + def json: String = if (boo) "true" else "false" + } + implicit class JsonComment(val cmt: Comment) extends AnyVal { def json: String = s"""{"body":${cmt.body.json},"short":${cmt.short.json}}""" } @@ -43,7 +47,7 @@ object json { case ref: OrTypeReference => s"""{"left":${refToJson(ref.left)},"right":${refToJson(ref.right)},"kind":"OrTypeReference"}""" case ref: NamedReference => - s"""{"title":${ref.title.json},"ref":${refToJson(ref.ref)},"kind":"NamedReference"}""" + s"""{"title":${ref.title.json},"ref":${refToJson(ref.ref)},"isByName":${ref.isByName.json},"kind":"NamedReference"}""" case ref: ConstantReference => s"""{"title":${ref.title.json},"kind": "ConstantReference"}""" } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 526eff50cefe..d7ad4de71b23 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -103,5 +103,5 @@ sealed trait Reference final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[MaterializableLink]) extends Reference final case class OrTypeReference(left: Reference, right: Reference) extends Reference final case class AndTypeReference(left: Reference, right: Reference) extends Reference -final case class NamedReference(title: String, ref: Reference) extends Reference +final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false) extends Reference final case class ConstantReference(title: String) extends Reference diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 452c1a3b4496..72e52a96f1f4 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -113,7 +113,7 @@ object factories { case mt: MethodType => mt.paramNames.zip(mt.paramTypes).map { case (name, tpe) => - NamedReference(name.decode.toString, returnType(tpe)) + NamedReference(name.decode.toString, returnType(tpe), tpe.isInstanceOf[ExprType]) } :: paramLists(mt.resultType) case annot: AnnotatedType => paramLists(annot.tpe) From 61169c03c78af7fff428d20f3249e2de2d21fd96 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 11 Jul 2016 14:17:45 +0200 Subject: [PATCH 067/100] Add warning message on UnsetLink in doc-ui --- dottydoc/js/src/html/Member.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 772a1ed23dec..271885753df4 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -106,8 +106,9 @@ trait MemberLayout { a(href := url, t).render case "NoLink" => span(link.title).render - //FIXME: there should be no UnsetLinks - either MaterializedLink or NoLink - case "UnsetLink" => span(link.title).render + case "UnsetLink" => + println(s"UnsetLink found: $link") + span(link.title).render } ref.kind match { From 00ea4fc5f46ebc984ac68a463b3a87d553a2c2f4 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Sat, 16 Jul 2016 15:51:53 +0200 Subject: [PATCH 068/100] Rebase dottydoc over new HK scheme --- .../dotty/tools/dottydoc/core/DocASTPhase.scala | 2 +- .../tools/dottydoc/core/DocImplicitsPhase.scala | 2 +- .../dotty/tools/dottydoc/model/factories.scala | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala index 72e679565e5a..a2d440e8c92c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -56,7 +56,7 @@ class DocASTPhase extends Phase { } def addedFromSymbol(sym: Symbol): List[Entity] = { - val defs = sym.info.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => + val defs = sym.info.bounds.hi.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => track(meth.symbol, ctx) { DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), paramLists(meth.info)) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala index 0847648568c4..5d53d639719d 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala @@ -18,7 +18,7 @@ class DocImplicitsPhase extends MiniPhaseTransform { thisTransformer => tree.vparamss.length > 0 && tree.vparamss(0).length == 1 // should only take one arg, since it has to be a transformation ) { - val convertee = tree.vparamss(0)(0).symbol.info.widenDealias.finalResultType.typeSymbol//denot.typeRef // the pimped type (i.e. `class`) + val convertee = tree.vparamss(0)(0).symbol.info.widenDealias.finalResultType.typeSymbol // the pimped type (i.e. `class`) ctx.base.addDef(convertee, tree.symbol.info.widenDealias.finalResultType.typeSymbol) } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 72e52a96f1f4..ef4854979d8d 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -55,8 +55,8 @@ object factories { } def expandTpe(t: Type, params: List[MaterializableLink] = Nil): Reference = t match { - case ref @ RefinedType(parent, rn) => { - val paramName = (ref.refinedInfo match { + case ref @ RefinedType(parent, rn, info) => { + val paramName = (info match { case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => ta.alias.asInstanceOf[NamedType].name.show case _ => rn.show @@ -64,6 +64,15 @@ object factories { val param = UnsetLink(paramName, paramName) expandTpe(parent, param :: params) } + case HKApply(tycon, args) => + def paramName: Type => String = { tpe => + (tpe match { + case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => + ta.alias.asInstanceOf[NamedType].name.show + case _ => tpe.show + }).split("\\$").last + } + expandTpe(tycon, args.map(paramName).map(x => UnsetLink(x,x))) case TypeRef(_, n) => val name = n.decode.toString.split("\\$").last typeRef(name, params = params) @@ -118,7 +127,7 @@ object factories { case annot: AnnotatedType => paramLists(annot.tpe) case (_: PolyParam | _: RefinedType | _: TypeRef | _: ThisType | - _: ExprType | _: OrType | _: AndType) => Nil // return types should not be in the paramlist + _: ExprType | _: OrType | _: AndType | _: HKApply) => Nil // return types should not be in the paramlist } def superTypes(t: Tree)(implicit ctx: Context): List[MaterializableLink] = t.symbol.denot match { From a284cad4e58d48dd6fbaa0219bf00a2fd90e3d9d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 19 Jul 2016 15:17:23 +0200 Subject: [PATCH 069/100] Change TypeReference#paramLinks' type from `MaterializableLink` to `Reference` --- dottydoc/js/src/model/references.scala | 2 +- .../src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala | 8 +------- .../dotty/tools/dottydoc/model/comment/BodyEntities.scala | 2 +- .../main/scala/dotty/tools/dottydoc/model/factories.scala | 7 ++++--- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/dottydoc/js/src/model/references.scala b/dottydoc/js/src/model/references.scala index 3fab228af1a0..b0e8a86749ee 100644 --- a/dottydoc/js/src/model/references.scala +++ b/dottydoc/js/src/model/references.scala @@ -16,7 +16,7 @@ sealed trait Reference extends sjs.Object { trait TypeReference extends Reference { val title: String val tpeLink: MaterializableLink - val paramLinks: sjs.Array[MaterializableLink] + val paramLinks: sjs.Array[Reference] } @ScalaJSDefined diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index c1ad520fff60..a6d474c8fac7 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -51,13 +51,7 @@ trait TypeLinker extends MemberLookup { } val target = handleEntityLink(title, makeEntityLink(ent, packs, Text(t), NoPosition, query).link) - - val tpTargets = tps.map { - case UnsetLink(t, query) => - handleEntityLink(t, makeEntityLink(ent, packs, Text(t), NoPosition, query).link) - case x => x - } - + val tpTargets = tps.map(linkReference(ent, _, packs)) rv.copy(tpeLink = target, paramLinks = tpTargets) case rv @ OrTypeReference(left, right) => rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index d7ad4de71b23..691661ac5611 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -100,7 +100,7 @@ final case class MaterializedLink(title: String, target: String) extends Materia final case class NoLink(title: String, target: String) extends MaterializableLink sealed trait Reference -final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[MaterializableLink]) extends Reference +final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[Reference]) extends Reference final case class OrTypeReference(left: Reference, right: Reference) extends Reference final case class AndTypeReference(left: Reference, right: Reference) extends Reference final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false) extends Reference diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index ef4854979d8d..8453b528fe36 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -4,6 +4,7 @@ package model import comment._ import dotty.tools.dotc import dotc.core.Types._ +import dotc.core.TypeApplications._ import dotc.core.Flags import dotc.core.Contexts.Context import dotc.core.Symbols.Symbol @@ -49,7 +50,7 @@ object factories { } def returnType(t: Type)(implicit ctx: Context): Reference = { - def typeRef(name: String, query: String = "", params: List[MaterializableLink] = Nil) = { + def typeRef(name: String, query: String = "", params: List[Reference] = Nil) = { val realQuery = if (query != "") query else name TypeReference(name, UnsetLink(name, realQuery), params) } @@ -76,6 +77,8 @@ object factories { case TypeRef(_, n) => val name = n.decode.toString.split("\\$").last typeRef(name, params = params) + case ta: TypeAlias => + expandTpe(ta.alias.widenDealias) case OrType(left, right) => OrTypeReference(expandTpe(left), expandTpe(right)) case AndType(left, right) => @@ -90,8 +93,6 @@ object factories { expandTpe(tt.underlying) case ci: ClassInfo => typeRef(ci.cls.show) - case ta: TypeAlias => - expandTpe(ta.alias.widenDealias) case mt: MethodType => expandTpe(mt.resultType) case pt: PolyType => From fe1ff8f0570d3d582a884a9b8f35a14235c0c71f Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 19 Jul 2016 15:19:04 +0200 Subject: [PATCH 070/100] Fix #28: render functions passed as arguments --- dottydoc/js/src/html/Member.scala | 50 ++++++++++++++++++- dottydoc/js/src/model/references.scala | 12 +++++ .../src/dotty/tools/dottydoc/model/json.scala | 4 ++ .../dottydoc/model/comment/BodyEntities.scala | 2 + .../tools/dottydoc/model/factories.scala | 38 +++++++------- 5 files changed, 85 insertions(+), 21 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 271885753df4..1d84e7831659 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -119,7 +119,7 @@ trait MemberLayout { "[", tref .paramLinks - .map(linkToAnchor) + .map(referenceToLinks) .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)) .toList.dropRight(1), "]" @@ -141,6 +141,30 @@ trait MemberLayout { span(cls := "type-separator", "&"), referenceToLinks(right) ).render + + case "BoundsReference" => + val (low, high) = (ref.asInstanceOf[BoundsReference].low, ref.asInstanceOf[BoundsReference].high) + span( + referenceToLinks(low), + span(cls := "type-separator", "<:"), + referenceToLinks(high) + ).render + + case "FunctionReference" => { + val func = ref.asInstanceOf[FunctionReference] + span( + cls := "no-left-margin", + if (func.args.length > 1) "(" else "", + if (func.args.isEmpty) + span("()") + else func + .args + .map(referenceToLinks) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, + if (func.args.length > 1) ") => " else " => ", + referenceToLinks(func.returnValue) + ).render + } } } @@ -183,7 +207,7 @@ trait MemberLayout { returnValue, "[", trv.paramLinks - .map(decodeTpeLink) + .map(link) .flatMap { sp => Seq(sp, span(cls := "type-separator no-left-margin", ",").render) } @@ -208,6 +232,28 @@ trait MemberLayout { span(cls := "type-separator", "&"), link(right) ).render + + case "BoundsReference" => + val (low, high) = (rv.asInstanceOf[BoundsReference].low, rv.asInstanceOf[BoundsReference].high) + span( + link(low), + span(cls := "type-separator", "<:"), + link(high) + ).render + case "FunctionReference" => + val func = rv.asInstanceOf[FunctionReference] + span( + cls := "no-left-margin", + if (func.args.length > 1) "(" else "", + if (func.args.isEmpty) + span("()") + else func + .args + .map(link) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, + if (func.args.length > 1) ") => " else " => ", + link(func.returnValue) + ).render } } diff --git a/dottydoc/js/src/model/references.scala b/dottydoc/js/src/model/references.scala index b0e8a86749ee..7cd396e94f33 100644 --- a/dottydoc/js/src/model/references.scala +++ b/dottydoc/js/src/model/references.scala @@ -31,6 +31,12 @@ trait AndTypeReference extends Reference { val right: Reference } +@ScalaJSDefined +trait BoundsReference extends Reference { + val low: Reference + val high: Reference +} + @ScalaJSDefined trait NamedReference extends Reference { val title: String @@ -43,6 +49,12 @@ trait ConstantReference extends Reference { val title: String } +@ScalaJSDefined +trait FunctionReference extends Reference { + val args: sjs.Array[Reference] + val returnValue: Reference +} + /** Materializable links */ @ScalaJSDefined sealed trait MaterializableLink extends sjs.Object { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 621ab08686a3..52bb9d36ca53 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -46,10 +46,14 @@ object json { s"""{"left":${refToJson(ref.left)},"right":${refToJson(ref.right)},"kind":"AndTypeReference"}""" case ref: OrTypeReference => s"""{"left":${refToJson(ref.left)},"right":${refToJson(ref.right)},"kind":"OrTypeReference"}""" + case ref: BoundsReference => + s"""{"low":${refToJson(ref.low)},"high":${refToJson(ref.high)},"kind":"BoundsReference"}""" case ref: NamedReference => s"""{"title":${ref.title.json},"ref":${refToJson(ref.ref)},"isByName":${ref.isByName.json},"kind":"NamedReference"}""" case ref: ConstantReference => s"""{"title":${ref.title.json},"kind": "ConstantReference"}""" + case ref: FunctionReference => + s"""{"args":${ref.args.map(refToJson).mkString("[",",","]")},"returnValue":${refToJson(ref.returnValue)},"kind": "FunctionReference"}""" } implicit class ReferenceJson(val ref: Reference) extends AnyVal { def json: String = refToJson(ref) } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 691661ac5611..b8918c493c43 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -103,5 +103,7 @@ sealed trait Reference final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[Reference]) extends Reference final case class OrTypeReference(left: Reference, right: Reference) extends Reference final case class AndTypeReference(left: Reference, right: Reference) extends Reference +final case class FunctionReference(args: List[Reference], returnValue: Reference) extends Reference +final case class BoundsReference(low: Reference, high: Reference) extends Reference final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false) extends Reference final case class ConstantReference(title: String) extends Reference diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index 8453b528fe36..a48f6d9b0ef3 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -55,25 +55,23 @@ object factories { TypeReference(name, UnsetLink(name, realQuery), params) } - def expandTpe(t: Type, params: List[MaterializableLink] = Nil): Reference = t match { - case ref @ RefinedType(parent, rn, info) => { - val paramName = (info match { - case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => - ta.alias.asInstanceOf[NamedType].name.show - case _ => rn.show - }).split("\\$").last - val param = UnsetLink(paramName, paramName) - expandTpe(parent, param :: params) - } - case HKApply(tycon, args) => - def paramName: Type => String = { tpe => - (tpe match { - case ta: TypeAlias if ta.alias.isInstanceOf[NamedType] => - ta.alias.asInstanceOf[NamedType].name.show - case _ => tpe.show - }).split("\\$").last - } - expandTpe(tycon, args.map(paramName).map(x => UnsetLink(x,x))) + def expandTpe(t: Type, params: List[Reference] = Nil): Reference = t match { + case tl: TypeLambda => + //FIXME: should be handled correctly + // example, in `Option`: + // + // {{{ + // def companion: GenericCompanion[collection.Iterable] + // }}} + // + // Becomes: def companion: [+X0] -> collection.Iterable[X0] + typeRef(tl.show + " (not handled)") + case AppliedType(tycon, args) => + FunctionReference(args.init.map(expandTpe(_, Nil)), expandTpe(args.last)) + case ref @ RefinedType(parent, rn, info) => + expandTpe(parent) //FIXME: will be a refined HK, aka class Foo[X] { def bar: List[X] } or similar + case ref @ HKApply(tycon, args) => + expandTpe(tycon, args.map(expandTpe(_, params))) case TypeRef(_, n) => val name = n.decode.toString.split("\\$").last typeRef(name, params = params) @@ -83,6 +81,8 @@ object factories { OrTypeReference(expandTpe(left), expandTpe(right)) case AndType(left, right) => AndTypeReference(expandTpe(left), expandTpe(right)) + case tb @ TypeBounds(lo, hi) => + BoundsReference(expandTpe(lo), expandTpe(hi)) case AnnotatedType(tpe, _) => expandTpe(tpe) case ExprType(tpe) => From 7d8458ff50f56cee13698ce933a295090680d11e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 10:21:26 +0200 Subject: [PATCH 071/100] Add support for repeated parameters in producer --- dottydoc/js/src/model/references.scala | 6 ++++++ .../dotty/tools/dottydoc/core/TypeLinkingPhases.scala | 2 +- dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala | 2 +- .../tools/dottydoc/model/comment/BodyEntities.scala | 2 +- .../scala/dotty/tools/dottydoc/model/factories.scala | 9 ++++++++- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/dottydoc/js/src/model/references.scala b/dottydoc/js/src/model/references.scala index 7cd396e94f33..051251b68d07 100644 --- a/dottydoc/js/src/model/references.scala +++ b/dottydoc/js/src/model/references.scala @@ -42,6 +42,7 @@ trait NamedReference extends Reference { val title: String val ref: Reference val isByName: Boolean + val isRepeated: Boolean } @ScalaJSDefined @@ -55,6 +56,11 @@ trait FunctionReference extends Reference { val returnValue: Reference } +@ScalaJSDefined +trait TupleReference extends Reference { + val args: sjs.Array[Reference] +} + /** Materializable links */ @ScalaJSDefined sealed trait MaterializableLink extends sjs.Object { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index a6d474c8fac7..d05d1acbd94b 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -57,7 +57,7 @@ trait TypeLinker extends MemberLookup { rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) case rv @ AndTypeReference(left, right) => rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) - case rv @ NamedReference(_, ref, _) => rv.copy(ref = linkReference(ent, ref, packs)) + case rv @ NamedReference(_, ref, _, _) => rv.copy(ref = linkReference(ent, ref, packs)) case _ => rv } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 52bb9d36ca53..3618d325f0cd 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -49,7 +49,7 @@ object json { case ref: BoundsReference => s"""{"low":${refToJson(ref.low)},"high":${refToJson(ref.high)},"kind":"BoundsReference"}""" case ref: NamedReference => - s"""{"title":${ref.title.json},"ref":${refToJson(ref.ref)},"isByName":${ref.isByName.json},"kind":"NamedReference"}""" + s"""{"title":${ref.title.json},"ref":${refToJson(ref.ref)},"isByName":${ref.isByName.json},"isRepeated":${ref.isRepeated.json},"kind":"NamedReference"}""" case ref: ConstantReference => s"""{"title":${ref.title.json},"kind": "ConstantReference"}""" case ref: FunctionReference => diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index b8918c493c43..ef8343d7722b 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -105,5 +105,5 @@ final case class OrTypeReference(left: Reference, right: Reference) extends Refe final case class AndTypeReference(left: Reference, right: Reference) extends Reference final case class FunctionReference(args: List[Reference], returnValue: Reference) extends Reference final case class BoundsReference(low: Reference, high: Reference) extends Reference -final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false) extends Reference +final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false, isRepeated: Boolean = false) extends Reference final case class ConstantReference(title: String) extends Reference diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index a48f6d9b0ef3..bd38701d9f53 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -50,6 +50,8 @@ object factories { } def returnType(t: Type)(implicit ctx: Context): Reference = { + val defn = ctx.definitions + def typeRef(name: String, query: String = "", params: List[Reference] = Nil) = { val realQuery = if (query != "") query else name TypeReference(name, UnsetLink(name, realQuery), params) @@ -123,7 +125,12 @@ object factories { case mt: MethodType => mt.paramNames.zip(mt.paramTypes).map { case (name, tpe) => - NamedReference(name.decode.toString, returnType(tpe), tpe.isInstanceOf[ExprType]) + NamedReference( + name.decode.toString, + returnType(tpe), + isByName = tpe.isInstanceOf[ExprType], + isRepeated = tpe.isRepeatedParam + ) } :: paramLists(mt.resultType) case annot: AnnotatedType => paramLists(annot.tpe) From 354a67c964b344602148178bb567123badcc3b2b Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 10:22:14 +0200 Subject: [PATCH 072/100] Render repeated parameters correctly in client --- dottydoc/js/src/html/Member.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 1d84e7831659..184314f7119a 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -87,7 +87,9 @@ trait MemberLayout { Seq( span(cls := "param-name", tr.title).render, span(cls := "type-separator no-left-margin", if (tr.isByName) ": =>" else ":").render, + span(if (tr.ref.kind == "FunctionReference" && tr.isRepeated) "(" else "").render, span(referenceToLinks(tr.ref)).render, + span(if (tr.ref.kind == "FunctionReference" && tr.isRepeated) ")*" else if (tr.isRepeated) "*" else "").render, span(cls := "type-separator no-left-margin", ",").render ) }.toList.dropRight(1), From 3efdb93cb760cc243e6eddcf041286de7f04195e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 10:22:52 +0200 Subject: [PATCH 073/100] Add support for rendering tuples idiomatically --- dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala | 2 ++ .../scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala | 1 + 2 files changed, 3 insertions(+) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 3618d325f0cd..44129e9d8b82 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -54,6 +54,8 @@ object json { s"""{"title":${ref.title.json},"kind": "ConstantReference"}""" case ref: FunctionReference => s"""{"args":${ref.args.map(refToJson).mkString("[",",","]")},"returnValue":${refToJson(ref.returnValue)},"kind": "FunctionReference"}""" + case ref: TupleReference => + s"""{"args":${ref.args.map(refToJson).mkString("[",",","]")},"kind": "TupleReference"}""" } implicit class ReferenceJson(val ref: Reference) extends AnyVal { def json: String = refToJson(ref) } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala index ef8343d7722b..08da81059bfa 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -104,6 +104,7 @@ final case class TypeReference(title: String, tpeLink: MaterializableLink, param final case class OrTypeReference(left: Reference, right: Reference) extends Reference final case class AndTypeReference(left: Reference, right: Reference) extends Reference final case class FunctionReference(args: List[Reference], returnValue: Reference) extends Reference +final case class TupleReference(args: List[Reference]) extends Reference final case class BoundsReference(low: Reference, high: Reference) extends Reference final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false, isRepeated: Boolean = false) extends Reference final case class ConstantReference(title: String) extends Reference From 58b83ce614ae65d3a57517d37a66935e42a10d2d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 10:23:21 +0200 Subject: [PATCH 074/100] Render idiomatic tuples in client --- dottydoc/js/src/html/Member.scala | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 184314f7119a..7e39f9a4c957 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -167,6 +167,19 @@ trait MemberLayout { referenceToLinks(func.returnValue) ).render } + + case "TupleReference" => { + val func = ref.asInstanceOf[TupleReference] + span( + cls := "no-left-margin", + "(", + func + .args + .map(referenceToLinks) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, + ")" + ).render + } } } @@ -256,6 +269,19 @@ trait MemberLayout { if (func.args.length > 1) ") => " else " => ", link(func.returnValue) ).render + + case "TupleReference" => { + val func = rv.asInstanceOf[TupleReference] + span( + cls := "no-left-margin", + "(", + func + .args + .map(link) + .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, + ")" + ).render + } } } From c1b57e984a448248569adab579e91a79235ba1e7 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 10:23:47 +0200 Subject: [PATCH 075/100] Correctly parse tuples, functions and applied types like `Map[K,V]` from compiler internals --- .../scala/dotty/tools/dottydoc/model/factories.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index bd38701d9f53..c6ef6cb35a7b 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -69,7 +69,16 @@ object factories { // Becomes: def companion: [+X0] -> collection.Iterable[X0] typeRef(tl.show + " (not handled)") case AppliedType(tycon, args) => - FunctionReference(args.init.map(expandTpe(_, Nil)), expandTpe(args.last)) + val cls = tycon.typeSymbol + if (tycon.isRepeatedParam) + expandTpe(args.head) + else if (defn.isFunctionClass(cls)) + FunctionReference(args.init.map(expandTpe(_, Nil)), expandTpe(args.last)) + else if (defn.isTupleClass(cls)) + TupleReference(args.map(expandTpe(_, Nil))) + else + typeRef(tycon.show, params = args.map(expandTpe(_, Nil))) + case ref @ RefinedType(parent, rn, info) => expandTpe(parent) //FIXME: will be a refined HK, aka class Foo[X] { def bar: List[X] } or similar case ref @ HKApply(tycon, args) => From 5d6c15f023b07fd3b6a62b31a1ab32911b9ca01a Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 17:25:45 +0200 Subject: [PATCH 076/100] Handle all types of references when linking --- .../dottydoc/core/TypeLinkingPhases.scala | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index d05d1acbd94b..08898f3b173c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -38,9 +38,11 @@ class LinkParamListTypes extends DocMiniPhase with TypeLinker { } trait TypeLinker extends MemberLookup { - def linkReference(ent: Entity, rv: Reference, packs: Map[String, Package]): Reference = - rv match { - case rv @ TypeReference(_, UnsetLink(t, query), tps) => + def linkReference(ent: Entity, ref: Reference, packs: Map[String, Package]): Reference = { + def linkRef(ref: Reference) = linkReference(ent, ref, packs) + + ref match { + case ref @ TypeReference(_, UnsetLink(t, query), tps) => val inlineToHtml = InlineToHtml(ent) val title = t @@ -52,12 +54,21 @@ trait TypeLinker extends MemberLookup { val target = handleEntityLink(title, makeEntityLink(ent, packs, Text(t), NoPosition, query).link) val tpTargets = tps.map(linkReference(ent, _, packs)) - rv.copy(tpeLink = target, paramLinks = tpTargets) - case rv @ OrTypeReference(left, right) => - rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) - case rv @ AndTypeReference(left, right) => - rv.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) - case rv @ NamedReference(_, ref, _, _) => rv.copy(ref = linkReference(ent, ref, packs)) - case _ => rv + ref.copy(tpeLink = target, paramLinks = tpTargets) + case ref @ OrTypeReference(left, right) => + ref.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) + case ref @ AndTypeReference(left, right) => + ref.copy(left = linkReference(ent, left, packs), right = linkReference(ent, right, packs)) + case ref @ NamedReference(_, rf, _, _) => + ref.copy(ref = linkRef(rf)) + case ref @ FunctionReference(args, rv) => + ref.copy(args = args.map(linkReference(ent, _, packs)), returnValue = linkReference(ent, rv, packs)) + case ref @ TupleReference(args) => + ref.copy(args = args.map(linkRef)) + case ref @ BoundsReference(low, high) => + ref.copy(low = linkRef(low), high = linkRef(high)) + case _ => + ref } + } } From c05d62817bda480d16366a8c2041287c1524dadb Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 17:26:49 +0200 Subject: [PATCH 077/100] Change from absolute name to type name in link names --- .../main/scala/dotty/tools/dottydoc/model/factories.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index c6ef6cb35a7b..c18465c657c7 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -76,8 +76,11 @@ object factories { FunctionReference(args.init.map(expandTpe(_, Nil)), expandTpe(args.last)) else if (defn.isTupleClass(cls)) TupleReference(args.map(expandTpe(_, Nil))) - else - typeRef(tycon.show, params = args.map(expandTpe(_, Nil))) + else { + val query = tycon.show + val name = query.split("\\.").last + typeRef(name, query, params = args.map(expandTpe(_, Nil))) + } case ref @ RefinedType(parent, rn, info) => expandTpe(parent) //FIXME: will be a refined HK, aka class Foo[X] { def bar: List[X] } or similar From c53c115a10cce9b86898ee0af79838b1f9013267 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 17:53:32 +0200 Subject: [PATCH 078/100] Add indication that paramList takes implicit arguments --- dottydoc/js/src/html/Member.scala | 3 ++- dottydoc/js/src/model/entities.scala | 8 +++++++- dottydoc/jvm/resources/index.css | 3 ++- .../src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala | 4 ++-- dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala | 7 ++++++- dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala | 2 +- .../main/scala/dotty/tools/dottydoc/model/entities.scala | 7 ++++++- .../main/scala/dotty/tools/dottydoc/model/factories.scala | 7 ++++--- .../main/scala/dotty/tools/dottydoc/model/internal.scala | 7 ++++++- 9 files changed, 36 insertions(+), 12 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index 7e39f9a4c957..e7aa34c61ee5 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -83,7 +83,8 @@ trait MemberLayout { span( cls := "param-list", "(", - xs.flatMap { tr => + span(cls := "is-implicit no-left-margin", if (xs.isImplicit) "implicit " else ""), + xs.list.flatMap { tr => Seq( span(cls := "param-name", tr.title).render, span(cls := "type-separator no-left-margin", if (tr.isByName) ": =>" else ":").render, diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index adf7bc4ca921..4ae76c58c615 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -72,10 +72,16 @@ trait Object extends Class @ScalaJSDefined trait Trait extends Class +@ScalaJSDefined +trait ParamList extends sjs.Object { + val list: sjs.Array[NamedReference] + val isImplicit: Boolean +} + @ScalaJSDefined trait Def extends Entity with Modifiers with ReturnValue { val typeParams: sjs.Array[String] - val paramLists: sjs.Array[sjs.Array[NamedReference]] + val paramLists: sjs.Array[ParamList] } @ScalaJSDefined diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index 47e0ea7173d4..79eeaaee0bd4 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -128,7 +128,8 @@ div.member-definition > span+span { margin-left: 10px; } -div.member-definition > span.member-name { +div.member-definition > span.member-name, +div.member-definition > span.member-param-list span.is-implicit { color: #458; font-weight: 600; } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 08898f3b173c..0cf0923f3c87 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -29,9 +29,9 @@ class LinkReturnTypes extends DocMiniPhase with TypeLinker { class LinkParamListTypes extends DocMiniPhase with TypeLinker { override def transformDef(implicit ctx: Context) = { case df: DefImpl => val newParamLists = for { - list <- df.paramLists + ParamListImpl(list, isImplicit) <- df.paramLists newList = list.map(linkReference(df, _, ctx.base.packages[Package].toMap)) - } yield newList.asInstanceOf[List[NamedReference]] + } yield ParamListImpl(newList.asInstanceOf[List[NamedReference]], isImplicit) df.copy(paramLists = newParamLists) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index 44129e9d8b82..ea9658b5d252 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -39,6 +39,11 @@ object json { } } + implicit class ParamListJson(val plist: ParamList) extends AnyVal { + def json: String = + s"""{"list":${plist.list.map(_.json).mkString("[",",","]")},"isImplicit":${plist.isImplicit.json}}""" + } + private def refToJson(ref: Reference): String = ref match { case ref: TypeReference => s"""{"title":${ref.title.json},"tpeLink":${ref.tpeLink.json},"paramLinks":${ref.paramLinks.map(_.json).mkString("[",",","]")},"kind":"TypeReference"}""" @@ -71,7 +76,7 @@ object json { case ent: Object => s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" case ent: Def => - s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"paramLists":${ent.paramLists.map{ xs =>xs.map(_.json).mkString("[",",","]")}.mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"def"}""" + s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"paramLists":${ent.paramLists.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"def"}""" case ent: Val => s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"val"}""" } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala index 4ce94459de44..84e3beb5bc98 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala @@ -24,7 +24,7 @@ object setters { case _ => () } - def setParamLists(ent: Entity, refs: List[List[NamedReference]]) = ent match { + def setParamLists(ent: Entity, refs: List[ParamList]) = ent match { case x: DefImpl => x.paramLists = refs case _ => () } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala index 6f6f1e0b7b12..391bd514ff20 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala @@ -51,6 +51,11 @@ trait ReturnValue { def returnValue: Reference } +trait ParamList { + def list: List[NamedReference] + def isImplicit: Boolean +} + trait Package extends Entity with Members { val kind = "package" @@ -74,7 +79,7 @@ trait Object extends Entity with Modifiers with SuperTypes with Members { } trait Def extends Entity with Modifiers with TypeParams with ReturnValue { - def paramLists: List[List[NamedReference]] + def paramLists: List[ParamList] val kind = "def" } diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala index c18465c657c7..f0c78fa41cb1 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala @@ -16,6 +16,7 @@ import dotc.ast.Trees._ object factories { import dotty.tools.dotc.ast.tpd._ + import dotty.tools.dottydoc.model.internal.ParamListImpl import DottyFlags._ type TypeTree = dotty.tools.dotc.ast.Trees.Tree[Type] @@ -131,19 +132,19 @@ object factories { case _ => Nil } - def paramLists(tpe: Type)(implicit ctx: Context): List[List[NamedReference]] = tpe match { + def paramLists(tpe: Type)(implicit ctx: Context): List[ParamList] = tpe match { case pt: PolyType => paramLists(pt.resultType) case mt: MethodType => - mt.paramNames.zip(mt.paramTypes).map { case (name, tpe) => + ParamListImpl(mt.paramNames.zip(mt.paramTypes).map { case (name, tpe) => NamedReference( name.decode.toString, returnType(tpe), isByName = tpe.isInstanceOf[ExprType], isRepeated = tpe.isRepeatedParam ) - } :: paramLists(mt.resultType) + }, mt.isImplicit) :: paramLists(mt.resultType) case annot: AnnotatedType => paramLists(annot.tpe) case (_: PolyParam | _: RefinedType | _: TypeRef | _: ThisType | diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala index 0c204c06691b..ec1adfa889b7 100644 --- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala @@ -64,7 +64,7 @@ object internal { path: List[String], var returnValue: Reference, var typeParams: List[String] = Nil, - var paramLists: List[List[NamedReference]] = Nil, + var paramLists: List[ParamList] = Nil, var comment: Option[Comment] = None ) extends Def with Impl @@ -75,4 +75,9 @@ object internal { var returnValue: Reference, var comment: Option[Comment] = None ) extends Val with Impl + + final case class ParamListImpl( + list: List[NamedReference], + isImplicit: Boolean + ) extends ParamList } From a1c73e9cdf8a47c3e892a12b21d1b7028f20340d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 18:09:58 +0200 Subject: [PATCH 079/100] Define special handling of infix types like "<:<" and "=:=" --- dottydoc/js/src/html/Member.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index e7aa34c61ee5..a62a1ab34055 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -117,7 +117,15 @@ trait MemberLayout { ref.kind match { case "TypeReference" => val tref = ref.asInstanceOf[TypeReference] - if (tref.paramLinks.nonEmpty) span( + val infixTypes = "<:<" :: "=:=" :: Nil + if (tref.paramLinks.length == 2 && infixTypes.contains(tref.title)) span( + referenceToLinks(tref.paramLinks(0)), + span(cls := "type-separator no-left-margin"), + linkToAnchor(tref.tpeLink), + span(cls := "type-separator no-left-margin"), + referenceToLinks(tref.paramLinks(1)) + ).render + else if (tref.paramLinks.nonEmpty) span( linkToAnchor(tref.tpeLink), "[", tref From c4ec1b6e1178d9508e5ca9cb8b0b18e7c21f7711 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 18:14:19 +0200 Subject: [PATCH 080/100] Sort members when serializing to JSON --- dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index ea9658b5d252..fe23fc976c41 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -66,15 +66,15 @@ object json { private def entToJson(ent: Entity): String = ent match { case ent: Package => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"package"}""" + s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"package"}""" case ent: Class => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}""" + s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}""" case ent: CaseClass => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}""" + s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}""" case ent: Trait => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}""" + s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}""" case ent: Object => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" + s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" case ent: Def => s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"paramLists":${ent.paramLists.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"def"}""" case ent: Val => From 87ecca23c65564a6e182e52dbfe1d2f2c262b596 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 18:27:18 +0200 Subject: [PATCH 081/100] Add a SortMembers phase to sort the members instead of doing it when serializing to json --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 3 +- .../dottydoc/core/SortMembersPhase.scala | 32 +++++++++++++++++++ .../src/dotty/tools/dottydoc/model/json.scala | 10 +++--- 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/SortMembersPhase.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index 8fd51aeea3b5..b5cdcf645f54 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -30,7 +30,8 @@ class DottyDocCompiler extends Compiler { List(new DocImplicitsPhase), List(new DocASTPhase), List(DocMiniTransformations(new LinkReturnTypes, - new LinkParamListTypes)), + new LinkParamListTypes, + new SortMembers)), List(new PrintPhase) ) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/SortMembersPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/SortMembersPhase.scala new file mode 100644 index 000000000000..c8de532bb0bc --- /dev/null +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/SortMembersPhase.scala @@ -0,0 +1,32 @@ +package dotty.tools +package dottydoc +package core + +import dotc.core.Contexts.Context + +import transform.DocMiniPhase +import model._ +import model.internal._ + +/** This DocMiniPhase sorts the members of all classes, traits, objects and packages */ +class SortMembers extends DocMiniPhase { + override def transformPackage(implicit ctx: Context) = { case p: PackageImpl => + p.copy(members = p.members.sortBy(_.name)) + } + + override def transformClass(implicit ctx: Context) = { case c: ClassImpl => + c.copy(members = c.members.sortBy(_.name)) + } + + override def transformCaseClass(implicit ctx: Context) = { case cc: CaseClassImpl => + cc.copy(members = cc.members.sortBy(_.name)) + } + + override def transformTrait(implicit ctx: Context) = { case t: TraitImpl => + t.copy(members = t.members.sortBy(_.name)) + } + + override def transformObject(implicit ctx: Context) = { case o: ObjectImpl => + o.copy(members = o.members.sortBy(_.name)) + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index fe23fc976c41..ea9658b5d252 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -66,15 +66,15 @@ object json { private def entToJson(ent: Entity): String = ent match { case ent: Package => - s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"package"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"package"}""" case ent: Class => - s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}""" case ent: CaseClass => - s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}""" case ent: Trait => - s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}""" case ent: Object => - s"""{"name":${ent.name.json},"members":${ent.members.sortBy(_.name).map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" case ent: Def => s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"paramLists":${ent.paramLists.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"def"}""" case ent: Val => From 553f9b20a10a16ff0348733c0af936cb36148fd5 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 20 Jul 2016 18:33:09 +0200 Subject: [PATCH 082/100] Remove shared directory - nothing shared anymore --- .../src}/dotty/tools/dottydoc/model/comment/BodyEntities.scala | 0 .../src}/dotty/tools/dottydoc/model/comment/Comment.scala | 0 .../scala => jvm/src}/dotty/tools/dottydoc/model/entities.scala | 0 .../scala => jvm/src}/dotty/tools/dottydoc/model/factories.scala | 0 .../scala => jvm/src}/dotty/tools/dottydoc/model/internal.scala | 0 .../scala => jvm/src}/dotty/tools/dottydoc/util/Traversing.scala | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename dottydoc/{shared/src/main/scala => jvm/src}/dotty/tools/dottydoc/model/comment/BodyEntities.scala (100%) rename dottydoc/{shared/src/main/scala => jvm/src}/dotty/tools/dottydoc/model/comment/Comment.scala (100%) rename dottydoc/{shared/src/main/scala => jvm/src}/dotty/tools/dottydoc/model/entities.scala (100%) rename dottydoc/{shared/src/main/scala => jvm/src}/dotty/tools/dottydoc/model/factories.scala (100%) rename dottydoc/{shared/src/main/scala => jvm/src}/dotty/tools/dottydoc/model/internal.scala (100%) rename dottydoc/{shared/src/main/scala => jvm/src}/dotty/tools/dottydoc/util/Traversing.scala (100%) diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala similarity index 100% rename from dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala similarity index 100% rename from dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/Comment.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala similarity index 100% rename from dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala similarity index 100% rename from dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala similarity index 100% rename from dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala similarity index 100% rename from dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala rename to dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala From 98b61dd22c1aebaecbe27e86aa9e98abff4971c6 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 2 Aug 2016 14:26:16 +0200 Subject: [PATCH 083/100] Fix #25: move doc related structures to `DocBase` To access `DocBase`: `ctx.docbase.docstring(...)` --- .../src/dotty/tools/dottydoc/core/DocASTPhase.scala | 4 ++-- .../tools/dottydoc/core/DocImplicitsPhase.scala | 2 +- .../tools/dottydoc/core/MiniPhaseTransform.scala | 6 +++--- .../src/dotty/tools/dottydoc/core/PrintPhase.scala | 2 +- .../tools/dottydoc/core/TypeLinkingPhases.scala | 6 +++--- .../dottydoc/model/comment/CommentExpander.scala | 6 +++--- .../jvm/src/dotty/tools/dottydoc/model/parsers.scala | 4 ++-- src/dotty/tools/dotc/core/Contexts.scala | 12 +++++++++++- src/dotty/tools/dotc/typer/Namer.scala | 2 +- 9 files changed, 27 insertions(+), 17 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala index a2d440e8c92c..19ed0ce17126 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -37,7 +37,7 @@ class DocASTPhase extends Phase { /** Build documentation hierarchy from existing tree */ def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { - val implicitlyAddedMembers = ctx.base.defs(tree.symbol) + val implicitlyAddedMembers = ctx.docbase.defs(tree.symbol) def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = xs.map(collect(_, ps)).filter(_ != NonEntity) @@ -169,7 +169,7 @@ class DocASTPhase extends Phase { commentParser.clear() // (5) Update Doc AST in ctx.base - for (kv <- packages) ctx.base.packages += kv + for (kv <- packages) ctx.docbase.packages += kv // Return super's result compUnits diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala index 5d53d639719d..f322d7a5a62d 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala @@ -19,7 +19,7 @@ class DocImplicitsPhase extends MiniPhaseTransform { thisTransformer => tree.vparamss(0).length == 1 // should only take one arg, since it has to be a transformation ) { val convertee = tree.vparamss(0)(0).symbol.info.widenDealias.finalResultType.typeSymbol // the pimped type (i.e. `class`) - ctx.base.addDef(convertee, tree.symbol.info.widenDealias.finalResultType.typeSymbol) + ctx.docbase.addDef(convertee, tree.symbol.info.widenDealias.finalResultType.typeSymbol) } tree diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala index b12ceeb95622..1da03583e982 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala @@ -43,9 +43,9 @@ object transform { override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { for { rootName <- rootPackages - pack = ctx.base.packages[Package](rootName) + pack = ctx.docbase.packages[Package](rootName) transformed = performPackageTransform(pack) - } yield ctx.base.packages(rootName) = transformed + } yield ctx.docbase.packages(rootName) = transformed super.runOn(units) } @@ -53,7 +53,7 @@ object transform { var currentDepth = Int.MaxValue var packs = List.empty[String] - for (key <- ctx.base.packages.keys) { + for (key <- ctx.docbase.packages.keys) { val keyDepth = key.split("\\.").length packs = if (keyDepth < currentDepth) { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala index 9c9070d24999..cbcc55451540 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala @@ -16,7 +16,7 @@ class PrintPhase extends Phase { override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { val compUnits = super.runOn(units) - val packages = ctx.base.packages[Package].toMap + val packages = ctx.docbase.packages[Package].toMap val outputDir = { val out = ctx.settings.DocOutput.value diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 0cf0923f3c87..e8c8790d9b46 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -16,12 +16,12 @@ import util.internal.setters._ class LinkReturnTypes extends DocMiniPhase with TypeLinker { override def transformDef(implicit ctx: Context) = { case df: DefImpl => - val returnValue = linkReference(df, df.returnValue, ctx.base.packages[Package].toMap) + val returnValue = linkReference(df, df.returnValue, ctx.docbase.packages[Package].toMap) df.copy(returnValue = returnValue) } override def transformVal(implicit ctx: Context) = { case vl: ValImpl => - val returnValue = linkReference(vl, vl.returnValue, ctx.base.packages[Package].toMap) + val returnValue = linkReference(vl, vl.returnValue, ctx.docbase.packages[Package].toMap) vl.copy(returnValue = returnValue) } } @@ -30,7 +30,7 @@ class LinkParamListTypes extends DocMiniPhase with TypeLinker { override def transformDef(implicit ctx: Context) = { case df: DefImpl => val newParamLists = for { ParamListImpl(list, isImplicit) <- df.paramLists - newList = list.map(linkReference(df, _, ctx.base.packages[Package].toMap)) + newList = list.map(linkReference(df, _, ctx.docbase.packages[Package].toMap)) } yield ParamListImpl(newList.asInstanceOf[List[NamedReference]], isImplicit) df.copy(paramLists = newParamLists) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala index f90e95f33f5c..b5f6b903ae67 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala @@ -77,7 +77,7 @@ trait CommentExpander { def cookedDocComment(sym: Symbol, docStr: String = "")(implicit ctx: Context): String = cookedDocComments.getOrElseUpdate(sym, { var ownComment = - if (docStr.length == 0) ctx.base.docstring(sym).map(c => template(c.chrs)).getOrElse("") + if (docStr.length == 0) ctx.docbase.docstring(sym).map(c => template(c.chrs)).getOrElse("") else template(docStr) ownComment = replaceInheritDocToInheritdoc(ownComment) @@ -287,7 +287,7 @@ trait CommentExpander { def defineVariables(sym: Symbol)(implicit ctx: Context) = { val Trim = "(?s)^[\\s&&[^\n\r]]*(.*?)\\s*$".r - val raw = ctx.base.docstring(sym).map(_.chrs).getOrElse("") + val raw = ctx.docbase.docstring(sym).map(_.chrs).getOrElse("") defs(sym) ++= defines(raw).map { str => { val start = skipWhitespace(str, "@define".length) @@ -328,7 +328,7 @@ trait CommentExpander { * the position of the doc comment of the overridden version is returned instead. */ def docCommentPos(sym: Symbol)(implicit ctx: Context): Position = - ctx.base.docstring(sym).map(_.pos).getOrElse(NoPosition) + ctx.docbase.docstring(sym).map(_.pos).getOrElse(NoPosition) /** A version which doesn't consider self types, as a temporary measure: * an infinite loop has broken out between superComment and cookedDocComment diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index 3b2f2df4379e..e00fd1324a89 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -23,7 +23,7 @@ object parsers { * which can then be awaited near the end of the run - before the pickling. */ def parseHtml(sym: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): (String, Option[Comment]) = { - val cmt = ctx.base.docstring(sym).map { d => + val cmt = ctx.docbase.docstring(sym).map { d => val expanded = expand(sym) val body = parse(entity, packages, clean(expanded), expanded, d.pos) val summary = body.summary.map(_.toHtml(entity)).getOrElse("") @@ -43,7 +43,7 @@ object parsers { } val path = entity.path.mkString(".") - if (!commentCache.contains(path) || ctx.base.docstring(symbol).isDefined) + if (!commentCache.contains(path) || ctx.docbase.docstring(symbol).isDefined) commentCache = commentCache + (path -> commentParser) } diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 7490a62cc6cc..cd76fe88bb45 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -532,6 +532,9 @@ object Contexts { /** The symbol loaders */ val loaders = new SymbolLoaders + /** Documentation base */ + val docbase = new DocBase + /** The platform, initialized by `initPlatform()`. */ private var _platform: Platform = _ @@ -568,8 +571,10 @@ object Contexts { def squashed(p: Phase): Phase = { allPhases.find(_.period.containsPhaseId(p.id)).getOrElse(NoPhase) } + } - val _docstrings: mutable.Map[Symbol, Comment] = + class DocBase { + private[this] val _docstrings: mutable.Map[Symbol, Comment] = mutable.Map.empty def docstring(sym: Symbol): Option[Comment] = _docstrings.get(sym) @@ -577,6 +582,11 @@ object Contexts { def addDocstring(sym: Symbol, doc: Option[Comment]): Unit = doc.map(d => _docstrings += (sym -> d)) + /* + * Dottydoc places instances of `Package` in this map - but we do not want + * to depend on `dottydoc` for the compiler, as such this is defined as a + * map of `String -> AnyRef` + */ private[this] val _packages: mutable.Map[String, AnyRef] = mutable.Map.empty def packages[A]: mutable.Map[String, A] = _packages.asInstanceOf[mutable.Map[String, A]] diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 698f7e9a9d26..b8e75664cb11 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -426,7 +426,7 @@ class Namer { typer: Typer => } def setDocstring(sym: Symbol, tree: Tree)(implicit ctx: Context) = tree match { - case t: MemberDef => ctx.base.addDocstring(sym, t.rawComment) + case t: MemberDef => ctx.docbase.addDocstring(sym, t.rawComment) case _ => () } From 94dd0bccbb68618bc668c6005316d6930ae26069 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 2 Aug 2016 16:00:20 +0200 Subject: [PATCH 084/100] Get docstring from overriden symbol if not present on the overriding method --- .../tools/dottydoc/core/DocASTPhase.scala | 19 +++++++------ .../model/comment/CommentExpander.scala | 14 +++++----- .../dotty/tools/dottydoc/model/parsers.scala | 27 +++++++++++++++---- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala index 19ed0ce17126..40e778059097 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -8,7 +8,7 @@ import dotc.CompilationUnit import dotc.config.Printers.dottydoc import dotc.core.Contexts.Context import dotc.core.Phases.Phase -import dotc.core.Symbols.Symbol +import dotc.core.Symbols.{ Symbol, NoSymbol } class DocASTPhase extends Phase { import model._ @@ -26,18 +26,18 @@ class DocASTPhase extends Phase { private[this] val commentParser = new WikiParser /** Saves the commentParser function for later evaluation, for when the AST has been filled */ - def track(symbol: Symbol, ctx: Context)(op: => Entity) = { + def track(symbol: Symbol, ctx: Context, parent: Symbol = NoSymbol)(op: => Entity) = { val entity = op if (entity != NonEntity) - commentParser += (entity, symbol, ctx) + commentParser += (entity, symbol, parent, ctx) entity } /** Build documentation hierarchy from existing tree */ def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { - val implicitlyAddedMembers = ctx.docbase.defs(tree.symbol) + val implicitConversions = ctx.docbase.defs(tree.symbol) def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = xs.map(collect(_, ps)).filter(_ != NonEntity) @@ -45,25 +45,24 @@ class DocASTPhase extends Phase { def collectEntityMembers(xs: List[Tree], ps: List[String])(implicit ctx: Context) = collectList(xs, ps).asInstanceOf[List[Entity with Members]] - /** TODO: should be a set, not a uniqued list */ def collectMembers(tree: Tree, ps: List[String] = prev)(implicit ctx: Context): List[Entity] = { val defs = (tree match { case t: Template => collectList(t.body, ps) case _ => Nil - }) ++ implicitlyAddedMembers.flatMap(addedFromSymbol) + }) - defs + defs ++ implicitConversions.flatMap(membersFromSymbol) } - def addedFromSymbol(sym: Symbol): List[Entity] = { + def membersFromSymbol(sym: Symbol): List[Entity] = { val defs = sym.info.bounds.hi.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => - track(meth.symbol, ctx) { + track(meth.symbol, ctx, tree.symbol) { DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), paramLists(meth.info)) } }.toList val vals = sym.info.fields.filterNot(_.symbol.is(Flags.Private | Flags.Synthetic)).map { value => - track(value.symbol, ctx) { + track(value.symbol, ctx, tree.symbol) { ValImpl(value.symbol.name.decode.toString, Nil, path(value.symbol), returnType(value.info)) } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala index b5f6b903ae67..32a0d8128b55 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala @@ -20,9 +20,10 @@ import scala.collection.mutable trait CommentExpander { import CommentUtils._ - def expand(sym: Symbol)(implicit ctx: Context): String = { - defineVariables(sym) - expandedDocComment(sym, sym) + def expand(sym: Symbol, site: Symbol)(implicit ctx: Context): String = { + val parent = if (site != NoSymbol) site else sym + defineVariables(parent) + expandedDocComment(sym, parent) } /** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing. @@ -35,9 +36,9 @@ trait CommentExpander { */ def expandedDocComment(sym: Symbol, site: Symbol, docStr: String = "")(implicit ctx: Context): String = { // when parsing a top level class or module, use the (module-)class itself to look up variable definitions - val site1 = if ((sym.is(Flags.Module) || sym.isClass) && site.is(Flags.Package)) sym - else site - expandVariables(cookedDocComment(sym, docStr), sym, site1) + val parent = if ((sym.is(Flags.Module) || sym.isClass) && site.is(Flags.Package)) sym + else site + expandVariables(cookedDocComment(sym, docStr), sym, parent) } private def template(raw: String): String = { @@ -74,7 +75,6 @@ trait CommentExpander { * If a symbol does not have a doc comment but some overridden version of it does, * the doc comment of the overridden version is copied instead. */ - def cookedDocComment(sym: Symbol, docStr: String = "")(implicit ctx: Context): String = cookedDocComments.getOrElseUpdate(sym, { var ownComment = if (docStr.length == 0) ctx.docbase.docstring(sym).map(c => template(c.chrs)).getOrElse("") diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index e00fd1324a89..afd1cf982f41 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -22,9 +22,9 @@ object parsers { * The idea here is to use this fact to create `Future[Seq[(String, Option[Comment]]]` * which can then be awaited near the end of the run - before the pickling. */ - def parseHtml(sym: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): (String, Option[Comment]) = { + def parseHtml(sym: Symbol, parent: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): (String, Option[Comment]) = { val cmt = ctx.docbase.docstring(sym).map { d => - val expanded = expand(sym) + val expanded = expand(sym, parent) val body = parse(entity, packages, clean(expanded), expanded, d.pos) val summary = body.summary.map(_.toHtml(entity)).getOrElse("") body.toHtml(entity) match { @@ -37,17 +37,34 @@ object parsers { } - def add(entity: Entity, symbol: Symbol, ctx: Context): Unit = { + def add(entity: Entity, symbol: Symbol, parent: Symbol, ctx: Context): Unit = { val commentParser = { (entity: Entity, packs: Map[String, Package]) => - parseHtml(symbol, entity, packs)(ctx)._2 + parseHtml(symbol, parent, entity, packs)(ctx)._2 } + /** TODO: this if statement searches for doc comments in parent + * definitions if one is not defined for the current symbol. + * + * It might be a good idea to factor this out of the WikiParser - since + * it mutates the state of docbase sort of silently. + */ + implicit val implCtx = ctx + if (!ctx.docbase.docstring(symbol).isDefined) { + val parentCmt = + symbol.extendedOverriddenSymbols + .find(ctx.docbase.docstring(_).isDefined) + .flatMap(p => ctx.docbase.docstring(p)) + + ctx.docbase.addDocstring(symbol, parentCmt) + } + + val path = entity.path.mkString(".") if (!commentCache.contains(path) || ctx.docbase.docstring(symbol).isDefined) commentCache = commentCache + (path -> commentParser) } - def +=(entity: Entity, symbol: Symbol, ctx: Context) = add(entity, symbol, ctx) + def +=(entity: Entity, symbol: Symbol, parent: Symbol, ctx: Context) = add(entity, symbol, parent, ctx) def size: Int = commentCache.size From 922788ac39f7538b79b58c326bd22c641a8e2490 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Sat, 6 Aug 2016 20:53:15 +0200 Subject: [PATCH 085/100] Add info on where implicitly added members originate from --- dottydoc/js/src/html/Member.scala | 12 +++++++-- dottydoc/js/src/model/entities.scala | 22 +++++++++++++-- dottydoc/jvm/resources/index.css | 4 +++ .../src/dotty/tools/dottydoc/DottyDoc.scala | 1 + .../tools/dottydoc/core/DocASTPhase.scala | 27 ++++++++++++++----- .../dottydoc/core/MiniPhaseTransform.scala | 6 +++-- .../dottydoc/core/TypeLinkingPhases.scala | 12 +++++++++ .../dotty/tools/dottydoc/model/entities.scala | 4 ++- .../tools/dottydoc/model/factories.scala | 19 ++----------- .../dotty/tools/dottydoc/model/internal.scala | 6 +++-- .../src/dotty/tools/dottydoc/model/json.scala | 4 +-- 11 files changed, 83 insertions(+), 34 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index a62a1ab34055..dbd1883fae4e 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -9,6 +9,7 @@ import org.scalajs.dom.html.{Anchor, Div, Span} trait MemberLayout { import js.model._ + import js.model.ops._ def member(m: Entity, parent: Entity) = { def toggleBetween(short: Div, and: Div): Unit = @@ -31,10 +32,10 @@ trait MemberLayout { val fullComment = div( cls := "mdl-cell mdl-cell--12-col full-comment", style := "display: none;", + fromImplicitSpan(m), raw(m.comment.fold("")(_.body)) ).render - val hasLongerFullComment = m.comment.fold(false) { c => c.short.length + 5 < c.body.length } @@ -53,7 +54,7 @@ trait MemberLayout { entity.modifiers.mkString(" ") + " " + m.kind ), span( - cls := "member-name", + cls := { if (m.addedImplicitly) "member-name implicitly-added" else "member-name" }, m.name ), spanWith("member-type-params no-left-margin", typeParams(m)), @@ -68,6 +69,13 @@ trait MemberLayout { } } + def fromImplicitSpan(m: Entity) = m.foldImplicitlyAdded { ref => + span( + "Implicitly added from: ", + referenceToLinks(ref) + ) + }.getOrElse(span()) + def spanWith(clazz: String, contents: String) = contents match { case "" => None case _ => Some(span(cls := clazz, contents)) diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 4ae76c58c615..49d0ec005fb2 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -82,13 +82,23 @@ trait ParamList extends sjs.Object { trait Def extends Entity with Modifiers with ReturnValue { val typeParams: sjs.Array[String] val paramLists: sjs.Array[ParamList] + val implicitlyAddedFrom: sjs.UndefOr[Reference] } @ScalaJSDefined -trait Val extends Entity with Modifiers +trait Val extends Entity with Modifiers { + val implicitlyAddedFrom: sjs.UndefOr[Reference] +} + +@ScalaJSDefined +trait Var extends Entity with Modifiers { + val implicitlyAddedFrom: sjs.UndefOr[Reference] +} @ScalaJSDefined -trait Var extends Entity with Modifiers +trait ImplicitlyAddedEntity extends Entity { + val implicitlyAddedFrom: sjs.UndefOr[Reference] +} object ops { val EntitiesWithModifiers = @@ -140,5 +150,13 @@ object ops { def isPrivate: Boolean = hasModifiers && ent.asInstanceOf[Modifiers].modifiers.contains("private") + + def addedImplicitly: Boolean = (ent.kind == "def" || ent.kind == "val") && { + ent.asInstanceOf[ImplicitlyAddedEntity].implicitlyAddedFrom.isDefined + } + + def foldImplicitlyAdded[B](f: Reference => B): sjs.UndefOr[B] = + if (ent.kind == "def" || ent.kind == "val") ent.asInstanceOf[ImplicitlyAddedEntity].implicitlyAddedFrom.map(f) + else sjs.undefined } } diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css index 79eeaaee0bd4..eaf26bbf7c94 100644 --- a/dottydoc/jvm/resources/index.css +++ b/dottydoc/jvm/resources/index.css @@ -134,6 +134,10 @@ div.member-definition > span.member-param-list span.is-implicit { font-weight: 600; } +div.member-definition > span.member-name.implicitly-added { + color: #16A085; +} + div.member { min-height: 70px; } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala index b5cdcf645f54..120b743b8c3c 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala @@ -31,6 +31,7 @@ class DottyDocCompiler extends Compiler { List(new DocASTPhase), List(DocMiniTransformations(new LinkReturnTypes, new LinkParamListTypes, + new LinkImplicitlyAddedTypes, new SortMembers)), List(new PrintPhase) ) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala index 40e778059097..d9fb3bacc273 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -55,15 +55,30 @@ class DocASTPhase extends Phase { } def membersFromSymbol(sym: Symbol): List[Entity] = { - val defs = sym.info.bounds.hi.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private).map { meth => - track(meth.symbol, ctx, tree.symbol) { - DefImpl(meth.symbol.name.decode.toString, Nil, path(meth.symbol), returnType(meth.info), typeParams(meth.symbol), paramLists(meth.info)) - } - }.toList + val defs = sym.info.bounds.hi.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private) + .filterNot(_.symbol.owner.name.show == "Any") + .map { meth => + track(meth.symbol, ctx, tree.symbol) { + DefImpl( + meth.symbol.name.show, + Nil, + path(meth.symbol), + returnType(meth.info), + typeParams(meth.symbol), + paramLists(meth.info), + implicitlyAddedFrom = Some(returnType(meth.symbol.owner.info)) + ) + } + }.toList val vals = sym.info.fields.filterNot(_.symbol.is(Flags.Private | Flags.Synthetic)).map { value => track(value.symbol, ctx, tree.symbol) { - ValImpl(value.symbol.name.decode.toString, Nil, path(value.symbol), returnType(value.info)) + ValImpl( + value.symbol.name.show, + Nil, path(value.symbol), + returnType(value.info), + implicitlyAddedFrom = Some(returnType(value.symbol.owner.info)) + ) } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala index 1da03583e982..cd1fef52f5a1 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala @@ -134,7 +134,8 @@ object transform { df.returnValue, df.typeParams, df.paramLists, - df.comment + df.comment, + df.implicitlyAddedFrom ) } case vl: Val => transformEntity(vl, _.valTransformation) { vl => @@ -143,7 +144,8 @@ object transform { vl.modifiers, vl.path, vl.returnValue, - vl.comment + vl.comment, + vl.implicitlyAddedFrom ) } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index e8c8790d9b46..7ce6b187bb41 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -37,6 +37,18 @@ class LinkParamListTypes extends DocMiniPhase with TypeLinker { } } +class LinkImplicitlyAddedTypes extends DocMiniPhase with TypeLinker { + override def transformDef(implicit ctx: Context) = { case df: DefImpl if df.implicitlyAddedFrom.isDefined => + val implicitlyAddedFrom = linkReference(df, df.implicitlyAddedFrom.get, ctx.docbase.packages[Package].toMap) + df.copy(implicitlyAddedFrom = Some(implicitlyAddedFrom)) + } + + override def transformVal(implicit ctx: Context) = { case vl: ValImpl if vl.implicitlyAddedFrom.isDefined => + val implicitlyAddedFrom = linkReference(vl, vl.implicitlyAddedFrom.get, ctx.docbase.packages[Package].toMap) + vl.copy(implicitlyAddedFrom = Some(implicitlyAddedFrom)) + } +} + trait TypeLinker extends MemberLookup { def linkReference(ent: Entity, ref: Reference, packs: Map[String, Package]): Reference = { def linkRef(ref: Reference) = linkReference(ent, ref, packs) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala index 391bd514ff20..16d05306e527 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala @@ -79,12 +79,14 @@ trait Object extends Entity with Modifiers with SuperTypes with Members { } trait Def extends Entity with Modifiers with TypeParams with ReturnValue { - def paramLists: List[ParamList] val kind = "def" + def paramLists: List[ParamList] + def implicitlyAddedFrom: Option[Reference] } trait Val extends Entity with Modifiers with ReturnValue { val kind = "val" + def implicitlyAddedFrom: Option[Reference] } trait Var extends Entity with Modifiers with ReturnValue { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala index f0c78fa41cb1..4d80c08a90df 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala @@ -29,26 +29,11 @@ object factories { def path(sym: Symbol)(implicit ctx: Context): List[String] = sym match { case sym if sym.name.decode.toString == "" => Nil - case sym if sym is Flags.Module => path(sym.owner) :+ sym.name.decode.toString.dropRight(1) - case sym => path(sym.owner) :+ sym.name.decode.toString + case sym => path(sym.owner) :+ sym.name.show } private val product = """Product[1-9][0-9]*""".r - private def cleanTitle(title: String): String = title match { - // matches Entity.this.Something - case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last - // Matches Entity[P, ...] - case x if x matches "[^\\[]+\\[[^\\]]+\\]" => - val Array(tpe, params) = x.dropRight(1).split("\\[") - s"""$tpe[${params.split(",").map(x => cleanTitle(x.trim)).mkString(", ")}]""" - case _ => title - } - - private def cleanQuery(query: String): String = query match { - case x if x matches "[^\\[]+\\[[^\\]]+\\]" => x.takeWhile(_ != '[') - case _ => query - } def returnType(t: Type)(implicit ctx: Context): Reference = { val defn = ctx.definitions @@ -107,7 +92,7 @@ object factories { case tt: ThisType => expandTpe(tt.underlying) case ci: ClassInfo => - typeRef(ci.cls.show) + typeRef(ci.cls.name.show) case mt: MethodType => expandTpe(mt.resultType) case pt: PolyType => diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala index ec1adfa889b7..a8756c82a694 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala @@ -65,7 +65,8 @@ object internal { var returnValue: Reference, var typeParams: List[String] = Nil, var paramLists: List[ParamList] = Nil, - var comment: Option[Comment] = None + var comment: Option[Comment] = None, + implicitlyAddedFrom: Option[Reference] = None ) extends Def with Impl final case class ValImpl( @@ -73,7 +74,8 @@ object internal { modifiers: List[String], path: List[String], var returnValue: Reference, - var comment: Option[Comment] = None + var comment: Option[Comment] = None, + implicitlyAddedFrom: Option[Reference] = None ) extends Val with Impl final case class ParamListImpl( diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index ea9658b5d252..f83f43138559 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -76,9 +76,9 @@ object json { case ent: Object => s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" case ent: Def => - s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"paramLists":${ent.paramLists.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"def"}""" + s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"paramLists":${ent.paramLists.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}${ent.implicitlyAddedFrom.fold("")(ref => s""""implicitlyAddedFrom":${ref.json},""")}"kind":"def"}""" case ent: Val => - s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"val"}""" + s"""{"name":${ent.name.json},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"returnValue":${ent.returnValue.json},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}${ent.implicitlyAddedFrom.fold("")(ref => s""""implicitlyAddedFrom":${ref.json},""")}"kind":"val"}""" } implicit class EntityJson(val ent: Entity) extends AnyVal { def json: String = entToJson(ent) } implicit class PackageJson(val pack: Package) extends AnyVal { def json: String = (pack: Entity).json } From 5fdc353794e1175a3967a7df10e5d80c443a5754 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Sun, 7 Aug 2016 16:21:24 +0200 Subject: [PATCH 086/100] Fix phase fusion for subpackages, fix links in implicitly added methods --- dottydoc/js/src/html/Member.scala | 3 ++- .../tools/dottydoc/core/MiniPhaseTransform.scala | 7 ++++++- .../tools/dottydoc/core/TypeLinkingPhases.scala | 14 ++++++++------ .../src/dotty/tools/dottydoc/model/factories.scala | 3 ++- .../dotty/tools/dottydoc/util/MemberLookup.scala | 3 +-- .../src/dotty/tools/dottydoc/util/Traversing.scala | 2 ++ 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala index dbd1883fae4e..ec17b5021622 100644 --- a/dottydoc/js/src/html/Member.scala +++ b/dottydoc/js/src/html/Member.scala @@ -118,7 +118,8 @@ trait MemberLayout { case "NoLink" => span(link.title).render case "UnsetLink" => - println(s"UnsetLink found: $link") + println("UnsetLink found:") + scala.scalajs.js.Dynamic.global.console.log(link) span(link.title).render } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala index cd1fef52f5a1..7bdb2bf4e177 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala @@ -76,12 +76,17 @@ object transform { def traverse(ent: Entity): Entity = ent match { case p: Package => transformEntity(p, _.packageTransformation) { p => - PackageImpl( + val newPackage = PackageImpl( p.name, p.members.map(traverse), p.path, p.comment ) + + // Update reference in context to newPackage + ctx.docbase.packages[Package] += (newPackage.path.mkString(".") -> newPackage) + + newPackage } case c: Class => transformEntity(c, _.classTransformation) { newClass => ClassImpl( diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 7ce6b187bb41..9d29176c2e3e 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -38,14 +38,16 @@ class LinkParamListTypes extends DocMiniPhase with TypeLinker { } class LinkImplicitlyAddedTypes extends DocMiniPhase with TypeLinker { - override def transformDef(implicit ctx: Context) = { case df: DefImpl if df.implicitlyAddedFrom.isDefined => - val implicitlyAddedFrom = linkReference(df, df.implicitlyAddedFrom.get, ctx.docbase.packages[Package].toMap) - df.copy(implicitlyAddedFrom = Some(implicitlyAddedFrom)) + override def transformDef(implicit ctx: Context) = { + case df: DefImpl if df.implicitlyAddedFrom.isDefined => + val implicitlyAddedFrom = linkReference(df, df.implicitlyAddedFrom.get, ctx.docbase.packages[Package].toMap) + df.copy(implicitlyAddedFrom = Some(implicitlyAddedFrom)) } - override def transformVal(implicit ctx: Context) = { case vl: ValImpl if vl.implicitlyAddedFrom.isDefined => - val implicitlyAddedFrom = linkReference(vl, vl.implicitlyAddedFrom.get, ctx.docbase.packages[Package].toMap) - vl.copy(implicitlyAddedFrom = Some(implicitlyAddedFrom)) + override def transformVal(implicit ctx: Context) = { + case vl: ValImpl if vl.implicitlyAddedFrom.isDefined => + val implicitlyAddedFrom = linkReference(vl, vl.implicitlyAddedFrom.get, ctx.docbase.packages[Package].toMap) + vl.copy(implicitlyAddedFrom = Some(implicitlyAddedFrom)) } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala index 4d80c08a90df..929d42d4f5e3 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala @@ -92,7 +92,8 @@ object factories { case tt: ThisType => expandTpe(tt.underlying) case ci: ClassInfo => - typeRef(ci.cls.name.show) + val query = path(ci.typeSymbol).mkString(".") + typeRef(ci.cls.name.show, query = query) case mt: MethodType => expandTpe(mt.resultType) case pt: PolyType => diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala index d8abb0319bcc..40c775428a89 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala @@ -77,8 +77,7 @@ trait MemberLookup { case (x :: _, e: Entity with Members) if x == entity.name => downwardLookup(e, querys) case (x :: xs, _) => - if (xs.nonEmpty) - globalLookup + if (xs.nonEmpty) globalLookup else lookup(entity, packages, "scala." + query, pos) } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala index 2ac8eae4f7ce..a3b60fa44aef 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala @@ -13,6 +13,8 @@ object traversing { def relativePath(from: Entity, to: Entity) = { val offset = from match { + case v: Val if v.implicitlyAddedFrom.isDefined => 3 + case d: Def if d.implicitlyAddedFrom.isDefined => 3 case _: Val | _: Def => 2 case _ => 1 } From 20fda579d76690cc86a1f0a5c9e703fa4a94cb47 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Sun, 7 Aug 2016 17:04:12 +0200 Subject: [PATCH 087/100] Fix type params of classes, traits defs, which broke after new HK scheme --- dottydoc/js/src/model/entities.scala | 4 ++-- .../tools/dottydoc/core/DocASTPhase.scala | 4 ++-- .../dotty/tools/dottydoc/model/factories.scala | 18 +++++++++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 49d0ec005fb2..4180ad431937 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -61,13 +61,13 @@ trait SuperTypes extends sjs.Object { trait Package extends Entity with Members @ScalaJSDefined -trait Class extends Entity with Members with Modifiers +trait Class extends Entity with Members with Modifiers with TypeParams @ScalaJSDefined trait CaseClass extends Class @ScalaJSDefined -trait Object extends Class +trait Object extends Entity with Members with Modifiers @ScalaJSDefined trait Trait extends Class diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala index d9fb3bacc273..01301097194d 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -39,10 +39,10 @@ class DocASTPhase extends Phase { def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { val implicitConversions = ctx.docbase.defs(tree.symbol) - def collectList(xs: List[Tree], ps: List[String])(implicit ctx: Context): List[Entity] = + def collectList(xs: List[Tree], ps: List[String]): List[Entity] = xs.map(collect(_, ps)).filter(_ != NonEntity) - def collectEntityMembers(xs: List[Tree], ps: List[String])(implicit ctx: Context) = + def collectEntityMembers(xs: List[Tree], ps: List[String]) = collectList(xs, ps).asInstanceOf[List[Entity with Members]] def collectMembers(tree: Tree, ps: List[String] = prev)(implicit ctx: Context): List[Entity] = { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala index 929d42d4f5e3..dae8442e8b62 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala @@ -112,10 +112,22 @@ object factories { } def typeParams(sym: Symbol)(implicit ctx: Context): List[String] = - sym.denot.info match { - case pt: PolyType => + sym.info match { + case pt: PolyType => // TODO: not sure if this case is needed anymore pt.paramNames.map(_.show.split("\\$").last) - case _ => Nil + case ClassInfo(_, _, _, decls, _) => + decls.iterator + .filter(_.flags is Flags.TypeParam) + .map { tp => + val prefix = + if (tp.flags is Flags.Covariant) "+" + else if (tp.flags is Flags.Contravariant) "-" + else "" + prefix + tp.name.show.split("\\$").last + } + .toList + case _ => + Nil } def paramLists(tpe: Type)(implicit ctx: Context): List[ParamList] = tpe match { From 079e3db0f157ee6eae9e8a34b3bbf7a75cdaa929 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 8 Aug 2016 14:19:57 +0200 Subject: [PATCH 088/100] Implement annotation parsing like CommentFactoryBase from nsc --- dottydoc/js/src/html/EntityLayout.scala | 48 +++---- dottydoc/js/src/model/entities.scala | 22 +++- .../dottydoc/model/comment/Comment.scala | 24 +++- .../model/comment/CommentParser.scala | 119 ++++++++++++------ .../src/dotty/tools/dottydoc/model/json.scala | 3 +- .../dotty/tools/dottydoc/model/parsers.scala | 9 +- 6 files changed, 158 insertions(+), 67 deletions(-) diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index 251644075c61..f81f42e02ef1 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -58,28 +58,34 @@ case class EntityLayout(entity: Entity) extends MemberLayout { main( id := "entity-container", cls := "mdl-layout__content", - div( - cls := "page-content", - div(cls := "entity-title", entityTitle), - div(raw(entity.comment.fold("")(_.body))), - entity match { - case x if x.hasMembers => - val e = x.asInstanceOf[Entity with Members] - if (e.members.nonEmpty) - Seq( - h5("Members"), - div( - cls := "mld-grid", - e.members - .collect { - case x if x.hasModifiers && !x.isPrivate => x - } - .flatMap(member(_, entity)).toList + div( + cls := "page-content", + div(cls := "entity-title", entityTitle), + div(raw(entity.comment.fold("")(_.body))), + entity.comment.filter(_.authors.nonEmpty).map { comment => + dl( + dt(cls := "entity-authors", "Authors"), + comment.authors.map(x => dd(cls := "entity-author", raw(x))).toList + ) + }.toOption, + entity match { + case x if x.hasMembers => + val e = x.asInstanceOf[Entity with Members] + if (e.members.nonEmpty) + Seq( + h5("Members"), + div( + cls := "mdl-grid", + e.members + .collect { + case x if x.hasModifiers && !x.isPrivate => x + } + .flatMap(member(_, entity)).toList + ) ) - ) - case _ => () - } - ) + case _ => () + } + ) ), main( id := "search-results", diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 4180ad431937..ca1b5ec6935f 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -28,8 +28,26 @@ trait Entity extends sjs.Object { @ScalaJSDefined trait Comment extends sjs.Object { - val body: String - val short: String + val body: String + val short: String + val authors: sjs.Array[String] + val see: sjs.Array[String] + val result: sjs.UndefOr[String] + val throws: Map[String, String] + val valueParams: Map[String, String] + val typeParams: Map[String, String] + val version: sjs.UndefOr[String] + val since: sjs.UndefOr[String] + val todo: List[String] + val deprecated: sjs.UndefOr[String] + val note: List[String] + val example: List[String] + val constructor: sjs.UndefOr[String] + val group: sjs.UndefOr[String] + val groupDesc: Map[String, String] + val groupNames: Map[String, String] + val groupPrio: Map[String, String] + val hideImplicitConversions: List[String] } @ScalaJSDefined diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala index ad53b9ae7d43..c4f6ccf5d246 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala @@ -3,4 +3,26 @@ package dottydoc package model package comment -case class Comment(body: String, short: String) +case class Comment ( + body: String, + short: String, + authors: List[String], + see: List[String], + result: Option[String], + throws: Map[String, String], + valueParams: Map[String, String], + typeParams: Map[String, String], + version: Option[String], + since: Option[String], + todo: List[String], + deprecated: Option[String], + note: List[String], + example: List[String], + constructor: Option[String], + group: Option[String], + groupDesc: Map[String, String], + groupNames: Map[String, String], + groupPrio: Map[String, String], + /** List of conversions to hide - containing e.g: `scala.Predef.FloatArrayOps` */ + hideImplicitConversions: List[String] +) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala index fb2119fc0ad4..589e2ebe21a2 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala @@ -13,6 +13,59 @@ trait CommentParser extends util.MemberLookup { import Regexes._ import model.internal._ + case class FullComment ( + body: Body, + authors: List[Body], + see: List[Body], + result: Option[Body], + throws: Map[String, Body], + valueParams: Map[String, Body], + typeParams: Map[String, Body], + version: Option[Body], + since: Option[Body], + todo: List[Body], + deprecated: Option[Body], + note: List[Body], + example: List[Body], + constructor: Option[Body], + group: Option[Body], + groupDesc: Map[String, Body], + groupNames: Map[String, Body], + groupPrio: Map[String, Body], + hideImplicitConversions: List[Body], + shortDescription: List[Body] + ) { + + /** + * Transform this CommentParser.FullComment to a Comment using the supplied + * Body transformer + */ + def toComment(transform: Body => String) = Comment( + transform(body), + short = + if (shortDescription.nonEmpty) shortDescription.map(transform).mkString + else body.summary.map(transform).getOrElse(""), + authors.map(transform), + see.map(transform), + result.map(transform), + throws.map { case (k, v) => (k, transform(v)) }, + valueParams.map { case (k, v) => (k, transform(v)) }, + typeParams.map { case (k, v) => (k, transform(v)) }, + version.map(transform), + since.map(transform), + todo.map(transform), + deprecated.map(transform), + note.map(transform), + example.map(transform), + constructor.map(transform), + group.map(transform), + groupDesc.map { case (k, v) => (k, transform(v)) }, + groupNames.map { case (k, v) => (k, transform(v)) }, + groupPrio.map { case (k, v) => (k, transform(v)) }, + hideImplicitConversions.map(transform) + ) + } + /** Parses a raw comment string into a `Comment` object. * @param packages all packages parsed by Scaladoc tool, used for lookup * @param cleanComment a cleaned comment to be parsed @@ -26,7 +79,7 @@ trait CommentParser extends util.MemberLookup { src: String, pos: Position, site: Symbol = NoSymbol - )(implicit ctx: Context): Body = { + )(implicit ctx: Context): FullComment = { /** Parses a comment (in the form of a list of lines) to a `Comment` * instance, recursively on lines. To do so, it splits the whole comment @@ -48,7 +101,7 @@ trait CommentParser extends util.MemberLookup { lastTagKey: Option[TagKey], remaining: List[String], inCodeBlock: Boolean - ): Body = remaining match { + ): FullComment = remaining match { case CodeBlockStartRegex(before, marker, after) :: ls if (!inCodeBlock) => if (!before.trim.isEmpty && !after.trim.isEmpty) @@ -155,8 +208,8 @@ trait CommentParser extends util.MemberLookup { case _ => None } - def allTags(key: SimpleTagKey): List[Body] = - (bodyTags remove key).getOrElse(Nil).filterNot(_.blocks.isEmpty) + def allTags[B](key: SimpleTagKey): List[Body] = + (bodyTags remove key).getOrElse(Nil).filterNot(_.blocks.isEmpty).reverse def allSymsOneTag(key: TagKey, filterEmpty: Boolean = true): Map[String, Body] = { val keys: Seq[SymbolTagKey] = @@ -193,37 +246,33 @@ trait CommentParser extends util.MemberLookup { } } - // TODO: this method should return a parsed comment with the members below - //val com = createComment ( - // body0 = Some(parseWikiAtSymbol(docBody.toString, pos, site)), - // authors0 = allTags(SimpleTagKey("author")), - // see0 = allTags(SimpleTagKey("see")), - // result0 = oneTag(SimpleTagKey("return")), - // throws0 = linkedExceptions, - // valueParams0 = allSymsOneTag(SimpleTagKey("param")), - // typeParams0 = allSymsOneTag(SimpleTagKey("tparam")), - // version0 = oneTag(SimpleTagKey("version")), - // since0 = oneTag(SimpleTagKey("since")), - // todo0 = allTags(SimpleTagKey("todo")), - // deprecated0 = oneTag(SimpleTagKey("deprecated"), filterEmpty = false), - // note0 = allTags(SimpleTagKey("note")), - // example0 = allTags(SimpleTagKey("example")), - // constructor0 = oneTag(SimpleTagKey("constructor")), - // source0 = Some(clean(src).mkString("\n")), - // inheritDiagram0 = inheritDiagramText, - // contentDiagram0 = contentDiagramText, - // group0 = oneTag(SimpleTagKey("group")), - // groupDesc0 = allSymsOneTag(SimpleTagKey("groupdesc")), - // groupNames0 = allSymsOneTag(SimpleTagKey("groupname")), - // groupPrio0 = allSymsOneTag(SimpleTagKey("groupprio")), - // hideImplicitConversions0 = allTags(SimpleTagKey("hideImplicitConversion")), - // shortDescription0 = allTags(SimpleTagKey("shortDescription")) - //) - // - //for ((key, _) <- bodyTags) - // dottydoc.println(s"$pos: Tag '@${key.name}' is not recognised") - - parseWikiAtSymbol(entity, packages, docBody.toString, pos, site) + val cmt = FullComment( + body = parseWikiAtSymbol(entity, packages, docBody.toString, pos, site), + authors = allTags(SimpleTagKey("author")), + see = allTags(SimpleTagKey("see")), + result = oneTag(SimpleTagKey("return")), + throws = linkedExceptions, + valueParams = allSymsOneTag(SimpleTagKey("param")), + typeParams = allSymsOneTag(SimpleTagKey("tparam")), + version = oneTag(SimpleTagKey("version")), + since = oneTag(SimpleTagKey("since")), + todo = allTags(SimpleTagKey("todo")), + deprecated = oneTag(SimpleTagKey("deprecated"), filterEmpty = false), + note = allTags(SimpleTagKey("note")), + example = allTags(SimpleTagKey("example")), + constructor = oneTag(SimpleTagKey("constructor")), + group = oneTag(SimpleTagKey("group")), + groupDesc = allSymsOneTag(SimpleTagKey("groupdesc")), + groupNames = allSymsOneTag(SimpleTagKey("groupname")), + groupPrio = allSymsOneTag(SimpleTagKey("groupprio")), + hideImplicitConversions = allTags(SimpleTagKey("hideImplicitConversion")), + shortDescription = allTags(SimpleTagKey("shortDescription")) + ) + + for ((key, _) <- bodyTags) + dottydoc.println(s"$pos: Tag '@${key.name}' is not recognised") + + cmt } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index f83f43138559..a512ee352bcf 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -25,7 +25,8 @@ object json { } implicit class JsonComment(val cmt: Comment) extends AnyVal { - def json: String = s"""{"body":${cmt.body.json},"short":${cmt.short.json}}""" + def json: String = + s"""{"body":${cmt.body.json},"short":${cmt.short.json},"authors":${cmt.authors.map(_.json).mkString("[",",","]")},"see":${cmt.see.map(_.json).mkString("[",",","]")},${cmt.result.map(res => s""""result":${res.json},""").getOrElse("")}"throws":${cmt.throws.map { case (k, v) => s"${k.json}:${v.json}" }.mkString("{",",","}")},"valueParams":${cmt.valueParams.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"typeParams":${cmt.typeParams.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},${cmt.version.map(x => s""""version":${x.json},""").getOrElse("")}${cmt.since.map(x => s""""since":${x.json},""").getOrElse("")}"todo":${cmt.todo.map(_.json).mkString("[",",","]")},${cmt.deprecated.map(x => s""""deprecated":${x.json},""").getOrElse("")}"note":${cmt.note.map(_.json).mkString("[",",","]")},"example":${cmt.example.map(_.json).mkString("[",",","]")},${cmt.constructor.map(x => s""""constructor":${x.json},""").getOrElse("")}${cmt.group.map(x => s""""group":${x.json},""").getOrElse("")}"groupDesc":${cmt.groupDesc.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"groupNames":${cmt.groupNames.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"groupPrio":${cmt.groupPrio.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"hideImplicitConversions":${cmt.hideImplicitConversions.map(_.json).mkString("[",",","]")}}""" } implicit class LinkJson(val link: MaterializableLink) extends AnyVal { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index afd1cf982f41..fa54163e5838 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -25,13 +25,8 @@ object parsers { def parseHtml(sym: Symbol, parent: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): (String, Option[Comment]) = { val cmt = ctx.docbase.docstring(sym).map { d => val expanded = expand(sym, parent) - val body = parse(entity, packages, clean(expanded), expanded, d.pos) - val summary = body.summary.map(_.toHtml(entity)).getOrElse("") - body.toHtml(entity) match { - case "" => None - case x => Some(Comment(x, summary)) - } - }.flatten + parse(entity, packages, clean(expanded), expanded, d.pos).toComment(_.toHtml(entity)) + } (entity.path.mkString("."), cmt) } From 5cd1d51c3cb44b2c9b2c1abd433da50a00e5219e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 9 Aug 2016 18:42:54 +0200 Subject: [PATCH 089/100] Remove client from dottydoc - no more Scala.JS deps! --- dottydoc/js/src/DottyDoc.scala | 28 - dottydoc/js/src/EntityIndex.scala | 25 - dottydoc/js/src/Search.scala | 121 - dottydoc/js/src/html/CustomTags.scala | 13 - dottydoc/js/src/html/EntityLayout.scala | 212 -- dottydoc/js/src/html/Member.scala | 313 --- dottydoc/js/src/model/entities.scala | 180 -- dottydoc/js/src/model/references.scala | 84 - .../jvm/resources/MaterialIcons-Regular.eot | Bin 143258 -> 0 bytes .../jvm/resources/MaterialIcons-Regular.ijmap | 1 - .../jvm/resources/MaterialIcons-Regular.svg | 2373 ----------------- .../jvm/resources/MaterialIcons-Regular.ttf | Bin 128180 -> 0 bytes .../jvm/resources/MaterialIcons-Regular.woff | Bin 78776 -> 0 bytes .../jvm/resources/MaterialIcons-Regular.woff2 | Bin 42304 -> 0 bytes dottydoc/jvm/resources/codepoints | 932 ------- dottydoc/jvm/resources/github.css | 1 - dottydoc/jvm/resources/highlight.pack.js | 2 - dottydoc/jvm/resources/index.css | 185 -- dottydoc/jvm/resources/material-icons.css | 38 - dottydoc/jvm/resources/material.min.css | 9 - dottydoc/jvm/resources/material.min.js | 10 - .../tools/dottydoc/core/PrintPhase.scala | 30 - .../tools/dottydoc/html/EntityPage.scala | 44 - .../tools/dottydoc/util/OutputWriter.scala | 87 - dottydoc/jvm/test/WhitelistedStdLibMain.scala | 23 - .../src/dotty/tools/dottydoc/DottyDoc.scala | 31 +- .../tools/dottydoc/core/DocASTPhase.scala | 0 .../dottydoc/core/DocImplicitsPhase.scala | 0 .../dottydoc/core/MiniPhaseTransform.scala | 0 .../tools/dottydoc/core/OutputJsonPhase.scala | 13 + .../tools/dottydoc/core/PrintPhase.scala | 30 + .../dottydoc/core/SortMembersPhase.scala | 0 .../dottydoc/core/TypeLinkingPhases.scala | 5 +- .../tools/dottydoc/interface/Dottydoc.java | 27 + .../dottydoc/model/comment/BodyEntities.scala | 16 - .../dottydoc/model/comment/BodyParsers.scala | 0 .../dottydoc/model/comment/Comment.scala | 0 .../model/comment/CommentCleaner.scala | 2 +- .../model/comment/CommentExpander.scala | 0 .../model/comment/CommentParser.scala | 0 .../dottydoc/model/comment/CommentRegex.scala | 0 .../dottydoc/model/comment/CommentUtils.scala | 0 .../dotty/tools/dottydoc/model/entities.scala | 3 +- .../tools/dottydoc/model/factories.scala | 1 + .../dotty/tools/dottydoc/model/internal.scala | 3 +- .../src/dotty/tools/dottydoc/model/java.scala | 223 ++ .../src/dotty/tools/dottydoc/model/json.scala | 5 +- .../dotty/tools/dottydoc/model/parsers.scala | 0 .../tools/dottydoc/model/references.scala | 20 + .../tools/dottydoc/util/MemberLookup.scala | 0 .../tools/dottydoc/util/OutputWriter.scala | 110 + .../tools/dottydoc/util/Traversing.scala | 0 .../dotty/tools/dottydoc/util/mutate.scala | 3 +- dottydoc/{jvm => }/test/BaseTest.scala | 0 .../{jvm => }/test/PackageStructure.scala | 0 dottydoc/{jvm => }/test/SimpleComments.scala | 0 .../{jvm => }/test/WhitelistedStdLib.scala | 0 dottydoc/test/WhitelistedStdLibMain.scala | 47 + project/Build.scala | 24 +- 59 files changed, 513 insertions(+), 4761 deletions(-) delete mode 100644 dottydoc/js/src/DottyDoc.scala delete mode 100644 dottydoc/js/src/EntityIndex.scala delete mode 100644 dottydoc/js/src/Search.scala delete mode 100644 dottydoc/js/src/html/CustomTags.scala delete mode 100644 dottydoc/js/src/html/EntityLayout.scala delete mode 100644 dottydoc/js/src/html/Member.scala delete mode 100644 dottydoc/js/src/model/entities.scala delete mode 100644 dottydoc/js/src/model/references.scala delete mode 100755 dottydoc/jvm/resources/MaterialIcons-Regular.eot delete mode 100755 dottydoc/jvm/resources/MaterialIcons-Regular.ijmap delete mode 100755 dottydoc/jvm/resources/MaterialIcons-Regular.svg delete mode 100755 dottydoc/jvm/resources/MaterialIcons-Regular.ttf delete mode 100755 dottydoc/jvm/resources/MaterialIcons-Regular.woff delete mode 100755 dottydoc/jvm/resources/MaterialIcons-Regular.woff2 delete mode 100755 dottydoc/jvm/resources/codepoints delete mode 100644 dottydoc/jvm/resources/github.css delete mode 100644 dottydoc/jvm/resources/highlight.pack.js delete mode 100644 dottydoc/jvm/resources/index.css delete mode 100755 dottydoc/jvm/resources/material-icons.css delete mode 100644 dottydoc/jvm/resources/material.min.css delete mode 100644 dottydoc/jvm/resources/material.min.js delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala delete mode 100644 dottydoc/jvm/test/WhitelistedStdLibMain.scala rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/DottyDoc.scala (78%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/core/DocASTPhase.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala (100%) create mode 100644 dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala create mode 100644 dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/core/SortMembersPhase.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala (98%) create mode 100644 dottydoc/src/dotty/tools/dottydoc/interface/Dottydoc.java rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala (77%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/Comment.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala (88%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/CommentParser.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/entities.scala (96%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/factories.scala (99%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/internal.scala (96%) create mode 100644 dottydoc/src/dotty/tools/dottydoc/model/java.scala rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/json.scala (98%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/model/parsers.scala (100%) create mode 100644 dottydoc/src/dotty/tools/dottydoc/model/references.scala rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/util/MemberLookup.scala (100%) create mode 100644 dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/util/Traversing.scala (100%) rename dottydoc/{jvm => }/src/dotty/tools/dottydoc/util/mutate.scala (96%) rename dottydoc/{jvm => }/test/BaseTest.scala (100%) rename dottydoc/{jvm => }/test/PackageStructure.scala (100%) rename dottydoc/{jvm => }/test/SimpleComments.scala (100%) rename dottydoc/{jvm => }/test/WhitelistedStdLib.scala (100%) create mode 100644 dottydoc/test/WhitelistedStdLibMain.scala diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala deleted file mode 100644 index d33648e4900b..000000000000 --- a/dottydoc/js/src/DottyDoc.scala +++ /dev/null @@ -1,28 +0,0 @@ -package dotty.tools.dottydoc -package js - -import scala.scalajs.{ js => sjs } -import sjs.Dynamic.global -import sjs.JSApp -import sjs.annotation.{ JSExport, JSName } -import org.scalajs.dom -import dom.document -import dom.webworkers.Worker -import model._ -import html.EntityLayout - -@JSExport object DottyDocJS { - @JSExport def main(target: dom.html.Div) = { - document.title = "Dotty " + EntityIndex.currentEntity.path.mkString(".") - target.appendChild(EntityLayout(EntityIndex.currentEntity).html.render) - hljs.initHighlightingOnLoad() - - val searchInput = document.getElementById("search").asInstanceOf[dom.html.Input] - searchInput.onkeyup = new Search(searchInput).search() - } -} - -/** Library wrapper for highlighting */ -@sjs.native object hljs extends sjs.Object { - def initHighlightingOnLoad(): sjs.Any = sjs.native -} diff --git a/dottydoc/js/src/EntityIndex.scala b/dottydoc/js/src/EntityIndex.scala deleted file mode 100644 index 358298ca0b81..000000000000 --- a/dottydoc/js/src/EntityIndex.scala +++ /dev/null @@ -1,25 +0,0 @@ -package dotty.tools -package dottydoc -package js - -import scala.scalajs.{ js => sjs } -import sjs.JSConverters._ -import sjs.Dynamic.global -import sjs.JSApp -import sjs.annotation.JSName - -/** The unpickled AST available as scala classes */ -object EntityIndex { - import js.model._ - - lazy val packages: Map[String, Package] = - Unparsed.packages.toMap[String, Package] - - val currentEntity: Entity = Unparsed.currentEntity - - /** Unparsed index stores the pickled AST generated by the dottydoc tool */ - @sjs.native @JSName("UnparsedIndex") private object Unparsed extends sjs.Object { - def packages: sjs.Dictionary[Package] = sjs.native - def currentEntity: Entity = sjs.native - } -} diff --git a/dottydoc/js/src/Search.scala b/dottydoc/js/src/Search.scala deleted file mode 100644 index 6625e3c78949..000000000000 --- a/dottydoc/js/src/Search.scala +++ /dev/null @@ -1,121 +0,0 @@ -package dotty.tools.dottydoc -package js - -import scala.scalajs.{ js => sjs } -import sjs.timers.setTimeout -import scalatags.JsDom.all._ -import org.scalajs.dom.html.{ Input, Div } -import org.scalajs.dom.{ document, Event } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future - -import js.model._ -import js.model.ops._ - -class Search(val input: Input) { - private var isSearching = false - - private val mainDiv = document - .getElementById("entity-container") - .asInstanceOf[Div] - private val resultsDiv = document - .getElementById("search-results") - .asInstanceOf[Div] - - /** Search result ADTs */ - private case class PackageResults(matching: Stream[Package], nonMatching: Stream[Package]) - private object PackageResults { - def empty = PackageResults(Stream.empty, Stream.empty) - } - - /** Entry point into search, will consider whether to start searching or not, - * then call `performSearch` - */ - def search(): Event => Unit = { e => - val query = input.value.trim - if (query.length > 2) setTimeout(200) { - if (!isSearching) { - isSearching = true - performSearch(query.toLowerCase).map { _ => isSearching = false } - } - } - else if (query.length == 0) - hideSearchDiv() - } - - private def performSearch(query: String): Future[Unit] = - for (PackageResults(matching, nonMatching) <- searchPackages(query)) yield { - // Clear old results, add new result categories add close button - resultsDiv.innerHTML = "" - val toplevelRes = div(id := "toplevel-results").render - val methodRes = div(id := "method-results").render - val closeButton = button( - id := "close-button", - onclick := { _: Event => - resetInput() - hideSearchDiv() - }, - cls := "mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored", - i(cls := "material-icons", "clear") - ).render - - resultsDiv.appendChild(toplevelRes) - resultsDiv.appendChild(methodRes) - resultsDiv.appendChild(closeButton) - - // Add all matching toplevel entities - matching - .toStream - .sortBy(_.name) - .map(createPackageCard) - .foreach(toplevelRes.appendChild) - - // Hide entity and show results instead - showSearchDiv() - } - - private def searchPackages(query: String): Future[PackageResults] = Future { - EntityIndex.packages.values.foldLeft(PackageResults.empty) { (acc, p) => - val matchingMembers = p.members.collect { - case x if (x.name.toLowerCase.contains(query) && x.kind != "package") => x - } - - println("We found all matching members maybe") - sjs.Dynamic.global.console.log(p) - - if (p.name.toLowerCase.contains(query) || matchingMembers.nonEmpty) - acc.copy(matching = p.withMembers(matchingMembers) #:: acc.matching) - else acc - } - } - - private def createPackageCard(pack: Package): Div = div( - cls := "mdl-card mdl-shadow--2dp package-result", - div(cls := "mdl-card__title", h2(cls := "mdl-card__title-text", pack.name)), - ul(pack.members.map(createEntityLi).toList) - ).render - - private def createEntityLi(e: Entity) = li( - a( - href := toRoot + e.path.mkString("", "/", ".html"), - e.kind + " " + e.name - ) - ) - - private def toRoot = "../" * (EntityIndex.currentEntity.path.length - 1) - - private def resetInput() = { - input.value = "" - input.parentElement.className = input.parentElement.className.replaceAll("is-dirty", "") - } - - private def showSearchDiv() = { - mainDiv.style.display = "none" - resultsDiv.style.display = "block" - } - - private def hideSearchDiv() = { - resultsDiv.style.display = "none" - mainDiv.style.display = "block" - } -} diff --git a/dottydoc/js/src/html/CustomTags.scala b/dottydoc/js/src/html/CustomTags.scala deleted file mode 100644 index af3667f11d0e..000000000000 --- a/dottydoc/js/src/html/CustomTags.scala +++ /dev/null @@ -1,13 +0,0 @@ -package dotty.tools.dottydoc -package js -package html - -import scalatags.JsDom.all._ -import scalatags.generic -import scalatags.generic.Util -import org.scalajs.dom - -object CustomTags { - lazy val nav = "nav".tag - lazy val main = "main".tag -} diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala deleted file mode 100644 index f81f42e02ef1..000000000000 --- a/dottydoc/js/src/html/EntityLayout.scala +++ /dev/null @@ -1,212 +0,0 @@ -package dotty.tools.dottydoc -package js -package html - -import scalatags.JsDom.all._ -import org.scalajs.dom -import org.scalajs.dom.html.{Anchor, Div} -import js.model._ -import js.model.ops._ - -case class EntityLayout(entity: Entity) extends MemberLayout { - import CustomTags._ - import EntityIndex.packages - - private def relativePath(to: Entity) = { - val offset = entity.kind match { - case "val" | "def" => 2 - case _ => 1 - } - - val prefix = entity.kind match { - case "package" => "../" - case _ => "" - } - - prefix + { - "../" * (entity.path.length - offset) + to.path.mkString("","/",".html") - } - } - - def html = - div( - cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", - div( - cls := "mdl-layout__drawer", - span( - cls := "mdl-layout-title subtitle", - entity.path.dropRight(1).mkString(".") - ), - span( - cls := "mdl-layout-title", - if (entity.kind == "package") entity.name.split("\\.").last - else entity.name - ), - nav( - cls := "related mdl-navigation", - companionAnchor, - a(cls := "mdl-navigation__link", href := "#", "Source") - ), - span( - cls := "mdl-layout-title", - id := "docs-title", - "Docs" - ), - searchView, - packageView - ), - main( - id := "entity-container", - cls := "mdl-layout__content", - div( - cls := "page-content", - div(cls := "entity-title", entityTitle), - div(raw(entity.comment.fold("")(_.body))), - entity.comment.filter(_.authors.nonEmpty).map { comment => - dl( - dt(cls := "entity-authors", "Authors"), - comment.authors.map(x => dd(cls := "entity-author", raw(x))).toList - ) - }.toOption, - entity match { - case x if x.hasMembers => - val e = x.asInstanceOf[Entity with Members] - if (e.members.nonEmpty) - Seq( - h5("Members"), - div( - cls := "mdl-grid", - e.members - .collect { - case x if x.hasModifiers && !x.isPrivate => x - } - .flatMap(member(_, entity)).toList - ) - ) - case _ => () - } - ) - ), - main( - id := "search-results", - cls := "mdl-layout__content" - ) - ) - - def packageView = ul( - cls := "mdl-list packages", - { - val keys: Seq[String] = packages.keys.toSeq.sorted - val productReg = """^Product[0-9]+$""".r - keys.flatMap { k => - val pack = packages(k) - val children = - pack.children - .sortBy(_.name) - .filterNot { ent => - // Filter out ProductX where X > 3 - productReg.findFirstIn(ent.name).map(_.slice(7, 99).toInt > 3).getOrElse(false) || - // Filter out packages - ent.kind == "package" || - // Filter out objects that have companions - (ent.kind == "object" && companion(ent).isDefined) || - ent.name == "AnyValCompanion" - } - .map { entity => - val comp = companion(entity) - val entityUrl = relativePath(entity) - val compUrl = comp.map(relativePath).getOrElse("#") - li( - cls := s"""mdl-list__item entity ${ if (comp.isDefined) "two" else "one" }""", - comp.map { _ => a(cls := "entity-button object", href := compUrl, "O") }.getOrElse(()), - a( - cls := s"""entity-button shadowed ${entity.kind.replaceAll(" ", "")}""", - href := entityUrl, - entity.kind(0).toUpper.toString - ), - a( - cls := "entity-name", - href := entityUrl, - entity.name - ) - ) - } - - if (children.length > 0) - li(cls := "mdl-list__item package", href := relativePath(pack), k) :: children.toList - else Nil - } - } - ) - - - def entityTitle = { - val modifiers = entity.kind match { - case "Modifiers" => - val m = entity.asInstanceOf[Modifiers] - if (m.modifiers.nonEmpty) - Some(span(cls := "entity-modifiers", m.modifiers.mkString(" "))) - else - None - case _ => None - } - - val typeParams = entity match { - case x if x.hasTypeParams => - val t = entity.asInstanceOf[TypeParams] - if (t.typeParams.nonEmpty) - Some(span(cls := "entity-type-params no-left-margin", t.typeParams.mkString("[", ", ", "]"))) - else None - case _ => None - } - - val superTypes = entity match { - case x if x.hasSuperTypes => - val st = entity.asInstanceOf[SuperTypes] - if (st.superTypes.nonEmpty) - Some(span( - cls := "entity-super-types", - st.superTypes.collect { - case x => x.title - }.mkString("extends ", " with ", "") - )) - else None - case _ => None - } - - modifiers :: - Some(span(cls := "entity-kind", entity.kind)) :: - Some(span(cls := "entity-name", entity.name)) :: - typeParams :: - superTypes :: - Nil - - }.flatten - - def companion(entity: Entity) = { - val pack = entity.path.dropRight(1).mkString(".") - for { - p <- packages.get(pack) - child <- p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) - } yield child - } - - def companionAnchor = - companion(entity).map { c => - a( - cls := "mdl-navigation__link", - href := c.path.last + ".html", - "Companion " + c.kind - ) - }.getOrElse(span()) - - def searchView = - div( - cls := "search-container", - div( - cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", - input(cls := "mdl-textfield__input", `type` := "text", id := "search"), - label(cls := "mdl-textfield__label", `for` := "search", "Search") - ) - ) -} diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala deleted file mode 100644 index ec17b5021622..000000000000 --- a/dottydoc/js/src/html/Member.scala +++ /dev/null @@ -1,313 +0,0 @@ -package dotty.tools.dottydoc -package js -package html - -import scalatags.JsDom.all._ -import scalatags.JsDom.TypedTag -import org.scalajs.dom -import org.scalajs.dom.html.{Anchor, Div, Span} - -trait MemberLayout { - import js.model._ - import js.model.ops._ - - def member(m: Entity, parent: Entity) = { - def toggleBetween(short: Div, and: Div): Unit = - if (and.style.display == "none") { - and.style.display = "block" - short.style.display = "none" - } else { - and.style.display = "none" - short.style.display = "block" - } - - m.kind match { - case "class" | "case class" | "object" | "trait" | "def" | "val" => - val entity = m.asInstanceOf[Entity with Modifiers] - val shortComment = div( - cls := "mdl-cell mdl-cell--12-col summary-comment", - raw(m.comment.fold("")(_.short)) - ).render - - val fullComment = div( - cls := "mdl-cell mdl-cell--12-col full-comment", - style := "display: none;", - fromImplicitSpan(m), - raw(m.comment.fold("")(_.body)) - ).render - - val hasLongerFullComment = m.comment.fold(false) { c => - c.short.length + 5 < c.body.length - } - - val divs = div( - cls := - s""" - mdl-cell mdl-cell--12-col member - ${if (hasLongerFullComment) "member-fullcomment" else ""} - """, - onclick := { () => toggleBetween(shortComment, and = fullComment) }, - div( - cls := "mdl-cell mdl-cell--12-col member-definition", - span( - cls := "member-modifiers-kind", - entity.modifiers.mkString(" ") + " " + m.kind - ), - span( - cls := { if (m.addedImplicitly) "member-name implicitly-added" else "member-name" }, - m.name - ), - spanWith("member-type-params no-left-margin", typeParams(m)), - span(cls := "member-param-list no-left-margin", paramList(m)), - returnValue(entity, parent) - ), - shortComment, - fullComment - ) - Seq(divs) - case _ => Seq(h1("ERROR: " + m.name)) - } - } - - def fromImplicitSpan(m: Entity) = m.foldImplicitlyAdded { ref => - span( - "Implicitly added from: ", - referenceToLinks(ref) - ) - }.getOrElse(span()) - - def spanWith(clazz: String, contents: String) = contents match { - case "" => None - case _ => Some(span(cls := clazz, contents)) - } - - def paramList(m: Entity): Span = m.kind match { - case "def" => - val d = m.asInstanceOf[Def] - if (d.paramLists.nonEmpty) - span( - cls := "member-param-lists", - d.paramLists.map { xs => - span( - cls := "param-list", - "(", - span(cls := "is-implicit no-left-margin", if (xs.isImplicit) "implicit " else ""), - xs.list.flatMap { tr => - Seq( - span(cls := "param-name", tr.title).render, - span(cls := "type-separator no-left-margin", if (tr.isByName) ": =>" else ":").render, - span(if (tr.ref.kind == "FunctionReference" && tr.isRepeated) "(" else "").render, - span(referenceToLinks(tr.ref)).render, - span(if (tr.ref.kind == "FunctionReference" && tr.isRepeated) ")*" else if (tr.isRepeated) "*" else "").render, - span(cls := "type-separator no-left-margin", ",").render - ) - }.toList.dropRight(1), - ")" - ).render - }.toList - ).render - else span().render - case _ => span().render - } - - def referenceToLinks(ref: Reference): Span = { - def linkToAnchor(link: MaterializableLink) = link.kind match { - case "MaterializedLink" => - val (t, url) = (link.asInstanceOf[MaterializedLink].title, link.asInstanceOf[MaterializedLink].target) - a(href := url, t).render - case "NoLink" => span(link.title).render - - case "UnsetLink" => - println("UnsetLink found:") - scala.scalajs.js.Dynamic.global.console.log(link) - span(link.title).render - } - - ref.kind match { - case "TypeReference" => - val tref = ref.asInstanceOf[TypeReference] - val infixTypes = "<:<" :: "=:=" :: Nil - if (tref.paramLinks.length == 2 && infixTypes.contains(tref.title)) span( - referenceToLinks(tref.paramLinks(0)), - span(cls := "type-separator no-left-margin"), - linkToAnchor(tref.tpeLink), - span(cls := "type-separator no-left-margin"), - referenceToLinks(tref.paramLinks(1)) - ).render - else if (tref.paramLinks.nonEmpty) span( - linkToAnchor(tref.tpeLink), - "[", - tref - .paramLinks - .map(referenceToLinks) - .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)) - .toList.dropRight(1), - "]" - ).render - else span(linkToAnchor(tref.tpeLink)).render - - case "OrTypeReference" => - val (left, right) = (ref.asInstanceOf[OrTypeReference].left, ref.asInstanceOf[OrTypeReference].right) - span( - referenceToLinks(left), - span(cls := "type-separator", "|"), - referenceToLinks(right) - ).render - - case "AndTypeReference" => - val (left, right) = (ref.asInstanceOf[AndTypeReference].left, ref.asInstanceOf[AndTypeReference].right) - span( - referenceToLinks(left), - span(cls := "type-separator", "&"), - referenceToLinks(right) - ).render - - case "BoundsReference" => - val (low, high) = (ref.asInstanceOf[BoundsReference].low, ref.asInstanceOf[BoundsReference].high) - span( - referenceToLinks(low), - span(cls := "type-separator", "<:"), - referenceToLinks(high) - ).render - - case "FunctionReference" => { - val func = ref.asInstanceOf[FunctionReference] - span( - cls := "no-left-margin", - if (func.args.length > 1) "(" else "", - if (func.args.isEmpty) - span("()") - else func - .args - .map(referenceToLinks) - .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, - if (func.args.length > 1) ") => " else " => ", - referenceToLinks(func.returnValue) - ).render - } - - case "TupleReference" => { - val func = ref.asInstanceOf[TupleReference] - span( - cls := "no-left-margin", - "(", - func - .args - .map(referenceToLinks) - .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, - ")" - ).render - } - } - } - - def typeParams(m: Entity): String = m.kind match { - case "def" => - val d = m.asInstanceOf[Def] - if (d.typeParams.nonEmpty) - d.typeParams.mkString("[", ", ", "]") - else "" - case _ => "" - } - - def returnValue(m: Entity with Modifiers, parent: Entity) = { - // shortens: "Option.this.A" => "A" - def shorten(s: String): String = s.split('.').toList match { - case x :: Nil => x - case x :: xs if x == parent.name => xs.last - case xs => s - } - - def link(rv: Reference): Span = { - def decodeTpeLink(link: MaterializableLink): Span = link.kind match { - case "MaterializedLink" => - val ml = link.asInstanceOf[MaterializedLink] - span(cls := "member-return-value", a(href := ml.target, ml.title)).render - case "UnsetLink" => - val un = link.asInstanceOf[UnsetLink] - span(cls := "member-return-value", shorten(un.query)).render - case "NoLink" => - val no = link.asInstanceOf[NoLink] - span(cls := "member-return-value", shorten(no.title)).render - } - - rv.kind match { - case "TypeReference" => - val trv = rv.asInstanceOf[TypeReference] - val returnValue = decodeTpeLink(trv.tpeLink) - - if (trv.paramLinks.nonEmpty) span( - returnValue, - "[", - trv.paramLinks - .map(link) - .flatMap { sp => - Seq(sp, span(cls := "type-separator no-left-margin", ",").render) - } - .toList.dropRight(1), - "]" - ).render - else returnValue - - case "OrTypeReference" => - val (left, right) = (rv.asInstanceOf[OrTypeReference].left, rv.asInstanceOf[OrTypeReference].right) - span( - cls := "member-return-value or-type", - link(left), - span(cls := "type-separator", "|"), - link(right) - ).render - case "AndTypeReference" => - val (left, right) = (rv.asInstanceOf[AndTypeReference].left, rv.asInstanceOf[AndTypeReference].right) - span( - cls := "member-return-value and-type", - link(left), - span(cls := "type-separator", "&"), - link(right) - ).render - - case "BoundsReference" => - val (low, high) = (rv.asInstanceOf[BoundsReference].low, rv.asInstanceOf[BoundsReference].high) - span( - link(low), - span(cls := "type-separator", "<:"), - link(high) - ).render - case "FunctionReference" => - val func = rv.asInstanceOf[FunctionReference] - span( - cls := "no-left-margin", - if (func.args.length > 1) "(" else "", - if (func.args.isEmpty) - span("()") - else func - .args - .map(link) - .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, - if (func.args.length > 1) ") => " else " => ", - link(func.returnValue) - ).render - - case "TupleReference" => { - val func = rv.asInstanceOf[TupleReference] - span( - cls := "no-left-margin", - "(", - func - .args - .map(link) - .flatMap(link => Seq(link, span(cls := "type-separator no-left-margin", ",").render)).init.toList, - ")" - ).render - } - } - } - - m.kind match { - case "def" => - val rv = m.asInstanceOf[ReturnValue] - Some(span(cls := "no-left-margin", ": ", link(rv.returnValue))) - case _ => None - } - } -} diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala deleted file mode 100644 index ca1b5ec6935f..000000000000 --- a/dottydoc/js/src/model/entities.scala +++ /dev/null @@ -1,180 +0,0 @@ -package dotty.tools -package dottydoc -package js -package model - -import scala.scalajs.{ js => sjs } -import sjs.annotation.ScalaJSDefined - -/** This file defines the interface for which to interact with the searchable - * index. To use the normal operations available on the traits on the JVM: - * - * {{{ - * import dotty.tools.dottydoc.js.model.ops._ - * val x: Package = ... - * }}} - * - * Please note that some of the actual fields have not been added to this - * interface, this is simply due to the fact that they're not necessary for - * search - YET. They could be added, for instance `comment` is missing. - */ -@ScalaJSDefined -trait Entity extends sjs.Object { - val kind: String - val name: String - val path: sjs.Array[String] - val comment: sjs.UndefOr[Comment] -} - -@ScalaJSDefined -trait Comment extends sjs.Object { - val body: String - val short: String - val authors: sjs.Array[String] - val see: sjs.Array[String] - val result: sjs.UndefOr[String] - val throws: Map[String, String] - val valueParams: Map[String, String] - val typeParams: Map[String, String] - val version: sjs.UndefOr[String] - val since: sjs.UndefOr[String] - val todo: List[String] - val deprecated: sjs.UndefOr[String] - val note: List[String] - val example: List[String] - val constructor: sjs.UndefOr[String] - val group: sjs.UndefOr[String] - val groupDesc: Map[String, String] - val groupNames: Map[String, String] - val groupPrio: Map[String, String] - val hideImplicitConversions: List[String] -} - -@ScalaJSDefined -trait Members extends sjs.Object { - val members: sjs.Array[Entity] -} - -@ScalaJSDefined -trait Modifiers extends sjs.Object { - val modifiers: sjs.Array[String] -} - -@ScalaJSDefined -trait ReturnValue extends sjs.Object { - val returnValue: Reference -} - -@ScalaJSDefined -trait TypeParams extends sjs.Object { - val typeParams: sjs.Array[String] -} - -@ScalaJSDefined -trait SuperTypes extends sjs.Object { - val superTypes: sjs.Array[MaterializableLink] -} - -@ScalaJSDefined -trait Package extends Entity with Members - -@ScalaJSDefined -trait Class extends Entity with Members with Modifiers with TypeParams - -@ScalaJSDefined -trait CaseClass extends Class - -@ScalaJSDefined -trait Object extends Entity with Members with Modifiers - -@ScalaJSDefined -trait Trait extends Class - -@ScalaJSDefined -trait ParamList extends sjs.Object { - val list: sjs.Array[NamedReference] - val isImplicit: Boolean -} - -@ScalaJSDefined -trait Def extends Entity with Modifiers with ReturnValue { - val typeParams: sjs.Array[String] - val paramLists: sjs.Array[ParamList] - val implicitlyAddedFrom: sjs.UndefOr[Reference] -} - -@ScalaJSDefined -trait Val extends Entity with Modifiers { - val implicitlyAddedFrom: sjs.UndefOr[Reference] -} - -@ScalaJSDefined -trait Var extends Entity with Modifiers { - val implicitlyAddedFrom: sjs.UndefOr[Reference] -} - -@ScalaJSDefined -trait ImplicitlyAddedEntity extends Entity { - val implicitlyAddedFrom: sjs.UndefOr[Reference] -} - -object ops { - val EntitiesWithModifiers = - "case class" :: "class" :: "object" :: "trait" :: "def" :: "val" :: Nil - - val EntitiesWithMembers = - "package" :: "case class" :: "class" :: "object" :: "trait" :: Nil - - val EntitiesWithTypeParams = - "case class" :: "class" :: "trait" :: "def" :: Nil - - val EntitiesWithSuperTypes = - "case class" :: "class" :: "trait" :: "object" :: Nil - - implicit class PackageOps(val p: Package) { - def children: sjs.Array[Entity with Members] = - p.members.collect { - case x if EntitiesWithMembers contains x.kind => - x.asInstanceOf[Entity with Members] - } - - def withMembers(mbrs: sjs.Array[Entity]): Package = new Package { - val kind = p.kind - val name = p.name - val path = p.path - val members = mbrs - val comment = p.comment - } - } - - implicit class EntityOps(val ent: Entity) { - def typeParams: sjs.Array[String] = - if (ent.kind == "def") - ent.asInstanceOf[Def].typeParams - else sjs.Array() - - def hasMembers: Boolean = - EntitiesWithMembers contains ent.kind - - def hasModifiers: Boolean = - EntitiesWithModifiers contains ent.kind - - def hasTypeParams: Boolean = - EntitiesWithTypeParams contains ent.kind - - def hasSuperTypes: Boolean = - EntitiesWithSuperTypes contains ent.kind - - def isPrivate: Boolean = - hasModifiers && - ent.asInstanceOf[Modifiers].modifiers.contains("private") - - def addedImplicitly: Boolean = (ent.kind == "def" || ent.kind == "val") && { - ent.asInstanceOf[ImplicitlyAddedEntity].implicitlyAddedFrom.isDefined - } - - def foldImplicitlyAdded[B](f: Reference => B): sjs.UndefOr[B] = - if (ent.kind == "def" || ent.kind == "val") ent.asInstanceOf[ImplicitlyAddedEntity].implicitlyAddedFrom.map(f) - else sjs.undefined - } -} diff --git a/dottydoc/js/src/model/references.scala b/dottydoc/js/src/model/references.scala deleted file mode 100644 index 051251b68d07..000000000000 --- a/dottydoc/js/src/model/references.scala +++ /dev/null @@ -1,84 +0,0 @@ -package dotty.tools -package dottydoc -package js -package model - -import scala.scalajs.{ js => sjs } -import sjs.annotation.ScalaJSDefined - -/** Type References */ -@ScalaJSDefined -sealed trait Reference extends sjs.Object { - val kind: String -} - -@ScalaJSDefined -trait TypeReference extends Reference { - val title: String - val tpeLink: MaterializableLink - val paramLinks: sjs.Array[Reference] -} - -@ScalaJSDefined -trait OrTypeReference extends Reference { - val left: Reference - val right: Reference -} - -@ScalaJSDefined -trait AndTypeReference extends Reference { - val left: Reference - val right: Reference -} - -@ScalaJSDefined -trait BoundsReference extends Reference { - val low: Reference - val high: Reference -} - -@ScalaJSDefined -trait NamedReference extends Reference { - val title: String - val ref: Reference - val isByName: Boolean - val isRepeated: Boolean -} - -@ScalaJSDefined -trait ConstantReference extends Reference { - val title: String -} - -@ScalaJSDefined -trait FunctionReference extends Reference { - val args: sjs.Array[Reference] - val returnValue: Reference -} - -@ScalaJSDefined -trait TupleReference extends Reference { - val args: sjs.Array[Reference] -} - -/** Materializable links */ -@ScalaJSDefined -sealed trait MaterializableLink extends sjs.Object { - val kind: String - val title: String -} - -@ScalaJSDefined -trait UnsetLink extends MaterializableLink { - val query: String -} - -@ScalaJSDefined -trait MaterializedLink extends MaterializableLink { - val target: String -} - -@ScalaJSDefined -trait NoLink extends MaterializableLink { - val target: String -} diff --git a/dottydoc/jvm/resources/MaterialIcons-Regular.eot b/dottydoc/jvm/resources/MaterialIcons-Regular.eot deleted file mode 100755 index 70508ebabc9992e64f1314f866b2d7ab90438c58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143258 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 Hzx)3OGG_Ot diff --git a/dottydoc/jvm/resources/MaterialIcons-Regular.ijmap b/dottydoc/jvm/resources/MaterialIcons-Regular.ijmap deleted file mode 100755 index d9f1d259f3b1..000000000000 --- a/dottydoc/jvm/resources/MaterialIcons-Regular.ijmap +++ /dev/null @@ -1 +0,0 @@ -{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}} \ No newline at end of file diff --git a/dottydoc/jvm/resources/MaterialIcons-Regular.svg b/dottydoc/jvm/resources/MaterialIcons-Regular.svg deleted file mode 100755 index a449327e22c0..000000000000 --- a/dottydoc/jvm/resources/MaterialIcons-Regular.svg +++ /dev/null @@ -1,2373 +0,0 @@ - - - - - -Created by FontForge 20151118 at Mon Feb 8 11:58:02 2016 - By shyndman -Copyright 2015 Google, Inc. All Rights Reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dottydoc/jvm/resources/MaterialIcons-Regular.ttf b/dottydoc/jvm/resources/MaterialIcons-Regular.ttf deleted file mode 100755 index 7015564ad166a3e9d88c82f17829f0cc01ebe29a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128180 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 ohyj3!`#ee%L;DTjx@8!5k5~VH0QmdE^#A|> diff --git a/dottydoc/jvm/resources/MaterialIcons-Regular.woff b/dottydoc/jvm/resources/MaterialIcons-Regular.woff deleted file mode 100755 index a0bfd17e73cdba0229cd143b2eb38550c58e1cd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78776 zcmV)vK$X9DPew*hR8&s@0W-J&4FCWD0sja90RRgC000000000000000000000000( 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 `ZUVxvPc?;2naBlS+{8YhA^;>}E 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 diff --git a/dottydoc/jvm/resources/codepoints b/dottydoc/jvm/resources/codepoints deleted file mode 100755 index 3c8b07507460..000000000000 --- a/dottydoc/jvm/resources/codepoints +++ /dev/null @@ -1,932 +0,0 @@ -3d_rotation e84d -ac_unit eb3b -access_alarm e190 -access_alarms e191 -access_time e192 -accessibility e84e -accessible e914 -account_balance e84f -account_balance_wallet e850 -account_box e851 -account_circle e853 -adb e60e -add e145 -add_a_photo e439 -add_alarm e193 -add_alert e003 -add_box e146 -add_circle e147 -add_circle_outline e148 -add_location e567 -add_shopping_cart e854 -add_to_photos e39d -add_to_queue e05c -adjust e39e -airline_seat_flat e630 -airline_seat_flat_angled e631 -airline_seat_individual_suite e632 -airline_seat_legroom_extra e633 -airline_seat_legroom_normal e634 -airline_seat_legroom_reduced e635 -airline_seat_recline_extra e636 -airline_seat_recline_normal e637 -airplanemode_active e195 -airplanemode_inactive e194 -airplay e055 -airport_shuttle eb3c -alarm e855 -alarm_add e856 -alarm_off e857 -alarm_on e858 -album e019 -all_inclusive eb3d -all_out e90b -android e859 -announcement e85a -apps e5c3 -archive e149 -arrow_back e5c4 -arrow_downward e5db -arrow_drop_down e5c5 -arrow_drop_down_circle e5c6 -arrow_drop_up e5c7 -arrow_forward e5c8 -arrow_upward e5d8 -art_track e060 -aspect_ratio e85b -assessment e85c -assignment e85d -assignment_ind e85e -assignment_late e85f -assignment_return e860 -assignment_returned e861 -assignment_turned_in e862 -assistant e39f -assistant_photo e3a0 -attach_file e226 -attach_money e227 -attachment e2bc -audiotrack e3a1 -autorenew e863 -av_timer e01b -backspace e14a -backup e864 -battery_alert e19c -battery_charging_full e1a3 -battery_full e1a4 -battery_std e1a5 -battery_unknown e1a6 -beach_access eb3e -beenhere e52d -block e14b -bluetooth e1a7 -bluetooth_audio e60f -bluetooth_connected e1a8 -bluetooth_disabled e1a9 -bluetooth_searching e1aa -blur_circular e3a2 -blur_linear e3a3 -blur_off e3a4 -blur_on e3a5 -book e865 -bookmark e866 -bookmark_border e867 -border_all e228 -border_bottom e229 -border_clear e22a -border_color e22b -border_horizontal e22c -border_inner e22d -border_left e22e -border_outer e22f -border_right e230 -border_style e231 -border_top e232 -border_vertical e233 -branding_watermark e06b -brightness_1 e3a6 -brightness_2 e3a7 -brightness_3 e3a8 -brightness_4 e3a9 -brightness_5 e3aa -brightness_6 e3ab -brightness_7 e3ac -brightness_auto e1ab -brightness_high e1ac -brightness_low e1ad -brightness_medium e1ae -broken_image e3ad -brush e3ae -bubble_chart e6dd -bug_report e868 -build e869 -burst_mode e43c -business e0af -business_center eb3f -cached e86a -cake e7e9 -call e0b0 -call_end e0b1 -call_made e0b2 -call_merge e0b3 -call_missed e0b4 -call_missed_outgoing e0e4 -call_received e0b5 -call_split e0b6 -call_to_action e06c -camera e3af -camera_alt e3b0 -camera_enhance e8fc -camera_front e3b1 -camera_rear e3b2 -camera_roll e3b3 -cancel e5c9 -card_giftcard e8f6 -card_membership e8f7 -card_travel e8f8 -casino eb40 -cast e307 -cast_connected e308 -center_focus_strong e3b4 -center_focus_weak e3b5 -change_history e86b -chat e0b7 -chat_bubble e0ca -chat_bubble_outline e0cb -check e5ca -check_box e834 -check_box_outline_blank e835 -check_circle e86c -chevron_left e5cb -chevron_right e5cc -child_care eb41 -child_friendly eb42 -chrome_reader_mode e86d -class e86e -clear e14c -clear_all e0b8 -close e5cd -closed_caption e01c -cloud e2bd -cloud_circle e2be -cloud_done e2bf -cloud_download e2c0 -cloud_off e2c1 -cloud_queue e2c2 -cloud_upload e2c3 -code e86f -collections e3b6 -collections_bookmark e431 -color_lens e3b7 -colorize e3b8 -comment e0b9 -compare e3b9 -compare_arrows e915 -computer e30a -confirmation_number e638 -contact_mail e0d0 -contact_phone e0cf -contacts e0ba -content_copy e14d -content_cut e14e -content_paste e14f -control_point e3ba -control_point_duplicate e3bb -copyright e90c -create e150 -create_new_folder e2cc -credit_card e870 -crop e3be -crop_16_9 e3bc -crop_3_2 e3bd -crop_5_4 e3bf -crop_7_5 e3c0 -crop_din e3c1 -crop_free e3c2 -crop_landscape e3c3 -crop_original e3c4 -crop_portrait e3c5 -crop_rotate e437 -crop_square e3c6 -dashboard e871 -data_usage e1af -date_range e916 -dehaze e3c7 -delete e872 -delete_forever e92b -delete_sweep e16c -description e873 -desktop_mac e30b -desktop_windows e30c -details e3c8 -developer_board e30d -developer_mode e1b0 -device_hub e335 -devices e1b1 -devices_other e337 -dialer_sip e0bb -dialpad e0bc -directions e52e -directions_bike e52f -directions_boat e532 -directions_bus e530 -directions_car e531 -directions_railway e534 -directions_run e566 -directions_subway e533 -directions_transit e535 -directions_walk e536 -disc_full e610 -dns e875 -do_not_disturb e612 -do_not_disturb_alt e611 -do_not_disturb_off e643 -do_not_disturb_on e644 -dock e30e -domain e7ee -done e876 -done_all e877 -donut_large e917 -donut_small e918 -drafts e151 -drag_handle e25d -drive_eta e613 -dvr e1b2 -edit e3c9 -edit_location e568 -eject e8fb -email e0be -enhanced_encryption e63f -equalizer e01d -error e000 -error_outline e001 -euro_symbol e926 -ev_station e56d -event e878 -event_available e614 -event_busy e615 -event_note e616 -event_seat e903 -exit_to_app e879 -expand_less e5ce -expand_more e5cf -explicit e01e -explore e87a -exposure e3ca -exposure_neg_1 e3cb -exposure_neg_2 e3cc -exposure_plus_1 e3cd -exposure_plus_2 e3ce -exposure_zero e3cf -extension e87b -face e87c -fast_forward e01f -fast_rewind e020 -favorite e87d -favorite_border e87e -featured_play_list e06d -featured_video e06e -feedback e87f -fiber_dvr e05d -fiber_manual_record e061 -fiber_new e05e -fiber_pin e06a -fiber_smart_record e062 -file_download e2c4 -file_upload e2c6 -filter e3d3 -filter_1 e3d0 -filter_2 e3d1 -filter_3 e3d2 -filter_4 e3d4 -filter_5 e3d5 -filter_6 e3d6 -filter_7 e3d7 -filter_8 e3d8 -filter_9 e3d9 -filter_9_plus e3da -filter_b_and_w e3db -filter_center_focus e3dc -filter_drama e3dd -filter_frames e3de -filter_hdr e3df -filter_list e152 -filter_none e3e0 -filter_tilt_shift e3e2 -filter_vintage e3e3 -find_in_page e880 -find_replace e881 -fingerprint e90d -first_page e5dc -fitness_center eb43 -flag e153 -flare e3e4 -flash_auto e3e5 -flash_off e3e6 -flash_on e3e7 -flight e539 -flight_land e904 -flight_takeoff e905 -flip e3e8 -flip_to_back e882 -flip_to_front e883 -folder e2c7 -folder_open e2c8 -folder_shared e2c9 -folder_special e617 -font_download e167 -format_align_center e234 -format_align_justify e235 -format_align_left e236 -format_align_right e237 -format_bold e238 -format_clear e239 -format_color_fill e23a -format_color_reset e23b -format_color_text e23c -format_indent_decrease e23d -format_indent_increase e23e -format_italic e23f -format_line_spacing e240 -format_list_bulleted e241 -format_list_numbered e242 -format_paint e243 -format_quote e244 -format_shapes e25e -format_size e245 -format_strikethrough e246 -format_textdirection_l_to_r e247 -format_textdirection_r_to_l e248 -format_underlined e249 -forum e0bf -forward e154 -forward_10 e056 -forward_30 e057 -forward_5 e058 -free_breakfast eb44 -fullscreen e5d0 -fullscreen_exit e5d1 -functions e24a -g_translate e927 -gamepad e30f -games e021 -gavel e90e -gesture e155 -get_app e884 -gif e908 -golf_course eb45 -gps_fixed e1b3 -gps_not_fixed e1b4 -gps_off e1b5 -grade e885 -gradient e3e9 -grain e3ea -graphic_eq e1b8 -grid_off e3eb -grid_on e3ec -group e7ef -group_add e7f0 -group_work e886 -hd e052 -hdr_off e3ed -hdr_on e3ee -hdr_strong e3f1 -hdr_weak e3f2 -headset e310 -headset_mic e311 -healing e3f3 -hearing e023 -help e887 -help_outline e8fd -high_quality e024 -highlight e25f -highlight_off e888 -history e889 -home e88a -hot_tub eb46 -hotel e53a -hourglass_empty e88b -hourglass_full e88c -http e902 -https e88d -image e3f4 -image_aspect_ratio e3f5 -import_contacts e0e0 -import_export e0c3 -important_devices e912 -inbox e156 -indeterminate_check_box e909 -info e88e -info_outline e88f -input e890 -insert_chart e24b -insert_comment e24c -insert_drive_file e24d -insert_emoticon e24e -insert_invitation e24f -insert_link e250 -insert_photo e251 -invert_colors e891 -invert_colors_off e0c4 -iso e3f6 -keyboard e312 -keyboard_arrow_down e313 -keyboard_arrow_left e314 -keyboard_arrow_right e315 -keyboard_arrow_up e316 -keyboard_backspace e317 -keyboard_capslock e318 -keyboard_hide e31a -keyboard_return e31b -keyboard_tab e31c -keyboard_voice e31d -kitchen eb47 -label e892 -label_outline e893 -landscape e3f7 -language e894 -laptop e31e -laptop_chromebook e31f -laptop_mac e320 -laptop_windows e321 -last_page e5dd -launch e895 -layers e53b -layers_clear e53c -leak_add e3f8 -leak_remove e3f9 -lens e3fa -library_add e02e -library_books e02f -library_music e030 -lightbulb_outline e90f -line_style e919 -line_weight e91a -linear_scale e260 -link e157 -linked_camera e438 -list e896 -live_help e0c6 -live_tv e639 -local_activity e53f -local_airport e53d -local_atm e53e -local_bar e540 -local_cafe e541 -local_car_wash e542 -local_convenience_store e543 -local_dining e556 -local_drink e544 -local_florist e545 -local_gas_station e546 -local_grocery_store e547 -local_hospital e548 -local_hotel e549 -local_laundry_service e54a -local_library e54b -local_mall e54c -local_movies e54d -local_offer e54e -local_parking e54f -local_pharmacy e550 -local_phone e551 -local_pizza e552 -local_play e553 -local_post_office e554 -local_printshop e555 -local_see e557 -local_shipping e558 -local_taxi e559 -location_city e7f1 -location_disabled e1b6 -location_off e0c7 -location_on e0c8 -location_searching e1b7 -lock e897 -lock_open e898 -lock_outline e899 -looks e3fc -looks_3 e3fb -looks_4 e3fd -looks_5 e3fe -looks_6 e3ff -looks_one e400 -looks_two e401 -loop e028 -loupe e402 -low_priority e16d -loyalty e89a -mail e158 -mail_outline e0e1 -map e55b -markunread e159 -markunread_mailbox e89b -memory e322 -menu e5d2 -merge_type e252 -message e0c9 -mic e029 -mic_none e02a -mic_off e02b -mms e618 -mode_comment e253 -mode_edit e254 -monetization_on e263 -money_off e25c -monochrome_photos e403 -mood e7f2 -mood_bad e7f3 -more e619 -more_horiz e5d3 -more_vert e5d4 -motorcycle e91b -mouse e323 -move_to_inbox e168 -movie e02c -movie_creation e404 -movie_filter e43a -multiline_chart e6df -music_note e405 -music_video e063 -my_location e55c -nature e406 -nature_people e407 -navigate_before e408 -navigate_next e409 -navigation e55d -near_me e569 -network_cell e1b9 -network_check e640 -network_locked e61a -network_wifi e1ba -new_releases e031 -next_week e16a -nfc e1bb -no_encryption e641 -no_sim e0cc -not_interested e033 -note e06f -note_add e89c -notifications e7f4 -notifications_active e7f7 -notifications_none e7f5 -notifications_off e7f6 -notifications_paused e7f8 -offline_pin e90a -ondemand_video e63a -opacity e91c -open_in_browser e89d -open_in_new e89e -open_with e89f -pages e7f9 -pageview e8a0 -palette e40a -pan_tool e925 -panorama e40b -panorama_fish_eye e40c -panorama_horizontal e40d -panorama_vertical e40e -panorama_wide_angle e40f -party_mode e7fa -pause e034 -pause_circle_filled e035 -pause_circle_outline e036 -payment e8a1 -people e7fb -people_outline e7fc -perm_camera_mic e8a2 -perm_contact_calendar e8a3 -perm_data_setting e8a4 -perm_device_information e8a5 -perm_identity e8a6 -perm_media e8a7 -perm_phone_msg e8a8 -perm_scan_wifi e8a9 -person e7fd -person_add e7fe -person_outline e7ff -person_pin e55a -person_pin_circle e56a -personal_video e63b -pets e91d -phone e0cd -phone_android e324 -phone_bluetooth_speaker e61b -phone_forwarded e61c -phone_in_talk e61d -phone_iphone e325 -phone_locked e61e -phone_missed e61f -phone_paused e620 -phonelink e326 -phonelink_erase e0db -phonelink_lock e0dc -phonelink_off e327 -phonelink_ring e0dd -phonelink_setup e0de -photo e410 -photo_album e411 -photo_camera e412 -photo_filter e43b -photo_library e413 -photo_size_select_actual e432 -photo_size_select_large e433 -photo_size_select_small e434 -picture_as_pdf e415 -picture_in_picture e8aa -picture_in_picture_alt e911 -pie_chart e6c4 -pie_chart_outlined e6c5 -pin_drop e55e -place e55f -play_arrow e037 -play_circle_filled e038 -play_circle_outline e039 -play_for_work e906 -playlist_add e03b -playlist_add_check e065 -playlist_play e05f -plus_one e800 -poll e801 -polymer e8ab -pool eb48 -portable_wifi_off e0ce -portrait e416 -power e63c -power_input e336 -power_settings_new e8ac -pregnant_woman e91e -present_to_all e0df -print e8ad -priority_high e645 -public e80b -publish e255 -query_builder e8ae -question_answer e8af -queue e03c -queue_music e03d -queue_play_next e066 -radio e03e -radio_button_checked e837 -radio_button_unchecked e836 -rate_review e560 -receipt e8b0 -recent_actors e03f -record_voice_over e91f -redeem e8b1 -redo e15a -refresh e5d5 -remove e15b -remove_circle e15c -remove_circle_outline e15d -remove_from_queue e067 -remove_red_eye e417 -remove_shopping_cart e928 -reorder e8fe -repeat e040 -repeat_one e041 -replay e042 -replay_10 e059 -replay_30 e05a -replay_5 e05b -reply e15e -reply_all e15f -report e160 -report_problem e8b2 -restaurant e56c -restaurant_menu e561 -restore e8b3 -restore_page e929 -ring_volume e0d1 -room e8b4 -room_service eb49 -rotate_90_degrees_ccw e418 -rotate_left e419 -rotate_right e41a -rounded_corner e920 -router e328 -rowing e921 -rss_feed e0e5 -rv_hookup e642 -satellite e562 -save e161 -scanner e329 -schedule e8b5 -school e80c -screen_lock_landscape e1be -screen_lock_portrait e1bf -screen_lock_rotation e1c0 -screen_rotation e1c1 -screen_share e0e2 -sd_card e623 -sd_storage e1c2 -search e8b6 -security e32a -select_all e162 -send e163 -sentiment_dissatisfied e811 -sentiment_neutral e812 -sentiment_satisfied e813 -sentiment_very_dissatisfied e814 -sentiment_very_satisfied e815 -settings e8b8 -settings_applications e8b9 -settings_backup_restore e8ba -settings_bluetooth e8bb -settings_brightness e8bd -settings_cell e8bc -settings_ethernet e8be -settings_input_antenna e8bf -settings_input_component e8c0 -settings_input_composite e8c1 -settings_input_hdmi e8c2 -settings_input_svideo e8c3 -settings_overscan e8c4 -settings_phone e8c5 -settings_power e8c6 -settings_remote e8c7 -settings_system_daydream e1c3 -settings_voice e8c8 -share e80d -shop e8c9 -shop_two e8ca -shopping_basket e8cb -shopping_cart e8cc -short_text e261 -show_chart e6e1 -shuffle e043 -signal_cellular_4_bar e1c8 -signal_cellular_connected_no_internet_4_bar e1cd -signal_cellular_no_sim e1ce -signal_cellular_null e1cf -signal_cellular_off e1d0 -signal_wifi_4_bar e1d8 -signal_wifi_4_bar_lock e1d9 -signal_wifi_off e1da -sim_card e32b -sim_card_alert e624 -skip_next e044 -skip_previous e045 -slideshow e41b -slow_motion_video e068 -smartphone e32c -smoke_free eb4a -smoking_rooms eb4b -sms e625 -sms_failed e626 -snooze e046 -sort e164 -sort_by_alpha e053 -spa eb4c -space_bar e256 -speaker e32d -speaker_group e32e -speaker_notes e8cd -speaker_notes_off e92a -speaker_phone e0d2 -spellcheck e8ce -star e838 -star_border e83a -star_half e839 -stars e8d0 -stay_current_landscape e0d3 -stay_current_portrait e0d4 -stay_primary_landscape e0d5 -stay_primary_portrait e0d6 -stop e047 -stop_screen_share e0e3 -storage e1db -store e8d1 -store_mall_directory e563 -straighten e41c -streetview e56e -strikethrough_s e257 -style e41d -subdirectory_arrow_left e5d9 -subdirectory_arrow_right e5da -subject e8d2 -subscriptions e064 -subtitles e048 -subway e56f -supervisor_account e8d3 -surround_sound e049 -swap_calls e0d7 -swap_horiz e8d4 -swap_vert e8d5 -swap_vertical_circle e8d6 -switch_camera e41e -switch_video e41f -sync e627 -sync_disabled e628 -sync_problem e629 -system_update e62a -system_update_alt e8d7 -tab e8d8 -tab_unselected e8d9 -tablet e32f -tablet_android e330 -tablet_mac e331 -tag_faces e420 -tap_and_play e62b -terrain e564 -text_fields e262 -text_format e165 -textsms e0d8 -texture e421 -theaters e8da -thumb_down e8db -thumb_up e8dc -thumbs_up_down e8dd -time_to_leave e62c -timelapse e422 -timeline e922 -timer e425 -timer_10 e423 -timer_3 e424 -timer_off e426 -title e264 -toc e8de -today e8df -toll e8e0 -tonality e427 -touch_app e913 -toys e332 -track_changes e8e1 -traffic e565 -train e570 -tram e571 -transfer_within_a_station e572 -transform e428 -translate e8e2 -trending_down e8e3 -trending_flat e8e4 -trending_up e8e5 -tune e429 -turned_in e8e6 -turned_in_not e8e7 -tv e333 -unarchive e169 -undo e166 -unfold_less e5d6 -unfold_more e5d7 -update e923 -usb e1e0 -verified_user e8e8 -vertical_align_bottom e258 -vertical_align_center e259 -vertical_align_top e25a -vibration e62d -video_call e070 -video_label e071 -video_library e04a -videocam e04b -videocam_off e04c -videogame_asset e338 -view_agenda e8e9 -view_array e8ea -view_carousel e8eb -view_column e8ec -view_comfy e42a -view_compact e42b -view_day e8ed -view_headline e8ee -view_list e8ef -view_module e8f0 -view_quilt e8f1 -view_stream e8f2 -view_week e8f3 -vignette e435 -visibility e8f4 -visibility_off e8f5 -voice_chat e62e -voicemail e0d9 -volume_down e04d -volume_mute e04e -volume_off e04f -volume_up e050 -vpn_key e0da -vpn_lock e62f -wallpaper e1bc -warning e002 -watch e334 -watch_later e924 -wb_auto e42c -wb_cloudy e42d -wb_incandescent e42e -wb_iridescent e436 -wb_sunny e430 -wc e63d -web e051 -web_asset e069 -weekend e16b -whatshot e80e -widgets e1bd -wifi e63e -wifi_lock e1e1 -wifi_tethering e1e2 -work e8f9 -wrap_text e25b -youtube_searched_for e8fa -zoom_in e8ff -zoom_out e900 -zoom_out_map e56b diff --git a/dottydoc/jvm/resources/github.css b/dottydoc/jvm/resources/github.css deleted file mode 100644 index 0ea7d8657a5d..000000000000 --- a/dottydoc/jvm/resources/github.css +++ /dev/null @@ -1 +0,0 @@ -.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8;-webkit-text-size-adjust:none}.diff .hljs-header,.hljs-comment,.hljs-javadoc{color:#998;font-style:italic}.css .rule .hljs-keyword,.hljs-keyword,.hljs-request,.hljs-status,.hljs-subst,.hljs-winutils,.nginx .hljs-title{color:#333;font-weight:700}.hljs-hexcolor,.hljs-number,.ruby .hljs-constant{color:teal}.hljs-dartdoc,.hljs-phpdoc,.hljs-string,.hljs-tag .hljs-value,.tex .hljs-formula{color:#d14}.hljs-id,.hljs-title,.scss .hljs-preprocessor{color:#900;font-weight:700}.hljs-list .hljs-keyword,.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type,.tex .hljs-command,.vhdl .hljs-literal{color:#458;font-weight:700}.django .hljs-tag .hljs-keyword,.hljs-rules .hljs-property,.hljs-tag,.hljs-tag .hljs-title{color:navy;font-weight:400}.hljs-attribute,.hljs-variable,.lisp .hljs-body{color:teal}.hljs-regexp{color:#009926}.clojure .hljs-keyword,.hljs-prompt,.hljs-symbol,.lisp .hljs-keyword,.ruby .hljs-symbol .hljs-string,.scheme .hljs-keyword,.tex .hljs-special{color:#990073}.hljs-built_in{color:#0086b3}.hljs-cdata,.hljs-doctype,.hljs-pi,.hljs-pragma,.hljs-preprocessor,.hljs-shebang{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.diff .hljs-change{background:#0086b3}.hljs-chunk{color:#aaa} \ No newline at end of file diff --git a/dottydoc/jvm/resources/highlight.pack.js b/dottydoc/jvm/resources/highlight.pack.js deleted file mode 100644 index 60dbdab66c78..000000000000 --- a/dottydoc/jvm/resources/highlight.pack.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){var n=(e.className+" "+(e.parentNode?e.parentNode.className:"")).split(/\s+/);return n=n.map(function(e){return e.replace(/^lang(uage)?-/,"")}),n.filter(function(e){return N(e)||/no(-?)highlight/.test(e)})[0]}function o(e,n){var t={};for(var r in e)t[r]=e[r];if(n)for(var r in n)t[r]=n[r];return t}function i(e){var n=[];return function r(e,a){for(var o=e.firstChild;o;o=o.nextSibling)3==o.nodeType?a+=o.nodeValue.length:1==o.nodeType&&(n.push({event:"start",offset:a,node:o}),a=r(o,a),t(o).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:o}));return a}(e,0),n}function c(e,r,a){function o(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"==e.event?i:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=o();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=o();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(i)}else"start"==g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function u(e){function n(e){return e&&e.source||e}function t(t,r){return RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var c={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");c[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):Object.keys(a.k).forEach(function(e){u(e,a.k[e])}),a.k=c}a.lR=t(a.l||/\b[A-Za-z0-9_]+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function s(e,t,a,o){function i(e,n){for(var t=0;t";return o+=e+'">',o+n+i}function d(){if(!w.k)return n(y);var e="",t=0;w.lR.lastIndex=0;for(var r=w.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(w,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=w.lR.lastIndex,r=w.lR.exec(y)}return e+n(y.substr(t))}function h(){if(w.sL&&!R[w.sL])return n(y);var e=w.sL?s(w.sL,y,!0,L[w.sL]):l(y);return w.r>0&&(B+=e.r),"continuous"==w.subLanguageMode&&(L[w.sL]=e.top),p(e.language,e.value,!1,!0)}function v(){return void 0!==w.sL?h():d()}function b(e,t){var r=e.cN?p(e.cN,"",!0):"";e.rB?(M+=r,y=""):e.eB?(M+=n(t)+r,y=""):(M+=r,y=t),w=Object.create(e,{parent:{value:w}})}function m(e,t){if(y+=e,void 0===t)return M+=v(),0;var r=i(t,w);if(r)return M+=v(),b(r,t),r.rB?0:t.length;var a=c(w,t);if(a){var o=w;o.rE||o.eE||(y+=t),M+=v();do w.cN&&(M+=""),B+=w.r,w=w.parent;while(w!=a.parent);return o.eE&&(M+=n(t)),y="",a.starts&&b(a.starts,""),o.rE?0:t.length}if(f(t,w))throw new Error('Illegal lexeme "'+t+'" for mode "'+(w.cN||"")+'"');return y+=t,t.length||1}var x=N(e);if(!x)throw new Error('Unknown language: "'+e+'"');u(x);for(var w=o||x,L={},M="",k=w;k!=x;k=k.parent)k.cN&&(M=p(k.cN,"",!0)+M);var y="",B=0;try{for(var C,j,I=0;;){if(w.t.lastIndex=I,C=w.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}m(t.substr(I));for(var k=w;k.parent;k=k.parent)k.cN&&(M+="");return{r:B,value:M,language:e,top:w}}catch(A){if(-1!=A.message.indexOf("Illegal"))return{r:0,value:n(t)};throw A}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(N(n)){var t=s(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function f(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
    ")),e}function g(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/(\s|^)hljs(\s|$)/)||a.push("hljs"),r&&a.push(r),a.join(" ").trim()}function p(e){var n=a(e);if(!/no(-?)highlight/.test(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?s(n,r,!0):l(r),u=i(t);if(u.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(u,i(p),r)}o.value=f(o.value),e.innerHTML=o.value,e.className=g(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",h,!1),addEventListener("load",h,!1)}function b(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function m(){return Object.keys(R)}function N(e){return R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=s,e.highlightAuto=l,e.fixMarkup=f,e.highlightBlock=p,e.configure=d,e.initHighlighting=h,e.initHighlightingOnLoad=v,e.registerLanguage=b,e.listLanguages=m,e.getLanguage=N,e.inherit=o,e.IR="[a-zA-Z][a-zA-Z0-9_]*",e.UIR="[a-zA-Z_][a-zA-Z0-9_]*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.CLCM={cN:"comment",b:"//",e:"$",c:[e.PWM]},e.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM]},e.HCM={cN:"comment",b:"#",e:"$",c:[e.PWM]},e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("asciidoc",function(){return{c:[{cN:"comment",b:"^/{4,}\\n",e:"\\n/{4,}$",r:10},{cN:"comment",b:"^//",e:"$",r:0},{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"smartquote",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("cpp",function(t){var i={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex _Complex _Imaginaryintmax_t uintmax_t int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_tint_least8_t uint_least8_t int_least16_t uint_least16_t int_least32_t uint_least32_tint_least64_t uint_least64_t int_fast8_t uint_fast8_t int_fast16_t uint_fast16_t int_fast32_tuint_fast32_t int_fast64_t uint_fast64_t intptr_t uintptr_t atomic_bool atomic_char atomic_scharatomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llongatomic_ullong atomic_wchar_t atomic_char16_t atomic_char32_t atomic_intmax_t atomic_uintmax_tatomic_intptr_t atomic_uintptr_t atomic_size_t atomic_ptrdiff_t atomic_int_least8_t atomic_int_least16_tatomic_int_least32_t atomic_int_least64_t atomic_uint_least8_t atomic_uint_least16_t atomic_uint_least32_tatomic_uint_least64_t atomic_int_fast8_t atomic_int_fast16_t atomic_int_fast32_t atomic_int_fast64_tatomic_uint_fast8_t atomic_uint_fast16_t atomic_uint_fast32_t atomic_uint_fast64_t",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf"};return{aliases:["c","h","c++","h++"],k:i,i:""]',k:"include",i:"\\n"},t.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:i,c:["self"]},{b:t.IR+"::"},{bK:"new throw return",r:0},{cN:"function",b:"("+t.IR+"\\s+)+"+t.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:t.IR+"\\s*\\(",rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:i,r:0,c:[t.CBCM]},t.CLCM,t.CBCM]}]}});hljs.registerLanguage("haskell",function(e){var i={cN:"comment",v:[{b:"--",e:"$"},{b:"{-",e:"-}",c:["self"]}]},c={cN:"pragma",b:"{-#",e:"#-}"},a={cN:"preprocessor",b:"^#",e:"$"},n={cN:"type",b:"\\b[A-Z][\\w']*",r:0},l={cN:"container",b:"\\(",e:"\\)",i:'"',c:[c,i,a,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"})]},t={cN:"container",b:"{",e:"}",c:l.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{cN:"module",b:"\\bmodule\\b",e:"where",k:"module where",c:[l,i],i:"\\W\\.|;"},{cN:"import",b:"\\bimport\\b",e:"$",k:"import|0 qualified as hiding",c:[l,i],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[n,l,i]},{cN:"typedef",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[c,i,n,l,t]},{cN:"default",bK:"default",e:"$",c:[n,l,i]},{cN:"infix",bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{cN:"foreign",b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[n,e.QSM,i]},{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},c,i,a,e.QSM,e.CNM,n,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),{b:"->|<-"}]}});hljs.registerLanguage("rsl",function(e){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:""},{b:"<=",r:0},{b:"=>",r:0},{b:"/\\\\"},{b:"\\\\/"}]},c={cN:"built_in",v:[{b:":-\\|-->"},{b:"=",r:0}]};return{aliases:["m","moo"],k:i,c:[s,c,t,_,n,e.NM,a,o,{b:/:-/}]}});hljs.registerLanguage("axapta",function(e){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bK:"class interface",e:"{",eE:!0,i:":",c:[{bK:"extends implements"},e.UTM]}]}});hljs.registerLanguage("verilog",function(e){return{aliases:["v"],cI:!0,k:{keyword:"always and assign begin buf bufif0 bufif1 case casex casez cmos deassign default defparam disable edge else end endcase endfunction endmodule endprimitive endspecify endtable endtask event for force forever fork function if ifnone initial inout input join macromodule module nand negedge nmos nor not notif0 notif1 or output parameter pmos posedge primitive pulldown pullup rcmos release repeat rnmos rpmos rtran rtranif0 rtranif1 specify specparam table task timescale tran tranif0 tranif1 wait while xnor xor",typename:"highz0 highz1 integer large medium pull0 pull1 real realtime reg scalared signed small strong0 strong1 supply0 supply0 supply1 supply1 time tri tri0 tri1 triand trior trireg vectored wand weak0 weak1 wire wor"},c:[e.CBCM,e.CLCM,e.QSM,{cN:"number",b:"\\b(\\d+'(b|h|o|d|B|H|O|D))?[0-9xzXZ]+",c:[e.BE],r:0},{cN:"typename",b:"\\.\\w+",r:0},{cN:"value",b:"#\\((?!parameter).+\\)"},{cN:"keyword",b:"\\+|-|\\*|/|%|<|>|=|#|`|\\!|&|\\||@|:|\\^|~|\\{|\\}",r:0}]}});hljs.registerLanguage("matlab",function(e){var a=[e.CNM,{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]}],s={r:0,c:[{cN:"operator",b:/'['\.]*/}]};return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{b:/[a-zA-Z_][a-zA-Z_0-9]*'['\.]*/,rB:!0,r:0,c:[{b:/[a-zA-Z_][a-zA-Z_0-9]*/,r:0},s.c[0]]},{cN:"matrix",b:"\\[",e:"\\]",c:a,r:0,starts:s},{cN:"cell",b:"\\{",e:/\}/,c:a,r:0,i:/:/,starts:s},{b:/\)/,r:0,starts:s},{cN:"comment",b:"\\%",e:"$"}].concat(a)}});hljs.registerLanguage("handlebars",function(){var e="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z- .]+",k:e},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z- .]+",k:e},{cN:"variable",b:"[a-zA-Z-.]+",k:e}]}]}});hljs.registerLanguage("php",function(e){var c={cN:"variable",b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},i={cN:"preprocessor",b:/<\?(php)?|\?>/},a={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.CLCM,e.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"},i]},{cN:"comment",b:"__halt_compiler.+?;",eW:!0,k:"__halt_compiler",l:e.UIR},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},i,c,{b:/->+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,a,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},a,n]}});hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",n="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:n},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},s={eW:!0,rE:!0,l:r,k:n,r:0},i={cN:"function",bK:"def defmacro",e:/\bdo\b/,c:[e.inherit(e.TM,{b:b,starts:s})]},l=e.inherit(i,{cN:"class",bK:"defmodule defrecord",e:/\bdo\b|$|;/}),t=[a,e.HCM,l,i,{cN:"constant",b:"(\\b[A-Z_]\\w*(.)?)+",r:0},{cN:"symbol",b:":",c:[a,{b:b}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=t,s.c=t,{l:r,k:n,c:t}});hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch|10 stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...|10",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]}]}});hljs.registerLanguage("xl",function(e){var t="ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts",o={keyword:"if then else do while until for loop import with is as where when by data constant",literal:"true false nil",type:"integer real text name boolean symbol infix prefix postfix block tree",built_in:"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at",module:t,id:"text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons"},a={cN:"constant",b:"[A-Z][A-Z_0-9]+",r:0},r={cN:"variable",b:"([A-Z][a-z_0-9]+)+",r:0},i={cN:"id",b:"[a-z][a-z_0-9]+",r:0},l={cN:"string",b:'"',e:'"',i:"\\n"},n={cN:"string",b:"'",e:"'",i:"\\n"},s={cN:"string",b:"<<",e:">>"},c={cN:"number",b:"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?",r:10},_={cN:"import",bK:"import",e:"$",k:{keyword:"import",module:t},r:0,c:[l]},d={cN:"function",b:"[a-z].*->"};return{aliases:["tao"],l:/[a-zA-Z][a-zA-Z0-9_?]*/,k:o,c:[e.CLCM,e.CBCM,l,n,s,d,_,a,r,i,c,e.NM]}});hljs.registerLanguage("sql",function(e){var t={cN:"comment",b:"--",e:"$"};return{cI:!0,i:/[<>]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate savepoint release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup",e:/;/,eW:!0,k:{keyword:"abs absolute acos action add adddate addtime aes_decrypt aes_encrypt after aggregate all allocate alter analyze and any are as asc ascii asin assertion at atan atan2 atn2 authorization authors avg backup before begin benchmark between bin binlog bit_and bit_count bit_length bit_or bit_xor both by cache call cascade cascaded case cast catalog ceil ceiling chain change changed char_length character_length charindex charset check checksum checksum_agg choose close coalesce coercibility collate collation collationproperty column columns columns_updated commit compress concat concat_ws concurrent connect connection connection_id consistent constraint constraints continue contributors conv convert convert_tz corresponding cos cot count count_big crc32 create cross cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime data database databases datalength date_add date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts datetimeoffsetfromparts day dayname dayofmonth dayofweek dayofyear deallocate declare decode default deferrable deferred degrees delayed delete des_decrypt des_encrypt des_key_file desc describe descriptor diagnostics difference disconnect distinct distinctrow div do domain double drop dumpfile each else elt enclosed encode encrypt end end-exec engine engines eomonth errors escape escaped event eventdata events except exception exec execute exists exp explain export_set extended external extract fast fetch field fields find_in_set first first_value floor flush for force foreign format found found_rows from from_base64 from_days from_unixtime full function get get_format get_lock getdate getutcdate global go goto grant grants greatest group group_concat grouping grouping_id gtid_subset gtid_subtract handler having help hex high_priority hosts hour ident_current ident_incr ident_seed identified identity if ifnull ignore iif ilike immediate in index indicator inet6_aton inet6_ntoa inet_aton inet_ntoa infile initially inner innodb input insert install instr intersect into is is_free_lock is_ipv4 is_ipv4_compat is_ipv4_mapped is_not is_not_null is_used_lock isdate isnull isolation join key kill language last last_day last_insert_id last_value lcase lead leading least leaves left len lenght level like limit lines ln load load_file local localtime localtimestamp locate lock log log10 log2 logfile logs low_priority lower lpad ltrim make_set makedate maketime master master_pos_wait match matched max md5 medium merge microsecond mid min minute mod mode module month monthname mutex name_const names national natural nchar next no no_write_to_binlog not now nullif nvarchar oct octet_length of old_password on only open optimize option optionally or ord order outer outfile output pad parse partial partition password patindex percent_rank percentile_cont percentile_disc period_add period_diff pi plugin position pow power pragma precision prepare preserve primary prior privileges procedure procedure_analyze processlist profile profiles public publishingservername purge quarter query quick quote quotename radians rand read references regexp relative relaylog release release_lock rename repair repeat replace replicate reset restore restrict return returns reverse revoke right rlike rollback rollup round row row_count rows rpad rtrim savepoint schema scroll sec_to_time second section select serializable server session session_user set sha sha1 sha2 share show sign sin size slave sleep smalldatetimefromparts snapshot some soname soundex sounds_like space sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sql_variant_property sqlstate sqrt square start starting status std stddev stddev_pop stddev_samp stdev stdevp stop str str_to_date straight_join strcmp string stuff subdate substr substring subtime subtring_index sum switchoffset sysdate sysdatetime sysdatetimeoffset system_user sysutcdatetime table tables tablespace tan temporary terminated tertiary_weights then time time_format time_to_sec timediff timefromparts timestamp timestampadd timestampdiff timezone_hour timezone_minute to to_base64 to_days to_seconds todatetimeoffset trailing transaction translation trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse ucase uncompress uncompressed_length unhex unicode uninstall union unique unix_timestamp unknown unlock update upgrade upped upper usage use user user_resources using utc_date utc_time utc_timestamp uuid uuid_short validate_password_strength value values var var_pop var_samp variables variance varp version view warnings week weekday weekofyear weight_string when whenever where with work write xml xor year yearweek zon",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int integer interval number numeric real serial smallint varchar varying int8 serial8 text"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",a={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},n={cN:"comment",b:"%",e:"$"},b={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},i={b:"fun\\s+"+r+"/\\d+"},o={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{cN:"function_name",b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},d={cN:"tuple",b:"{",e:"}",r:0},t={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},l={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0},f={b:"#"+e.UIR,r:0,rB:!0,c:[{cN:"record_name",b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:a};s.c=[n,i,e.inherit(e.ASM,{cN:""}),s,o,e.QSM,b,d,t,l,f];var u=[n,i,s,o,e.QSM,b,d,t,l,f];o.c[1].c=u,d.c=u,f.c[1].c=u;var v={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:a,i:"(",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[v,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:a,c:u}},n,{cN:"pp",b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[v]},b,e.QSM,f,t,l,d,{b:/\.$/}]}});hljs.registerLanguage("makefile",function(e){var a={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{cN:"constant",e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:"title",b:/^[\w]+:\s*$/},{cN:"phony",b:/^\.PHONY:/,e:/$/,k:".PHONY",l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,a]}]}});hljs.registerLanguage("nsis",function(e){var t={cN:"symbol",b:"\\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)"},n={cN:"constant",b:"\\$+{[a-zA-Z0-9_]+}"},i={cN:"variable",b:"\\$+[a-zA-Z0-9_]+",i:"\\(\\){}"},r={cN:"constant",b:"\\$+\\([a-zA-Z0-9_]+\\)"},o={cN:"params",b:"(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)"},l={cN:"constant",b:"\\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)"};return{cI:!1,k:{keyword:"Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetPluginUnload SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption SubSectionEnd Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle",literal:"admin all auto both colored current false force hide highest lastused leave listonly none normal notset off on open print show silent silentlog smooth textonly true user "},c:[e.HCM,e.CBCM,{cN:"string",b:'"',e:'"',i:"\\n",c:[{cN:"symbol",b:"\\$(\\\\(n|r|t)|\\$)"},t,n,i,r]},{cN:"comment",b:";",e:"$",r:0},{cN:"function",bK:"Function PageEx Section SectionGroup SubSection",e:"$"},l,n,i,r,o,e.NM,{cN:"literal",b:e.IR+"::"+e.IR}]}});hljs.registerLanguage("stata",function(e){return{aliases:["do","ado"],cI:!0,k:"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5",c:[{cN:"label",v:[{b:"\\$\\{?[a-zA-Z_]+\\}?"},{b:"`[a-zA-Z_]+'"}]},{cN:"string",v:[{b:'`".*"\''},{b:'".*"'}]},{cN:"literal",v:[{b:"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},{cN:"comment",v:[{b:"^\\*.*$"},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("nimrod",function(t){return{k:{keyword:"addr and as asm bind block break|0 case|0 cast const|0 continue|0 converter discard distinct|10 div do elif else|0 end|0 enum|0 except export finally for from generic if|0 import|0 in include|0 interface is isnot|10 iterator|10 let|0 macro method|10 mixin mod nil not notin|10 object|0 of or out proc|10 ptr raise ref|10 return shl shr static template|10 try|0 tuple type|0 using|0 var|0 when while|0 with without xor yield",literal:"shared guarded stdin stdout stderr result|10 true false"},c:[{cN:"decorator",b:/{\./,e:/\.}/,r:10},{cN:"string",b:/[a-zA-Z]\w*"/,e:/"/,c:[{b:/""/}]},{cN:"string",b:/([a-zA-Z]\w*)?"""/,e:/"""/},{cN:"string",b:/"/,e:/"/,i:/\n/,c:[{b:/\\./}]},{cN:"type",b:/\b[A-Z]\w+\b/,r:0},{cN:"type",b:/\b(int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|float|float32|float64|bool|char|string|cstring|pointer|expr|stmt|void|auto|any|range|array|openarray|varargs|seq|set|clong|culong|cchar|cschar|cshort|cint|csize|clonglong|cfloat|cdouble|clongdouble|cuchar|cushort|cuint|culonglong|cstringarray|semistatic)\b/},{cN:"number",b:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/,r:0},{cN:"number",b:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/,r:0},{cN:"number",b:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/,r:0},{cN:"number",b:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/,r:0},t.HCM]}});hljs.registerLanguage("haxe",function(e){var r="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";return{aliases:["hx"],k:{keyword:"break callback case cast catch class continue default do dynamic else enum extends extern for function here if implements import in inline interface never new override package private public return static super switch this throw trace try typedef untyped using var while",literal:"true false null"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end error"},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM]},{cN:"type",b:":",e:r,r:10}]}]}});hljs.registerLanguage("clojure",function(e){var t={built_in:"def cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},c=e.inherit(e.QSM,{i:null}),i={cN:"comment",b:";",e:"$",r:0},d={cN:"literal",b:/\b(true|false|nil)\b/},l={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p={cN:"comment",b:"\\^\\{",e:"\\}"},u={cN:"attribute",b:"[:]"+n},f={cN:"list",b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"keyword",b:n,starts:h},b=[f,c,m,p,i,u,l,s,d,o];return f.c=[{cN:"comment",b:"comment"},y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,c,m,p,i,u,l,s,d]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"title",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("step21",function(e){var r="[A-Z_][A-Z0-9_.]*",c="END-ISO-10303-21;",i={literal:"",built_in:"",keyword:"HEADER ENDSEC DATA"},t={cN:"preprocessor",b:"ISO-10303-21;",r:10},l=[e.CLCM,{cN:"comment",b:"/\\*\\*!",e:"\\*/",c:[e.PWM]},e.CBCM,e.CNM,e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"'",e:"'"},{cN:"label",v:[{b:"#",e:"\\d+",i:"\\W"}]}];return{aliases:["p21","step","stp"],cI:!0,l:r,k:i,c:[{cN:"preprocessor",b:c,r:10},t].concat(l)}});hljs.registerLanguage("applescript",function(e){var t=e.inherit(e.QSM,{i:""}),r={cN:"params",b:"\\(",e:"\\)",c:["self",e.CNM,t]},o=[{cN:"comment",b:"--",e:"$"},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",{b:"--",e:"$"}]},e.HCM];return{aliases:["osascript"],k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[t,e.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bK:"on",i:"[${=;\\n]",c:[e.UTM,r]}].concat(o),i:"//|->|=>"}});hljs.registerLanguage("thrift",function(e){var t="bool byte i16 i32 i64 double string binary";return{k:{keyword:"namespace const typedef struct enum service exception void oneway set list map required optional",built_in:t,literal:"true false"},c:[e.QSM,e.NM,e.CLCM,e.CBCM,{cN:"class",bK:"struct enum service exception",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"stl_container",b:"\\b(set|list|map)\\s*<",e:">",k:t,c:["self"]}]}});hljs.registerLanguage("xml",function(){var t="[A-Za-z0-9\\._:-]+",e={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"},c={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[c],starts:{e:"",rE:!0,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[c],starts:{e:"",rE:!0,sL:"javascript"}},e,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},c]}]}});hljs.registerLanguage("clojure-repl",function(){return{c:[{cN:"prompt",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure",subLanguageMode:"continuous"}}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,e.NM,s,a,t]}});hljs.registerLanguage("delphi",function(e){var r="exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure",t={cN:"comment",v:[{b:/\{/,e:/\}/,r:0},{b:/\(\*/,e:/\*\)/,r:10}]},i={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},c={cN:"string",b:/(#\d+)+/},o={b:e.IR+"\\s*=\\s*class\\s*\\(",rB:!0,c:[e.TM]},n={cN:"function",bK:"function constructor destructor procedure",e:/[:;]/,k:"function constructor|10 destructor|10 procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[i,c]},t]};return{cI:!0,k:r,i:/"|\$[G-Zg-z]|\/\*|<\/|\|/,c:[t,e.CLCM,i,c,e.NM,o,n]}});hljs.registerLanguage("profile",function(e){return{c:[e.CNM,{cN:"built_in",b:"{",e:"}$",eB:!0,eE:!0,c:[e.ASM,e.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:!0},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[e.CNM],r:10},e.ASM,e.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[e.UTM],r:0}]}});hljs.registerLanguage("ini",function(e){return{cI:!0,i:/\S/,c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:!0,k:"on off true false yes no",c:[e.QSM,e.NM],r:0}]}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",t={cN:"subst",b:/#\{/,e:/}/,k:c},r=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,t]},{b:/"/,e:/"/,c:[e.BE,t]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[t,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];t.c=r;var i=e.inherit(e.TM,{b:n}),s="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(r)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:r.concat([{cN:"comment",b:"###",e:"###",c:[e.PWM]},e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+s,e:"[-=]>",rB:!0,c:[i,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:s,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("aspectj",function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence",i="get set args call";return{k:t,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"aspect",bK:"aspect",e:/[{;=]/,eE:!0,i:/[:;"\[\]]/,c:[{bK:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UTM,{b:/\([^\)]*/,e:/[)]+/,k:t+" "+i,eE:!1}]},{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,r:0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"pointcut after before around throwing returning",e:/[)]/,eE:!1,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",rB:!0,c:[e.UTM]}]},{b:/[:]/,rB:!0,e:/[{;]/,r:0,eE:!1,k:t,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",k:t+" "+i},e.QSM]},{bK:"new throw",r:0},{cN:"function",b:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s\,]+)?[\{\;]/,rB:!0,e:/[{;=]/,k:t,eE:!0,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,r:0,k:t,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},e.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("actionscript",function(e){var a="[a-zA-Z_$][a-zA-Z0-9_$]*",c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)",t={cN:"rest_arg",b:"[.]{3}",e:a,r:10};return{aliases:["as"],k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"package",bK:"package",e:"{",c:[e.TM]},{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"preprocessor",bK:"import include",e:";"},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM,t]},{cN:"type",b:":",e:c,r:10}]}]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"{",e:"}"},n={cN:"variable",v:[{b:/\$\d/},{b:/[\$\%\@](\^\w\b|#\w+(\:\:\w+)*|{\w+}|\w+(\:\:\w*)*)/},{b:/[\$\%\@][^\s\w{]/,r:0}]},o={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5},i=[e.BE,r,n],c=[n,e.HCM,o,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:!0},s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,o,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",r:5},{cN:"operator",b:"-\\w\\b",r:0}];return r.c=c,s.c=c,{aliases:["pl"],k:t,c:c}});hljs.registerLanguage("vbscript-html",function(){return{sL:"xml",subLanguageMode:"continuous",c:[{b:"<%",e:"%>",sL:"vbscript"}]}});hljs.registerLanguage("powershell",function(e){var t={b:"`[\\s\\S]",r:0},r={cN:"variable",v:[{b:/\$[\w\d][\w\d_:]*/}]},o={cN:"string",b:/"/,e:/"/,c:[t,r,{cN:"variable",b:/\$[A-z]/,e:/[^A-z]/}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["ps"],l:/-?[A-z\.\-]+/,cI:!0,k:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",literal:"$null $true $false",built_in:"Add-Content Add-History Add-Member Add-PSSnapin Clear-Content Clear-Item Clear-Item Property Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ConvertTo-Html ConvertTo-SecureString Copy-Item Copy-ItemProperty Export-Alias Export-Clixml Export-Console Export-Csv ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item Join-Path Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug Set-Service Set-TraceSource Set-Variable Sort-Object Split-Path Start-Service Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where-Object Write-Debug Write-Error Write-Host Write-Output Write-Progress Write-Verbose Write-Warning",operator:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},c:[e.HCM,e.NM,o,a,r]}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"tag",b:""},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("twig",function(){var e={cN:"params",b:"\\(",e:"\\)"},t="attribute block constant cycle date dump include max min parent random range source template_from_string",a={cN:"function",bK:t,r:0,c:[e]},r={cN:"filter",b:/\|[A-Za-z]+\:?/,k:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",c:[a]},c="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return c=c+" "+c.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"comment",b:/\{#/,e:/#}/},{cN:"template_tag",b:/\{%/,e:/%}/,k:c,c:[r,a]},{cN:"variable",b:/\{\{/,e:/}}/,c:[r,a]}]}});hljs.registerLanguage("autohotkey",function(e){var r={cN:"escape",b:"`[\\s\\S]"},c={cN:"comment",b:";",e:"$",r:0},n=[{cN:"built_in",b:"A_[a-zA-Z0-9]+"},{cN:"built_in",bK:"ComSpec Clipboard ClipboardAll ErrorLevel"}];return{cI:!0,k:{keyword:"Break Continue Else Gosub If Loop Return While",literal:"A true false NOT AND OR"},c:n.concat([r,e.inherit(e.QSM,{c:[r]}),c,{cN:"number",b:e.NR,r:0},{cN:"var_expand",b:"%",e:"%",i:"\\n",c:[r]},{cN:"label",c:[r],v:[{b:'^[^\\n";]+::(?!=)'},{b:'^[^\\n";]+:(?!=)',r:0}]},{b:",\\s*,",r:10}])}});hljs.registerLanguage("smalltalk",function(a){var c="[a-z][a-zA-Z0-9_]*",e={cN:"char",b:"\\$.{1}"},r={cN:"symbol",b:"#"+a.UIR};return{aliases:["st"],k:"self super nil true false thisContext",c:[{cN:"comment",b:'"',e:'"'},a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:c+":",r:0},a.CNM,r,e,{cN:"localvars",b:"\\|[ ]*"+c+"([ ]+"+c+")*[ ]*\\|",rB:!0,e:/\|/,i:/\S/,c:[{b:"(\\|[ ]*)?"+c}]},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,e,a.CNM,r]}]}});hljs.registerLanguage("cs",function(e){var r="abstract as base bool break byte case catch char checked const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",t=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:r,i:/::/,c:[{cN:"comment",b:"///",e:"$",rB:!0,c:[{cN:"xmlDocTag",v:[{b:"///",r:0},{b:""},{b:""}]}]},e.CLCM,e.CBCM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class namespace interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("diff",function(){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});hljs.registerLanguage("livescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger case default function var with then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super case default function var void const let enum export import native __hasProp __extends __slice __bind __indexOf",literal:"true false null undefined yes no on off it that void",built_in:"npm require console print module global window document"},s="[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*",i=e.inherit(e.TM,{b:s}),n={cN:"subst",b:/#\{/,e:/\}/,k:t},c={cN:"subst",b:/#[A-Za-z$_]/,e:/(?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*/,k:t},r=[e.BNM,{cN:"number",b:"(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)",r:0,starts:{e:"(\\s*/)?",r:0}},{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,n,c]},{b:/"/,e:/"/,c:[e.BE,n,c]},{b:/\\/,e:/(\s|$)/,eE:!0}]},{cN:"pi",v:[{b:"//",e:"//[gim]*",c:[n,e.HCM]},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+s},{b:"``",e:"``",eB:!0,eE:!0,sL:"javascript"}];n.c=r;var a={cN:"params",b:"\\(",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(r)}]};return{aliases:["ls"],k:t,i:/\/\*/,c:r.concat([{cN:"comment",b:"\\/\\*",e:"\\*\\/"},e.HCM,{cN:"function",c:[i,a],rB:!0,v:[{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?",e:"\\->\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?",e:"[-~]{1,2}>\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?",e:"!?[-~]{1,2}>\\*?"}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:s+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("typescript",function(e){return{aliases:["ts"],k:{keyword:"in if for while finally var new function|0 do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private get set super interface extendsstatic constructor implements enum export import declare",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:0},e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/,r:0},{cN:"constructor",bK:"constructor",e:/\{/,eE:!0,r:10},{cN:"module",bK:"module",e:/\{/,eE:!0},{cN:"interface",bK:"interface",e:/\{/,eE:!0},{b:/\$[(.]/},{b:"\\."+e.IR,r:0}]}});hljs.registerLanguage("tcl",function(e){return{aliases:["tk"],k:"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while",c:[{cN:"comment",v:[{b:";[ \\t]*#",e:"$"},{b:"^[ \\t]*#",e:"$"}]},{bK:"proc",e:"[\\{]",eE:!0,c:[{cN:"symbol",b:"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"[ \\t\\n\\r]",eW:!0,eE:!0}]},{cN:"variable",eE:!0,v:[{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)",e:"[^a-zA-Z0-9_\\}\\$]"},{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{cN:"string",c:[e.BE],v:[e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},{cN:"number",v:[e.BNM,e.CNM]}]}});hljs.registerLanguage("vala",function(e){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bK:"class interface delegate namespace",e:"{",eE:!0,i:"[^,:\\n\\s\\.]",c:[e.UTM]},e.CLCM,e.CBCM,{cN:"string",b:'"""',e:'"""',r:5},e.ASM,e.QSM,e.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}});hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)"},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self"]},{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"tag",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"char",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("haml",function(){return{cI:!0,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(!=#|=#|-#|/).*$",r:0},{b:"^\\s*(-|=|!=)(?!#)",starts:{e:"\\n",sL:"ruby"}},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+"},{cN:"value",b:"[#\\.]\\w+"},{b:"{\\s*",e:"\\s*}",eE:!0,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:!0,eW:!0,c:[{cN:"symbol",b:":\\w+"},{cN:"string",b:'"',e:'"'},{cN:"string",b:"'",e:"'"},{b:"\\w+",r:0}]}]},{b:"\\(\\s*",e:"\\s*\\)",eE:!0,c:[{b:"\\w+\\s*=",e:"\\s+",rB:!0,eW:!0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"'},{cN:"string",b:"'",e:"'"},{b:"\\w+",r:0}]}]}]},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"}}]}});hljs.registerLanguage("erlang-repl",function(e){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},e.ASM,e.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}});hljs.registerLanguage("stylus",function(t){var e={cN:"variable",b:"\\$"+t.IR},o={cN:"hexcolor",b:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})",r:10},i=["charset","css","debug","extend","font-face","for","import","include","media","mixin","page","warn","while"],r=["after","before","first-letter","first-line","active","first-child","focus","hover","lang","link","visited"],n=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],a="[\\.\\s\\n\\[\\:,]",l=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-variant-ligatures","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"],d=["\\{","\\}","\\?","(\\bReturn\\b)","(\\bEnd\\b)","(\\bend\\b)",";","#\\s","\\*\\s","===\\s","\\|"];return{aliases:["styl"],cI:!1,i:"("+d.join("|")+")",k:"if else for in",c:[t.QSM,t.ASM,t.CLCM,t.CBCM,o,{b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"class",b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"id",b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\b("+n.join("|")+")"+a,rB:!0,c:[{cN:"tag",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{cN:"pseudo",b:"&?:?:\\b("+r.join("|")+")"+a},{cN:"at_rule",b:"@("+i.join("|")+")\\b"},e,t.CSSNM,t.NM,{cN:"function",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)",i:"[\\n]",rB:!0,c:[{cN:"title",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{cN:"params",b:/\(/,e:/\)/,c:[o,e,t.ASM,t.CSSNM,t.NM,t.QSM]}]},{cN:"attribute",b:"\\b("+l.reverse().join("|")+")\\b"}]}});hljs.registerLanguage("gherkin",function(e){return{aliases:["feature"],k:"Feature Background Ability Business Need Scenario Scenarios Scenario Outline Scenario Template Examples Given And Then But When",c:[{cN:"keyword",b:"\\*"},{cN:"comment",b:"@[^@\r\n ]+",e:"$"},{cN:"string",b:"\\|",e:"\\$"},{cN:"variable",b:"<",e:">"},e.HCM,{cN:"string",b:'"""',e:'"""'},e.QSM]}});hljs.registerLanguage("scala",function(e){var t={cN:"annotation",b:"@[A-Za-z]+"},a={cN:"string",b:'u?r?"""',e:'"""',r:10},r={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},c={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},i={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},l={cN:"class",bK:"class object trait type",e:/[:={\[(\n;]/,c:[{cN:"keyword",bK:"extends with",r:10},i]},n={cN:"function",bK:"def val",e:/[:={\[(\n;]/,c:[i]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,a,e.QSM,r,c,n,l,e.CNM,t]}});hljs.registerLanguage("java",function(e){var a=e.UIR+"(<"+e.UIR+">)?",t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",c="(\\b(0b[01_]+)|\\b0[xX][a-fA-F0-9_]+|(\\b[\\d_]+(\\.[\\d_]*)?|\\.[\\d_]+)([eE][-+]?\\d+)?)[lLfF]?",r={cN:"number",b:c,r:0};return{aliases:["jsp"],k:t,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return",r:0},{cN:"function",b:"("+a+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},r,{cN:"annotation",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("lasso",function(e){var r="[a-zA-Z_][a-zA-Z0-9_.]*",a="<\\?(lasso(script)?|=)",t="\\]|\\?>",s={literal:"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft",built_in:"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome"},n={cN:"comment",b:"",r:0},o={cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:!0,c:[n]}},i={cN:"preprocessor",b:"\\[/noprocess|"+a},l={cN:"variable",b:"'"+r+"'"},c=[e.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/",c:[e.PWM]},e.CBCM,e.inherit(e.CNM,{b:e.CNR+"|(-?infinity|nan)\\b"}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",v:[{b:"[#$]"+r},{b:"#",e:"\\d+",i:"\\W"}]},{cN:"tag",b:"::\\s*",e:r,i:"\\W"},{cN:"attribute",v:[{b:"-"+e.UIR,r:0},{b:"(\\.\\.\\.)"}]},{cN:"subst",v:[{b:"->\\s*",c:[l]},{b:":=|/(?!\\w)=?|[-+*%=<>&|!?\\\\]+",r:0}]},{cN:"built_in",b:"\\.\\.?\\s*",r:0,c:[l]},{cN:"class",bK:"define",rE:!0,e:"\\(|=>",c:[e.inherit(e.TM,{b:e.UIR+"(=(?!>))?"})]}];return{aliases:["ls","lassoscript"],cI:!0,l:r+"|&[lg]t;",k:s,c:[{cN:"preprocessor",b:t,r:0,starts:{cN:"markup",e:"\\[|"+a,rE:!0,r:0,c:[n]}},o,i,{cN:"preprocessor",b:"\\[no_square_brackets",starts:{e:"\\[/no_square_brackets\\]",l:r+"|&[lg]t;",k:s,c:[{cN:"preprocessor",b:t,r:0,starts:{cN:"markup",e:"\\[noprocess\\]|"+a,rE:!0,c:[n]}},o,i].concat(c)}},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10}].concat(c)}});hljs.registerLanguage("objectivec",function(e){var t={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSData NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView NSView NSViewController NSWindow NSWindowController NSSet NSUUID NSIndexSet UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection NSURLSession NSURLSessionDataTask NSURLSessionDownloadTask NSURLSessionUploadTask NSURLResponseUIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},o=/[a-zA-Z@][a-zA-Z0-9_]*/,a="@interface @class @protocol @implementation";return{aliases:["m","mm","objc","obj-c"],k:t,l:o,i:""}]}]},{cN:"class",b:"("+a.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:a,l:o,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("smali",function(){var r=["add","and","cmp","cmpg","cmpl","const","div","double","float","goto","if","int","long","move","mul","neg","new","nop","not","or","rem","return","shl","shr","sput","sub","throw","ushr","xor"],t=["aget","aput","array","check","execute","fill","filled","goto/16","goto/32","iget","instance","invoke","iput","monitor","packed","sget","sparse"],n=["transient","constructor","abstract","final","synthetic","public","private","protected","static","bridge","system"];return{aliases:["smali"],c:[{cN:"string",b:'"',e:'"',r:0},{cN:"comment",b:"#",e:"$",r:0},{cN:"keyword",b:"\\s*\\.end\\s[a-zA-Z0-9]*",r:1},{cN:"keyword",b:"^[ ]*\\.[a-zA-Z]*",r:0},{cN:"keyword",b:"\\s:[a-zA-Z_0-9]*",r:0},{cN:"keyword",b:"\\s("+n.join("|")+")",r:1},{cN:"keyword",b:"\\[",r:0},{cN:"instruction",b:"\\s("+r.join("|")+")\\s",r:1},{cN:"instruction",b:"\\s("+r.join("|")+")((\\-|/)[a-zA-Z0-9]+)+\\s",r:10},{cN:"instruction",b:"\\s("+t.join("|")+")((\\-|/)[a-zA-Z0-9]+)*\\s",r:10},{cN:"class",b:"L[^(;:\n]*;",r:0},{cN:"function",b:'( |->)[^(\n ;"]*\\(',r:0},{cN:"function",b:"\\)",r:0},{cN:"variable",b:"[vp][0-9]+",r:0}]}});hljs.registerLanguage("nix",function(e){var t={keyword:"rec with let in inherit assert if else then",constant:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},i={cN:"subst",b:/\$\{/,e:/\}/,k:t},r={cN:"variable",b:/[a-zA-Z0-9-_]+(\s*=)/},n={cN:"string",b:"''",e:"''",c:[i]},s={cN:"string",b:'"',e:'"',c:[i]},a=[e.NM,e.HCM,e.CBCM,n,s,r];return i.c=a,{aliases:["nixos"],k:t,c:a}});hljs.registerLanguage("parser3",function(e){return{sL:"xml",r:0,c:[{cN:"comment",b:"^#",e:"$"},{cN:"comment",b:"\\^rem{",e:"}",r:10,c:[{b:"{",e:"}",c:["self"]}]},{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},e.CNM]}});hljs.registerLanguage("x86asm",function(s){return{cI:!0,l:"\\.?"+s.IR,k:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",literal:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l",pseudo:"db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times",preprocessor:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public ",built_in:"bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},c:[{cN:"comment",b:";",e:"$",r:0},{cN:"number",b:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",r:0},{cN:"number",b:"\\$[0-9][0-9A-Fa-f]*",r:0},{cN:"number",b:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[HhXx]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{cN:"number",b:"\\b(?:0[HhXx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"},s.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"[^\\\\]`",r:0},{cN:"string",b:"\\.[A-Za-z0-9]+",r:0},{cN:"label",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0},{cN:"label",b:"^\\s*%%[A-Za-z0-9_$#@~.?]*:",r:0},{cN:"argument",b:"%[0-9]+",r:0},{cN:"built_in",b:"%!S+",r:0}]}});hljs.registerLanguage("dos",function(e){var r={cN:"comment",b:/@?rem\b/,e:/$/,r:10},t={cN:"label",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0};return{aliases:["bat","cmd"],cI:!0,k:{flow:"if else goto for in do call exit not exist errorlevel defined",operator:"equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del",built_in:"append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol"},c:[{cN:"envvar",b:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{cN:"function",b:t.b,e:"goto:eof",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),r]},{cN:"number",b:"\\b\\d+",r:0},r]}});hljs.registerLanguage("brainfuck",function(){var r={cN:"literal",b:"[\\+\\-]",r:0};return{aliases:["bf"],c:[{cN:"comment",b:"[^\\[\\]\\.,\\+\\-<> \r\n]",rE:!0,e:"[\\[\\]\\.,\\+\\-<> \r\n]",r:0},{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]",r:0},{b:/\+\+|\-\-/,rB:!0,c:[r]},r]}});hljs.registerLanguage("lisp",function(e){var b="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*",c="\\|[^]*?\\|",r="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?",t={cN:"shebang",b:"^#!",e:"$"},a={cN:"literal",b:"\\b(t{1}|nil)\\b"},i={cN:"number",v:[{b:r,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"},{b:"#c\\("+r+" +"+r,e:"\\)"}]},l=e.inherit(e.QSM,{i:null}),n={cN:"comment",b:";",e:"$",r:0},N={cN:"variable",b:"\\*",e:"\\*"},d={cN:"keyword",b:"[:&]"+b},o={b:c},u={b:"\\(",e:"\\)",c:["self",a,l,i]},s={cN:"quoted",c:[i,l,N,d,u],v:[{b:"['`]\\(",e:"\\)"},{b:"\\(quote ",e:"\\)",k:"quote"},{b:"'"+c}]},f={cN:"quoted",b:"'"+b},v={cN:"list",b:"\\(",e:"\\)"},g={eW:!0,r:0};return v.c=[{cN:"keyword",v:[{b:b},{b:c}]},g],g.c=[s,f,v,a,i,l,n,N,d,o],{i:/\S/,c:[i,t,a,l,n,s,f,v]}});hljs.registerLanguage("d",function(e){var r={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},t="(0|[1-9][\\d_]*)",a="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",i="0[bB][01_]+",n="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",c="0[xX]"+n,_="([eE][+-]?"+a+")",d="("+a+"(\\.\\d*|"+_+")|\\d+\\."+a+a+"|\\."+t+_+"?)",o="(0[xX]("+n+"\\."+n+"|\\.?"+n+")[pP][+-]?"+a+")",s="("+t+"|"+i+"|"+c+")",l="("+o+"|"+d+")",u="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",b={cN:"number",b:"\\b"+s+"(L|u|U|Lu|LU|uL|UL)?",r:0},f={cN:"number",b:"\\b("+l+"([fF]|L|i|[fF]i|Li)?|"+s+"(i|[fF]i|Li))",r:0},g={cN:"string",b:"'("+u+"|.)",e:"'",i:"."},h={b:u,r:0},p={cN:"string",b:'"',c:[h],e:'"[cwd]?'},N={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5},m={cN:"string",b:"`",e:"`[cwd]?"},w={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10},A={cN:"string",b:'q"\\{',e:'\\}"'},F={cN:"shebang",b:"^#!",e:"$",r:5},y={cN:"preprocessor",b:"#(line)",e:"$",r:5},L={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"},v={cN:"comment",b:"\\/\\+",c:["self"],e:"\\+\\/",r:10};return{l:e.UIR,k:r,c:[e.CLCM,e.CBCM,v,w,p,N,m,A,f,b,g,F,y,L]}});hljs.registerLanguage("mel",function(e){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:">|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",c={cN:"yardoctag",b:"@[A-Za-z]+"},a={cN:"value",b:"#<",e:">"},s={cN:"comment",v:[{b:"#",e:"$",c:[c]},{b:"^\\=begin",e:"^\\=end",c:[c],r:10},{b:"^__END__",e:"\\n$"}]},n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},i={cN:"params",b:"\\(",e:"\\)",k:r},d=[t,a,s,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]},s]},{cN:"function",bK:"def",e:" |$|;",r:0,c:[e.inherit(e.TM,{b:b}),i,s]},{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,s,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];n.c=d,i.c=d;var l="[>?]>",u="[\\w#]+\\(\\w+\\):\\d+:\\d+>",N="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",o=[{b:/^\s*=>/,cN:"status",starts:{e:"$",c:d}},{cN:"prompt",b:"^("+l+"|"+u+"|"+N+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,c:[s].concat(o).concat(d)}});hljs.registerLanguage("roboconf",function(e){var n="[a-zA-Z-_][^\n{\r\n]+\\{";return{aliases:["graph","instances"],cI:!0,k:"import",c:[{cN:"facet",b:"^facet "+n,e:"}",k:"facet installer exports children extends",c:[e.HCM]},{cN:"instance-of",b:"^instance of "+n,e:"}",k:"name count channels instance-data instance-state instance of",c:[{cN:"keyword",b:"[a-zA-Z-_]+( | )*:"},e.HCM]},{cN:"component",b:"^"+n,e:"}",l:"\\(?[a-zA-Z]+\\)?",k:"installer exports children extends imports facets alias (optional)",c:[{cN:"string",b:"\\.[a-zA-Z-_]+",e:"\\s|,|;",eE:!0},e.HCM]},e.HCM]}});hljs.registerLanguage("erb",function(){return{sL:"xml",subLanguageMode:"continuous",c:[{cN:"comment",b:"<%#",e:"%>"},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0}]}});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage("dust",function(){var e="if eq ne lt lte gt gte select default math sep";return{aliases:["dst"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"expression",b:"{",e:"}",r:0,c:[{cN:"begin-block",b:"#[a-zA-Z- .]+",k:e},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z- .]+",k:e},{cN:"variable",b:"[a-zA-Z-.]+",k:e,r:0}]}]}});hljs.registerLanguage("markdown",function(){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link_url",e:"$"}}]}]}});hljs.registerLanguage("1c",function(c){var e="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*",r="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт",t="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон",i={cN:"dquote",b:'""'},n={cN:"string",b:'"',e:'"|$',c:[i]},a={cN:"string",b:"\\|",e:'"|$',c:[i]};return{cI:!0,l:e,k:{keyword:r,built_in:t},c:[c.CLCM,c.NM,n,a,{cN:"function",b:"(процедура|функция)",e:"$",l:e,k:"процедура функция",c:[c.inherit(c.TM,{b:e}),{cN:"tail",eW:!0,c:[{cN:"params",b:"\\(",e:"\\)",l:e,k:"знач",c:[n,a]},{cN:"export",b:"экспорт",eW:!0,l:e,k:"экспорт",c:[c.CLCM]}]},c.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}});hljs.registerLanguage("glsl",function(e){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[e.CLCM,e.CBCM,e.CNM,{cN:"preprocessor",b:"#",e:"$"}]}});hljs.registerLanguage("sml",function(e){return{aliases:["ml"],k:{keyword:"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while",built_in:"array bool char exn int list option order real ref string substring vector unit word",literal:"true false NONE SOME LESS EQUAL GREATER nil"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)"},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",e.PWM]},{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"tag",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"char",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("livecodeserver",function(e){var r={cN:"variable",b:"\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+",r:0},t={cN:"comment",e:"$",v:[e.CBCM,e.HCM,{b:"--"},{b:"[^:]//"}]},a=e.inherit(e.TM,{v:[{b:"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{b:"\\b_[a-z0-9\\-]+"}]}),o=e.inherit(e.TM,{b:"\\b([A-Za-z0-9_\\-]+)\\b"});return{cI:!1,k:{keyword:"after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if",constant:"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK",operator:"div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys",built_in:"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg base64Decode base64Encode baseConvert binaryDecode binaryEncode byteToNum cachedURL cachedURLs charToNum cipherNames commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames global globals hasMemory hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames num number numToByte numToChar offset open openfiles openProcesses openProcessIDs openSockets paramCount param params peerAddress pendingMessages platform processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_Execute revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sec secs seconds sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName tick ticks time to toLower toUpper transpose trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus value variableNames version waitDepth weekdayNames wordOffset add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket process post seek rel relative read from process rename replace require resetAll revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split subtract union unload wait write"},c:[r,{cN:"keyword",b:"\\bend\\sif\\b"},{cN:"function",bK:"function",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"function",bK:"end",e:"$",c:[o,a]},{cN:"command",bK:"command on",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"command",bK:"end",e:"$",c:[o,a]},{cN:"preprocessor",b:"<\\?rev|<\\?lc|<\\?livecode",r:10},{cN:"preprocessor",b:"<\\?"},{cN:"preprocessor",b:"\\?>"},t,e.ASM,e.QSM,e.BNM,e.CNM,a],i:";$|^\\[|^="}});hljs.registerLanguage("scheme",function(e){var t="[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+",r="(\\-|\\+)?\\d+([./]\\d+)?",i=r+"[+\\-]"+r+"i",a={built_in:"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"},n={cN:"shebang",b:"^#!",e:"$"},c={cN:"literal",b:"(#t|#f|#\\\\"+t+"|#\\\\.)"},l={cN:"number",v:[{b:r,r:0},{b:i,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"}]},s=e.QSM,o={cN:"comment",v:[{b:";",e:"$",r:0},{b:"#\\|",e:"\\|#"}]},u={b:t,r:0},p={cN:"variable",b:"'"+t},d={eW:!0,r:0},g={cN:"list",v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}],c:[{cN:"keyword",b:t,l:t,k:a},d]};return d.c=[c,l,s,o,u,p,g],{i:/\S/,c:[n,l,s,o,p,g]}});hljs.registerLanguage("monkey",function(e){var n={cN:"number",r:0,v:[{b:"[$][a-fA-F0-9]+"},e.NM]};return{cI:!0,k:{keyword:"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw",built_in:"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI",literal:"true false null and or shl shr mod"},c:[{cN:"comment",b:"#rem",e:"#end"},{cN:"comment",b:"'",e:"$",r:0},{cN:"function",bK:"function method",e:"[(=:]|$",i:/\n/,c:[e.UTM]},{cN:"class",bK:"class interface",e:"$",c:[{bK:"extends implements"},e.UTM]},{cN:"variable",b:"\\b(self|super)\\b"},{cN:"preprocessor",bK:"import",e:"$"},{cN:"preprocessor",b:"\\s*#",e:"$",k:"if else elseif endif end then"},{cN:"pi",b:"^\\s*strict\\b"},{bK:"alias",e:"=",c:[e.UTM]},e.QSM,n]}});hljs.registerLanguage("vbnet",function(e){return{aliases:["vb"],cI:!0,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"//|{|}|endif|gosub|variant|wend",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$",rB:!0,c:[{cN:"xmlDocTag",b:"'''|"},{cN:"xmlDocTag",b:""}]},e.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"}]}});hljs.registerLanguage("avrasm",function(r){return{cI:!0,l:"\\.?"+r.IR,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf",preprocessor:".byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list .listmac .macro .nolist .org .set"},c:[r.CBCM,{cN:"comment",b:";",e:"$",r:0},r.CNM,r.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},r.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"localvars",b:"@[0-9]+"}]}});hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})+",a=[],c=[],n=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},i=function(e,r,t){return{cN:e,b:r,r:t}},s=function(r,t,a){return e.inherit({cN:r,b:t+"\\(",e:"\\(",rB:!0,eE:!0,r:0},a)},b={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,n("'"),n('"'),e.CSSNM,i("hexcolor","#[0-9A-Fa-f]+\\b"),s("function","(url|data-uri)",{starts:{cN:"string",e:"[\\)\\n]",eE:!0}}),s("function",r),b,i("variable","@@?"+r,10),i("variable","@{"+r+"}"),i("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0});var o=c.concat({b:"{",e:"}",c:a}),u={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},C={cN:"attribute",b:t,e:":",eE:!0,c:[e.CLCM,e.CBCM],i:/\S/,starts:{e:"[;}]",rE:!0,c:c,i:"[<=$]"}},l={cN:"at_rule",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},d={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:o}},p={v:[{b:"[\\.#:&\\[]",e:"[;{}]"},{b:t+"[^;]*{",e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",c:[e.CLCM,e.CBCM,u,i("keyword","all\\b"),i("variable","@{"+r+"}"),i("tag",t+"%?",0),i("id","#"+t),i("class","\\."+t,0),i("keyword","&",0),s("pseudo",":not"),s("keyword",":extend"),i("pseudo","::?"+t),{cN:"attr_selector",b:"\\[",e:"\\]"},{b:"\\(",e:"\\)",c:o},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,l,d,p,C),{cI:!0,i:"[=>'/<($\"]",c:a}});hljs.registerLanguage("capnproto",function(t){return{aliases:["capnp"],k:{keyword:"struct enum interface union group import using const annotation extends in of on as with from fixed",built_in:"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List",literal:"true false"},c:[t.QSM,t.NM,t.HCM,{cN:"shebang",b:/@0x[\w\d]{16};/,i:/\n/},{cN:"number",b:/@\d+\b/},{cN:"class",bK:"struct enum",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]},{cN:"class",bK:"interface",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]}]}});hljs.registerLanguage("mathematica",function(e){return{aliases:["mma"],l:"(\\$|\\b)"+e.IR+"\\b",k:"AbelianGroup Abort AbortKernels AbortProtect Above Abs Absolute AbsoluteCorrelation AbsoluteCorrelationFunction AbsoluteCurrentValue AbsoluteDashing AbsoluteFileName AbsoluteOptions AbsolutePointSize AbsoluteThickness AbsoluteTime AbsoluteTiming AccountingForm Accumulate Accuracy AccuracyGoal ActionDelay ActionMenu ActionMenuBox ActionMenuBoxOptions Active ActiveItem ActiveStyle AcyclicGraphQ AddOnHelpPath AddTo AdjacencyGraph AdjacencyList AdjacencyMatrix AdjustmentBox AdjustmentBoxOptions AdjustTimeSeriesForecast AffineTransform After AiryAi AiryAiPrime AiryAiZero AiryBi AiryBiPrime AiryBiZero AlgebraicIntegerQ AlgebraicNumber AlgebraicNumberDenominator AlgebraicNumberNorm AlgebraicNumberPolynomial AlgebraicNumberTrace AlgebraicRules AlgebraicRulesData Algebraics AlgebraicUnitQ Alignment AlignmentMarker AlignmentPoint All AllowedDimensions AllowGroupClose AllowInlineCells AllowKernelInitialization AllowReverseGroupClose AllowScriptLevelChange AlphaChannel AlternatingGroup AlternativeHypothesis Alternatives AmbientLight Analytic AnchoredSearch And AndersonDarlingTest AngerJ AngleBracket AngularGauge Animate AnimationCycleOffset AnimationCycleRepetitions AnimationDirection AnimationDisplayTime AnimationRate AnimationRepetitions AnimationRunning Animator AnimatorBox AnimatorBoxOptions AnimatorElements Annotation Annuity AnnuityDue Antialiasing Antisymmetric Apart ApartSquareFree Appearance AppearanceElements AppellF1 Append AppendTo Apply ArcCos ArcCosh ArcCot ArcCoth ArcCsc ArcCsch ArcSec ArcSech ArcSin ArcSinDistribution ArcSinh ArcTan ArcTanh Arg ArgMax ArgMin ArgumentCountQ ARIMAProcess ArithmeticGeometricMean ARMAProcess ARProcess Array ArrayComponents ArrayDepth ArrayFlatten ArrayPad ArrayPlot ArrayQ ArrayReshape ArrayRules Arrays Arrow Arrow3DBox ArrowBox Arrowheads AspectRatio AspectRatioFixed Assert Assuming Assumptions AstronomicalData Asynchronous AsynchronousTaskObject AsynchronousTasks AtomQ Attributes AugmentedSymmetricPolynomial AutoAction AutoDelete AutoEvaluateEvents AutoGeneratedPackage AutoIndent AutoIndentSpacings AutoItalicWords AutoloadPath AutoMatch Automatic AutomaticImageSize AutoMultiplicationSymbol AutoNumberFormatting AutoOpenNotebooks AutoOpenPalettes AutorunSequencing AutoScaling AutoScroll AutoSpacing AutoStyleOptions AutoStyleWords Axes AxesEdge AxesLabel AxesOrigin AxesStyle Axis BabyMonsterGroupB Back Background BackgroundTasksSettings Backslash Backsubstitution Backward Band BandpassFilter BandstopFilter BarabasiAlbertGraphDistribution BarChart BarChart3D BarLegend BarlowProschanImportance BarnesG BarOrigin BarSpacing BartlettHannWindow BartlettWindow BaseForm Baseline BaselinePosition BaseStyle BatesDistribution BattleLemarieWavelet Because BeckmannDistribution Beep Before Begin BeginDialogPacket BeginFrontEndInteractionPacket BeginPackage BellB BellY Below BenfordDistribution BeniniDistribution BenktanderGibratDistribution BenktanderWeibullDistribution BernoulliB BernoulliDistribution BernoulliGraphDistribution BernoulliProcess BernsteinBasis BesselFilterModel BesselI BesselJ BesselJZero BesselK BesselY BesselYZero Beta BetaBinomialDistribution BetaDistribution BetaNegativeBinomialDistribution BetaPrimeDistribution BetaRegularized BetweennessCentrality BezierCurve BezierCurve3DBox BezierCurve3DBoxOptions BezierCurveBox BezierCurveBoxOptions BezierFunction BilateralFilter Binarize BinaryFormat BinaryImageQ BinaryRead BinaryReadList BinaryWrite BinCounts BinLists Binomial BinomialDistribution BinomialProcess BinormalDistribution BiorthogonalSplineWavelet BipartiteGraphQ BirnbaumImportance BirnbaumSaundersDistribution BitAnd BitClear BitGet BitLength BitNot BitOr BitSet BitShiftLeft BitShiftRight BitXor Black BlackmanHarrisWindow BlackmanNuttallWindow BlackmanWindow Blank BlankForm BlankNullSequence BlankSequence Blend Block BlockRandom BlomqvistBeta BlomqvistBetaTest Blue Blur BodePlot BohmanWindow Bold Bookmarks Boole BooleanConsecutiveFunction BooleanConvert BooleanCountingFunction BooleanFunction BooleanGraph BooleanMaxterms BooleanMinimize BooleanMinterms Booleans BooleanTable BooleanVariables BorderDimensions BorelTannerDistribution Bottom BottomHatTransform BoundaryStyle Bounds Box BoxBaselineShift BoxData BoxDimensions Boxed Boxes BoxForm BoxFormFormatTypes BoxFrame BoxID BoxMargins BoxMatrix BoxRatios BoxRotation BoxRotationPoint BoxStyle BoxWhiskerChart Bra BracketingBar BraKet BrayCurtisDistance BreadthFirstScan Break Brown BrownForsytheTest BrownianBridgeProcess BrowserCategory BSplineBasis BSplineCurve BSplineCurve3DBox BSplineCurveBox BSplineCurveBoxOptions BSplineFunction BSplineSurface BSplineSurface3DBox BubbleChart BubbleChart3D BubbleScale BubbleSizes BulletGauge BusinessDayQ ButterflyGraph ButterworthFilterModel Button ButtonBar ButtonBox ButtonBoxOptions ButtonCell ButtonContents ButtonData ButtonEvaluator ButtonExpandable ButtonFrame ButtonFunction ButtonMargins ButtonMinHeight ButtonNote ButtonNotebook ButtonSource ButtonStyle ButtonStyleMenuListing Byte ByteCount ByteOrdering C CachedValue CacheGraphics CalendarData CalendarType CallPacket CanberraDistance Cancel CancelButton CandlestickChart Cap CapForm CapitalDifferentialD CardinalBSplineBasis CarmichaelLambda Cases Cashflow Casoratian Catalan CatalanNumber Catch CauchyDistribution CauchyWindow CayleyGraph CDF CDFDeploy CDFInformation CDFWavelet Ceiling Cell CellAutoOverwrite CellBaseline CellBoundingBox CellBracketOptions CellChangeTimes CellContents CellContext CellDingbat CellDynamicExpression CellEditDuplicate CellElementsBoundingBox CellElementSpacings CellEpilog CellEvaluationDuplicate CellEvaluationFunction CellEventActions CellFrame CellFrameColor CellFrameLabelMargins CellFrameLabels CellFrameMargins CellGroup CellGroupData CellGrouping CellGroupingRules CellHorizontalScrolling CellID CellLabel CellLabelAutoDelete CellLabelMargins CellLabelPositioning CellMargins CellObject CellOpen CellPrint CellProlog Cells CellSize CellStyle CellTags CellularAutomaton CensoredDistribution Censoring Center CenterDot CentralMoment CentralMomentGeneratingFunction CForm ChampernowneNumber ChanVeseBinarize Character CharacterEncoding CharacterEncodingsPath CharacteristicFunction CharacteristicPolynomial CharacterRange Characters ChartBaseStyle ChartElementData ChartElementDataFunction ChartElementFunction ChartElements ChartLabels ChartLayout ChartLegends ChartStyle Chebyshev1FilterModel Chebyshev2FilterModel ChebyshevDistance ChebyshevT ChebyshevU Check CheckAbort CheckAll Checkbox CheckboxBar CheckboxBox CheckboxBoxOptions ChemicalData ChessboardDistance ChiDistribution ChineseRemainder ChiSquareDistribution ChoiceButtons ChoiceDialog CholeskyDecomposition Chop Circle CircleBox CircleDot CircleMinus CirclePlus CircleTimes CirculantGraph CityData Clear ClearAll ClearAttributes ClearSystemCache ClebschGordan ClickPane Clip ClipboardNotebook ClipFill ClippingStyle ClipPlanes ClipRange Clock ClockGauge ClockwiseContourIntegral Close Closed CloseKernels ClosenessCentrality Closing ClosingAutoSave ClosingEvent ClusteringComponents CMYKColor Coarse Coefficient CoefficientArrays CoefficientDomain CoefficientList CoefficientRules CoifletWavelet Collect Colon ColonForm ColorCombine ColorConvert ColorData ColorDataFunction ColorFunction ColorFunctionScaling Colorize ColorNegate ColorOutput ColorProfileData ColorQuantize ColorReplace ColorRules ColorSelectorSettings ColorSeparate ColorSetter ColorSetterBox ColorSetterBoxOptions ColorSlider ColorSpace Column ColumnAlignments ColumnBackgrounds ColumnForm ColumnLines ColumnsEqual ColumnSpacings ColumnWidths CommonDefaultFormatTypes Commonest CommonestFilter CommonUnits CommunityBoundaryStyle CommunityGraphPlot CommunityLabels CommunityRegionStyle CompatibleUnitQ CompilationOptions CompilationTarget Compile Compiled CompiledFunction Complement CompleteGraph CompleteGraphQ CompleteKaryTree CompletionsListPacket Complex Complexes ComplexExpand ComplexInfinity ComplexityFunction ComponentMeasurements ComponentwiseContextMenu Compose ComposeList ComposeSeries Composition CompoundExpression CompoundPoissonDistribution CompoundPoissonProcess CompoundRenewalProcess Compress CompressedData Condition ConditionalExpression Conditioned Cone ConeBox ConfidenceLevel ConfidenceRange ConfidenceTransform ConfigurationPath Congruent Conjugate ConjugateTranspose Conjunction Connect ConnectedComponents ConnectedGraphQ ConnesWindow ConoverTest ConsoleMessage ConsoleMessagePacket ConsolePrint Constant ConstantArray Constants ConstrainedMax ConstrainedMin ContentPadding ContentsBoundingBox ContentSelectable ContentSize Context ContextMenu Contexts ContextToFilename ContextToFileName Continuation Continue ContinuedFraction ContinuedFractionK ContinuousAction ContinuousMarkovProcess ContinuousTimeModelQ ContinuousWaveletData ContinuousWaveletTransform ContourDetect ContourGraphics ContourIntegral ContourLabels ContourLines ContourPlot ContourPlot3D Contours ContourShading ContourSmoothing ContourStyle ContraharmonicMean Control ControlActive ControlAlignment ControllabilityGramian ControllabilityMatrix ControllableDecomposition ControllableModelQ ControllerDuration ControllerInformation ControllerInformationData ControllerLinking ControllerManipulate ControllerMethod ControllerPath ControllerState ControlPlacement ControlsRendering ControlType Convergents ConversionOptions ConversionRules ConvertToBitmapPacket ConvertToPostScript ConvertToPostScriptPacket Convolve ConwayGroupCo1 ConwayGroupCo2 ConwayGroupCo3 CoordinateChartData CoordinatesToolOptions CoordinateTransform CoordinateTransformData CoprimeQ Coproduct CopulaDistribution Copyable CopyDirectory CopyFile CopyTag CopyToClipboard CornerFilter CornerNeighbors Correlation CorrelationDistance CorrelationFunction CorrelationTest Cos Cosh CoshIntegral CosineDistance CosineWindow CosIntegral Cot Coth Count CounterAssignments CounterBox CounterBoxOptions CounterClockwiseContourIntegral CounterEvaluator CounterFunction CounterIncrements CounterStyle CounterStyleMenuListing CountRoots CountryData Covariance CovarianceEstimatorFunction CovarianceFunction CoxianDistribution CoxIngersollRossProcess CoxModel CoxModelFit CramerVonMisesTest CreateArchive CreateDialog CreateDirectory CreateDocument CreateIntermediateDirectories CreatePalette CreatePalettePacket CreateScheduledTask CreateTemporary CreateWindow CriticalityFailureImportance CriticalitySuccessImportance CriticalSection Cross CrossingDetect CrossMatrix Csc Csch CubeRoot Cubics Cuboid CuboidBox Cumulant CumulantGeneratingFunction Cup CupCap Curl CurlyDoubleQuote CurlyQuote CurrentImage CurrentlySpeakingPacket CurrentValue CurvatureFlowFilter CurveClosed Cyan CycleGraph CycleIndexPolynomial Cycles CyclicGroup Cyclotomic Cylinder CylinderBox CylindricalDecomposition D DagumDistribution DamerauLevenshteinDistance DampingFactor Darker Dashed Dashing DataCompression DataDistribution DataRange DataReversed Date DateDelimiters DateDifference DateFunction DateList DateListLogPlot DateListPlot DatePattern DatePlus DateRange DateString DateTicksFormat DaubechiesWavelet DavisDistribution DawsonF DayCount DayCountConvention DayMatchQ DayName DayPlus DayRange DayRound DeBruijnGraph Debug DebugTag Decimal DeclareKnownSymbols DeclarePackage Decompose Decrement DedekindEta Default DefaultAxesStyle DefaultBaseStyle DefaultBoxStyle DefaultButton DefaultColor DefaultControlPlacement DefaultDuplicateCellStyle DefaultDuration DefaultElement DefaultFaceGridsStyle DefaultFieldHintStyle DefaultFont DefaultFontProperties DefaultFormatType DefaultFormatTypeForStyle DefaultFrameStyle DefaultFrameTicksStyle DefaultGridLinesStyle DefaultInlineFormatType DefaultInputFormatType DefaultLabelStyle DefaultMenuStyle DefaultNaturalLanguage DefaultNewCellStyle DefaultNewInlineCellStyle DefaultNotebook DefaultOptions DefaultOutputFormatType DefaultStyle DefaultStyleDefinitions DefaultTextFormatType DefaultTextInlineFormatType DefaultTicksStyle DefaultTooltipStyle DefaultValues Defer DefineExternal DefineInputStreamMethod DefineOutputStreamMethod Definition Degree DegreeCentrality DegreeGraphDistribution DegreeLexicographic DegreeReverseLexicographic Deinitialization Del Deletable Delete DeleteBorderComponents DeleteCases DeleteContents DeleteDirectory DeleteDuplicates DeleteFile DeleteSmallComponents DeleteWithContents DeletionWarning Delimiter DelimiterFlashTime DelimiterMatching Delimiters Denominator DensityGraphics DensityHistogram DensityPlot DependentVariables Deploy Deployed Depth DepthFirstScan Derivative DerivativeFilter DescriptorStateSpace DesignMatrix Det DGaussianWavelet DiacriticalPositioning Diagonal DiagonalMatrix Dialog DialogIndent DialogInput DialogLevel DialogNotebook DialogProlog DialogReturn DialogSymbols Diamond DiamondMatrix DiceDissimilarity DictionaryLookup DifferenceDelta DifferenceOrder DifferenceRoot DifferenceRootReduce Differences DifferentialD DifferentialRoot DifferentialRootReduce DifferentiatorFilter DigitBlock DigitBlockMinimum DigitCharacter DigitCount DigitQ DihedralGroup Dilation Dimensions DiracComb DiracDelta DirectedEdge DirectedEdges DirectedGraph DirectedGraphQ DirectedInfinity Direction Directive Directory DirectoryName DirectoryQ DirectoryStack DirichletCharacter DirichletConvolve DirichletDistribution DirichletL DirichletTransform DirichletWindow DisableConsolePrintPacket DiscreteChirpZTransform DiscreteConvolve DiscreteDelta DiscreteHadamardTransform DiscreteIndicator DiscreteLQEstimatorGains DiscreteLQRegulatorGains DiscreteLyapunovSolve DiscreteMarkovProcess DiscretePlot DiscretePlot3D DiscreteRatio DiscreteRiccatiSolve DiscreteShift DiscreteTimeModelQ DiscreteUniformDistribution DiscreteVariables DiscreteWaveletData DiscreteWaveletPacketTransform DiscreteWaveletTransform Discriminant Disjunction Disk DiskBox DiskMatrix Dispatch DispersionEstimatorFunction Display DisplayAllSteps DisplayEndPacket DisplayFlushImagePacket DisplayForm DisplayFunction DisplayPacket DisplayRules DisplaySetSizePacket DisplayString DisplayTemporary DisplayWith DisplayWithRef DisplayWithVariable DistanceFunction DistanceTransform Distribute Distributed DistributedContexts DistributeDefinitions DistributionChart DistributionDomain DistributionFitTest DistributionParameterAssumptions DistributionParameterQ Dithering Div Divergence Divide DivideBy Dividers Divisible Divisors DivisorSigma DivisorSum DMSList DMSString Do DockedCells DocumentNotebook DominantColors DOSTextFormat Dot DotDashed DotEqual Dotted DoubleBracketingBar DoubleContourIntegral DoubleDownArrow DoubleLeftArrow DoubleLeftRightArrow DoubleLeftTee DoubleLongLeftArrow DoubleLongLeftRightArrow DoubleLongRightArrow DoubleRightArrow DoubleRightTee DoubleUpArrow DoubleUpDownArrow DoubleVerticalBar DoublyInfinite Down DownArrow DownArrowBar DownArrowUpArrow DownLeftRightVector DownLeftTeeVector DownLeftVector DownLeftVectorBar DownRightTeeVector DownRightVector DownRightVectorBar Downsample DownTee DownTeeArrow DownValues DragAndDrop DrawEdges DrawFrontFaces DrawHighlighted Drop DSolve Dt DualLinearProgramming DualSystemsModel DumpGet DumpSave DuplicateFreeQ Dynamic DynamicBox DynamicBoxOptions DynamicEvaluationTimeout DynamicLocation DynamicModule DynamicModuleBox DynamicModuleBoxOptions DynamicModuleParent DynamicModuleValues DynamicName DynamicNamespace DynamicReference DynamicSetting DynamicUpdating DynamicWrapper DynamicWrapperBox DynamicWrapperBoxOptions E EccentricityCentrality EdgeAdd EdgeBetweennessCentrality EdgeCapacity EdgeCapForm EdgeColor EdgeConnectivity EdgeCost EdgeCount EdgeCoverQ EdgeDashing EdgeDelete EdgeDetect EdgeForm EdgeIndex EdgeJoinForm EdgeLabeling EdgeLabels EdgeLabelStyle EdgeList EdgeOpacity EdgeQ EdgeRenderingFunction EdgeRules EdgeShapeFunction EdgeStyle EdgeThickness EdgeWeight Editable EditButtonSettings EditCellTagsSettings EditDistance EffectiveInterest Eigensystem Eigenvalues EigenvectorCentrality Eigenvectors Element ElementData Eliminate EliminationOrder EllipticE EllipticExp EllipticExpPrime EllipticF EllipticFilterModel EllipticK EllipticLog EllipticNomeQ EllipticPi EllipticReducedHalfPeriods EllipticTheta EllipticThetaPrime EmitSound EmphasizeSyntaxErrors EmpiricalDistribution Empty EmptyGraphQ EnableConsolePrintPacket Enabled Encode End EndAdd EndDialogPacket EndFrontEndInteractionPacket EndOfFile EndOfLine EndOfString EndPackage EngineeringForm Enter EnterExpressionPacket EnterTextPacket Entropy EntropyFilter Environment Epilog Equal EqualColumns EqualRows EqualTilde EquatedTo Equilibrium EquirippleFilterKernel Equivalent Erf Erfc Erfi ErlangB ErlangC ErlangDistribution Erosion ErrorBox ErrorBoxOptions ErrorNorm ErrorPacket ErrorsDialogSettings EstimatedDistribution EstimatedProcess EstimatorGains EstimatorRegulator EuclideanDistance EulerE EulerGamma EulerianGraphQ EulerPhi Evaluatable Evaluate Evaluated EvaluatePacket EvaluationCell EvaluationCompletionAction EvaluationElements EvaluationMode EvaluationMonitor EvaluationNotebook EvaluationObject EvaluationOrder Evaluator EvaluatorNames EvenQ EventData EventEvaluator EventHandler EventHandlerTag EventLabels ExactBlackmanWindow ExactNumberQ ExactRootIsolation ExampleData Except ExcludedForms ExcludePods Exclusions ExclusionsStyle Exists Exit ExitDialog Exp Expand ExpandAll ExpandDenominator ExpandFileName ExpandNumerator Expectation ExpectationE ExpectedValue ExpGammaDistribution ExpIntegralE ExpIntegralEi Exponent ExponentFunction ExponentialDistribution ExponentialFamily ExponentialGeneratingFunction ExponentialMovingAverage ExponentialPowerDistribution ExponentPosition ExponentStep Export ExportAutoReplacements ExportPacket ExportString Expression ExpressionCell ExpressionPacket ExpToTrig ExtendedGCD Extension ExtentElementFunction ExtentMarkers ExtentSize ExternalCall ExternalDataCharacterEncoding Extract ExtractArchive ExtremeValueDistribution FaceForm FaceGrids FaceGridsStyle Factor FactorComplete Factorial Factorial2 FactorialMoment FactorialMomentGeneratingFunction FactorialPower FactorInteger FactorList FactorSquareFree FactorSquareFreeList FactorTerms FactorTermsList Fail FailureDistribution False FARIMAProcess FEDisableConsolePrintPacket FeedbackSector FeedbackSectorStyle FeedbackType FEEnableConsolePrintPacket Fibonacci FieldHint FieldHintStyle FieldMasked FieldSize File FileBaseName FileByteCount FileDate FileExistsQ FileExtension FileFormat FileHash FileInformation FileName FileNameDepth FileNameDialogSettings FileNameDrop FileNameJoin FileNames FileNameSetter FileNameSplit FileNameTake FilePrint FileType FilledCurve FilledCurveBox Filling FillingStyle FillingTransform FilterRules FinancialBond FinancialData FinancialDerivative FinancialIndicator Find FindArgMax FindArgMin FindClique FindClusters FindCurvePath FindDistributionParameters FindDivisions FindEdgeCover FindEdgeCut FindEulerianCycle FindFaces FindFile FindFit FindGeneratingFunction FindGeoLocation FindGeometricTransform FindGraphCommunities FindGraphIsomorphism FindGraphPartition FindHamiltonianCycle FindIndependentEdgeSet FindIndependentVertexSet FindInstance FindIntegerNullVector FindKClan FindKClique FindKClub FindKPlex FindLibrary FindLinearRecurrence FindList FindMaximum FindMaximumFlow FindMaxValue FindMinimum FindMinimumCostFlow FindMinimumCut FindMinValue FindPermutation FindPostmanTour FindProcessParameters FindRoot FindSequenceFunction FindSettings FindShortestPath FindShortestTour FindThreshold FindVertexCover FindVertexCut Fine FinishDynamic FiniteAbelianGroupCount FiniteGroupCount FiniteGroupData First FirstPassageTimeDistribution FischerGroupFi22 FischerGroupFi23 FischerGroupFi24Prime FisherHypergeometricDistribution FisherRatioTest FisherZDistribution Fit FitAll FittedModel FixedPoint FixedPointList FlashSelection Flat Flatten FlattenAt FlatTopWindow FlipView Floor FlushPrintOutputPacket Fold FoldList Font FontColor FontFamily FontForm FontName FontOpacity FontPostScriptName FontProperties FontReencoding FontSize FontSlant FontSubstitutions FontTracking FontVariations FontWeight For ForAll Format FormatRules FormatType FormatTypeAutoConvert FormatValues FormBox FormBoxOptions FortranForm Forward ForwardBackward Fourier FourierCoefficient FourierCosCoefficient FourierCosSeries FourierCosTransform FourierDCT FourierDCTFilter FourierDCTMatrix FourierDST FourierDSTMatrix FourierMatrix FourierParameters FourierSequenceTransform FourierSeries FourierSinCoefficient FourierSinSeries FourierSinTransform FourierTransform FourierTrigSeries FractionalBrownianMotionProcess FractionalPart FractionBox FractionBoxOptions FractionLine Frame FrameBox FrameBoxOptions Framed FrameInset FrameLabel Frameless FrameMargins FrameStyle FrameTicks FrameTicksStyle FRatioDistribution FrechetDistribution FreeQ FrequencySamplingFilterKernel FresnelC FresnelS Friday FrobeniusNumber FrobeniusSolve FromCharacterCode FromCoefficientRules FromContinuedFraction FromDate FromDigits FromDMS Front FrontEndDynamicExpression FrontEndEventActions FrontEndExecute FrontEndObject FrontEndResource FrontEndResourceString FrontEndStackSize FrontEndToken FrontEndTokenExecute FrontEndValueCache FrontEndVersion FrontFaceColor FrontFaceOpacity Full FullAxes FullDefinition FullForm FullGraphics FullOptions FullSimplify Function FunctionExpand FunctionInterpolation FunctionSpace FussellVeselyImportance GaborFilter GaborMatrix GaborWavelet GainMargins GainPhaseMargins Gamma GammaDistribution GammaRegularized GapPenalty Gather GatherBy GaugeFaceElementFunction GaugeFaceStyle GaugeFrameElementFunction GaugeFrameSize GaugeFrameStyle GaugeLabels GaugeMarkers GaugeStyle GaussianFilter GaussianIntegers GaussianMatrix GaussianWindow GCD GegenbauerC General GeneralizedLinearModelFit GenerateConditions GeneratedCell GeneratedParameters GeneratingFunction Generic GenericCylindricalDecomposition GenomeData GenomeLookup GeodesicClosing GeodesicDilation GeodesicErosion GeodesicOpening GeoDestination GeodesyData GeoDirection GeoDistance GeoGridPosition GeometricBrownianMotionProcess GeometricDistribution GeometricMean GeometricMeanFilter GeometricTransformation GeometricTransformation3DBox GeometricTransformation3DBoxOptions GeometricTransformationBox GeometricTransformationBoxOptions GeoPosition GeoPositionENU GeoPositionXYZ GeoProjectionData GestureHandler GestureHandlerTag Get GetBoundingBoxSizePacket GetContext GetEnvironment GetFileName GetFrontEndOptionsDataPacket GetLinebreakInformationPacket GetMenusPacket GetPageBreakInformationPacket Glaisher GlobalClusteringCoefficient GlobalPreferences GlobalSession Glow GoldenRatio GompertzMakehamDistribution GoodmanKruskalGamma GoodmanKruskalGammaTest Goto Grad Gradient GradientFilter GradientOrientationFilter Graph GraphAssortativity GraphCenter GraphComplement GraphData GraphDensity GraphDiameter GraphDifference GraphDisjointUnion GraphDistance GraphDistanceMatrix GraphElementData GraphEmbedding GraphHighlight GraphHighlightStyle GraphHub Graphics Graphics3D Graphics3DBox Graphics3DBoxOptions GraphicsArray GraphicsBaseline GraphicsBox GraphicsBoxOptions GraphicsColor GraphicsColumn GraphicsComplex GraphicsComplex3DBox GraphicsComplex3DBoxOptions GraphicsComplexBox GraphicsComplexBoxOptions GraphicsContents GraphicsData GraphicsGrid GraphicsGridBox GraphicsGroup GraphicsGroup3DBox GraphicsGroup3DBoxOptions GraphicsGroupBox GraphicsGroupBoxOptions GraphicsGrouping GraphicsHighlightColor GraphicsRow GraphicsSpacing GraphicsStyle GraphIntersection GraphLayout GraphLinkEfficiency GraphPeriphery GraphPlot GraphPlot3D GraphPower GraphPropertyDistribution GraphQ GraphRadius GraphReciprocity GraphRoot GraphStyle GraphUnion Gray GrayLevel GreatCircleDistance Greater GreaterEqual GreaterEqualLess GreaterFullEqual GreaterGreater GreaterLess GreaterSlantEqual GreaterTilde Green Grid GridBaseline GridBox GridBoxAlignment GridBoxBackground GridBoxDividers GridBoxFrame GridBoxItemSize GridBoxItemStyle GridBoxOptions GridBoxSpacings GridCreationSettings GridDefaultElement GridElementStyleOptions GridFrame GridFrameMargins GridGraph GridLines GridLinesStyle GroebnerBasis GroupActionBase GroupCentralizer GroupElementFromWord GroupElementPosition GroupElementQ GroupElements GroupElementToWord GroupGenerators GroupMultiplicationTable GroupOrbits GroupOrder GroupPageBreakWithin GroupSetwiseStabilizer GroupStabilizer GroupStabilizerChain Gudermannian GumbelDistribution HaarWavelet HadamardMatrix HalfNormalDistribution HamiltonianGraphQ HammingDistance HammingWindow HankelH1 HankelH2 HankelMatrix HannPoissonWindow HannWindow HaradaNortonGroupHN HararyGraph HarmonicMean HarmonicMeanFilter HarmonicNumber Hash HashTable Haversine HazardFunction Head HeadCompose Heads HeavisideLambda HeavisidePi HeavisideTheta HeldGroupHe HeldPart HelpBrowserLookup HelpBrowserNotebook HelpBrowserSettings HermiteDecomposition HermiteH HermitianMatrixQ HessenbergDecomposition Hessian HexadecimalCharacter Hexahedron HexahedronBox HexahedronBoxOptions HiddenSurface HighlightGraph HighlightImage HighpassFilter HigmanSimsGroupHS HilbertFilter HilbertMatrix Histogram Histogram3D HistogramDistribution HistogramList HistogramTransform HistogramTransformInterpolation HitMissTransform HITSCentrality HodgeDual HoeffdingD HoeffdingDTest Hold HoldAll HoldAllComplete HoldComplete HoldFirst HoldForm HoldPattern HoldRest HolidayCalendar HomeDirectory HomePage Horizontal HorizontalForm HorizontalGauge HorizontalScrollPosition HornerForm HotellingTSquareDistribution HoytDistribution HTMLSave Hue HumpDownHump HumpEqual HurwitzLerchPhi HurwitzZeta HyperbolicDistribution HypercubeGraph HyperexponentialDistribution Hyperfactorial Hypergeometric0F1 Hypergeometric0F1Regularized Hypergeometric1F1 Hypergeometric1F1Regularized Hypergeometric2F1 Hypergeometric2F1Regularized HypergeometricDistribution HypergeometricPFQ HypergeometricPFQRegularized HypergeometricU Hyperlink HyperlinkCreationSettings Hyphenation HyphenationOptions HypoexponentialDistribution HypothesisTestData I Identity IdentityMatrix If IgnoreCase Im Image Image3D Image3DSlices ImageAccumulate ImageAdd ImageAdjust ImageAlign ImageApply ImageAspectRatio ImageAssemble ImageCache ImageCacheValid ImageCapture ImageChannels ImageClip ImageColorSpace ImageCompose ImageConvolve ImageCooccurrence ImageCorners ImageCorrelate ImageCorrespondingPoints ImageCrop ImageData ImageDataPacket ImageDeconvolve ImageDemosaic ImageDifference ImageDimensions ImageDistance ImageEffect ImageFeatureTrack ImageFileApply ImageFileFilter ImageFileScan ImageFilter ImageForestingComponents ImageForwardTransformation ImageHistogram ImageKeypoints ImageLevels ImageLines ImageMargins ImageMarkers ImageMeasurements ImageMultiply ImageOffset ImagePad ImagePadding ImagePartition ImagePeriodogram ImagePerspectiveTransformation ImageQ ImageRangeCache ImageReflect ImageRegion ImageResize ImageResolution ImageRotate ImageRotated ImageScaled ImageScan ImageSize ImageSizeAction ImageSizeCache ImageSizeMultipliers ImageSizeRaw ImageSubtract ImageTake ImageTransformation ImageTrim ImageType ImageValue ImageValuePositions Implies Import ImportAutoReplacements ImportString ImprovementImportance In IncidenceGraph IncidenceList IncidenceMatrix IncludeConstantBasis IncludeFileExtension IncludePods IncludeSingularTerm Increment Indent IndentingNewlineSpacings IndentMaxFraction IndependenceTest IndependentEdgeSetQ IndependentUnit IndependentVertexSetQ Indeterminate IndexCreationOptions Indexed IndexGraph IndexTag Inequality InexactNumberQ InexactNumbers Infinity Infix Information Inherited InheritScope Initialization InitializationCell InitializationCellEvaluation InitializationCellWarning InlineCounterAssignments InlineCounterIncrements InlineRules Inner Inpaint Input InputAliases InputAssumptions InputAutoReplacements InputField InputFieldBox InputFieldBoxOptions InputForm InputGrouping InputNamePacket InputNotebook InputPacket InputSettings InputStream InputString InputStringPacket InputToBoxFormPacket Insert InsertionPointObject InsertResults Inset Inset3DBox Inset3DBoxOptions InsetBox InsetBoxOptions Install InstallService InString Integer IntegerDigits IntegerExponent IntegerLength IntegerPart IntegerPartitions IntegerQ Integers IntegerString Integral Integrate Interactive InteractiveTradingChart Interlaced Interleaving InternallyBalancedDecomposition InterpolatingFunction InterpolatingPolynomial Interpolation InterpolationOrder InterpolationPoints InterpolationPrecision Interpretation InterpretationBox InterpretationBoxOptions InterpretationFunction InterpretTemplate InterquartileRange Interrupt InterruptSettings Intersection Interval IntervalIntersection IntervalMemberQ IntervalUnion Inverse InverseBetaRegularized InverseCDF InverseChiSquareDistribution InverseContinuousWaveletTransform InverseDistanceTransform InverseEllipticNomeQ InverseErf InverseErfc InverseFourier InverseFourierCosTransform InverseFourierSequenceTransform InverseFourierSinTransform InverseFourierTransform InverseFunction InverseFunctions InverseGammaDistribution InverseGammaRegularized InverseGaussianDistribution InverseGudermannian InverseHaversine InverseJacobiCD InverseJacobiCN InverseJacobiCS InverseJacobiDC InverseJacobiDN InverseJacobiDS InverseJacobiNC InverseJacobiND InverseJacobiNS InverseJacobiSC InverseJacobiSD InverseJacobiSN InverseLaplaceTransform InversePermutation InverseRadon InverseSeries InverseSurvivalFunction InverseWaveletTransform InverseWeierstrassP InverseZTransform Invisible InvisibleApplication InvisibleTimes IrreduciblePolynomialQ IsolatingInterval IsomorphicGraphQ IsotopeData Italic Item ItemBox ItemBoxOptions ItemSize ItemStyle ItoProcess JaccardDissimilarity JacobiAmplitude Jacobian JacobiCD JacobiCN JacobiCS JacobiDC JacobiDN JacobiDS JacobiNC JacobiND JacobiNS JacobiP JacobiSC JacobiSD JacobiSN JacobiSymbol JacobiZeta JankoGroupJ1 JankoGroupJ2 JankoGroupJ3 JankoGroupJ4 JarqueBeraALMTest JohnsonDistribution Join Joined JoinedCurve JoinedCurveBox JoinForm JordanDecomposition JordanModelDecomposition K KagiChart KaiserBesselWindow KaiserWindow KalmanEstimator KalmanFilter KarhunenLoeveDecomposition KaryTree KatzCentrality KCoreComponents KDistribution KelvinBei KelvinBer KelvinKei KelvinKer KendallTau KendallTauTest KernelExecute KernelMixtureDistribution KernelObject Kernels Ket Khinchin KirchhoffGraph KirchhoffMatrix KleinInvariantJ KnightTourGraph KnotData KnownUnitQ KolmogorovSmirnovTest KroneckerDelta KroneckerModelDecomposition KroneckerProduct KroneckerSymbol KuiperTest KumaraswamyDistribution Kurtosis KuwaharaFilter Label Labeled LabeledSlider LabelingFunction LabelStyle LaguerreL LambdaComponents LambertW LanczosWindow LandauDistribution Language LanguageCategory LaplaceDistribution LaplaceTransform Laplacian LaplacianFilter LaplacianGaussianFilter Large Larger Last Latitude LatitudeLongitude LatticeData LatticeReduce Launch LaunchKernels LayeredGraphPlot LayerSizeFunction LayoutInformation LCM LeafCount LeapYearQ LeastSquares LeastSquaresFilterKernel Left LeftArrow LeftArrowBar LeftArrowRightArrow LeftDownTeeVector LeftDownVector LeftDownVectorBar LeftRightArrow LeftRightVector LeftTee LeftTeeArrow LeftTeeVector LeftTriangle LeftTriangleBar LeftTriangleEqual LeftUpDownVector LeftUpTeeVector LeftUpVector LeftUpVectorBar LeftVector LeftVectorBar LegendAppearance Legended LegendFunction LegendLabel LegendLayout LegendMargins LegendMarkers LegendMarkerSize LegendreP LegendreQ LegendreType Length LengthWhile LerchPhi Less LessEqual LessEqualGreater LessFullEqual LessGreater LessLess LessSlantEqual LessTilde LetterCharacter LetterQ Level LeveneTest LeviCivitaTensor LevyDistribution Lexicographic LibraryFunction LibraryFunctionError LibraryFunctionInformation LibraryFunctionLoad LibraryFunctionUnload LibraryLoad LibraryUnload LicenseID LiftingFilterData LiftingWaveletTransform LightBlue LightBrown LightCyan Lighter LightGray LightGreen Lighting LightingAngle LightMagenta LightOrange LightPink LightPurple LightRed LightSources LightYellow Likelihood Limit LimitsPositioning LimitsPositioningTokens LindleyDistribution Line Line3DBox LinearFilter LinearFractionalTransform LinearModelFit LinearOffsetFunction LinearProgramming LinearRecurrence LinearSolve LinearSolveFunction LineBox LineBreak LinebreakAdjustments LineBreakChart LineBreakWithin LineColor LineForm LineGraph LineIndent LineIndentMaxFraction LineIntegralConvolutionPlot LineIntegralConvolutionScale LineLegend LineOpacity LineSpacing LineWrapParts LinkActivate LinkClose LinkConnect LinkConnectedQ LinkCreate LinkError LinkFlush LinkFunction LinkHost LinkInterrupt LinkLaunch LinkMode LinkObject LinkOpen LinkOptions LinkPatterns LinkProtocol LinkRead LinkReadHeld LinkReadyQ Links LinkWrite LinkWriteHeld LiouvilleLambda List Listable ListAnimate ListContourPlot ListContourPlot3D ListConvolve ListCorrelate ListCurvePathPlot ListDeconvolve ListDensityPlot Listen ListFourierSequenceTransform ListInterpolation ListLineIntegralConvolutionPlot ListLinePlot ListLogLinearPlot ListLogLogPlot ListLogPlot ListPicker ListPickerBox ListPickerBoxBackground ListPickerBoxOptions ListPlay ListPlot ListPlot3D ListPointPlot3D ListPolarPlot ListQ ListStreamDensityPlot ListStreamPlot ListSurfacePlot3D ListVectorDensityPlot ListVectorPlot ListVectorPlot3D ListZTransform Literal LiteralSearch LocalClusteringCoefficient LocalizeVariables LocationEquivalenceTest LocationTest Locator LocatorAutoCreate LocatorBox LocatorBoxOptions LocatorCentering LocatorPane LocatorPaneBox LocatorPaneBoxOptions LocatorRegion Locked Log Log10 Log2 LogBarnesG LogGamma LogGammaDistribution LogicalExpand LogIntegral LogisticDistribution LogitModelFit LogLikelihood LogLinearPlot LogLogisticDistribution LogLogPlot LogMultinormalDistribution LogNormalDistribution LogPlot LogRankTest LogSeriesDistribution LongEqual Longest LongestAscendingSequence LongestCommonSequence LongestCommonSequencePositions LongestCommonSubsequence LongestCommonSubsequencePositions LongestMatch LongForm Longitude LongLeftArrow LongLeftRightArrow LongRightArrow Loopback LoopFreeGraphQ LowerCaseQ LowerLeftArrow LowerRightArrow LowerTriangularize LowpassFilter LQEstimatorGains LQGRegulator LQOutputRegulatorGains LQRegulatorGains LUBackSubstitution LucasL LuccioSamiComponents LUDecomposition LyapunovSolve LyonsGroupLy MachineID MachineName MachineNumberQ MachinePrecision MacintoshSystemPageSetup Magenta Magnification Magnify MainSolve MaintainDynamicCaches Majority MakeBoxes MakeExpression MakeRules MangoldtLambda ManhattanDistance Manipulate Manipulator MannWhitneyTest MantissaExponent Manual Map MapAll MapAt MapIndexed MAProcess MapThread MarcumQ MardiaCombinedTest MardiaKurtosisTest MardiaSkewnessTest MarginalDistribution MarkovProcessProperties Masking MatchingDissimilarity MatchLocalNameQ MatchLocalNames MatchQ Material MathematicaNotation MathieuC MathieuCharacteristicA MathieuCharacteristicB MathieuCharacteristicExponent MathieuCPrime MathieuGroupM11 MathieuGroupM12 MathieuGroupM22 MathieuGroupM23 MathieuGroupM24 MathieuS MathieuSPrime MathMLForm MathMLText Matrices MatrixExp MatrixForm MatrixFunction MatrixLog MatrixPlot MatrixPower MatrixQ MatrixRank Max MaxBend MaxDetect MaxExtraBandwidths MaxExtraConditions MaxFeatures MaxFilter Maximize MaxIterations MaxMemoryUsed MaxMixtureKernels MaxPlotPoints MaxPoints MaxRecursion MaxStableDistribution MaxStepFraction MaxSteps MaxStepSize MaxValue MaxwellDistribution McLaughlinGroupMcL Mean MeanClusteringCoefficient MeanDegreeConnectivity MeanDeviation MeanFilter MeanGraphDistance MeanNeighborDegree MeanShift MeanShiftFilter Median MedianDeviation MedianFilter Medium MeijerG MeixnerDistribution MemberQ MemoryConstrained MemoryInUse Menu MenuAppearance MenuCommandKey MenuEvaluator MenuItem MenuPacket MenuSortingValue MenuStyle MenuView MergeDifferences Mesh MeshFunctions MeshRange MeshShading MeshStyle Message MessageDialog MessageList MessageName MessageOptions MessagePacket Messages MessagesNotebook MetaCharacters MetaInformation Method MethodOptions MexicanHatWavelet MeyerWavelet Min MinDetect MinFilter MinimalPolynomial MinimalStateSpaceModel Minimize Minors MinRecursion MinSize MinStableDistribution Minus MinusPlus MinValue Missing MissingDataMethod MittagLefflerE MixedRadix MixedRadixQuantity MixtureDistribution Mod Modal Mode Modular ModularLambda Module Modulus MoebiusMu Moment Momentary MomentConvert MomentEvaluate MomentGeneratingFunction Monday Monitor MonomialList MonomialOrder MonsterGroupM MorletWavelet MorphologicalBinarize MorphologicalBranchPoints MorphologicalComponents MorphologicalEulerNumber MorphologicalGraph MorphologicalPerimeter MorphologicalTransform Most MouseAnnotation MouseAppearance MouseAppearanceTag MouseButtons Mouseover MousePointerNote MousePosition MovingAverage MovingMedian MoyalDistribution MultiedgeStyle MultilaunchWarning MultiLetterItalics MultiLetterStyle MultilineFunction Multinomial MultinomialDistribution MultinormalDistribution MultiplicativeOrder Multiplicity Multiselection MultivariateHypergeometricDistribution MultivariatePoissonDistribution MultivariateTDistribution N NakagamiDistribution NameQ Names NamespaceBox Nand NArgMax NArgMin NBernoulliB NCache NDSolve NDSolveValue Nearest NearestFunction NeedCurrentFrontEndPackagePacket NeedCurrentFrontEndSymbolsPacket NeedlemanWunschSimilarity Needs Negative NegativeBinomialDistribution NegativeMultinomialDistribution NeighborhoodGraph Nest NestedGreaterGreater NestedLessLess NestedScriptRules NestList NestWhile NestWhileList NevilleThetaC NevilleThetaD NevilleThetaN NevilleThetaS NewPrimitiveStyle NExpectation Next NextPrime NHoldAll NHoldFirst NHoldRest NicholsGridLines NicholsPlot NIntegrate NMaximize NMaxValue NMinimize NMinValue NominalVariables NonAssociative NoncentralBetaDistribution NoncentralChiSquareDistribution NoncentralFRatioDistribution NoncentralStudentTDistribution NonCommutativeMultiply NonConstants None NonlinearModelFit NonlocalMeansFilter NonNegative NonPositive Nor NorlundB Norm Normal NormalDistribution NormalGrouping Normalize NormalizedSquaredEuclideanDistance NormalsFunction NormFunction Not NotCongruent NotCupCap NotDoubleVerticalBar Notebook NotebookApply NotebookAutoSave NotebookClose NotebookConvertSettings NotebookCreate NotebookCreateReturnObject NotebookDefault NotebookDelete NotebookDirectory NotebookDynamicExpression NotebookEvaluate NotebookEventActions NotebookFileName NotebookFind NotebookFindReturnObject NotebookGet NotebookGetLayoutInformationPacket NotebookGetMisspellingsPacket NotebookInformation NotebookInterfaceObject NotebookLocate NotebookObject NotebookOpen NotebookOpenReturnObject NotebookPath NotebookPrint NotebookPut NotebookPutReturnObject NotebookRead NotebookResetGeneratedCells Notebooks NotebookSave NotebookSaveAs NotebookSelection NotebookSetupLayoutInformationPacket NotebooksMenu NotebookWrite NotElement NotEqualTilde NotExists NotGreater NotGreaterEqual NotGreaterFullEqual NotGreaterGreater NotGreaterLess NotGreaterSlantEqual NotGreaterTilde NotHumpDownHump NotHumpEqual NotLeftTriangle NotLeftTriangleBar NotLeftTriangleEqual NotLess NotLessEqual NotLessFullEqual NotLessGreater NotLessLess NotLessSlantEqual NotLessTilde NotNestedGreaterGreater NotNestedLessLess NotPrecedes NotPrecedesEqual NotPrecedesSlantEqual NotPrecedesTilde NotReverseElement NotRightTriangle NotRightTriangleBar NotRightTriangleEqual NotSquareSubset NotSquareSubsetEqual NotSquareSuperset NotSquareSupersetEqual NotSubset NotSubsetEqual NotSucceeds NotSucceedsEqual NotSucceedsSlantEqual NotSucceedsTilde NotSuperset NotSupersetEqual NotTilde NotTildeEqual NotTildeFullEqual NotTildeTilde NotVerticalBar NProbability NProduct NProductFactors NRoots NSolve NSum NSumTerms Null NullRecords NullSpace NullWords Number NumberFieldClassNumber NumberFieldDiscriminant NumberFieldFundamentalUnits NumberFieldIntegralBasis NumberFieldNormRepresentatives NumberFieldRegulator NumberFieldRootsOfUnity NumberFieldSignature NumberForm NumberFormat NumberMarks NumberMultiplier NumberPadding NumberPoint NumberQ NumberSeparator NumberSigns NumberString Numerator NumericFunction NumericQ NuttallWindow NValues NyquistGridLines NyquistPlot O ObservabilityGramian ObservabilityMatrix ObservableDecomposition ObservableModelQ OddQ Off Offset OLEData On ONanGroupON OneIdentity Opacity Open OpenAppend Opener OpenerBox OpenerBoxOptions OpenerView OpenFunctionInspectorPacket Opening OpenRead OpenSpecialOptions OpenTemporary OpenWrite Operate OperatingSystem OptimumFlowData Optional OptionInspectorSettings OptionQ Options OptionsPacket OptionsPattern OptionValue OptionValueBox OptionValueBoxOptions Or Orange Order OrderDistribution OrderedQ Ordering Orderless OrnsteinUhlenbeckProcess Orthogonalize Out Outer OutputAutoOverwrite OutputControllabilityMatrix OutputControllableModelQ OutputForm OutputFormData OutputGrouping OutputMathEditExpression OutputNamePacket OutputResponse OutputSizeLimit OutputStream Over OverBar OverDot Overflow OverHat Overlaps Overlay OverlayBox OverlayBoxOptions Overscript OverscriptBox OverscriptBoxOptions OverTilde OverVector OwenT OwnValues PackingMethod PaddedForm Padding PadeApproximant PadLeft PadRight PageBreakAbove PageBreakBelow PageBreakWithin PageFooterLines PageFooters PageHeaderLines PageHeaders PageHeight PageRankCentrality PageWidth PairedBarChart PairedHistogram PairedSmoothHistogram PairedTTest PairedZTest PaletteNotebook PalettePath Pane PaneBox PaneBoxOptions Panel PanelBox PanelBoxOptions Paneled PaneSelector PaneSelectorBox PaneSelectorBoxOptions PaperWidth ParabolicCylinderD ParagraphIndent ParagraphSpacing ParallelArray ParallelCombine ParallelDo ParallelEvaluate Parallelization Parallelize ParallelMap ParallelNeeds ParallelProduct ParallelSubmit ParallelSum ParallelTable ParallelTry Parameter ParameterEstimator ParameterMixtureDistribution ParameterVariables ParametricFunction ParametricNDSolve ParametricNDSolveValue ParametricPlot ParametricPlot3D ParentConnect ParentDirectory ParentForm Parenthesize ParentList ParetoDistribution Part PartialCorrelationFunction PartialD ParticleData Partition PartitionsP PartitionsQ ParzenWindow PascalDistribution PassEventsDown PassEventsUp Paste PasteBoxFormInlineCells PasteButton Path PathGraph PathGraphQ Pattern PatternSequence PatternTest PauliMatrix PaulWavelet Pause PausedTime PDF PearsonChiSquareTest PearsonCorrelationTest PearsonDistribution PerformanceGoal PeriodicInterpolation Periodogram PeriodogramArray PermutationCycles PermutationCyclesQ PermutationGroup PermutationLength PermutationList PermutationListQ PermutationMax PermutationMin PermutationOrder PermutationPower PermutationProduct PermutationReplace Permutations PermutationSupport Permute PeronaMalikFilter Perpendicular PERTDistribution PetersenGraph PhaseMargins Pi Pick PIDData PIDDerivativeFilter PIDFeedforward PIDTune Piecewise PiecewiseExpand PieChart PieChart3D PillaiTrace PillaiTraceTest Pink Pivoting PixelConstrained PixelValue PixelValuePositions Placed Placeholder PlaceholderReplace Plain PlanarGraphQ Play PlayRange Plot Plot3D Plot3Matrix PlotDivision PlotJoined PlotLabel PlotLayout PlotLegends PlotMarkers PlotPoints PlotRange PlotRangeClipping PlotRangePadding PlotRegion PlotStyle Plus PlusMinus Pochhammer PodStates PodWidth Point Point3DBox PointBox PointFigureChart PointForm PointLegend PointSize PoissonConsulDistribution PoissonDistribution PoissonProcess PoissonWindow PolarAxes PolarAxesOrigin PolarGridLines PolarPlot PolarTicks PoleZeroMarkers PolyaAeppliDistribution PolyGamma Polygon Polygon3DBox Polygon3DBoxOptions PolygonBox PolygonBoxOptions PolygonHoleScale PolygonIntersections PolygonScale PolyhedronData PolyLog PolynomialExtendedGCD PolynomialForm PolynomialGCD PolynomialLCM PolynomialMod PolynomialQ PolynomialQuotient PolynomialQuotientRemainder PolynomialReduce PolynomialRemainder Polynomials PopupMenu PopupMenuBox PopupMenuBoxOptions PopupView PopupWindow Position Positive PositiveDefiniteMatrixQ PossibleZeroQ Postfix PostScript Power PowerDistribution PowerExpand PowerMod PowerModList PowerSpectralDensity PowersRepresentations PowerSymmetricPolynomial Precedence PrecedenceForm Precedes PrecedesEqual PrecedesSlantEqual PrecedesTilde Precision PrecisionGoal PreDecrement PredictionRoot PreemptProtect PreferencesPath Prefix PreIncrement Prepend PrependTo PreserveImageOptions Previous PriceGraphDistribution PrimaryPlaceholder Prime PrimeNu PrimeOmega PrimePi PrimePowerQ PrimeQ Primes PrimeZetaP PrimitiveRoot PrincipalComponents PrincipalValue Print PrintAction PrintForm PrintingCopies PrintingOptions PrintingPageRange PrintingStartingPageNumber PrintingStyleEnvironment PrintPrecision PrintTemporary Prism PrismBox PrismBoxOptions PrivateCellOptions PrivateEvaluationOptions PrivateFontOptions PrivateFrontEndOptions PrivateNotebookOptions PrivatePaths Probability ProbabilityDistribution ProbabilityPlot ProbabilityPr ProbabilityScalePlot ProbitModelFit ProcessEstimator ProcessParameterAssumptions ProcessParameterQ ProcessStateDomain ProcessTimeDomain Product ProductDistribution ProductLog ProgressIndicator ProgressIndicatorBox ProgressIndicatorBoxOptions Projection Prolog PromptForm Properties Property PropertyList PropertyValue Proportion Proportional Protect Protected ProteinData Pruning PseudoInverse Purple Put PutAppend Pyramid PyramidBox PyramidBoxOptions QBinomial QFactorial QGamma QHypergeometricPFQ QPochhammer QPolyGamma QRDecomposition QuadraticIrrationalQ Quantile QuantilePlot Quantity QuantityForm QuantityMagnitude QuantityQ QuantityUnit Quartics QuartileDeviation Quartiles QuartileSkewness QueueingNetworkProcess QueueingProcess QueueProperties Quiet Quit Quotient QuotientRemainder RadialityCentrality RadicalBox RadicalBoxOptions RadioButton RadioButtonBar RadioButtonBox RadioButtonBoxOptions Radon RamanujanTau RamanujanTauL RamanujanTauTheta RamanujanTauZ Random RandomChoice RandomComplex RandomFunction RandomGraph RandomImage RandomInteger RandomPermutation RandomPrime RandomReal RandomSample RandomSeed RandomVariate RandomWalkProcess Range RangeFilter RangeSpecification RankedMax RankedMin Raster Raster3D Raster3DBox Raster3DBoxOptions RasterArray RasterBox RasterBoxOptions Rasterize RasterSize Rational RationalFunctions Rationalize Rationals Ratios Raw RawArray RawBoxes RawData RawMedium RayleighDistribution Re Read ReadList ReadProtected Real RealBlockDiagonalForm RealDigits RealExponent Reals Reap Record RecordLists RecordSeparators Rectangle RectangleBox RectangleBoxOptions RectangleChart RectangleChart3D RecurrenceFilter RecurrenceTable RecurringDigitsForm Red Reduce RefBox ReferenceLineStyle ReferenceMarkers ReferenceMarkerStyle Refine ReflectionMatrix ReflectionTransform Refresh RefreshRate RegionBinarize RegionFunction RegionPlot RegionPlot3D RegularExpression Regularization Reinstall Release ReleaseHold ReliabilityDistribution ReliefImage ReliefPlot Remove RemoveAlphaChannel RemoveAsynchronousTask Removed RemoveInputStreamMethod RemoveOutputStreamMethod RemoveProperty RemoveScheduledTask RenameDirectory RenameFile RenderAll RenderingOptions RenewalProcess RenkoChart Repeated RepeatedNull RepeatedString Replace ReplaceAll ReplaceHeldPart ReplaceImageValue ReplaceList ReplacePart ReplacePixelValue ReplaceRepeated Resampling Rescale RescalingTransform ResetDirectory ResetMenusPacket ResetScheduledTask Residue Resolve Rest Resultant ResumePacket Return ReturnExpressionPacket ReturnInputFormPacket ReturnPacket ReturnTextPacket Reverse ReverseBiorthogonalSplineWavelet ReverseElement ReverseEquilibrium ReverseGraph ReverseUpEquilibrium RevolutionAxis RevolutionPlot3D RGBColor RiccatiSolve RiceDistribution RidgeFilter RiemannR RiemannSiegelTheta RiemannSiegelZ Riffle Right RightArrow RightArrowBar RightArrowLeftArrow RightCosetRepresentative RightDownTeeVector RightDownVector RightDownVectorBar RightTee RightTeeArrow RightTeeVector RightTriangle RightTriangleBar RightTriangleEqual RightUpDownVector RightUpTeeVector RightUpVector RightUpVectorBar RightVector RightVectorBar RiskAchievementImportance RiskReductionImportance RogersTanimotoDissimilarity Root RootApproximant RootIntervals RootLocusPlot RootMeanSquare RootOfUnityQ RootReduce Roots RootSum Rotate RotateLabel RotateLeft RotateRight RotationAction RotationBox RotationBoxOptions RotationMatrix RotationTransform Round RoundImplies RoundingRadius Row RowAlignments RowBackgrounds RowBox RowHeights RowLines RowMinHeight RowReduce RowsEqual RowSpacings RSolve RudvalisGroupRu Rule RuleCondition RuleDelayed RuleForm RulerUnits Run RunScheduledTask RunThrough RuntimeAttributes RuntimeOptions RussellRaoDissimilarity SameQ SameTest SampleDepth SampledSoundFunction SampledSoundList SampleRate SamplingPeriod SARIMAProcess SARMAProcess SatisfiabilityCount SatisfiabilityInstances SatisfiableQ Saturday Save Saveable SaveAutoDelete SaveDefinitions SawtoothWave Scale Scaled ScaleDivisions ScaledMousePosition ScaleOrigin ScalePadding ScaleRanges ScaleRangeStyle ScalingFunctions ScalingMatrix ScalingTransform Scan ScheduledTaskActiveQ ScheduledTaskData ScheduledTaskObject ScheduledTasks SchurDecomposition ScientificForm ScreenRectangle ScreenStyleEnvironment ScriptBaselineShifts ScriptLevel ScriptMinSize ScriptRules ScriptSizeMultipliers Scrollbars ScrollingOptions ScrollPosition Sec Sech SechDistribution SectionGrouping SectorChart SectorChart3D SectorOrigin SectorSpacing SeedRandom Select Selectable SelectComponents SelectedCells SelectedNotebook Selection SelectionAnimate SelectionCell SelectionCellCreateCell SelectionCellDefaultStyle SelectionCellParentStyle SelectionCreateCell SelectionDebuggerTag SelectionDuplicateCell SelectionEvaluate SelectionEvaluateCreateCell SelectionMove SelectionPlaceholder SelectionSetStyle SelectWithContents SelfLoops SelfLoopStyle SemialgebraicComponentInstances SendMail Sequence SequenceAlignment SequenceForm SequenceHold SequenceLimit Series SeriesCoefficient SeriesData SessionTime Set SetAccuracy SetAlphaChannel SetAttributes Setbacks SetBoxFormNamesPacket SetDelayed SetDirectory SetEnvironment SetEvaluationNotebook SetFileDate SetFileLoadingContext SetNotebookStatusLine SetOptions SetOptionsPacket SetPrecision SetProperty SetSelectedNotebook SetSharedFunction SetSharedVariable SetSpeechParametersPacket SetStreamPosition SetSystemOptions Setter SetterBar SetterBox SetterBoxOptions Setting SetValue Shading Shallow ShannonWavelet ShapiroWilkTest Share Sharpen ShearingMatrix ShearingTransform ShenCastanMatrix Short ShortDownArrow Shortest ShortestMatch ShortestPathFunction ShortLeftArrow ShortRightArrow ShortUpArrow Show ShowAutoStyles ShowCellBracket ShowCellLabel ShowCellTags ShowClosedCellArea ShowContents ShowControls ShowCursorTracker ShowGroupOpenCloseIcon ShowGroupOpener ShowInvisibleCharacters ShowPageBreaks ShowPredictiveInterface ShowSelection ShowShortBoxForm ShowSpecialCharacters ShowStringCharacters ShowSyntaxStyles ShrinkingDelay ShrinkWrapBoundingBox SiegelTheta SiegelTukeyTest Sign Signature SignedRankTest SignificanceLevel SignPadding SignTest SimilarityRules SimpleGraph SimpleGraphQ Simplify Sin Sinc SinghMaddalaDistribution SingleEvaluation SingleLetterItalics SingleLetterStyle SingularValueDecomposition SingularValueList SingularValuePlot SingularValues Sinh SinhIntegral SinIntegral SixJSymbol Skeleton SkeletonTransform SkellamDistribution Skewness SkewNormalDistribution Skip SliceDistribution Slider Slider2D Slider2DBox Slider2DBoxOptions SliderBox SliderBoxOptions SlideView Slot SlotSequence Small SmallCircle Smaller SmithDelayCompensator SmithWatermanSimilarity SmoothDensityHistogram SmoothHistogram SmoothHistogram3D SmoothKernelDistribution SocialMediaData Socket SokalSneathDissimilarity Solve SolveAlways SolveDelayed Sort SortBy Sound SoundAndGraphics SoundNote SoundVolume Sow Space SpaceForm Spacer Spacings Span SpanAdjustments SpanCharacterRounding SpanFromAbove SpanFromBoth SpanFromLeft SpanLineThickness SpanMaxSize SpanMinSize SpanningCharacters SpanSymmetric SparseArray SpatialGraphDistribution Speak SpeakTextPacket SpearmanRankTest SpearmanRho Spectrogram SpectrogramArray Specularity SpellingCorrection SpellingDictionaries SpellingDictionariesPath SpellingOptions SpellingSuggestionsPacket Sphere SphereBox SphericalBesselJ SphericalBesselY SphericalHankelH1 SphericalHankelH2 SphericalHarmonicY SphericalPlot3D SphericalRegion SpheroidalEigenvalue SpheroidalJoiningFactor SpheroidalPS SpheroidalPSPrime SpheroidalQS SpheroidalQSPrime SpheroidalRadialFactor SpheroidalS1 SpheroidalS1Prime SpheroidalS2 SpheroidalS2Prime Splice SplicedDistribution SplineClosed SplineDegree SplineKnots SplineWeights Split SplitBy SpokenString Sqrt SqrtBox SqrtBoxOptions Square SquaredEuclideanDistance SquareFreeQ SquareIntersection SquaresR SquareSubset SquareSubsetEqual SquareSuperset SquareSupersetEqual SquareUnion SquareWave StabilityMargins StabilityMarginsStyle StableDistribution Stack StackBegin StackComplete StackInhibit StandardDeviation StandardDeviationFilter StandardForm Standardize StandbyDistribution Star StarGraph StartAsynchronousTask StartingStepSize StartOfLine StartOfString StartScheduledTask StartupSound StateDimensions StateFeedbackGains StateOutputEstimator StateResponse StateSpaceModel StateSpaceRealization StateSpaceTransform StationaryDistribution StationaryWaveletPacketTransform StationaryWaveletTransform StatusArea StatusCentrality StepMonitor StieltjesGamma StirlingS1 StirlingS2 StopAsynchronousTask StopScheduledTask StrataVariables StratonovichProcess StreamColorFunction StreamColorFunctionScaling StreamDensityPlot StreamPlot StreamPoints StreamPosition Streams StreamScale StreamStyle String StringBreak StringByteCount StringCases StringCount StringDrop StringExpression StringForm StringFormat StringFreeQ StringInsert StringJoin StringLength StringMatchQ StringPosition StringQ StringReplace StringReplaceList StringReplacePart StringReverse StringRotateLeft StringRotateRight StringSkeleton StringSplit StringTake StringToStream StringTrim StripBoxes StripOnInput StripWrapperBoxes StrokeForm StructuralImportance StructuredArray StructuredSelection StruveH StruveL Stub StudentTDistribution Style StyleBox StyleBoxAutoDelete StyleBoxOptions StyleData StyleDefinitions StyleForm StyleKeyMapping StyleMenuListing StyleNameDialogSettings StyleNames StylePrint StyleSheetPath Subfactorial Subgraph SubMinus SubPlus SubresultantPolynomialRemainders SubresultantPolynomials Subresultants Subscript SubscriptBox SubscriptBoxOptions Subscripted Subset SubsetEqual Subsets SubStar Subsuperscript SubsuperscriptBox SubsuperscriptBoxOptions Subtract SubtractFrom SubValues Succeeds SucceedsEqual SucceedsSlantEqual SucceedsTilde SuchThat Sum SumConvergence Sunday SuperDagger SuperMinus SuperPlus Superscript SuperscriptBox SuperscriptBoxOptions Superset SupersetEqual SuperStar Surd SurdForm SurfaceColor SurfaceGraphics SurvivalDistribution SurvivalFunction SurvivalModel SurvivalModelFit SuspendPacket SuzukiDistribution SuzukiGroupSuz SwatchLegend Switch Symbol SymbolName SymletWavelet Symmetric SymmetricGroup SymmetricMatrixQ SymmetricPolynomial SymmetricReduction Symmetrize SymmetrizedArray SymmetrizedArrayRules SymmetrizedDependentComponents SymmetrizedIndependentComponents SymmetrizedReplacePart SynchronousInitialization SynchronousUpdating Syntax SyntaxForm SyntaxInformation SyntaxLength SyntaxPacket SyntaxQ SystemDialogInput SystemException SystemHelpPath SystemInformation SystemInformationData SystemOpen SystemOptions SystemsModelDelay SystemsModelDelayApproximate SystemsModelDelete SystemsModelDimensions SystemsModelExtract SystemsModelFeedbackConnect SystemsModelLabels SystemsModelOrder SystemsModelParallelConnect SystemsModelSeriesConnect SystemsModelStateFeedbackConnect SystemStub Tab TabFilling Table TableAlignments TableDepth TableDirections TableForm TableHeadings TableSpacing TableView TableViewBox TabSpacings TabView TabViewBox TabViewBoxOptions TagBox TagBoxNote TagBoxOptions TaggingRules TagSet TagSetDelayed TagStyle TagUnset Take TakeWhile Tally Tan Tanh TargetFunctions TargetUnits TautologyQ TelegraphProcess TemplateBox TemplateBoxOptions TemplateSlotSequence TemporalData Temporary TemporaryVariable TensorContract TensorDimensions TensorExpand TensorProduct TensorQ TensorRank TensorReduce TensorSymmetry TensorTranspose TensorWedge Tetrahedron TetrahedronBox TetrahedronBoxOptions TeXForm TeXSave Text Text3DBox Text3DBoxOptions TextAlignment TextBand TextBoundingBox TextBox TextCell TextClipboardType TextData TextForm TextJustification TextLine TextPacket TextParagraph TextRecognize TextRendering TextStyle Texture TextureCoordinateFunction TextureCoordinateScaling Therefore ThermometerGauge Thick Thickness Thin Thinning ThisLink ThompsonGroupTh Thread ThreeJSymbol Threshold Through Throw Thumbnail Thursday Ticks TicksStyle Tilde TildeEqual TildeFullEqual TildeTilde TimeConstrained TimeConstraint Times TimesBy TimeSeriesForecast TimeSeriesInvertibility TimeUsed TimeValue TimeZone Timing Tiny TitleGrouping TitsGroupT ToBoxes ToCharacterCode ToColor ToContinuousTimeModel ToDate ToDiscreteTimeModel ToeplitzMatrix ToExpression ToFileName Together Toggle ToggleFalse Toggler TogglerBar TogglerBox TogglerBoxOptions ToHeldExpression ToInvertibleTimeSeries TokenWords Tolerance ToLowerCase ToNumberField TooBig Tooltip TooltipBox TooltipBoxOptions TooltipDelay TooltipStyle Top TopHatTransform TopologicalSort ToRadicals ToRules ToString Total TotalHeight TotalVariationFilter TotalWidth TouchscreenAutoZoom TouchscreenControlPlacement ToUpperCase Tr Trace TraceAbove TraceAction TraceBackward TraceDepth TraceDialog TraceForward TraceInternal TraceLevel TraceOff TraceOn TraceOriginal TracePrint TraceScan TrackedSymbols TradingChart TraditionalForm TraditionalFunctionNotation TraditionalNotation TraditionalOrder TransferFunctionCancel TransferFunctionExpand TransferFunctionFactor TransferFunctionModel TransferFunctionPoles TransferFunctionTransform TransferFunctionZeros TransformationFunction TransformationFunctions TransformationMatrix TransformedDistribution TransformedField Translate TranslationTransform TransparentColor Transpose TreeForm TreeGraph TreeGraphQ TreePlot TrendStyle TriangleWave TriangularDistribution Trig TrigExpand TrigFactor TrigFactorList Trigger TrigReduce TrigToExp TrimmedMean True TrueQ TruncatedDistribution TsallisQExponentialDistribution TsallisQGaussianDistribution TTest Tube TubeBezierCurveBox TubeBezierCurveBoxOptions TubeBox TubeBSplineCurveBox TubeBSplineCurveBoxOptions Tuesday TukeyLambdaDistribution TukeyWindow Tuples TuranGraph TuringMachine Transparent UnateQ Uncompress Undefined UnderBar Underflow Underlined Underoverscript UnderoverscriptBox UnderoverscriptBoxOptions Underscript UnderscriptBox UnderscriptBoxOptions UndirectedEdge UndirectedGraph UndirectedGraphQ UndocumentedTestFEParserPacket UndocumentedTestGetSelectionPacket Unequal Unevaluated UniformDistribution UniformGraphDistribution UniformSumDistribution Uninstall Union UnionPlus Unique UnitBox UnitConvert UnitDimensions Unitize UnitRootTest UnitSimplify UnitStep UnitTriangle UnitVector Unprotect UnsameQ UnsavedVariables Unset UnsetShared UntrackedVariables Up UpArrow UpArrowBar UpArrowDownArrow Update UpdateDynamicObjects UpdateDynamicObjectsSynchronous UpdateInterval UpDownArrow UpEquilibrium UpperCaseQ UpperLeftArrow UpperRightArrow UpperTriangularize Upsample UpSet UpSetDelayed UpTee UpTeeArrow UpValues URL URLFetch URLFetchAsynchronous URLSave URLSaveAsynchronous UseGraphicsRange Using UsingFrontEnd V2Get ValidationLength Value ValueBox ValueBoxOptions ValueForm ValueQ ValuesData Variables Variance VarianceEquivalenceTest VarianceEstimatorFunction VarianceGammaDistribution VarianceTest VectorAngle VectorColorFunction VectorColorFunctionScaling VectorDensityPlot VectorGlyphData VectorPlot VectorPlot3D VectorPoints VectorQ Vectors VectorScale VectorStyle Vee Verbatim Verbose VerboseConvertToPostScriptPacket VerifyConvergence VerifySolutions VerifyTestAssumptions Version VersionNumber VertexAdd VertexCapacity VertexColors VertexComponent VertexConnectivity VertexCoordinateRules VertexCoordinates VertexCorrelationSimilarity VertexCosineSimilarity VertexCount VertexCoverQ VertexDataCoordinates VertexDegree VertexDelete VertexDiceSimilarity VertexEccentricity VertexInComponent VertexInDegree VertexIndex VertexJaccardSimilarity VertexLabeling VertexLabels VertexLabelStyle VertexList VertexNormals VertexOutComponent VertexOutDegree VertexQ VertexRenderingFunction VertexReplace VertexShape VertexShapeFunction VertexSize VertexStyle VertexTextureCoordinates VertexWeight Vertical VerticalBar VerticalForm VerticalGauge VerticalSeparator VerticalSlider VerticalTilde ViewAngle ViewCenter ViewMatrix ViewPoint ViewPointSelectorSettings ViewPort ViewRange ViewVector ViewVertical VirtualGroupData Visible VisibleCell VoigtDistribution VonMisesDistribution WaitAll WaitAsynchronousTask WaitNext WaitUntil WakebyDistribution WalleniusHypergeometricDistribution WaringYuleDistribution WatershedComponents WatsonUSquareTest WattsStrogatzGraphDistribution WaveletBestBasis WaveletFilterCoefficients WaveletImagePlot WaveletListPlot WaveletMapIndexed WaveletMatrixPlot WaveletPhi WaveletPsi WaveletScale WaveletScalogram WaveletThreshold WeaklyConnectedComponents WeaklyConnectedGraphQ WeakStationarity WeatherData WeberE Wedge Wednesday WeibullDistribution WeierstrassHalfPeriods WeierstrassInvariants WeierstrassP WeierstrassPPrime WeierstrassSigma WeierstrassZeta WeightedAdjacencyGraph WeightedAdjacencyMatrix WeightedData WeightedGraphQ Weights WelchWindow WheelGraph WhenEvent Which While White Whitespace WhitespaceCharacter WhittakerM WhittakerW WienerFilter WienerProcess WignerD WignerSemicircleDistribution WilksW WilksWTest WindowClickSelect WindowElements WindowFloating WindowFrame WindowFrameElements WindowMargins WindowMovable WindowOpacity WindowSelected WindowSize WindowStatusArea WindowTitle WindowToolbars WindowWidth With WolframAlpha WolframAlphaDate WolframAlphaQuantity WolframAlphaResult Word WordBoundary WordCharacter WordData WordSearch WordSeparators WorkingPrecision Write WriteString Wronskian XMLElement XMLObject Xnor Xor Yellow YuleDissimilarity ZernikeR ZeroSymmetric ZeroTest ZeroWidthTimes Zeta ZetaZero ZipfDistribution ZTest ZTransform $Aborted $ActivationGroupID $ActivationKey $ActivationUserRegistered $AddOnsDirectory $AssertFunction $Assumptions $AsynchronousTask $BaseDirectory $BatchInput $BatchOutput $BoxForms $ByteOrdering $Canceled $CharacterEncoding $CharacterEncodings $CommandLine $CompilationTarget $ConditionHold $ConfiguredKernels $Context $ContextPath $ControlActiveSetting $CreationDate $CurrentLink $DateStringFormat $DefaultFont $DefaultFrontEnd $DefaultImagingDevice $DefaultPath $Display $DisplayFunction $DistributedContexts $DynamicEvaluation $Echo $Epilog $ExportFormats $Failed $FinancialDataSource $FormatType $FrontEnd $FrontEndSession $GeoLocation $HistoryLength $HomeDirectory $HTTPCookies $IgnoreEOF $ImagingDevices $ImportFormats $InitialDirectory $Input $InputFileName $InputStreamMethods $Inspector $InstallationDate $InstallationDirectory $InterfaceEnvironment $IterationLimit $KernelCount $KernelID $Language $LaunchDirectory $LibraryPath $LicenseExpirationDate $LicenseID $LicenseProcesses $LicenseServer $LicenseSubprocesses $LicenseType $Line $Linked $LinkSupported $LoadedFiles $MachineAddresses $MachineDomain $MachineDomains $MachineEpsilon $MachineID $MachineName $MachinePrecision $MachineType $MaxExtraPrecision $MaxLicenseProcesses $MaxLicenseSubprocesses $MaxMachineNumber $MaxNumber $MaxPiecewiseCases $MaxPrecision $MaxRootDegree $MessageGroups $MessageList $MessagePrePrint $Messages $MinMachineNumber $MinNumber $MinorReleaseNumber $MinPrecision $ModuleNumber $NetworkLicense $NewMessage $NewSymbol $Notebooks $NumberMarks $Off $OperatingSystem $Output $OutputForms $OutputSizeLimit $OutputStreamMethods $Packages $ParentLink $ParentProcessID $PasswordFile $PatchLevelID $Path $PathnameSeparator $PerformanceGoal $PipeSupported $Post $Pre $PreferencesDirectory $PrePrint $PreRead $PrintForms $PrintLiteral $ProcessID $ProcessorCount $ProcessorType $ProductInformation $ProgramName $RandomState $RecursionLimit $ReleaseNumber $RootDirectory $ScheduledTask $ScriptCommandLine $SessionID $SetParentLink $SharedFunctions $SharedVariables $SoundDisplay $SoundDisplayFunction $SuppressInputFormHeads $SynchronousEvaluation $SyntaxHandler $System $SystemCharacterEncoding $SystemID $SystemWordLength $TemporaryDirectory $TemporaryPrefix $TextStyle $TimedOut $TimeUnit $TimeZone $TopDirectory $TraceOff $TraceOn $TracePattern $TracePostAction $TracePreAction $Urgent $UserAddOnsDirectory $UserBaseDirectory $UserDocumentsDirectory $UserName $Version $VersionNumber",c:[{cN:"comment",b:/\(\*/,e:/\*\)/},e.ASM,e.QSM,e.CNM,{cN:"list",b:/\{/,e:/\}/,i:/:/}]} -});hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},{cN:"comment",b:"\\(\\*",e:"\\*\\)"},{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"attribute",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}});hljs.registerLanguage("dart",function(e){var t={cN:"subst",b:"\\$\\{",e:"}",k:"true false null this is new super"},r={cN:"string",v:[{b:"r'''",e:"'''"},{b:'r"""',e:'"""'},{b:"r'",e:"'",i:"\\n"},{b:'r"',e:'"',i:"\\n"},{b:"'''",e:"'''",c:[e.BE,t]},{b:'"""',e:'"""',c:[e.BE,t]},{b:"'",e:"'",i:"\\n",c:[e.BE,t]},{b:'"',e:'"',i:"\\n",c:[e.BE,t]}]};t.c=[e.CNM,r];var n={keyword:"assert break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch this throw true try var void while with",literal:"abstract as dynamic export external factory get implements import library operator part set static typedef",built_in:"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"};return{k:n,c:[r,{cN:"dartdoc",b:"/\\*\\*",e:"\\*/",sL:"markdown",subLanguageMode:"continuous"},{cN:"dartdoc",b:"///",e:"$",sL:"markdown",subLanguageMode:"continuous"},e.CLCM,e.CBCM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"annotation",b:"@[A-Za-z]+"},{b:"=>"}]}});hljs.registerLanguage("scilab",function(e){var n=[e.CNM,{cN:"string",b:"'|\"",e:"'|\"",c:[e.BE,{b:"''"}]}];return{aliases:["sci"],k:{keyword:"abort break case clear catch continue do elseif else endfunction end for functionglobal if pause return resume select try then while%f %F %t %T %pi %eps %inf %nan %e %i %z %s",built_in:"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp errorexec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isemptyisinfisnan isvector lasterror length load linspace list listfiles log10 log2 logmax min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand realround sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tantype typename warning zeros matrix"},i:'("|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function endfunction",e:"$",k:"function endfunction|10",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:"",r:0},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",r:0,c:n},{cN:"comment",b:"//",e:"$"}].concat(n)}});hljs.registerLanguage("tex",function(){var c={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"},e={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"},m={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:!0,c:[c,e,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:!0}],r:10},c,e,m,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[c,e,m],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[c,e,m],r:0},{cN:"comment",b:"%",e:"$",r:0}]}});hljs.registerLanguage("ruleslanguage",function(T){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[T.CLCM,T.CBCM,T.ASM,T.QSM,T.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}});hljs.registerLanguage("vbscript",function(e){return{aliases:["vbs"],cI:!0,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),{cN:"comment",b:/'/,e:/$/,r:0},e.CNM]}});hljs.registerLanguage("vhdl",function(e){return{cI:!0,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[e.CBCM,{cN:"comment",b:"--",e:"$"},e.QSM,e.CNM,{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[e.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[e.BE]}]}});hljs.registerLanguage("http",function(){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:!0}}]}});hljs.registerLanguage("oxygene",function(e){var r="abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained",t={cN:"comment",b:"{",e:"}",r:0},a={cN:"comment",b:"\\(\\*",e:"\\*\\)",r:10},n={cN:"string",b:"'",e:"'",c:[{b:"''"}]},o={cN:"string",b:"(#\\d+)+"},c={cN:"function",bK:"function constructor destructor procedure method",e:"[:;]",k:"function constructor|10 destructor|10 procedure|10 method|10",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",k:r,c:[n,o]},t,a]};return{cI:!0,k:r,i:'("|\\$[G-Zg-z]|\\/\\*||->)',c:[t,a,e.CLCM,n,o,e.NM,c,{cN:"class",b:"=\\bclass\\b",e:"end;",k:r,c:[n,o,t,a,e.CLCM,c]}]}});hljs.registerLanguage("puppet",function(e){var s="augeas computer cron exec file filebucket host interface k5login macauthorization mailalias maillist mcx mount nagios_command nagios_contact nagios_contactgroup nagios_host nagios_hostdependency nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service firewall nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo nagios_servicegroup nagios_timeperiod notify package resources router schedule scheduled_task selboolean selmodule service ssh_authorized_key sshkey stage tidy user vlan yumrepo zfs zone zpool",r="alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",a={keyword:"and case class default define else elsif false if in import enherits node or true undef unless main settings $string "+s,literal:r,built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},i={cN:"comment",b:"#",e:"$"},o={cN:"string",c:[e.BE],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},n=[o,i,{cN:"keyword",bK:"class",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"(::)?[A-Za-z_]\\w*(::\\w+)*"}),i,o]},{cN:"keyword",b:"([a-zA-Z_(::)]+ *\\{)",c:[o,i],r:0},{cN:"keyword",b:"(\\}|\\{)",r:0},{cN:"function",b:"[a-zA-Z_]+\\s*=>"},{cN:"constant",b:"(::)?(\\b[A-Z][a-z_]*(::)?)+",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0}];return{aliases:["pp"],k:a,c:n}});hljs.registerLanguage("gcode",function(e){var N="[A-Z_][A-Z0-9_.]*",c="\\%",i={literal:"",built_in:"",keyword:"IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR"},r={cN:"preprocessor",b:"([O])([0-9]+)"},t=[e.CLCM,{cN:"comment",b:/\(/,e:/\)/,c:[e.PWM]},e.CBCM,e.inherit(e.CNM,{b:"([-+]?([0-9]*\\.?[0-9]+\\.?))|"+e.CNR}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"keyword",b:"([G])([0-9]+\\.?[0-9]?)"},{cN:"title",b:"([M])([0-9]+\\.?[0-9]?)"},{cN:"title",b:"(VC|VS|#)",e:"(\\d+)"},{cN:"title",b:"(VZOFX|VZOFY|VZOFZ)"},{cN:"built_in",b:"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)",e:"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{cN:"label",v:[{b:"N",e:"\\d+",i:"\\W"}]}];return{aliases:["nc"],cI:!0,l:N,k:i,c:[{cN:"preprocessor",b:c},r].concat(t)}});hljs.registerLanguage("rust",function(e){var t=e.inherit(e.CBCM);return t.c.push("self"),{aliases:["rs"],k:{keyword:"alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self sizeof static struct super trait true type typeof unsafe unsized use virtual while yield int i8 i16 i32 i64 uint u8 u32 u64 float f32 f64 str char bool",built_in:"assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln!"},l:e.IR+"!?",i:""}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",a={cN:"function",b:c+"\\(",rB:!0,eE:!0,e:"\\("};return{cI:!0,i:"[=/|']",c:[e.CBCM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[a,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:c,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[e.CBCM,{cN:"rule",b:"[^\\s]",rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{cN:"value",eW:!0,eE:!0,c:[a,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}});hljs.registerLanguage("protobuf",function(e){return{k:{keyword:"package import option optional required repeated group",built_in:"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes",literal:"true false"},c:[e.QSM,e.NM,e.CLCM,{cN:"class",bK:"message enum service",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"function",bK:"rpc",e:/;/,eE:!0,k:"rpc returns"},{cN:"constant",b:/^\s*[A-Z_]+/,e:/\s*=/,eE:!0}]}});hljs.registerLanguage("swift",function(e){var t={keyword:"class deinit enum extension func import init let protocol static struct subscript typealias var break case continue default do else fallthrough if in for return switch where while as dynamicType is new super self Self Type __COLUMN__ __FILE__ __FUNCTION__ __LINE__ associativity didSet get infix inout left mutating none nonmutating operator override postfix precedence prefix right set unowned unowned safe unsafe weak willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue assert bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal false filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced join lexicographicalCompare map max maxElement min minElement nil numericCast partition posix print println quickSort reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith strideof strideofValue swap swift toString transcode true underestimateCount unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafePointers withVaList"},i={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM,"self"]},r={cN:"subst",b:/\\\(/,e:"\\)",k:t,c:[]},s={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0},o=e.inherit(e.QSM,{c:[r,e.BE]});return r.c=[s],{k:t,c:[o,e.CLCM,n,i,s,{cN:"func",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/,i:/\(/}),{cN:"generics",b:/\/,i:/\>/},{cN:"params",b:/\(/,e:/\)/,k:t,c:["self",s,o,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",k:"struct protocol class extension enum",b:"(struct|protocol|class(?! (func|var))|extension|enum)",e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/})]},{cN:"preprocessor",b:"(@assignment|@class_protocol|@exported|@final|@lazy|@noreturn|@NSCopying|@NSManaged|@objc|@optional|@required|@auto_closure|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix)"}]}});hljs.registerLanguage("vim",function(e){return{l:/[!#@\w]+/,k:{keyword:"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw d|0 delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu g|0 go gr grepa gu gv ha h|0 helpf helpg helpt hi hid his i|0 ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs n|0 new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf q|0 quita qa r|0 rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv s|0 sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync t|0 tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up v|0 ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank",built_in:"abs acos add and append argc argidx argv asin atan atan2 browse browsedir bufexists buflisted bufloaded bufname bufnr bufwinnr byte2line byteidx call ceil changenr char2nr cindent clearmatches col complete complete_add complete_check confirm copy cos cosh count cscope_connection cursor deepcopy delete did_filetype diff_filler diff_hlID empty escape eval eventhandler executable exists exp expand extend feedkeys filereadable filewritable filter finddir findfile float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreground function garbagecollect get getbufline getbufvar getchar getcharmod getcmdline getcmdpos getcmdtype getcwd getfontname getfperm getfsize getftime getftype getline getloclist getmatches getpid getpos getqflist getreg getregtype gettabvar gettabwinvar getwinposx getwinposy getwinvar glob globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlexists hlID hostname iconv indent index input inputdialog inputlist inputrestore inputsave inputsecret insert invert isdirectory islocked items join keys len libcall libcallnr line line2byte lispindent localtime log log10 luaeval map maparg mapcheck match matchadd matcharg matchdelete matchend matchlist matchstr max min mkdir mode mzeval nextnonblank nr2char or pathshorten pow prevnonblank printf pumvisible py3eval pyeval range readfile reltime reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remove rename repeat resolve reverse round screenattr screenchar screencol screenrow search searchdecl searchpair searchpairpos searchpos server2client serverlist setbufvar setcmdpos setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar setwinvar sha256 shellescape shiftwidth simplify sin sinh sort soundfold spellbadword spellsuggest split sqrt str2float str2nr strchars strdisplaywidth strftime stridx string strlen strpart strridx strtrans strwidth submatch substitute synconcealed synID synIDattr synIDtrans synstack system tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname tolower toupper tr trunc type undofile undotree values virtcol visualmode wildmenumode winbufnr wincol winheight winline winnr winrestcmd winrestview winsaveview winwidth writefile xor"},i:/[{:]/,c:[e.NM,e.ASM,{cN:"string",b:/"((\\")|[^"\n])*("|\n)/},{cN:"variable",b:/[bwtglsav]:[\w\d_]*/},{cN:"function",bK:"function function!",e:"$",r:0,c:[e.TM,{cN:"params",b:"\\(",e:"\\)"}]}]}});hljs.registerLanguage("fix",function(){return{c:[{b:/[^\u2401\u0001]+/,e:/[\u2401\u0001]/,eE:!0,rB:!0,rE:!1,c:[{b:/([^\u2401\u0001=]+)/,e:/=([^\u2401\u0001=]+)/,rE:!0,rB:!1,cN:"attribute"},{b:/=/,e:/([\u2401\u0001])/,eE:!0,eB:!0,cN:"string"}]}],cI:!0}});hljs.registerLanguage("javascript",function(r){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",r:10,v:[{b:/^\s*('|")use strict('|")/},{b:/^\s*('|")use asm('|")/}]},r.ASM,r.QSM,r.CLCM,r.CBCM,r.CNM,{b:"("+r.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[r.CLCM,r.CBCM,r.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[r.CLCM,r.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+r.IR,r:0}]}});hljs.registerLanguage("lua",function(e){var t="\\[=*\\[",a="\\]=*\\]",r={b:t,e:a,c:["self"]},n=[{cN:"comment",b:"--(?!"+t+")",e:"$"},{cN:"comment",b:"--"+t,e:a,c:[r],r:10}];return{l:e.UIR,k:{keyword:"and break do else elseif end false for if in local nil not or repeat return then true until while",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},c:n.concat([{cN:"function",bK:"function",e:"\\)",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{cN:"params",b:"\\(",eW:!0,c:n}].concat(n)},e.CNM,e.ASM,e.QSM,{cN:"string",b:t,e:a,c:[r],r:5}])}});hljs.registerLanguage("django",function(){var e={cN:"filter",b:/\|[A-Za-z]+\:?/,k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:/"/,e:/"/},{cN:"argument",b:/'/,e:/'/}]};return{aliases:["jinja"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"comment",b:/\{%\s*comment\s*%}/,e:/\{%\s*endcomment\s*%}/},{cN:"comment",b:/\{#/,e:/#}/},{cN:"template_tag",b:/\{%/,e:/%}/,k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[e]},{cN:"variable",b:/\{\{/,e:/}}/,c:[e]}]}});hljs.registerLanguage("python",function(e){var r={cN:"prompt",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},l={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},c={cN:"params",b:/\(/,e:/\)/,c:["self",r,l,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,l,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n]/,c:[e.UTM,c]},{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("cmake",function(e){return{aliases:["cmake.in"],cI:!0,k:{keyword:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or",operator:"equal less greater strless strgreater strequal matches"},c:[{cN:"envvar",b:"\\${",e:"}"},e.HCM,e.QSM,e.NM]}}); \ No newline at end of file diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css deleted file mode 100644 index eaf26bbf7c94..000000000000 --- a/dottydoc/jvm/resources/index.css +++ /dev/null @@ -1,185 +0,0 @@ -/* Fonts -------------------------------------------------------------------- */ -@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700,600); - -/* Sidebar ------------------------------------------------------------------ */ -span.subtitle { - font-size: 12px; - line-height: 0 !important; - padding-top: 32px; -} - -ul.packages { - padding-top: 0 !important; -} - -ul.packages > li.package { - padding-bottom: 0; - padding-left: 40px; - font-size: 14px; -} - -ul.packages > li.entity { - padding: 0; - transition: 0.3s; - min-height: 36px !important; - max-height: 36px !important; -} - -ul.packages > li.entity.one { - margin-left: -36px; -} - -ul.packages > li.entity.two { - margin-left: -72px; -} - -ul.packages > li.entity:hover { - background-color: #efefef; - margin-left: 0px; -} - -li.entity > a.entity-button { - float: left; - display: inline; - background-color: green; - height: 36px; - width: 36px; - line-height: 36px; - vertical-align: middle; - text-align: center; - text-decoration: none; - color: #fff; -} - -li.entity > a.entity-name { - text-decoration: none; - font-weight: normal; - color: #757575; - padding-left: 48px; - font-size: 14px; - font-family: "Helvetica","Arial",sans-serif; - letter-spacing: 0; -} - -li.entity > a.entity-button.object { - background-color: rgb(44, 108, 141); -} - -li.entity > a.entity-button.class, -li.entity > a.entity-button.caseclass { - background-color: rgb(68, 173, 125); -} - -li.entity > a.entity-button.trait { - background-color: rgb(25, 170, 207); -} - -li.entity > a.entity-button.shadowed { - -webkit-box-shadow: inset -2px 0px 5px -3px rgba(0,0,0,0.25); - -moz-box-shadow: inset -2px 0px 5px -3px rgba(0,0,0,0.25); - box-shadow: inset -2px 0px 5px -3px rgba(0,0,0,0.25); -} - -div.search-container { - margin: 0 2em 0 40px; -} - -a.mdl-navigation__link { - padding-top: 0.2em !important; - padding-bottom: 0.2em !important; -} - -nav.related { - padding-top: 0 !important; -} - -span#docs-title { - line-height: normal; - padding-top: 2em; -} - -/* Entity ------------------------------------------------------------------- */ -main > div.page-content { - padding: 30px 60px; -} - -div.entity-title { - color: #34495e; - margin: 1.5em 0 1.5em; -} - -div.entity-title > span { - font-size: 2.0em; -} - -div.entity-title > span+span { - margin-left: 9px; -} - -div.member-definition { - font-family: "Source Code Pro", sans-serif; - font-weight: 400; - font-size: 16px; - margin: 24px 0 16px; - line-height: 24px; -} - -div.member-definition > span+span { - margin-left: 10px; -} - -div.member-definition > span.member-name, -div.member-definition > span.member-param-list span.is-implicit { - color: #458; - font-weight: 600; -} - -div.member-definition > span.member-name.implicitly-added { - color: #16A085; -} - -div.member { - min-height: 70px; -} - -div.member.member-fullcomment:hover { - cursor: pointer; -} - -div.full-comment, -div.summary-comment { - margin-left: 0; -} - -span.type-separator { - margin: 0 10px; -} - - -/* Search results ----------------------------------------------------------- */ -main#search-results { - display: none; -} - -/* -main#search-results > div#toplevel-results { - float: left; - width: 50%; -} -*/ - -main#search-results > div#toplevel-results > div.mdl-card.package-result { - margin: 20px auto; - width: 80%; -} - -main#search-results > button#close-button { - position: fixed; - top: 1em; - right: 1em; -} - -/* Helper classes ----------------------------------------------------------- */ -.no-left-margin { - margin-left: 0 !important; -} diff --git a/dottydoc/jvm/resources/material-icons.css b/dottydoc/jvm/resources/material-icons.css deleted file mode 100755 index 43c889d6f23d..000000000000 --- a/dottydoc/jvm/resources/material-icons.css +++ /dev/null @@ -1,38 +0,0 @@ -@font-face { - font-family: 'Material Icons'; - font-style: normal; - font-weight: 400; - src: url(MaterialIcons-Regular.eot); /* For IE6-8 */ - src: local('Material Icons'), - local('MaterialIcons-Regular'), - url(MaterialIcons-Regular.woff2) format('woff2'), - url(MaterialIcons-Regular.woff) format('woff'), - url(MaterialIcons-Regular.ttf) format('truetype'); -} - -.material-icons { - font-family: 'Material Icons'; - font-weight: normal; - font-style: normal; - font-size: 24px; /* Preferred icon size */ - display: inline-block; - width: 1em; - height: 1em; - line-height: 1; - text-transform: none; - letter-spacing: normal; - word-wrap: normal; - white-space: nowrap; - direction: ltr; - - /* Support for all WebKit browsers. */ - -webkit-font-smoothing: antialiased; - /* Support for Safari and Chrome. */ - text-rendering: optimizeLegibility; - - /* Support for Firefox. */ - -moz-osx-font-smoothing: grayscale; - - /* Support for IE. */ - font-feature-settings: 'liga'; -} diff --git a/dottydoc/jvm/resources/material.min.css b/dottydoc/jvm/resources/material.min.css deleted file mode 100644 index e750f8137205..000000000000 --- a/dottydoc/jvm/resources/material.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/** - * material-design-lite - Material Design Components in CSS, JS and HTML - * @version v1.1.3 - * @license Apache-2.0 - * @copyright 2015 Google, Inc. - * @link https://github.com/google/material-design-lite - */ -@charset "UTF-8";html{color:rgba(0,0,0,.87)}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.browserupgrade{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.hidden{display:none!important}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}@media print{*,*:before,*:after,*:first-letter{background:transparent!important;color:#000!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}a,.mdl-accordion,.mdl-button,.mdl-card,.mdl-checkbox,.mdl-dropdown-menu,.mdl-icon-toggle,.mdl-item,.mdl-radio,.mdl-slider,.mdl-switch,.mdl-tabs__tab{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:rgba(255,255,255,0)}html{width:100%;height:100%;-ms-touch-action:manipulation;touch-action:manipulation}body{width:100%;min-height:100%;margin:0}main{display:block}*[hidden]{display:none!important}html,body{font-family:"Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:20px}h1,h2,h3,h4,h5,h6,p{padding:0}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400;line-height:1.35;letter-spacing:-.02em;opacity:.54;font-size:.6em}h1{font-size:56px;line-height:1.35;letter-spacing:-.02em;margin:24px 0}h1,h2{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h2{font-size:45px;line-height:48px}h2,h3{margin:24px 0}h3{font-size:34px;line-height:40px}h3,h4{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h4{font-size:24px;line-height:32px;-moz-osx-font-smoothing:grayscale;margin:24px 0 16px}h5{font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}h5,h6{font-family:"Roboto","Helvetica","Arial",sans-serif;margin:24px 0 16px}h6{font-size:16px;letter-spacing:.04em}h6,p{font-weight:400;line-height:24px}p{font-size:14px;letter-spacing:0;margin:0 0 16px}a{color:#ff4081;font-weight:500}blockquote{font-family:"Roboto","Helvetica","Arial",sans-serif;position:relative;font-size:24px;font-weight:300;font-style:italic;line-height:1.35;letter-spacing:.08em}blockquote:before{position:absolute;left:-.5em;content:'“'}blockquote:after{content:'”';margin-left:-.05em}mark{background-color:#f4ff81}dt{font-weight:700}address{font-size:12px;line-height:1;font-style:normal}address,ul,ol{font-weight:400;letter-spacing:0}ul,ol{font-size:14px;line-height:24px}.mdl-typography--display-4,.mdl-typography--display-4-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:112px;font-weight:300;line-height:1;letter-spacing:-.04em}.mdl-typography--display-4-color-contrast{opacity:.54}.mdl-typography--display-3,.mdl-typography--display-3-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:56px;font-weight:400;line-height:1.35;letter-spacing:-.02em}.mdl-typography--display-3-color-contrast{opacity:.54}.mdl-typography--display-2,.mdl-typography--display-2-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:45px;font-weight:400;line-height:48px}.mdl-typography--display-2-color-contrast{opacity:.54}.mdl-typography--display-1,.mdl-typography--display-1-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:34px;font-weight:400;line-height:40px}.mdl-typography--display-1-color-contrast{opacity:.54}.mdl-typography--headline,.mdl-typography--headline-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:24px;font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}.mdl-typography--headline-color-contrast{opacity:.87}.mdl-typography--title,.mdl-typography--title-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}.mdl-typography--title-color-contrast{opacity:.87}.mdl-typography--subhead,.mdl-typography--subhead-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;line-height:24px;letter-spacing:.04em}.mdl-typography--subhead-color-contrast{opacity:.87}.mdl-typography--body-2,.mdl-typography--body-2-color-contrast{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0}.mdl-typography--body-2-color-contrast{opacity:.87}.mdl-typography--body-1,.mdl-typography--body-1-color-contrast{font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-color-contrast{opacity:.87}.mdl-typography--body-2-force-preferred-font,.mdl-typography--body-2-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0}.mdl-typography--body-2-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--body-1-force-preferred-font,.mdl-typography--body-1-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--caption,.mdl-typography--caption-force-preferred-font{font-size:12px;font-weight:400;line-height:1;letter-spacing:0}.mdl-typography--caption-force-preferred-font{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--caption-color-contrast,.mdl-typography--caption-force-preferred-font-color-contrast{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;opacity:.54}.mdl-typography--caption-force-preferred-font-color-contrast,.mdl-typography--menu{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--menu{font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--menu-color-contrast{opacity:.87}.mdl-typography--menu-color-contrast,.mdl-typography--button,.mdl-typography--button-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--button,.mdl-typography--button-color-contrast{text-transform:uppercase}.mdl-typography--button-color-contrast{opacity:.87}.mdl-typography--text-left{text-align:left}.mdl-typography--text-right{text-align:right}.mdl-typography--text-center{text-align:center}.mdl-typography--text-justify{text-align:justify}.mdl-typography--text-nowrap{white-space:nowrap}.mdl-typography--text-lowercase{text-transform:lowercase}.mdl-typography--text-uppercase{text-transform:uppercase}.mdl-typography--text-capitalize{text-transform:capitalize}.mdl-typography--font-thin{font-weight:200!important}.mdl-typography--font-light{font-weight:300!important}.mdl-typography--font-regular{font-weight:400!important}.mdl-typography--font-medium{font-weight:500!important}.mdl-typography--font-bold{font-weight:700!important}.mdl-typography--font-black{font-weight:900!important}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased}.mdl-color-text--red{color:#f44336 !important}.mdl-color--red{background-color:#f44336 !important}.mdl-color-text--red-50{color:#ffebee !important}.mdl-color--red-50{background-color:#ffebee !important}.mdl-color-text--red-100{color:#ffcdd2 !important}.mdl-color--red-100{background-color:#ffcdd2 !important}.mdl-color-text--red-200{color:#ef9a9a !important}.mdl-color--red-200{background-color:#ef9a9a !important}.mdl-color-text--red-300{color:#e57373 !important}.mdl-color--red-300{background-color:#e57373 !important}.mdl-color-text--red-400{color:#ef5350 !important}.mdl-color--red-400{background-color:#ef5350 !important}.mdl-color-text--red-500{color:#f44336 !important}.mdl-color--red-500{background-color:#f44336 !important}.mdl-color-text--red-600{color:#e53935 !important}.mdl-color--red-600{background-color:#e53935 !important}.mdl-color-text--red-700{color:#d32f2f !important}.mdl-color--red-700{background-color:#d32f2f !important}.mdl-color-text--red-800{color:#c62828 !important}.mdl-color--red-800{background-color:#c62828 !important}.mdl-color-text--red-900{color:#b71c1c !important}.mdl-color--red-900{background-color:#b71c1c !important}.mdl-color-text--red-A100{color:#ff8a80 !important}.mdl-color--red-A100{background-color:#ff8a80 !important}.mdl-color-text--red-A200{color:#ff5252 !important}.mdl-color--red-A200{background-color:#ff5252 !important}.mdl-color-text--red-A400{color:#ff1744 !important}.mdl-color--red-A400{background-color:#ff1744 !important}.mdl-color-text--red-A700{color:#d50000 !important}.mdl-color--red-A700{background-color:#d50000 !important}.mdl-color-text--pink{color:#e91e63 !important}.mdl-color--pink{background-color:#e91e63 !important}.mdl-color-text--pink-50{color:#fce4ec !important}.mdl-color--pink-50{background-color:#fce4ec !important}.mdl-color-text--pink-100{color:#f8bbd0 !important}.mdl-color--pink-100{background-color:#f8bbd0 !important}.mdl-color-text--pink-200{color:#f48fb1 !important}.mdl-color--pink-200{background-color:#f48fb1 !important}.mdl-color-text--pink-300{color:#f06292 !important}.mdl-color--pink-300{background-color:#f06292 !important}.mdl-color-text--pink-400{color:#ec407a !important}.mdl-color--pink-400{background-color:#ec407a !important}.mdl-color-text--pink-500{color:#e91e63 !important}.mdl-color--pink-500{background-color:#e91e63 !important}.mdl-color-text--pink-600{color:#d81b60 !important}.mdl-color--pink-600{background-color:#d81b60 !important}.mdl-color-text--pink-700{color:#c2185b !important}.mdl-color--pink-700{background-color:#c2185b !important}.mdl-color-text--pink-800{color:#ad1457 !important}.mdl-color--pink-800{background-color:#ad1457 !important}.mdl-color-text--pink-900{color:#880e4f !important}.mdl-color--pink-900{background-color:#880e4f !important}.mdl-color-text--pink-A100{color:#ff80ab !important}.mdl-color--pink-A100{background-color:#ff80ab !important}.mdl-color-text--pink-A200{color:#ff4081 !important}.mdl-color--pink-A200{background-color:#ff4081 !important}.mdl-color-text--pink-A400{color:#f50057 !important}.mdl-color--pink-A400{background-color:#f50057 !important}.mdl-color-text--pink-A700{color:#c51162 !important}.mdl-color--pink-A700{background-color:#c51162 !important}.mdl-color-text--purple{color:#9c27b0 !important}.mdl-color--purple{background-color:#9c27b0 !important}.mdl-color-text--purple-50{color:#f3e5f5 !important}.mdl-color--purple-50{background-color:#f3e5f5 !important}.mdl-color-text--purple-100{color:#e1bee7 !important}.mdl-color--purple-100{background-color:#e1bee7 !important}.mdl-color-text--purple-200{color:#ce93d8 !important}.mdl-color--purple-200{background-color:#ce93d8 !important}.mdl-color-text--purple-300{color:#ba68c8 !important}.mdl-color--purple-300{background-color:#ba68c8 !important}.mdl-color-text--purple-400{color:#ab47bc !important}.mdl-color--purple-400{background-color:#ab47bc !important}.mdl-color-text--purple-500{color:#9c27b0 !important}.mdl-color--purple-500{background-color:#9c27b0 !important}.mdl-color-text--purple-600{color:#8e24aa !important}.mdl-color--purple-600{background-color:#8e24aa !important}.mdl-color-text--purple-700{color:#7b1fa2 !important}.mdl-color--purple-700{background-color:#7b1fa2 !important}.mdl-color-text--purple-800{color:#6a1b9a !important}.mdl-color--purple-800{background-color:#6a1b9a !important}.mdl-color-text--purple-900{color:#4a148c !important}.mdl-color--purple-900{background-color:#4a148c !important}.mdl-color-text--purple-A100{color:#ea80fc !important}.mdl-color--purple-A100{background-color:#ea80fc !important}.mdl-color-text--purple-A200{color:#e040fb !important}.mdl-color--purple-A200{background-color:#e040fb !important}.mdl-color-text--purple-A400{color:#d500f9 !important}.mdl-color--purple-A400{background-color:#d500f9 !important}.mdl-color-text--purple-A700{color:#a0f !important}.mdl-color--purple-A700{background-color:#a0f !important}.mdl-color-text--deep-purple{color:#673ab7 !important}.mdl-color--deep-purple{background-color:#673ab7 !important}.mdl-color-text--deep-purple-50{color:#ede7f6 !important}.mdl-color--deep-purple-50{background-color:#ede7f6 !important}.mdl-color-text--deep-purple-100{color:#d1c4e9 !important}.mdl-color--deep-purple-100{background-color:#d1c4e9 !important}.mdl-color-text--deep-purple-200{color:#b39ddb !important}.mdl-color--deep-purple-200{background-color:#b39ddb !important}.mdl-color-text--deep-purple-300{color:#9575cd !important}.mdl-color--deep-purple-300{background-color:#9575cd !important}.mdl-color-text--deep-purple-400{color:#7e57c2 !important}.mdl-color--deep-purple-400{background-color:#7e57c2 !important}.mdl-color-text--deep-purple-500{color:#673ab7 !important}.mdl-color--deep-purple-500{background-color:#673ab7 !important}.mdl-color-text--deep-purple-600{color:#5e35b1 !important}.mdl-color--deep-purple-600{background-color:#5e35b1 !important}.mdl-color-text--deep-purple-700{color:#512da8 !important}.mdl-color--deep-purple-700{background-color:#512da8 !important}.mdl-color-text--deep-purple-800{color:#4527a0 !important}.mdl-color--deep-purple-800{background-color:#4527a0 !important}.mdl-color-text--deep-purple-900{color:#311b92 !important}.mdl-color--deep-purple-900{background-color:#311b92 !important}.mdl-color-text--deep-purple-A100{color:#b388ff !important}.mdl-color--deep-purple-A100{background-color:#b388ff !important}.mdl-color-text--deep-purple-A200{color:#7c4dff !important}.mdl-color--deep-purple-A200{background-color:#7c4dff !important}.mdl-color-text--deep-purple-A400{color:#651fff !important}.mdl-color--deep-purple-A400{background-color:#651fff !important}.mdl-color-text--deep-purple-A700{color:#6200ea !important}.mdl-color--deep-purple-A700{background-color:#6200ea !important}.mdl-color-text--indigo{color:#3f51b5 !important}.mdl-color--indigo{background-color:#3f51b5 !important}.mdl-color-text--indigo-50{color:#e8eaf6 !important}.mdl-color--indigo-50{background-color:#e8eaf6 !important}.mdl-color-text--indigo-100{color:#c5cae9 !important}.mdl-color--indigo-100{background-color:#c5cae9 !important}.mdl-color-text--indigo-200{color:#9fa8da !important}.mdl-color--indigo-200{background-color:#9fa8da !important}.mdl-color-text--indigo-300{color:#7986cb !important}.mdl-color--indigo-300{background-color:#7986cb !important}.mdl-color-text--indigo-400{color:#5c6bc0 !important}.mdl-color--indigo-400{background-color:#5c6bc0 !important}.mdl-color-text--indigo-500{color:#3f51b5 !important}.mdl-color--indigo-500{background-color:#3f51b5 !important}.mdl-color-text--indigo-600{color:#3949ab !important}.mdl-color--indigo-600{background-color:#3949ab !important}.mdl-color-text--indigo-700{color:#303f9f !important}.mdl-color--indigo-700{background-color:#303f9f !important}.mdl-color-text--indigo-800{color:#283593 !important}.mdl-color--indigo-800{background-color:#283593 !important}.mdl-color-text--indigo-900{color:#1a237e !important}.mdl-color--indigo-900{background-color:#1a237e !important}.mdl-color-text--indigo-A100{color:#8c9eff !important}.mdl-color--indigo-A100{background-color:#8c9eff !important}.mdl-color-text--indigo-A200{color:#536dfe !important}.mdl-color--indigo-A200{background-color:#536dfe !important}.mdl-color-text--indigo-A400{color:#3d5afe !important}.mdl-color--indigo-A400{background-color:#3d5afe !important}.mdl-color-text--indigo-A700{color:#304ffe !important}.mdl-color--indigo-A700{background-color:#304ffe !important}.mdl-color-text--blue{color:#2196f3 !important}.mdl-color--blue{background-color:#2196f3 !important}.mdl-color-text--blue-50{color:#e3f2fd !important}.mdl-color--blue-50{background-color:#e3f2fd !important}.mdl-color-text--blue-100{color:#bbdefb !important}.mdl-color--blue-100{background-color:#bbdefb !important}.mdl-color-text--blue-200{color:#90caf9 !important}.mdl-color--blue-200{background-color:#90caf9 !important}.mdl-color-text--blue-300{color:#64b5f6 !important}.mdl-color--blue-300{background-color:#64b5f6 !important}.mdl-color-text--blue-400{color:#42a5f5 !important}.mdl-color--blue-400{background-color:#42a5f5 !important}.mdl-color-text--blue-500{color:#2196f3 !important}.mdl-color--blue-500{background-color:#2196f3 !important}.mdl-color-text--blue-600{color:#1e88e5 !important}.mdl-color--blue-600{background-color:#1e88e5 !important}.mdl-color-text--blue-700{color:#1976d2 !important}.mdl-color--blue-700{background-color:#1976d2 !important}.mdl-color-text--blue-800{color:#1565c0 !important}.mdl-color--blue-800{background-color:#1565c0 !important}.mdl-color-text--blue-900{color:#0d47a1 !important}.mdl-color--blue-900{background-color:#0d47a1 !important}.mdl-color-text--blue-A100{color:#82b1ff !important}.mdl-color--blue-A100{background-color:#82b1ff !important}.mdl-color-text--blue-A200{color:#448aff !important}.mdl-color--blue-A200{background-color:#448aff !important}.mdl-color-text--blue-A400{color:#2979ff !important}.mdl-color--blue-A400{background-color:#2979ff !important}.mdl-color-text--blue-A700{color:#2962ff !important}.mdl-color--blue-A700{background-color:#2962ff !important}.mdl-color-text--light-blue{color:#03a9f4 !important}.mdl-color--light-blue{background-color:#03a9f4 !important}.mdl-color-text--light-blue-50{color:#e1f5fe !important}.mdl-color--light-blue-50{background-color:#e1f5fe !important}.mdl-color-text--light-blue-100{color:#b3e5fc !important}.mdl-color--light-blue-100{background-color:#b3e5fc !important}.mdl-color-text--light-blue-200{color:#81d4fa !important}.mdl-color--light-blue-200{background-color:#81d4fa !important}.mdl-color-text--light-blue-300{color:#4fc3f7 !important}.mdl-color--light-blue-300{background-color:#4fc3f7 !important}.mdl-color-text--light-blue-400{color:#29b6f6 !important}.mdl-color--light-blue-400{background-color:#29b6f6 !important}.mdl-color-text--light-blue-500{color:#03a9f4 !important}.mdl-color--light-blue-500{background-color:#03a9f4 !important}.mdl-color-text--light-blue-600{color:#039be5 !important}.mdl-color--light-blue-600{background-color:#039be5 !important}.mdl-color-text--light-blue-700{color:#0288d1 !important}.mdl-color--light-blue-700{background-color:#0288d1 !important}.mdl-color-text--light-blue-800{color:#0277bd !important}.mdl-color--light-blue-800{background-color:#0277bd !important}.mdl-color-text--light-blue-900{color:#01579b !important}.mdl-color--light-blue-900{background-color:#01579b !important}.mdl-color-text--light-blue-A100{color:#80d8ff !important}.mdl-color--light-blue-A100{background-color:#80d8ff !important}.mdl-color-text--light-blue-A200{color:#40c4ff !important}.mdl-color--light-blue-A200{background-color:#40c4ff !important}.mdl-color-text--light-blue-A400{color:#00b0ff !important}.mdl-color--light-blue-A400{background-color:#00b0ff !important}.mdl-color-text--light-blue-A700{color:#0091ea !important}.mdl-color--light-blue-A700{background-color:#0091ea !important}.mdl-color-text--cyan{color:#00bcd4 !important}.mdl-color--cyan{background-color:#00bcd4 !important}.mdl-color-text--cyan-50{color:#e0f7fa !important}.mdl-color--cyan-50{background-color:#e0f7fa !important}.mdl-color-text--cyan-100{color:#b2ebf2 !important}.mdl-color--cyan-100{background-color:#b2ebf2 !important}.mdl-color-text--cyan-200{color:#80deea !important}.mdl-color--cyan-200{background-color:#80deea !important}.mdl-color-text--cyan-300{color:#4dd0e1 !important}.mdl-color--cyan-300{background-color:#4dd0e1 !important}.mdl-color-text--cyan-400{color:#26c6da !important}.mdl-color--cyan-400{background-color:#26c6da !important}.mdl-color-text--cyan-500{color:#00bcd4 !important}.mdl-color--cyan-500{background-color:#00bcd4 !important}.mdl-color-text--cyan-600{color:#00acc1 !important}.mdl-color--cyan-600{background-color:#00acc1 !important}.mdl-color-text--cyan-700{color:#0097a7 !important}.mdl-color--cyan-700{background-color:#0097a7 !important}.mdl-color-text--cyan-800{color:#00838f !important}.mdl-color--cyan-800{background-color:#00838f !important}.mdl-color-text--cyan-900{color:#006064 !important}.mdl-color--cyan-900{background-color:#006064 !important}.mdl-color-text--cyan-A100{color:#84ffff !important}.mdl-color--cyan-A100{background-color:#84ffff !important}.mdl-color-text--cyan-A200{color:#18ffff !important}.mdl-color--cyan-A200{background-color:#18ffff !important}.mdl-color-text--cyan-A400{color:#00e5ff !important}.mdl-color--cyan-A400{background-color:#00e5ff !important}.mdl-color-text--cyan-A700{color:#00b8d4 !important}.mdl-color--cyan-A700{background-color:#00b8d4 !important}.mdl-color-text--teal{color:#009688 !important}.mdl-color--teal{background-color:#009688 !important}.mdl-color-text--teal-50{color:#e0f2f1 !important}.mdl-color--teal-50{background-color:#e0f2f1 !important}.mdl-color-text--teal-100{color:#b2dfdb !important}.mdl-color--teal-100{background-color:#b2dfdb !important}.mdl-color-text--teal-200{color:#80cbc4 !important}.mdl-color--teal-200{background-color:#80cbc4 !important}.mdl-color-text--teal-300{color:#4db6ac !important}.mdl-color--teal-300{background-color:#4db6ac !important}.mdl-color-text--teal-400{color:#26a69a !important}.mdl-color--teal-400{background-color:#26a69a !important}.mdl-color-text--teal-500{color:#009688 !important}.mdl-color--teal-500{background-color:#009688 !important}.mdl-color-text--teal-600{color:#00897b !important}.mdl-color--teal-600{background-color:#00897b !important}.mdl-color-text--teal-700{color:#00796b !important}.mdl-color--teal-700{background-color:#00796b !important}.mdl-color-text--teal-800{color:#00695c !important}.mdl-color--teal-800{background-color:#00695c !important}.mdl-color-text--teal-900{color:#004d40 !important}.mdl-color--teal-900{background-color:#004d40 !important}.mdl-color-text--teal-A100{color:#a7ffeb !important}.mdl-color--teal-A100{background-color:#a7ffeb !important}.mdl-color-text--teal-A200{color:#64ffda !important}.mdl-color--teal-A200{background-color:#64ffda !important}.mdl-color-text--teal-A400{color:#1de9b6 !important}.mdl-color--teal-A400{background-color:#1de9b6 !important}.mdl-color-text--teal-A700{color:#00bfa5 !important}.mdl-color--teal-A700{background-color:#00bfa5 !important}.mdl-color-text--green{color:#4caf50 !important}.mdl-color--green{background-color:#4caf50 !important}.mdl-color-text--green-50{color:#e8f5e9 !important}.mdl-color--green-50{background-color:#e8f5e9 !important}.mdl-color-text--green-100{color:#c8e6c9 !important}.mdl-color--green-100{background-color:#c8e6c9 !important}.mdl-color-text--green-200{color:#a5d6a7 !important}.mdl-color--green-200{background-color:#a5d6a7 !important}.mdl-color-text--green-300{color:#81c784 !important}.mdl-color--green-300{background-color:#81c784 !important}.mdl-color-text--green-400{color:#66bb6a !important}.mdl-color--green-400{background-color:#66bb6a !important}.mdl-color-text--green-500{color:#4caf50 !important}.mdl-color--green-500{background-color:#4caf50 !important}.mdl-color-text--green-600{color:#43a047 !important}.mdl-color--green-600{background-color:#43a047 !important}.mdl-color-text--green-700{color:#388e3c !important}.mdl-color--green-700{background-color:#388e3c !important}.mdl-color-text--green-800{color:#2e7d32 !important}.mdl-color--green-800{background-color:#2e7d32 !important}.mdl-color-text--green-900{color:#1b5e20 !important}.mdl-color--green-900{background-color:#1b5e20 !important}.mdl-color-text--green-A100{color:#b9f6ca !important}.mdl-color--green-A100{background-color:#b9f6ca !important}.mdl-color-text--green-A200{color:#69f0ae !important}.mdl-color--green-A200{background-color:#69f0ae !important}.mdl-color-text--green-A400{color:#00e676 !important}.mdl-color--green-A400{background-color:#00e676 !important}.mdl-color-text--green-A700{color:#00c853 !important}.mdl-color--green-A700{background-color:#00c853 !important}.mdl-color-text--light-green{color:#8bc34a !important}.mdl-color--light-green{background-color:#8bc34a !important}.mdl-color-text--light-green-50{color:#f1f8e9 !important}.mdl-color--light-green-50{background-color:#f1f8e9 !important}.mdl-color-text--light-green-100{color:#dcedc8 !important}.mdl-color--light-green-100{background-color:#dcedc8 !important}.mdl-color-text--light-green-200{color:#c5e1a5 !important}.mdl-color--light-green-200{background-color:#c5e1a5 !important}.mdl-color-text--light-green-300{color:#aed581 !important}.mdl-color--light-green-300{background-color:#aed581 !important}.mdl-color-text--light-green-400{color:#9ccc65 !important}.mdl-color--light-green-400{background-color:#9ccc65 !important}.mdl-color-text--light-green-500{color:#8bc34a !important}.mdl-color--light-green-500{background-color:#8bc34a !important}.mdl-color-text--light-green-600{color:#7cb342 !important}.mdl-color--light-green-600{background-color:#7cb342 !important}.mdl-color-text--light-green-700{color:#689f38 !important}.mdl-color--light-green-700{background-color:#689f38 !important}.mdl-color-text--light-green-800{color:#558b2f !important}.mdl-color--light-green-800{background-color:#558b2f !important}.mdl-color-text--light-green-900{color:#33691e !important}.mdl-color--light-green-900{background-color:#33691e !important}.mdl-color-text--light-green-A100{color:#ccff90 !important}.mdl-color--light-green-A100{background-color:#ccff90 !important}.mdl-color-text--light-green-A200{color:#b2ff59 !important}.mdl-color--light-green-A200{background-color:#b2ff59 !important}.mdl-color-text--light-green-A400{color:#76ff03 !important}.mdl-color--light-green-A400{background-color:#76ff03 !important}.mdl-color-text--light-green-A700{color:#64dd17 !important}.mdl-color--light-green-A700{background-color:#64dd17 !important}.mdl-color-text--lime{color:#cddc39 !important}.mdl-color--lime{background-color:#cddc39 !important}.mdl-color-text--lime-50{color:#f9fbe7 !important}.mdl-color--lime-50{background-color:#f9fbe7 !important}.mdl-color-text--lime-100{color:#f0f4c3 !important}.mdl-color--lime-100{background-color:#f0f4c3 !important}.mdl-color-text--lime-200{color:#e6ee9c !important}.mdl-color--lime-200{background-color:#e6ee9c !important}.mdl-color-text--lime-300{color:#dce775 !important}.mdl-color--lime-300{background-color:#dce775 !important}.mdl-color-text--lime-400{color:#d4e157 !important}.mdl-color--lime-400{background-color:#d4e157 !important}.mdl-color-text--lime-500{color:#cddc39 !important}.mdl-color--lime-500{background-color:#cddc39 !important}.mdl-color-text--lime-600{color:#c0ca33 !important}.mdl-color--lime-600{background-color:#c0ca33 !important}.mdl-color-text--lime-700{color:#afb42b !important}.mdl-color--lime-700{background-color:#afb42b !important}.mdl-color-text--lime-800{color:#9e9d24 !important}.mdl-color--lime-800{background-color:#9e9d24 !important}.mdl-color-text--lime-900{color:#827717 !important}.mdl-color--lime-900{background-color:#827717 !important}.mdl-color-text--lime-A100{color:#f4ff81 !important}.mdl-color--lime-A100{background-color:#f4ff81 !important}.mdl-color-text--lime-A200{color:#eeff41 !important}.mdl-color--lime-A200{background-color:#eeff41 !important}.mdl-color-text--lime-A400{color:#c6ff00 !important}.mdl-color--lime-A400{background-color:#c6ff00 !important}.mdl-color-text--lime-A700{color:#aeea00 !important}.mdl-color--lime-A700{background-color:#aeea00 !important}.mdl-color-text--yellow{color:#ffeb3b !important}.mdl-color--yellow{background-color:#ffeb3b !important}.mdl-color-text--yellow-50{color:#fffde7 !important}.mdl-color--yellow-50{background-color:#fffde7 !important}.mdl-color-text--yellow-100{color:#fff9c4 !important}.mdl-color--yellow-100{background-color:#fff9c4 !important}.mdl-color-text--yellow-200{color:#fff59d !important}.mdl-color--yellow-200{background-color:#fff59d !important}.mdl-color-text--yellow-300{color:#fff176 !important}.mdl-color--yellow-300{background-color:#fff176 !important}.mdl-color-text--yellow-400{color:#ffee58 !important}.mdl-color--yellow-400{background-color:#ffee58 !important}.mdl-color-text--yellow-500{color:#ffeb3b !important}.mdl-color--yellow-500{background-color:#ffeb3b !important}.mdl-color-text--yellow-600{color:#fdd835 !important}.mdl-color--yellow-600{background-color:#fdd835 !important}.mdl-color-text--yellow-700{color:#fbc02d !important}.mdl-color--yellow-700{background-color:#fbc02d !important}.mdl-color-text--yellow-800{color:#f9a825 !important}.mdl-color--yellow-800{background-color:#f9a825 !important}.mdl-color-text--yellow-900{color:#f57f17 !important}.mdl-color--yellow-900{background-color:#f57f17 !important}.mdl-color-text--yellow-A100{color:#ffff8d !important}.mdl-color--yellow-A100{background-color:#ffff8d !important}.mdl-color-text--yellow-A200{color:#ff0 !important}.mdl-color--yellow-A200{background-color:#ff0 !important}.mdl-color-text--yellow-A400{color:#ffea00 !important}.mdl-color--yellow-A400{background-color:#ffea00 !important}.mdl-color-text--yellow-A700{color:#ffd600 !important}.mdl-color--yellow-A700{background-color:#ffd600 !important}.mdl-color-text--amber{color:#ffc107 !important}.mdl-color--amber{background-color:#ffc107 !important}.mdl-color-text--amber-50{color:#fff8e1 !important}.mdl-color--amber-50{background-color:#fff8e1 !important}.mdl-color-text--amber-100{color:#ffecb3 !important}.mdl-color--amber-100{background-color:#ffecb3 !important}.mdl-color-text--amber-200{color:#ffe082 !important}.mdl-color--amber-200{background-color:#ffe082 !important}.mdl-color-text--amber-300{color:#ffd54f !important}.mdl-color--amber-300{background-color:#ffd54f !important}.mdl-color-text--amber-400{color:#ffca28 !important}.mdl-color--amber-400{background-color:#ffca28 !important}.mdl-color-text--amber-500{color:#ffc107 !important}.mdl-color--amber-500{background-color:#ffc107 !important}.mdl-color-text--amber-600{color:#ffb300 !important}.mdl-color--amber-600{background-color:#ffb300 !important}.mdl-color-text--amber-700{color:#ffa000 !important}.mdl-color--amber-700{background-color:#ffa000 !important}.mdl-color-text--amber-800{color:#ff8f00 !important}.mdl-color--amber-800{background-color:#ff8f00 !important}.mdl-color-text--amber-900{color:#ff6f00 !important}.mdl-color--amber-900{background-color:#ff6f00 !important}.mdl-color-text--amber-A100{color:#ffe57f !important}.mdl-color--amber-A100{background-color:#ffe57f !important}.mdl-color-text--amber-A200{color:#ffd740 !important}.mdl-color--amber-A200{background-color:#ffd740 !important}.mdl-color-text--amber-A400{color:#ffc400 !important}.mdl-color--amber-A400{background-color:#ffc400 !important}.mdl-color-text--amber-A700{color:#ffab00 !important}.mdl-color--amber-A700{background-color:#ffab00 !important}.mdl-color-text--orange{color:#ff9800 !important}.mdl-color--orange{background-color:#ff9800 !important}.mdl-color-text--orange-50{color:#fff3e0 !important}.mdl-color--orange-50{background-color:#fff3e0 !important}.mdl-color-text--orange-100{color:#ffe0b2 !important}.mdl-color--orange-100{background-color:#ffe0b2 !important}.mdl-color-text--orange-200{color:#ffcc80 !important}.mdl-color--orange-200{background-color:#ffcc80 !important}.mdl-color-text--orange-300{color:#ffb74d !important}.mdl-color--orange-300{background-color:#ffb74d !important}.mdl-color-text--orange-400{color:#ffa726 !important}.mdl-color--orange-400{background-color:#ffa726 !important}.mdl-color-text--orange-500{color:#ff9800 !important}.mdl-color--orange-500{background-color:#ff9800 !important}.mdl-color-text--orange-600{color:#fb8c00 !important}.mdl-color--orange-600{background-color:#fb8c00 !important}.mdl-color-text--orange-700{color:#f57c00 !important}.mdl-color--orange-700{background-color:#f57c00 !important}.mdl-color-text--orange-800{color:#ef6c00 !important}.mdl-color--orange-800{background-color:#ef6c00 !important}.mdl-color-text--orange-900{color:#e65100 !important}.mdl-color--orange-900{background-color:#e65100 !important}.mdl-color-text--orange-A100{color:#ffd180 !important}.mdl-color--orange-A100{background-color:#ffd180 !important}.mdl-color-text--orange-A200{color:#ffab40 !important}.mdl-color--orange-A200{background-color:#ffab40 !important}.mdl-color-text--orange-A400{color:#ff9100 !important}.mdl-color--orange-A400{background-color:#ff9100 !important}.mdl-color-text--orange-A700{color:#ff6d00 !important}.mdl-color--orange-A700{background-color:#ff6d00 !important}.mdl-color-text--deep-orange{color:#ff5722 !important}.mdl-color--deep-orange{background-color:#ff5722 !important}.mdl-color-text--deep-orange-50{color:#fbe9e7 !important}.mdl-color--deep-orange-50{background-color:#fbe9e7 !important}.mdl-color-text--deep-orange-100{color:#ffccbc !important}.mdl-color--deep-orange-100{background-color:#ffccbc !important}.mdl-color-text--deep-orange-200{color:#ffab91 !important}.mdl-color--deep-orange-200{background-color:#ffab91 !important}.mdl-color-text--deep-orange-300{color:#ff8a65 !important}.mdl-color--deep-orange-300{background-color:#ff8a65 !important}.mdl-color-text--deep-orange-400{color:#ff7043 !important}.mdl-color--deep-orange-400{background-color:#ff7043 !important}.mdl-color-text--deep-orange-500{color:#ff5722 !important}.mdl-color--deep-orange-500{background-color:#ff5722 !important}.mdl-color-text--deep-orange-600{color:#f4511e !important}.mdl-color--deep-orange-600{background-color:#f4511e !important}.mdl-color-text--deep-orange-700{color:#e64a19 !important}.mdl-color--deep-orange-700{background-color:#e64a19 !important}.mdl-color-text--deep-orange-800{color:#d84315 !important}.mdl-color--deep-orange-800{background-color:#d84315 !important}.mdl-color-text--deep-orange-900{color:#bf360c !important}.mdl-color--deep-orange-900{background-color:#bf360c !important}.mdl-color-text--deep-orange-A100{color:#ff9e80 !important}.mdl-color--deep-orange-A100{background-color:#ff9e80 !important}.mdl-color-text--deep-orange-A200{color:#ff6e40 !important}.mdl-color--deep-orange-A200{background-color:#ff6e40 !important}.mdl-color-text--deep-orange-A400{color:#ff3d00 !important}.mdl-color--deep-orange-A400{background-color:#ff3d00 !important}.mdl-color-text--deep-orange-A700{color:#dd2c00 !important}.mdl-color--deep-orange-A700{background-color:#dd2c00 !important}.mdl-color-text--brown{color:#795548 !important}.mdl-color--brown{background-color:#795548 !important}.mdl-color-text--brown-50{color:#efebe9 !important}.mdl-color--brown-50{background-color:#efebe9 !important}.mdl-color-text--brown-100{color:#d7ccc8 !important}.mdl-color--brown-100{background-color:#d7ccc8 !important}.mdl-color-text--brown-200{color:#bcaaa4 !important}.mdl-color--brown-200{background-color:#bcaaa4 !important}.mdl-color-text--brown-300{color:#a1887f !important}.mdl-color--brown-300{background-color:#a1887f !important}.mdl-color-text--brown-400{color:#8d6e63 !important}.mdl-color--brown-400{background-color:#8d6e63 !important}.mdl-color-text--brown-500{color:#795548 !important}.mdl-color--brown-500{background-color:#795548 !important}.mdl-color-text--brown-600{color:#6d4c41 !important}.mdl-color--brown-600{background-color:#6d4c41 !important}.mdl-color-text--brown-700{color:#5d4037 !important}.mdl-color--brown-700{background-color:#5d4037 !important}.mdl-color-text--brown-800{color:#4e342e !important}.mdl-color--brown-800{background-color:#4e342e !important}.mdl-color-text--brown-900{color:#3e2723 !important}.mdl-color--brown-900{background-color:#3e2723 !important}.mdl-color-text--grey{color:#9e9e9e !important}.mdl-color--grey{background-color:#9e9e9e !important}.mdl-color-text--grey-50{color:#fafafa !important}.mdl-color--grey-50{background-color:#fafafa !important}.mdl-color-text--grey-100{color:#f5f5f5 !important}.mdl-color--grey-100{background-color:#f5f5f5 !important}.mdl-color-text--grey-200{color:#eee !important}.mdl-color--grey-200{background-color:#eee !important}.mdl-color-text--grey-300{color:#e0e0e0 !important}.mdl-color--grey-300{background-color:#e0e0e0 !important}.mdl-color-text--grey-400{color:#bdbdbd !important}.mdl-color--grey-400{background-color:#bdbdbd !important}.mdl-color-text--grey-500{color:#9e9e9e !important}.mdl-color--grey-500{background-color:#9e9e9e !important}.mdl-color-text--grey-600{color:#757575 !important}.mdl-color--grey-600{background-color:#757575 !important}.mdl-color-text--grey-700{color:#616161 !important}.mdl-color--grey-700{background-color:#616161 !important}.mdl-color-text--grey-800{color:#424242 !important}.mdl-color--grey-800{background-color:#424242 !important}.mdl-color-text--grey-900{color:#212121 !important}.mdl-color--grey-900{background-color:#212121 !important}.mdl-color-text--blue-grey{color:#607d8b !important}.mdl-color--blue-grey{background-color:#607d8b !important}.mdl-color-text--blue-grey-50{color:#eceff1 !important}.mdl-color--blue-grey-50{background-color:#eceff1 !important}.mdl-color-text--blue-grey-100{color:#cfd8dc !important}.mdl-color--blue-grey-100{background-color:#cfd8dc !important}.mdl-color-text--blue-grey-200{color:#b0bec5 !important}.mdl-color--blue-grey-200{background-color:#b0bec5 !important}.mdl-color-text--blue-grey-300{color:#90a4ae !important}.mdl-color--blue-grey-300{background-color:#90a4ae !important}.mdl-color-text--blue-grey-400{color:#78909c !important}.mdl-color--blue-grey-400{background-color:#78909c !important}.mdl-color-text--blue-grey-500{color:#607d8b !important}.mdl-color--blue-grey-500{background-color:#607d8b !important}.mdl-color-text--blue-grey-600{color:#546e7a !important}.mdl-color--blue-grey-600{background-color:#546e7a !important}.mdl-color-text--blue-grey-700{color:#455a64 !important}.mdl-color--blue-grey-700{background-color:#455a64 !important}.mdl-color-text--blue-grey-800{color:#37474f !important}.mdl-color--blue-grey-800{background-color:#37474f !important}.mdl-color-text--blue-grey-900{color:#263238 !important}.mdl-color--blue-grey-900{background-color:#263238 !important}.mdl-color--black{background-color:#000 !important}.mdl-color-text--black{color:#000 !important}.mdl-color--white{background-color:#fff !important}.mdl-color-text--white{color:#fff !important}.mdl-color--primary{background-color:#3f51b5 !important}.mdl-color--primary-contrast{background-color:#fff !important}.mdl-color--primary-dark{background-color:#303f9f !important}.mdl-color--accent{background-color:#ff4081 !important}.mdl-color--accent-contrast{background-color:#fff !important}.mdl-color-text--primary{color:#3f51b5 !important}.mdl-color-text--primary-contrast{color:#fff !important}.mdl-color-text--primary-dark{color:#303f9f !important}.mdl-color-text--accent{color:#ff4081 !important}.mdl-color-text--accent-contrast{color:#fff !important}.mdl-ripple{background:#000;border-radius:50%;height:50px;left:0;opacity:0;pointer-events:none;position:absolute;top:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:50px;overflow:hidden}.mdl-ripple.is-animating{transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1);transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1),-webkit-transform .3s cubic-bezier(0,0,.2,1)}.mdl-ripple.is-visible{opacity:.3}.mdl-animation--default,.mdl-animation--fast-out-slow-in{transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-animation--linear-out-slow-in{transition-timing-function:cubic-bezier(0,0,.2,1)}.mdl-animation--fast-out-linear-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.mdl-badge{position:relative;white-space:nowrap;margin-right:24px}.mdl-badge:not([data-badge]){margin-right:auto}.mdl-badge[data-badge]:after{content:attr(data-badge);display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:-11px;right:-24px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:600;font-size:12px;width:22px;height:22px;border-radius:50%;background:#ff4081;color:#fff}.mdl-button .mdl-badge[data-badge]:after{top:-10px;right:-5px}.mdl-badge.mdl-badge--no-background[data-badge]:after{color:#ff4081;background:rgba(255,255,255,.2);box-shadow:0 0 1px gray}.mdl-badge.mdl-badge--overlap{margin-right:10px}.mdl-badge.mdl-badge--overlap:after{right:-10px}.mdl-button{background:0 0;border:none;border-radius:2px;color:#000;position:relative;height:36px;margin:0;min-width:64px;padding:0 16px;display:inline-block;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;letter-spacing:0;overflow:hidden;will-change:box-shadow;transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:none;cursor:pointer;text-decoration:none;text-align:center;line-height:36px;vertical-align:middle}.mdl-button::-moz-focus-inner{border:0}.mdl-button:hover{background-color:rgba(158,158,158,.2)}.mdl-button:focus:not(:active){background-color:rgba(0,0,0,.12)}.mdl-button:active{background-color:rgba(158,158,158,.4)}.mdl-button.mdl-button--colored{color:#3f51b5}.mdl-button.mdl-button--colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.mdl-button[type="submit"]{-webkit-appearance:none}.mdl-button--raised{background:rgba(158,158,158,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-button--raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--raised.mdl-button--colored{background:#3f51b5;color:#fff}.mdl-button--raised.mdl-button--colored:hover{background-color:#3f51b5}.mdl-button--raised.mdl-button--colored:active{background-color:#3f51b5}.mdl-button--raised.mdl-button--colored:focus:not(:active){background-color:#3f51b5}.mdl-button--raised.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--fab{border-radius:50%;font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;overflow:hidden;background:rgba(158,158,158,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);position:relative;line-height:normal}.mdl-button--fab .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--fab.mdl-button--mini-fab{height:40px;min-width:40px;width:40px}.mdl-button--fab .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button--fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--fab.mdl-button--colored{background:#ff4081;color:#fff}.mdl-button--fab.mdl-button--colored:hover{background-color:#ff4081}.mdl-button--fab.mdl-button--colored:focus:not(:active){background-color:#ff4081}.mdl-button--fab.mdl-button--colored:active{background-color:#ff4081}.mdl-button--fab.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--icon{border-radius:50%;font-size:24px;height:32px;margin-left:0;margin-right:0;min-width:32px;width:32px;padding:0;overflow:hidden;color:inherit;line-height:normal}.mdl-button--icon .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon{height:24px;min-width:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon .material-icons{top:0;left:0}.mdl-button--icon .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button__ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-button[disabled] .mdl-button__ripple-container .mdl-ripple,.mdl-button.mdl-button--disabled .mdl-button__ripple-container .mdl-ripple{background-color:transparent}.mdl-button--primary.mdl-button--primary{color:#3f51b5}.mdl-button--primary.mdl-button--primary .mdl-ripple{background:#fff}.mdl-button--primary.mdl-button--primary.mdl-button--raised,.mdl-button--primary.mdl-button--primary.mdl-button--fab{color:#fff;background-color:#3f51b5}.mdl-button--accent.mdl-button--accent{color:#ff4081}.mdl-button--accent.mdl-button--accent .mdl-ripple{background:#fff}.mdl-button--accent.mdl-button--accent.mdl-button--raised,.mdl-button--accent.mdl-button--accent.mdl-button--fab{color:#fff;background-color:#ff4081}.mdl-button[disabled][disabled],.mdl-button.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26);cursor:default;background-color:transparent}.mdl-button--fab[disabled][disabled],.mdl-button--fab.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-button--raised[disabled][disabled],.mdl-button--raised.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:none}.mdl-button--colored[disabled][disabled],.mdl-button--colored.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26)}.mdl-button .material-icons{vertical-align:middle}.mdl-card{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;font-size:16px;font-weight:400;min-height:200px;overflow:hidden;width:330px;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.mdl-card__media{background-color:#ff4081;background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.mdl-card__title{-webkit-align-items:center;-ms-flex-align:center;align-items:center;color:#000;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;line-height:normal;padding:16px;-webkit-perspective-origin:165px 56px;perspective-origin:165px 56px;-webkit-transform-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.mdl-card__title.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__title-text{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;color:inherit;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:24px;font-weight:300;line-height:normal;overflow:hidden;-webkit-transform-origin:149px 48px;transform-origin:149px 48px;margin:0}.mdl-card__subtitle-text{font-size:14px;color:rgba(0,0,0,.54);margin:0}.mdl-card__supporting-text{color:rgba(0,0,0,.54);font-size:1rem;line-height:18px;overflow:hidden;padding:16px;width:90%}.mdl-card__actions{font-size:16px;line-height:normal;width:100%;background-color:transparent;padding:8px;box-sizing:border-box}.mdl-card__actions.mdl-card--border{border-top:1px solid rgba(0,0,0,.1)}.mdl-card--expand{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-card__menu{position:absolute;right:16px;top:16px}.mdl-checkbox{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0}.mdl-checkbox.is-upgraded{padding-left:24px}.mdl-checkbox__input{line-height:24px}.mdl-checkbox.is-upgraded .mdl-checkbox__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-checkbox__box-outline{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;overflow:hidden;border:2px solid rgba(0,0,0,.54);border-radius:2px;z-index:2}.mdl-checkbox.is-checked .mdl-checkbox__box-outline{border:2px solid #3f51b5}fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline,.mdl-checkbox.is-disabled .mdl-checkbox__box-outline{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__focus-helper{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;border-radius:50%;background-color:transparent}.mdl-checkbox.is-focused .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.mdl-checkbox__tick-outline{position:absolute;top:0;left:0;height:100%;width:100%;-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");background:0 0;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background}.mdl-checkbox.is-checked .mdl-checkbox__tick-outline{background:#3f51b5 url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}fieldset[disabled] .mdl-checkbox.is-checked .mdl-checkbox__tick-outline,.mdl-checkbox.is-checked.is-disabled .mdl-checkbox__tick-outline{background:rgba(0,0,0,.26)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}.mdl-checkbox__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0}fieldset[disabled] .mdl-checkbox .mdl-checkbox__label,.mdl-checkbox.is-disabled .mdl-checkbox__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__ripple-container{position:absolute;z-index:2;top:-6px;left:-10px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-checkbox__ripple-container .mdl-ripple{background:#3f51b5}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container{cursor:auto}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container .mdl-ripple,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container .mdl-ripple{background:0 0}.mdl-data-table{position:relative;border:1px solid rgba(0,0,0,.12);border-collapse:collapse;white-space:nowrap;font-size:13px;background-color:#fff}.mdl-data-table thead{padding-bottom:3px}.mdl-data-table thead .mdl-data-table__select{margin-top:0}.mdl-data-table tbody tr{position:relative;height:48px;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background-color}.mdl-data-table tbody tr.is-selected{background-color:#e0e0e0}.mdl-data-table tbody tr:hover{background-color:#eee}.mdl-data-table td{text-align:right}.mdl-data-table th{padding:0 18px 12px 18px;text-align:right}.mdl-data-table td:first-of-type,.mdl-data-table th:first-of-type{padding-left:24px}.mdl-data-table td:last-of-type,.mdl-data-table th:last-of-type{padding-right:24px}.mdl-data-table td{position:relative;height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding:12px 18px;box-sizing:border-box}.mdl-data-table td,.mdl-data-table td .mdl-data-table__select{vertical-align:middle}.mdl-data-table th{position:relative;vertical-align:bottom;text-overflow:ellipsis;font-weight:700;line-height:24px;letter-spacing:0;height:48px;font-size:12px;color:rgba(0,0,0,.54);padding-bottom:8px;box-sizing:border-box}.mdl-data-table th.mdl-data-table__header--sorted-ascending,.mdl-data-table th.mdl-data-table__header--sorted-descending{color:rgba(0,0,0,.87)}.mdl-data-table th.mdl-data-table__header--sorted-ascending:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:before{font-family:'Material Icons';font-weight:400;font-style:normal;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-size:16px;content:"\e5d8";margin-right:5px;vertical-align:sub}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover{cursor:pointer}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover:before{color:rgba(0,0,0,.26)}.mdl-data-table th.mdl-data-table__header--sorted-descending:before{content:"\e5db"}.mdl-data-table__select{width:16px}.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric{text-align:left}.mdl-dialog{border:none;box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);width:280px}.mdl-dialog__title{padding:24px 24px 0;margin:0;font-size:2.5rem}.mdl-dialog__actions{padding:8px 8px 8px 24px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.mdl-dialog__actions>*{margin-right:8px;height:36px}.mdl-dialog__actions>*:first-child{margin-right:0}.mdl-dialog__actions--full-width{padding:0 0 8px}.mdl-dialog__actions--full-width>*{height:48px;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;padding-right:16px;margin-right:0;text-align:right}.mdl-dialog__content{padding:20px 24px 24px;color:rgba(0,0,0,.54)}.mdl-mega-footer{padding:16px 40px;color:#9e9e9e;background-color:#424242}.mdl-mega-footer--top-section:after,.mdl-mega-footer--middle-section:after,.mdl-mega-footer--bottom-section:after,.mdl-mega-footer__top-section:after,.mdl-mega-footer__middle-section:after,.mdl-mega-footer__bottom-section:after{content:'';display:block;clear:both}.mdl-mega-footer--left-section,.mdl-mega-footer__left-section,.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{margin-bottom:16px}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:block;margin-bottom:16px;color:inherit;text-decoration:none}@media screen and (min-width:760px){.mdl-mega-footer--left-section,.mdl-mega-footer__left-section{float:left}.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{float:right}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:inline-block;margin-left:16px;line-height:36px;vertical-align:middle}}.mdl-mega-footer--social-btn,.mdl-mega-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{display:block;position:relative}@media screen and (min-width:760px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{width:33%}.mdl-mega-footer--drop-down-section:nth-child(1),.mdl-mega-footer--drop-down-section:nth-child(2),.mdl-mega-footer__drop-down-section:nth-child(1),.mdl-mega-footer__drop-down-section:nth-child(2){float:left}.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(3){float:right}.mdl-mega-footer--drop-down-section:nth-child(3):after,.mdl-mega-footer__drop-down-section:nth-child(3):after{clear:right}.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section:nth-child(4){clear:right;float:right}.mdl-mega-footer--middle-section:after,.mdl-mega-footer__middle-section:after{content:'';display:block;clear:both}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:0}}@media screen and (min-width:1024px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section,.mdl-mega-footer__drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(4){width:24%;float:left}}.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{position:absolute;width:100%;height:55.8px;padding:32px;margin:-16px 0 0;cursor:pointer;z-index:1;opacity:0}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CE'}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list{display:none}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CF'}.mdl-mega-footer--heading,.mdl-mega-footer__heading{position:relative;width:100%;padding-right:39.8px;margin-bottom:16px;box-sizing:border-box;font-size:14px;line-height:23.8px;font-weight:500;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:#e0e0e0}.mdl-mega-footer--heading:after,.mdl-mega-footer__heading:after{content:'';position:absolute;top:0;right:0;display:block;width:23.8px;height:23.8px;background-size:cover}.mdl-mega-footer--link-list,.mdl-mega-footer__link-list{list-style:none;padding:0;margin:0 0 32px}.mdl-mega-footer--link-list:after,.mdl-mega-footer__link-list:after{clear:both;display:block;content:''}.mdl-mega-footer--link-list li,.mdl-mega-footer__link-list li{font-size:14px;font-weight:400;letter-spacing:0;line-height:20px}.mdl-mega-footer--link-list a,.mdl-mega-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}@media screen and (min-width:760px){.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{display:none}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{content:''}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list{display:block}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{content:''}}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:16px;margin-bottom:16px}.mdl-logo{margin-bottom:16px;color:#fff}.mdl-mega-footer--bottom-section .mdl-mega-footer--link-list li,.mdl-mega-footer__bottom-section .mdl-mega-footer__link-list li{float:left;margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-logo{float:left;margin-bottom:0;margin-right:16px}}.mdl-mini-footer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:32px 16px;color:#9e9e9e;background-color:#424242}.mdl-mini-footer:after{content:'';display:block}.mdl-mini-footer .mdl-logo{line-height:36px}.mdl-mini-footer--link-list,.mdl-mini-footer__link-list{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;list-style:none;margin:0;padding:0}.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{line-height:36px}}.mdl-mini-footer--link-list a,.mdl-mini-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}.mdl-mini-footer--left-section,.mdl-mini-footer__left-section{display:inline-block;-webkit-order:0;-ms-flex-order:0;order:0}.mdl-mini-footer--right-section,.mdl-mini-footer__right-section{display:inline-block;-webkit-order:1;-ms-flex-order:1;order:1}.mdl-mini-footer--social-btn,.mdl-mini-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-icon-toggle{position:relative;z-index:1;vertical-align:middle;display:inline-block;height:32px;margin:0;padding:0}.mdl-icon-toggle__input{line-height:32px}.mdl-icon-toggle.is-upgraded .mdl-icon-toggle__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-icon-toggle__label{display:inline-block;position:relative;cursor:pointer;height:32px;width:32px;min-width:32px;color:#616161;border-radius:50%;padding:0;margin-left:0;margin-right:0;text-align:center;background-color:transparent;will-change:background-color;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.mdl-icon-toggle__label.material-icons{line-height:32px;font-size:24px}.mdl-icon-toggle.is-checked .mdl-icon-toggle__label{color:#3f51b5}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__label{color:rgba(0,0,0,.26);cursor:auto;transition:none}.mdl-icon-toggle.is-focused .mdl-icon-toggle__label{background-color:rgba(0,0,0,.12)}.mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label{background-color:rgba(63,81,181,.26)}.mdl-icon-toggle__ripple-container{position:absolute;z-index:2;top:-2px;left:-2px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-icon-toggle__ripple-container .mdl-ripple{background:#616161}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container{cursor:auto}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container .mdl-ripple{background:0 0}.mdl-list{display:block;padding:8px 0;list-style:none}.mdl-list__item{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;letter-spacing:.04em;line-height:1;min-height:48px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;padding:16px;cursor:default;color:rgba(0,0,0,.87);overflow:hidden}.mdl-list__item,.mdl-list__item .mdl-list__item-primary-content{box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.mdl-list__item .mdl-list__item-primary-content{-webkit-order:0;-ms-flex-order:0;order:0;-webkit-flex-grow:2;-ms-flex-positive:2;flex-grow:2;text-decoration:none}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-icon{margin-right:32px}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-avatar{margin-right:16px}.mdl-list__item .mdl-list__item-secondary-content{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:column;-ms-flex-flow:column;flex-flow:column;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end;margin-left:16px}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-action label{display:inline}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-info{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;color:rgba(0,0,0,.54)}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-sub-header{padding:0 0 0 16px}.mdl-list__item-icon,.mdl-list__item-icon.material-icons{height:24px;width:24px;font-size:24px;box-sizing:border-box;color:#757575}.mdl-list__item-avatar,.mdl-list__item-avatar.material-icons{height:40px;width:40px;box-sizing:border-box;border-radius:50%;background-color:#757575;font-size:40px;color:#fff}.mdl-list__item--two-line{height:72px}.mdl-list__item--two-line .mdl-list__item-primary-content{height:36px;line-height:20px;display:block}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-avatar{float:left}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left;margin-top:6px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-secondary-content{height:36px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-sub-title{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-list__item--three-line{height:88px}.mdl-list__item--three-line .mdl-list__item-primary-content{height:52px;line-height:20px;display:block}.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-avatar,.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left}.mdl-list__item--three-line .mdl-list__item-secondary-content{height:52px}.mdl-list__item--three-line .mdl-list__item-text-body{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;height:52px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-menu__container{display:block;margin:0;padding:0;border:none;position:absolute;overflow:visible;height:0;width:0;visibility:hidden;z-index:-1}.mdl-menu__container.is-visible,.mdl-menu__container.is-animating{z-index:999;visibility:visible}.mdl-menu__outline{display:block;background:#fff;margin:0;padding:0;border:none;border-radius:2px;position:absolute;top:0;left:0;overflow:hidden;opacity:0;-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:0 0;transform-origin:0 0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);will-change:transform;transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),-webkit-transform .3s cubic-bezier(.4,0,.2,1);z-index:-1}.mdl-menu__container.is-visible .mdl-menu__outline{opacity:1;-webkit-transform:scale(1);transform:scale(1);z-index:999}.mdl-menu__outline.mdl-menu--bottom-right{-webkit-transform-origin:100% 0;transform-origin:100% 0}.mdl-menu__outline.mdl-menu--top-left{-webkit-transform-origin:0 100%;transform-origin:0 100%}.mdl-menu__outline.mdl-menu--top-right{-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.mdl-menu{position:absolute;list-style:none;top:0;left:0;height:auto;width:auto;min-width:124px;padding:8px 0;margin:0;opacity:0;clip:rect(0 0 0 0);z-index:-1}.mdl-menu__container.is-visible .mdl-menu{opacity:1;z-index:999}.mdl-menu.is-animating{transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1)}.mdl-menu.mdl-menu--bottom-right{left:auto;right:0}.mdl-menu.mdl-menu--top-left{top:auto;bottom:0}.mdl-menu.mdl-menu--top-right{top:auto;left:auto;bottom:0;right:0}.mdl-menu.mdl-menu--unaligned{top:auto;left:auto}.mdl-menu__item{display:block;border:none;color:rgba(0,0,0,.87);background-color:transparent;text-align:left;margin:0;padding:0 16px;outline-color:#bdbdbd;position:relative;overflow:hidden;font-size:14px;font-weight:400;letter-spacing:0;text-decoration:none;cursor:pointer;height:48px;line-height:48px;white-space:nowrap;opacity:0;transition:opacity .2s cubic-bezier(.4,0,.2,1);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-menu__container.is-visible .mdl-menu__item{opacity:1}.mdl-menu__item::-moz-focus-inner{border:0}.mdl-menu__item--full-bleed-divider{border-bottom:1px solid rgba(0,0,0,.12)}.mdl-menu__item[disabled],.mdl-menu__item[data-mdl-disabled]{color:#bdbdbd;background-color:transparent;cursor:auto}.mdl-menu__item[disabled]:hover,.mdl-menu__item[data-mdl-disabled]:hover{background-color:transparent}.mdl-menu__item[disabled]:focus,.mdl-menu__item[data-mdl-disabled]:focus{background-color:transparent}.mdl-menu__item[disabled] .mdl-ripple,.mdl-menu__item[data-mdl-disabled] .mdl-ripple{background:0 0}.mdl-menu__item:hover{background-color:#eee}.mdl-menu__item:focus{outline:none;background-color:#eee}.mdl-menu__item:active{background-color:#e0e0e0}.mdl-menu__item--ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-progress{display:block;position:relative;height:4px;width:500px;max-width:100%}.mdl-progress>.bar{display:block;position:absolute;top:0;bottom:0;width:0%;transition:width .2s cubic-bezier(.4,0,.2,1)}.mdl-progress>.progressbar{background-color:#3f51b5;z-index:1;left:0}.mdl-progress>.bufferbar{background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5 ,#3f51b5);z-index:0;left:0}.mdl-progress>.auxbar{right:0}@supports (-webkit-appearance:none){.mdl-progress:not(.mdl-progress--indeterminate):not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate):not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5 ,#3f51b5);-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=")}}.mdl-progress:not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(255,255,255,.9),rgba(255,255,255,.9)),linear-gradient(to right,#3f51b5 ,#3f51b5)}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1{-webkit-animation-name:indeterminate1;animation-name:indeterminate1}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1,.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-color:#3f51b5;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-image:none;-webkit-animation-name:indeterminate2;animation-name:indeterminate2}@-webkit-keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@-webkit-keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}@keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}.mdl-navigation{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;box-sizing:border-box}.mdl-navigation__link{color:#424242;text-decoration:none;margin:0;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0;opacity:.87}.mdl-navigation__link .material-icons{vertical-align:middle}.mdl-layout{width:100%;height:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-overflow-scrolling:touch}.mdl-layout.is-small-screen .mdl-layout--large-screen-only{display:none}.mdl-layout:not(.is-small-screen) .mdl-layout--small-screen-only{display:none}.mdl-layout__container{position:absolute;width:100%;height:100%}.mdl-layout__title,.mdl-layout-title{display:block;position:relative;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.mdl-layout-spacer{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-layout__drawer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;width:240px;height:100%;max-height:100%;position:absolute;top:0;left:0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);box-sizing:border-box;border-right:1px solid #e0e0e0;background:#fafafa;-webkit-transform:translateX(-250px);transform:translateX(-250px);-webkit-transform-style:preserve-3d;transform-style:preserve-3d;will-change:transform;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;color:#424242;overflow:visible;overflow-y:auto;z-index:5}.mdl-layout__drawer.is-visible{-webkit-transform:translateX(0);transform:translateX(0)}.mdl-layout__drawer.is-visible~.mdl-layout__content.mdl-layout__content{overflow:hidden}.mdl-layout__drawer>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:64px;padding-left:40px}@media screen and (max-width:1024px){.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:56px;padding-left:16px}}.mdl-layout__drawer .mdl-navigation{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:stretch;-ms-flex-align:stretch;-ms-grid-row-align:stretch;align-items:stretch;padding-top:16px}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{display:block;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;padding:16px 40px;margin:0;color:#757575}@media screen and (max-width:1024px){.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{padding:16px}}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover{background-color:#e0e0e0}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link--current{background-color:#000;color:#e0e0e0}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__drawer{-webkit-transform:translateX(0);transform:translateX(0)}}.mdl-layout__drawer-button{display:block;position:absolute;height:48px;width:48px;border:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden;text-align:center;cursor:pointer;font-size:26px;line-height:50px;font-family:Helvetica,Arial,sans-serif;margin:10px 12px;top:0;left:0;color:#fff;z-index:4}.mdl-layout__header .mdl-layout__drawer-button{position:absolute;color:#fff;background-color:inherit}@media screen and (max-width:1024px){.mdl-layout__header .mdl-layout__drawer-button{margin:4px}}@media screen and (max-width:1024px){.mdl-layout__drawer-button{margin:4px;color:rgba(0,0,0,.5)}}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__drawer-button,.mdl-layout--no-desktop-drawer-button .mdl-layout__drawer-button{display:none}}.mdl-layout--no-drawer-button .mdl-layout__drawer-button{display:none}.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;margin:0;padding:0;border:none;min-height:64px;max-height:1000px;z-index:3;background-color:#3f51b5;color:#fff;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:max-height,box-shadow}@media screen and (max-width:1024px){.mdl-layout__header{min-height:56px}}.mdl-layout--fixed-drawer.is-upgraded:not(.is-small-screen)>.mdl-layout__header{margin-left:240px;width:calc(100% - 240px)}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__header .mdl-layout__header-row{padding-left:40px}}.mdl-layout__header>.mdl-layout-icon{position:absolute;left:40px;top:16px;height:32px;width:32px;overflow:hidden;z-index:3;display:block}@media screen and (max-width:1024px){.mdl-layout__header>.mdl-layout-icon{left:16px;top:12px}}.mdl-layout.has-drawer .mdl-layout__header>.mdl-layout-icon{display:none}.mdl-layout__header.is-compact{max-height:64px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact{max-height:56px}}.mdl-layout__header.is-compact.has-tabs{height:112px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact.has-tabs{min-height:104px}}@media screen and (max-width:1024px){.mdl-layout__header{display:none}.mdl-layout--fixed-header>.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex}}.mdl-layout__header--transparent.mdl-layout__header--transparent{background-color:transparent;box-shadow:none}.mdl-layout__header--seamed,.mdl-layout__header--scroll{box-shadow:none}.mdl-layout__header--waterfall{box-shadow:none;overflow:hidden}.mdl-layout__header--waterfall.is-casting-shadow{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-layout__header--waterfall.mdl-layout__header--waterfall-hide-top{-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.mdl-layout__header-row{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;box-sizing:border-box;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:64px;margin:0;padding:0 40px 0 80px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:40px}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__header-row{padding-left:40px}}@media screen and (max-width:1024px){.mdl-layout__header-row{height:56px;padding:0 16px 0 72px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:16px}}.mdl-layout__header-row>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__header--scroll .mdl-layout__header-row{width:100%}.mdl-layout__header-row .mdl-navigation{margin:0;padding:0;height:64px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-ms-flex-align:center;-ms-grid-row-align:center;align-items:center}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation{height:56px}}.mdl-layout__header-row .mdl-navigation__link{display:block;color:#fff;line-height:64px;padding:0 24px}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation__link{line-height:56px;padding:0 16px}}.mdl-layout__obfuscator{background-color:transparent;position:absolute;top:0;left:0;height:100%;width:100%;z-index:4;visibility:hidden;transition-property:background-color;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-layout__obfuscator.is-visible{background-color:rgba(0,0,0,.5);visibility:visible}@supports (pointer-events:auto){.mdl-layout__obfuscator{background-color:rgba(0,0,0,.5);opacity:0;transition-property:opacity;visibility:visible;pointer-events:none}.mdl-layout__obfuscator.is-visible{pointer-events:auto;opacity:1}}.mdl-layout__content{-ms-flex:0 1 auto;position:relative;display:inline-block;overflow-y:auto;overflow-x:hidden;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;z-index:1;-webkit-overflow-scrolling:touch}.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:240px}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow:visible}@media screen and (max-width:1024px){.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:0}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow-y:auto;overflow-x:hidden}}.mdl-layout__tab-bar{height:96px;margin:0;width:calc(100% - 112px);padding:0 0 0 56px;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:#3f51b5;overflow-y:hidden;overflow-x:scroll}.mdl-layout__tab-bar::-webkit-scrollbar{display:none}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}}@media screen and (max-width:1024px){.mdl-layout__tab-bar{width:calc(100% - 60px);padding:0 0 0 60px}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{width:calc(100% - 8px);padding-left:4px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar{padding:0;overflow:hidden;width:100%}.mdl-layout__tab-bar-container{position:relative;height:48px;width:100%;border:none;margin:0;z-index:2;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.mdl-layout__container>.mdl-layout__tab-bar-container{position:absolute;top:0;left:0}.mdl-layout__tab-bar-button{display:inline-block;position:absolute;top:0;height:48px;width:56px;z-index:4;text-align:center;background-color:#3f51b5;color:transparent;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button{width:16px}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button .material-icons,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button .material-icons{position:relative;left:-4px}@media screen and (max-width:1024px){.mdl-layout__tab-bar-button{display:none;width:60px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar-button{display:none}.mdl-layout__tab-bar-button .material-icons{line-height:48px}.mdl-layout__tab-bar-button.is-active{color:#fff}.mdl-layout__tab-bar-left-button{left:0}.mdl-layout__tab-bar-right-button{right:0}.mdl-layout__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(255,255,255,.6);overflow:hidden}@media screen and (max-width:1024px){.mdl-layout__tab{padding:0 12px}}.mdl-layout--fixed-tabs .mdl-layout__tab{float:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0}.mdl-layout.is-upgraded .mdl-layout__tab.is-active{color:#fff}.mdl-layout.is-upgraded .mdl-layout__tab.is-active::after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#ff4081;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-layout__tab .mdl-layout__tab-ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-layout__tab .mdl-layout__tab-ripple-container .mdl-ripple{background-color:#fff}.mdl-layout__tab-panel{display:block}.mdl-layout.is-upgraded .mdl-layout__tab-panel{display:none}.mdl-layout.is-upgraded .mdl-layout__tab-panel.is-active{display:block}.mdl-radio{position:relative;font-size:16px;line-height:24px;display:inline-block;box-sizing:border-box;margin:0;padding-left:0}.mdl-radio.is-upgraded{padding-left:24px}.mdl-radio__button{line-height:24px}.mdl-radio.is-upgraded .mdl-radio__button{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-radio__outer-circle{position:absolute;top:4px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;border:2px solid rgba(0,0,0,.54);border-radius:50%;z-index:2}.mdl-radio.is-checked .mdl-radio__outer-circle{border:2px solid #3f51b5}.mdl-radio__outer-circle fieldset[disabled] .mdl-radio,.mdl-radio.is-disabled .mdl-radio__outer-circle{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-radio__inner-circle{position:absolute;z-index:1;margin:0;top:8px;left:4px;box-sizing:border-box;width:8px;height:8px;cursor:pointer;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;-webkit-transform:scale3d(0,0,0);transform:scale3d(0,0,0);border-radius:50%;background:#3f51b5}.mdl-radio.is-checked .mdl-radio__inner-circle{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}fieldset[disabled] .mdl-radio .mdl-radio__inner-circle,.mdl-radio.is-disabled .mdl-radio__inner-circle{background:rgba(0,0,0,.26);cursor:auto}.mdl-radio.is-focused .mdl-radio__inner-circle{box-shadow:0 0 0 10px rgba(0,0,0,.1)}.mdl-radio__label{cursor:pointer}fieldset[disabled] .mdl-radio .mdl-radio__label,.mdl-radio.is-disabled .mdl-radio__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-radio__ripple-container{position:absolute;z-index:2;top:-9px;left:-13px;box-sizing:border-box;width:42px;height:42px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-radio__ripple-container .mdl-ripple{background:#3f51b5}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container,.mdl-radio.is-disabled .mdl-radio__ripple-container{cursor:auto}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container .mdl-ripple,.mdl-radio.is-disabled .mdl-radio__ripple-container .mdl-ripple{background:0 0}_:-ms-input-placeholder,:root .mdl-slider.mdl-slider.is-upgraded{-ms-appearance:none;height:32px;margin:0}.mdl-slider{width:calc(100% - 40px);margin:0 20px}.mdl-slider.is-upgraded{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:2px;background:0 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0;padding:0;color:#3f51b5;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;z-index:1;cursor:pointer}.mdl-slider.is-upgraded::-moz-focus-outer{border:0}.mdl-slider.is-upgraded::-ms-tooltip{display:none}.mdl-slider.is-upgraded::-webkit-slider-runnable-track{background:0 0}.mdl-slider.is-upgraded::-moz-range-track{background:0 0;border:none}.mdl-slider.is-upgraded::-ms-track{background:0 0;color:transparent;height:2px;width:100%;border:none}.mdl-slider.is-upgraded::-ms-fill-lower{padding:0;background:linear-gradient(to right,transparent,transparent 16px,#3f51b5 16px,#3f51b5 0)}.mdl-slider.is-upgraded::-ms-fill-upper{padding:0;background:linear-gradient(to left,transparent,transparent 16px,rgba(0,0,0,.26)16px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:#3f51b5;border:none;transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded::-moz-range-thumb{-moz-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background-image:none;background:#3f51b5;border:none}.mdl-slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.mdl-slider.is-upgraded:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.mdl-slider.is-upgraded:active::-webkit-slider-thumb{background-image:none;background:#3f51b5;-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded:active::-moz-range-thumb{background-image:none;background:#3f51b5;transform:scale(1.5)}.mdl-slider.is-upgraded::-ms-thumb{width:32px;height:32px;border:none;border-radius:50%;background:#3f51b5;transform:scale(.375);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,#3f51b5 0%,#3f51b5 37.5%,rgba(63,81,181,.26)37.5%,rgba(63,81,181,.26)100%);transform:scale(1)}.mdl-slider.is-upgraded:active::-ms-thumb{background:#3f51b5;transform:scale(.5625)}.mdl-slider.is-upgraded.is-lowest-value::-webkit-slider-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-moz-range-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb{border:1.6px solid rgba(0,0,0,.26);-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:9px}.mdl-slider.is-upgraded.is-lowest-value:active::-moz-range-thumb{border:1.5px solid rgba(0,0,0,.26);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value::-ms-thumb{background:radial-gradient(circle closest-side,transparent 0%,transparent 66.67%,rgba(0,0,0,.26)66.67%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgba(0,0,0,.12)0%,rgba(0,0,0,.12)25%,rgba(0,0,0,.26)25%,rgba(0,0,0,.26)37.5%,rgba(0,0,0,.12)37.5%,rgba(0,0,0,.12)100%);transform:scale(1)}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-thumb{transform:scale(.5625);background:radial-gradient(circle closest-side,transparent 0%,transparent 77.78%,rgba(0,0,0,.26)77.78%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-lower{background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-fill-upper{margin-left:9px}.mdl-slider.is-upgraded:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled::-webkit-slider-thumb{-webkit-transform:scale(.667);transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded:disabled::-moz-range-thumb{transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-lower{background-color:rgba(0,0,0,.26);left:-6px}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-webkit-slider-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;-webkit-transform:scale(.667);transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-moz-range-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded:disabled:active::-ms-thumb,.mdl-slider.is-upgraded:disabled::-ms-thumb{transform:scale(.25);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-ms-thumb{transform:scale(.25);background:radial-gradient(circle closest-side,transparent 0%,transparent 50%,rgba(0,0,0,.26)50%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded:disabled::-ms-fill-lower{margin-right:6px;background:linear-gradient(to right,transparent,transparent 25px,rgba(0,0,0,.26)25px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded:disabled::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-fill-upper{margin-left:6px}.mdl-slider__ie-container{height:18px;overflow:visible;border:none;margin:none;padding:none}.mdl-slider__container{height:18px;position:relative;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.mdl-slider__container,.mdl-slider__background-flex{background:0 0;display:-webkit-flex;display:-ms-flexbox;display:flex}.mdl-slider__background-flex{position:absolute;height:2px;width:calc(100% - 52px);top:50%;left:0;margin:0 26px;overflow:hidden;border:0;padding:0;-webkit-transform:translate(0,-1px);transform:translate(0,-1px)}.mdl-slider__background-lower{background:#3f51b5}.mdl-slider__background-lower,.mdl-slider__background-upper{-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0}.mdl-slider__background-upper{background:rgba(0,0,0,.26);transition:left .18s cubic-bezier(.4,0,.2,1)}.mdl-snackbar{position:fixed;bottom:0;left:50%;cursor:default;background-color:#323232;z-index:3;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;font-family:"Roboto","Helvetica","Arial",sans-serif;will-change:transform;-webkit-transform:translate(0,80px);transform:translate(0,80px);transition:transform .25s cubic-bezier(.4,0,1,1);transition:transform .25s cubic-bezier(.4,0,1,1),-webkit-transform .25s cubic-bezier(.4,0,1,1);pointer-events:none}@media (max-width:479px){.mdl-snackbar{width:100%;left:0;min-height:48px;max-height:80px}}@media (min-width:480px){.mdl-snackbar{min-width:288px;max-width:568px;border-radius:2px;-webkit-transform:translate(-50%,80px);transform:translate(-50%,80px)}}.mdl-snackbar--active{-webkit-transform:translate(0,0);transform:translate(0,0);pointer-events:auto;transition:transform .25s cubic-bezier(0,0,.2,1);transition:transform .25s cubic-bezier(0,0,.2,1),-webkit-transform .25s cubic-bezier(0,0,.2,1)}@media (min-width:480px){.mdl-snackbar--active{-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}}.mdl-snackbar__text{padding:14px 12px 14px 24px;vertical-align:middle;color:#fff;float:left}.mdl-snackbar__action{background:0 0;border:none;color:#ff4081;float:right;padding:14px 24px 14px 12px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;line-height:1;letter-spacing:0;overflow:hidden;outline:none;opacity:0;pointer-events:none;cursor:pointer;text-decoration:none;text-align:center;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.mdl-snackbar__action::-moz-focus-inner{border:0}.mdl-snackbar__action:not([aria-hidden]){opacity:1;pointer-events:auto}.mdl-spinner{display:inline-block;position:relative;width:28px;height:28px}.mdl-spinner:not(.is-upgraded).is-active:after{content:"Loading..."}.mdl-spinner.is-upgraded.is-active{-webkit-animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite;animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite}@-webkit-keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.mdl-spinner__layer{position:absolute;width:100%;height:100%;opacity:0}.mdl-spinner__layer-1{border-color:#42a5f5}.mdl-spinner--single-color .mdl-spinner__layer-1{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-1{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-2{border-color:#f44336}.mdl-spinner--single-color .mdl-spinner__layer-2{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-2{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-3{border-color:#fdd835}.mdl-spinner--single-color .mdl-spinner__layer-3{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-3{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-4{border-color:#4caf50}.mdl-spinner--single-color .mdl-spinner__layer-4{border-color:#3f51b5}.mdl-spinner.is-active .mdl-spinner__layer-4{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@-webkit-keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}@keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}.mdl-spinner__gap-patch{position:absolute;box-sizing:border-box;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__gap-patch .mdl-spinner__circle{width:1000%;left:-450%}.mdl-spinner__circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__circle-clipper .mdl-spinner__circle{width:200%}.mdl-spinner__circle{box-sizing:border-box;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent!important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0;left:0}.mdl-spinner__left .mdl-spinner__circle{border-right-color:transparent!important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.mdl-spinner.is-active .mdl-spinner__left .mdl-spinner__circle{-webkit-animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__right .mdl-spinner__circle{left:-100%;border-left-color:transparent!important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.mdl-spinner.is-active .mdl-spinner__right .mdl-spinner__circle{-webkit-animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}@keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}.mdl-switch{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0;overflow:visible;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-switch.is-upgraded{padding-left:28px}.mdl-switch__input{line-height:24px}.mdl-switch.is-upgraded .mdl-switch__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-switch__track{background:rgba(0,0,0,.26);position:absolute;left:0;top:5px;height:14px;width:36px;border-radius:14px;cursor:pointer}.mdl-switch.is-checked .mdl-switch__track{background:rgba(63,81,181,.5)}.mdl-switch__track fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__track{background:rgba(0,0,0,.12);cursor:auto}.mdl-switch__thumb{background:#fafafa;position:absolute;left:0;top:2px;height:20px;width:20px;border-radius:50%;cursor:pointer;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:left}.mdl-switch.is-checked .mdl-switch__thumb{background:#3f51b5;left:16px;box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-switch__thumb fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__thumb{background:#bdbdbd;cursor:auto}.mdl-switch__focus-helper{position:absolute;top:50%;left:50%;-webkit-transform:translate(-4px,-4px);transform:translate(-4px,-4px);display:inline-block;box-sizing:border-box;width:8px;height:8px;border-radius:50%;background-color:transparent}.mdl-switch.is-focused .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-switch.is-focused.is-checked .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.mdl-switch__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0;left:24px}.mdl-switch__label fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__label{color:#bdbdbd;cursor:auto}.mdl-switch__ripple-container{position:absolute;z-index:2;top:-12px;left:-14px;box-sizing:border-box;width:48px;height:48px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000);transition-duration:.4s;transition-timing-function:step-end;transition-property:left}.mdl-switch__ripple-container .mdl-ripple{background:#3f51b5}.mdl-switch__ripple-container fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__ripple-container{cursor:auto}fieldset[disabled] .mdl-switch .mdl-switch__ripple-container .mdl-ripple,.mdl-switch.is-disabled .mdl-switch__ripple-container .mdl-ripple{background:0 0}.mdl-switch.is-checked .mdl-switch__ripple-container{left:2px}.mdl-tabs{display:block;width:100%}.mdl-tabs__tab-bar{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:space-between;-ms-flex-line-pack:justify;align-content:space-between;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;height:48px;padding:0;margin:0;border-bottom:1px solid #e0e0e0}.mdl-tabs__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(0,0,0,.54);overflow:hidden}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active{color:rgba(0,0,0,.87)}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#3f51b5;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-tabs__tab .mdl-tabs__ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-tabs__tab .mdl-tabs__ripple-container .mdl-ripple{background:#3f51b5}.mdl-tabs__panel{display:block}.mdl-tabs.is-upgraded .mdl-tabs__panel{display:none}.mdl-tabs.is-upgraded .mdl-tabs__panel.is-active{display:block}@-webkit-keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}@keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}.mdl-textfield{position:relative;font-size:16px;display:inline-block;box-sizing:border-box;width:300px;max-width:100%;margin:0;padding:20px 0}.mdl-textfield .mdl-button{position:absolute;bottom:20px}.mdl-textfield--align-right{text-align:right}.mdl-textfield--full-width{width:100%}.mdl-textfield--expandable{min-width:32px;width:auto;min-height:32px}.mdl-textfield__input{border:none;border-bottom:1px solid rgba(0,0,0,.12);display:block;font-size:16px;font-family:"Helvetica","Arial",sans-serif;margin:0;padding:4px 0;width:100%;background:0 0;text-align:left;color:inherit}.mdl-textfield__input[type="number"]{-moz-appearance:textfield}.mdl-textfield__input[type="number"]::-webkit-inner-spin-button,.mdl-textfield__input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.mdl-textfield.is-focused .mdl-textfield__input{outline:none}.mdl-textfield.is-invalid .mdl-textfield__input{border-color:#d50000;box-shadow:none}fieldset[disabled] .mdl-textfield .mdl-textfield__input,.mdl-textfield.is-disabled .mdl-textfield__input{background-color:transparent;border-bottom:1px dotted rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-textfield textarea.mdl-textfield__input{display:block}.mdl-textfield__label{bottom:0;color:rgba(0,0,0,.26);font-size:16px;left:0;right:0;pointer-events:none;position:absolute;display:block;top:24px;width:100%;overflow:hidden;white-space:nowrap;text-align:left}.mdl-textfield.is-dirty .mdl-textfield__label,.mdl-textfield.has-placeholder .mdl-textfield__label{visibility:hidden}.mdl-textfield--floating-label .mdl-textfield__label{transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{transition:none}fieldset[disabled] .mdl-textfield .mdl-textfield__label,.mdl-textfield.is-disabled.is-disabled .mdl-textfield__label{color:rgba(0,0,0,.26)}.mdl-textfield--floating-label.is-focused .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{color:#3f51b5;font-size:12px;top:4px;visibility:visible}.mdl-textfield--floating-label.is-focused .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__expandable-holder .mdl-textfield__label{top:-16px}.mdl-textfield--floating-label.is-invalid .mdl-textfield__label{color:#d50000;font-size:12px}.mdl-textfield__label:after{background-color:#3f51b5;bottom:20px;content:'';height:2px;left:45%;position:absolute;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden;width:10px}.mdl-textfield.is-focused .mdl-textfield__label:after{left:0;visibility:visible;width:100%}.mdl-textfield.is-invalid .mdl-textfield__label:after{background-color:#d50000}.mdl-textfield__error{color:#d50000;position:absolute;font-size:12px;margin-top:3px;visibility:hidden;display:block}.mdl-textfield.is-invalid .mdl-textfield__error{visibility:visible}.mdl-textfield__expandable-holder{display:inline-block;position:relative;margin-left:32px;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:inline-block;max-width:.1px}.mdl-textfield.is-focused .mdl-textfield__expandable-holder,.mdl-textfield.is-dirty .mdl-textfield__expandable-holder{max-width:600px}.mdl-textfield__expandable-holder .mdl-textfield__label:after{bottom:0}.mdl-tooltip{-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:top center;transform-origin:top center;will-change:transform;z-index:999;background:rgba(97,97,97,.9);border-radius:2px;color:#fff;display:inline-block;font-size:10px;font-weight:500;line-height:14px;max-width:170px;position:fixed;top:-500px;left:-500px;padding:8px;text-align:center}.mdl-tooltip.is-active{-webkit-animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards;animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards}.mdl-tooltip--large{line-height:14px;font-size:14px;padding:16px}@-webkit-keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}@keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}.mdl-shadow--2dp{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.mdl-shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.mdl-shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.mdl-shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.mdl-shadow--24dp{box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2)}.mdl-grid{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;margin:0 auto;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.mdl-grid.mdl-grid--no-spacing{padding:0}.mdl-cell{box-sizing:border-box}.mdl-cell--top{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.mdl-cell--middle{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.mdl-cell--bottom{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.mdl-cell--stretch{-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch}.mdl-grid.mdl-grid--no-spacing>.mdl-cell{margin:0}.mdl-cell--order-1{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12{-webkit-order:12;-ms-flex-order:12;order:12}@media (max-width:479px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:100%}.mdl-cell--hide-phone{display:none!important}.mdl-cell--order-1-phone.mdl-cell--order-1-phone{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-phone.mdl-cell--order-2-phone{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-phone.mdl-cell--order-3-phone{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-phone.mdl-cell--order-4-phone{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-phone.mdl-cell--order-5-phone{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-phone.mdl-cell--order-6-phone{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-phone.mdl-cell--order-7-phone{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-phone.mdl-cell--order-8-phone{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-phone.mdl-cell--order-9-phone{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-phone.mdl-cell--order-10-phone{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-phone.mdl-cell--order-11-phone{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-phone.mdl-cell--order-12-phone{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:25%}.mdl-cell--2-col,.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:50%}.mdl-cell--3-col,.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:75%}.mdl-cell--4-col,.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:100%}.mdl-cell--5-col,.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:100%}.mdl-cell--6-col,.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:100%}.mdl-cell--7-col,.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:100%}.mdl-cell--8-col,.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:25%}.mdl-cell--2-offset,.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:50%}.mdl-cell--3-offset,.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:75%}}@media (min-width:480px) and (max-width:839px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:50%}.mdl-cell--hide-tablet{display:none!important}.mdl-cell--order-1-tablet.mdl-cell--order-1-tablet{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-tablet.mdl-cell--order-2-tablet{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-tablet.mdl-cell--order-3-tablet{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-tablet.mdl-cell--order-4-tablet{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-tablet.mdl-cell--order-5-tablet{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-tablet.mdl-cell--order-6-tablet{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-tablet.mdl-cell--order-7-tablet{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-tablet.mdl-cell--order-8-tablet{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-tablet.mdl-cell--order-9-tablet{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-tablet.mdl-cell--order-10-tablet{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-tablet.mdl-cell--order-11-tablet{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-tablet.mdl-cell--order-12-tablet{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:calc(12.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:12.5%}.mdl-cell--2-col,.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:25%}.mdl-cell--3-col,.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:calc(37.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:37.5%}.mdl-cell--4-col,.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:50%}.mdl-cell--5-col,.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:calc(62.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:62.5%}.mdl-cell--6-col,.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:75%}.mdl-cell--7-col,.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:calc(87.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:87.5%}.mdl-cell--8-col,.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:calc(12.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:12.5%}.mdl-cell--2-offset,.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:25%}.mdl-cell--3-offset,.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:calc(37.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:37.5%}.mdl-cell--4-offset,.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:50%}.mdl-cell--5-offset,.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:calc(62.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:62.5%}.mdl-cell--6-offset,.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:75%}.mdl-cell--7-offset,.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:calc(87.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:87.5%}}@media (min-width:840px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:33.3333333333%}.mdl-cell--hide-desktop{display:none!important}.mdl-cell--order-1-desktop.mdl-cell--order-1-desktop{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-desktop.mdl-cell--order-2-desktop{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-desktop.mdl-cell--order-3-desktop{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-desktop.mdl-cell--order-4-desktop{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-desktop.mdl-cell--order-5-desktop{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-desktop.mdl-cell--order-6-desktop{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-desktop.mdl-cell--order-7-desktop{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-desktop.mdl-cell--order-8-desktop{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-desktop.mdl-cell--order-9-desktop{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-desktop.mdl-cell--order-10-desktop{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-desktop.mdl-cell--order-11-desktop{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-desktop.mdl-cell--order-12-desktop{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:calc(8.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:8.3333333333%}.mdl-cell--2-col,.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:calc(16.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:16.6666666667%}.mdl-cell--3-col,.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:25%}.mdl-cell--4-col,.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:33.3333333333%}.mdl-cell--5-col,.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:calc(41.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:41.6666666667%}.mdl-cell--6-col,.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:50%}.mdl-cell--7-col,.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:calc(58.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:58.3333333333%}.mdl-cell--8-col,.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:calc(66.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:66.6666666667%}.mdl-cell--9-col,.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:75%}.mdl-cell--10-col,.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:calc(83.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:83.3333333333%}.mdl-cell--11-col,.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:calc(91.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:91.6666666667%}.mdl-cell--12-col,.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:calc(8.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:8.3333333333%}.mdl-cell--2-offset,.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:calc(16.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:16.6666666667%}.mdl-cell--3-offset,.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:25%}.mdl-cell--4-offset,.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:calc(33.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:33.3333333333%}.mdl-cell--5-offset,.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:calc(41.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:41.6666666667%}.mdl-cell--6-offset,.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:50%}.mdl-cell--7-offset,.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:calc(58.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:58.3333333333%}.mdl-cell--8-offset,.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:calc(66.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:66.6666666667%}.mdl-cell--9-offset,.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:75%}.mdl-cell--10-offset,.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:calc(83.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:83.3333333333%}.mdl-cell--11-offset,.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:calc(91.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:91.6666666667%}} -/*# sourceMappingURL=material.min.css.map */ diff --git a/dottydoc/jvm/resources/material.min.js b/dottydoc/jvm/resources/material.min.js deleted file mode 100644 index c9efeaf98f43..000000000000 --- a/dottydoc/jvm/resources/material.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * material-design-lite - Material Design Components in CSS, JS and HTML - * @version v1.1.3 - * @license Apache-2.0 - * @copyright 2015 Google, Inc. - * @link https://github.com/google/material-design-lite - */ -!function(){"use strict";function e(e,t){if(e){if(t.element_.classList.contains(t.CssClasses_.MDL_JS_RIPPLE_EFFECT)){var s=document.createElement("span");s.classList.add(t.CssClasses_.MDL_RIPPLE_CONTAINER),s.classList.add(t.CssClasses_.MDL_JS_RIPPLE_EFFECT);var i=document.createElement("span");i.classList.add(t.CssClasses_.MDL_RIPPLE),s.appendChild(i),e.appendChild(s)}e.addEventListener("click",function(s){s.preventDefault();var i=e.href.split("#")[1],n=t.element_.querySelector("#"+i);t.resetTabState_(),t.resetPanelState_(),e.classList.add(t.CssClasses_.ACTIVE_CLASS),n.classList.add(t.CssClasses_.ACTIVE_CLASS)})}}function t(e,t,s,i){function n(){var n=e.href.split("#")[1],a=i.content_.querySelector("#"+n);i.resetTabState_(t),i.resetPanelState_(s),e.classList.add(i.CssClasses_.IS_ACTIVE),a.classList.add(i.CssClasses_.IS_ACTIVE)}if(i.tabBar_.classList.contains(i.CssClasses_.JS_RIPPLE_EFFECT)){var a=document.createElement("span");a.classList.add(i.CssClasses_.RIPPLE_CONTAINER),a.classList.add(i.CssClasses_.JS_RIPPLE_EFFECT);var l=document.createElement("span");l.classList.add(i.CssClasses_.RIPPLE),a.appendChild(l),e.appendChild(a)}e.addEventListener("click",function(t){"#"===e.getAttribute("href").charAt(0)&&(t.preventDefault(),n())}),e.show=n}var s={upgradeDom:function(e,t){},upgradeElement:function(e,t){},upgradeElements:function(e){},upgradeAllRegistered:function(){},registerUpgradedCallback:function(e,t){},register:function(e){},downgradeElements:function(e){}};s=function(){function e(e,t){for(var s=0;s_;_++){if(r=l[_],!r)throw new Error("Unable to find a registered component for the given class.");a.push(r.className),i.setAttribute("data-upgraded",a.join(","));var C=new r.classConstructor(i);C[p]=r,c.push(C);for(var u=0,E=r.callbacks.length;E>u;u++)r.callbacks[u](i);r.widget&&(i[r.className]=C);var m;"CustomEvent"in window&&"function"==typeof window.CustomEvent?m=new Event("mdl-componentupgraded",{bubbles:!0,cancelable:!1}):(m=document.createEvent("Events"),m.initEvent("mdl-componentupgraded",!0,!0)),i.dispatchEvent(m)}}function a(e){Array.isArray(e)||(e="function"==typeof e.item?Array.prototype.slice.call(e):[e]);for(var t,s=0,i=e.length;i>s;s++)t=e[s],t instanceof HTMLElement&&(n(t),t.children.length>0&&a(t.children))}function l(t){var s="undefined"==typeof t.widget&&"undefined"==typeof t.widget,i=!0;s||(i=t.widget||t.widget);var n={classConstructor:t.constructor||t.constructor,className:t.classAsString||t.classAsString,cssClass:t.cssClass||t.cssClass,widget:i,callbacks:[]};if(h.forEach(function(e){if(e.cssClass===n.cssClass)throw new Error("The provided cssClass has already been registered: "+e.cssClass);if(e.className===n.className)throw new Error("The provided className has already been registered")}),t.constructor.prototype.hasOwnProperty(p))throw new Error("MDL component classes must not have "+p+" defined as a property.");var a=e(t.classAsString,n);a||h.push(n)}function o(t,s){var i=e(t);i&&i.callbacks.push(s)}function r(){for(var e=0;e0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)&&(e.keyCode===this.Keycodes_.UP_ARROW?(e.preventDefault(),t[t.length-1].focus()):e.keyCode===this.Keycodes_.DOWN_ARROW&&(e.preventDefault(),t[0].focus()))}},d.prototype.handleItemKeyboardEvent_=function(e){if(this.element_&&this.container_){var t=this.element_.querySelectorAll("."+this.CssClasses_.ITEM+":not([disabled])");if(t&&t.length>0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)){var s=Array.prototype.slice.call(t).indexOf(e.target);if(e.keyCode===this.Keycodes_.UP_ARROW)e.preventDefault(),s>0?t[s-1].focus():t[t.length-1].focus();else if(e.keyCode===this.Keycodes_.DOWN_ARROW)e.preventDefault(),t.length>s+1?t[s+1].focus():t[0].focus();else if(e.keyCode===this.Keycodes_.SPACE||e.keyCode===this.Keycodes_.ENTER){e.preventDefault();var i=new MouseEvent("mousedown");e.target.dispatchEvent(i),i=new MouseEvent("mouseup"),e.target.dispatchEvent(i),e.target.click()}else e.keyCode===this.Keycodes_.ESCAPE&&(e.preventDefault(),this.hide())}}},d.prototype.handleItemClick_=function(e){e.target.hasAttribute("disabled")?e.stopPropagation():(this.closing_=!0,window.setTimeout(function(e){this.hide(),this.closing_=!1}.bind(this),this.Constant_.CLOSE_TIMEOUT))},d.prototype.applyClip_=function(e,t){this.element_.classList.contains(this.CssClasses_.UNALIGNED)?this.element_.style.clip="":this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)?this.element_.style.clip="rect(0 "+t+"px 0 "+t+"px)":this.element_.classList.contains(this.CssClasses_.TOP_LEFT)?this.element_.style.clip="rect("+e+"px 0 "+e+"px 0)":this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?this.element_.style.clip="rect("+e+"px "+t+"px "+e+"px "+t+"px)":this.element_.style.clip=""},d.prototype.removeAnimationEndListener_=function(e){e.target.classList.remove(d.prototype.CssClasses_.IS_ANIMATING)},d.prototype.addAnimationEndListener_=function(){this.element_.addEventListener("transitionend",this.removeAnimationEndListener_),this.element_.addEventListener("webkitTransitionEnd",this.removeAnimationEndListener_)},d.prototype.show=function(e){if(this.element_&&this.container_&&this.outline_){var t=this.element_.getBoundingClientRect().height,s=this.element_.getBoundingClientRect().width;this.container_.style.width=s+"px",this.container_.style.height=t+"px",this.outline_.style.width=s+"px",this.outline_.style.height=t+"px";for(var i=this.Constant_.TRANSITION_DURATION_SECONDS*this.Constant_.TRANSITION_DURATION_FRACTION,n=this.element_.querySelectorAll("."+this.CssClasses_.ITEM),a=0;a0&&this.showSnackbar(this.queuedNotifications_.shift())},C.prototype.cleanup_=function(){this.element_.classList.remove(this.cssClasses_.ACTIVE),setTimeout(function(){this.element_.setAttribute("aria-hidden","true"),this.textElement_.textContent="",Boolean(this.actionElement_.getAttribute("aria-hidden"))||(this.setActionHidden_(!0),this.actionElement_.textContent="",this.actionElement_.removeEventListener("click",this.actionHandler_)),this.actionHandler_=void 0,this.message_=void 0,this.actionText_=void 0,this.active=!1,this.checkQueue_()}.bind(this),this.Constant_.ANIMATION_LENGTH)},C.prototype.setActionHidden_=function(e){e?this.actionElement_.setAttribute("aria-hidden","true"):this.actionElement_.removeAttribute("aria-hidden")},s.register({constructor:C,classAsString:"MaterialSnackbar",cssClass:"mdl-js-snackbar",widget:!0});var u=function(e){this.element_=e,this.init()};window.MaterialSpinner=u,u.prototype.Constant_={MDL_SPINNER_LAYER_COUNT:4},u.prototype.CssClasses_={MDL_SPINNER_LAYER:"mdl-spinner__layer",MDL_SPINNER_CIRCLE_CLIPPER:"mdl-spinner__circle-clipper",MDL_SPINNER_CIRCLE:"mdl-spinner__circle",MDL_SPINNER_GAP_PATCH:"mdl-spinner__gap-patch",MDL_SPINNER_LEFT:"mdl-spinner__left",MDL_SPINNER_RIGHT:"mdl-spinner__right"},u.prototype.createLayer=function(e){var t=document.createElement("div");t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER),t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER+"-"+e);var s=document.createElement("div");s.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),s.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);var i=document.createElement("div");i.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);var n=document.createElement("div");n.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),n.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);for(var a=[s,i,n],l=0;l=this.maxRows&&e.preventDefault()},L.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},L.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.onReset_=function(e){this.updateClasses_()},L.prototype.updateClasses_=function(){this.checkDisabled(),this.checkValidity(),this.checkDirty(),this.checkFocus()},L.prototype.checkDisabled=function(){this.input_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},L.prototype.checkDisabled=L.prototype.checkDisabled,L.prototype.checkFocus=function(){Boolean(this.element_.querySelector(":focus"))?this.element_.classList.add(this.CssClasses_.IS_FOCUSED):this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.checkFocus=L.prototype.checkFocus,L.prototype.checkValidity=function(){this.input_.validity&&(this.input_.validity.valid?this.element_.classList.remove(this.CssClasses_.IS_INVALID):this.element_.classList.add(this.CssClasses_.IS_INVALID))},L.prototype.checkValidity=L.prototype.checkValidity,L.prototype.checkDirty=function(){this.input_.value&&this.input_.value.length>0?this.element_.classList.add(this.CssClasses_.IS_DIRTY):this.element_.classList.remove(this.CssClasses_.IS_DIRTY)},L.prototype.checkDirty=L.prototype.checkDirty,L.prototype.disable=function(){this.input_.disabled=!0,this.updateClasses_()},L.prototype.disable=L.prototype.disable,L.prototype.enable=function(){this.input_.disabled=!1,this.updateClasses_()},L.prototype.enable=L.prototype.enable,L.prototype.change=function(e){this.input_.value=e||"",this.updateClasses_()},L.prototype.change=L.prototype.change,L.prototype.init=function(){if(this.element_&&(this.label_=this.element_.querySelector("."+this.CssClasses_.LABEL),this.input_=this.element_.querySelector("."+this.CssClasses_.INPUT),this.input_)){this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)&&(this.maxRows=parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE),10),isNaN(this.maxRows)&&(this.maxRows=this.Constant_.NO_MAX_ROWS)),this.input_.hasAttribute("placeholder")&&this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER),this.boundUpdateClassesHandler=this.updateClasses_.bind(this),this.boundFocusHandler=this.onFocus_.bind(this),this.boundBlurHandler=this.onBlur_.bind(this),this.boundResetHandler=this.onReset_.bind(this),this.input_.addEventListener("input",this.boundUpdateClassesHandler),this.input_.addEventListener("focus",this.boundFocusHandler),this.input_.addEventListener("blur",this.boundBlurHandler),this.input_.addEventListener("reset",this.boundResetHandler),this.maxRows!==this.Constant_.NO_MAX_ROWS&&(this.boundKeyDownHandler=this.onKeyDown_.bind(this),this.input_.addEventListener("keydown",this.boundKeyDownHandler));var e=this.element_.classList.contains(this.CssClasses_.IS_INVALID);this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED),e&&this.element_.classList.add(this.CssClasses_.IS_INVALID),this.input_.hasAttribute("autofocus")&&(this.element_.focus(),this.checkFocus())}},s.register({constructor:L,classAsString:"MaterialTextfield",cssClass:"mdl-js-textfield",widget:!0});var I=function(e){this.element_=e,this.init()};window.MaterialTooltip=I,I.prototype.Constant_={},I.prototype.CssClasses_={IS_ACTIVE:"is-active",BOTTOM:"mdl-tooltip--bottom",LEFT:"mdl-tooltip--left",RIGHT:"mdl-tooltip--right",TOP:"mdl-tooltip--top"},I.prototype.handleMouseEnter_=function(e){var t=e.target.getBoundingClientRect(),s=t.left+t.width/2,i=t.top+t.height/2,n=-1*(this.element_.offsetWidth/2),a=-1*(this.element_.offsetHeight/2);this.element_.classList.contains(this.CssClasses_.LEFT)||this.element_.classList.contains(this.CssClasses_.RIGHT)?(s=t.width/2,0>i+a?(this.element_.style.top=0,this.element_.style.marginTop=0):(this.element_.style.top=i+"px",this.element_.style.marginTop=a+"px")):0>s+n?(this.element_.style.left=0,this.element_.style.marginLeft=0):(this.element_.style.left=s+"px",this.element_.style.marginLeft=n+"px"),this.element_.classList.contains(this.CssClasses_.TOP)?this.element_.style.top=t.top-this.element_.offsetHeight-10+"px":this.element_.classList.contains(this.CssClasses_.RIGHT)?this.element_.style.left=t.left+t.width+10+"px":this.element_.classList.contains(this.CssClasses_.LEFT)?this.element_.style.left=t.left-this.element_.offsetWidth-10+"px":this.element_.style.top=t.top+t.height+10+"px",this.element_.classList.add(this.CssClasses_.IS_ACTIVE)},I.prototype.handleMouseLeave_=function(){this.element_.classList.remove(this.CssClasses_.IS_ACTIVE)},I.prototype.init=function(){if(this.element_){var e=this.element_.getAttribute("for");e&&(this.forElement_=document.getElementById(e)),this.forElement_&&(this.forElement_.hasAttribute("tabindex")||this.forElement_.setAttribute("tabindex","0"),this.boundMouseEnterHandler=this.handleMouseEnter_.bind(this),this.boundMouseLeaveHandler=this.handleMouseLeave_.bind(this),this.forElement_.addEventListener("mouseenter",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("touchend",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("mouseleave",this.boundMouseLeaveHandler,!1),window.addEventListener("touchstart",this.boundMouseLeaveHandler))}},s.register({constructor:I,classAsString:"MaterialTooltip",cssClass:"mdl-tooltip"});var f=function(e){this.element_=e,this.init()};window.MaterialLayout=f,f.prototype.Constant_={MAX_WIDTH:"(max-width: 1024px)",TAB_SCROLL_PIXELS:100,RESIZE_TIMEOUT:100,MENU_ICON:"",CHEVRON_LEFT:"chevron_left",CHEVRON_RIGHT:"chevron_right"},f.prototype.Keycodes_={ENTER:13,ESCAPE:27,SPACE:32},f.prototype.Mode_={STANDARD:0,SEAMED:1,WATERFALL:2,SCROLL:3},f.prototype.CssClasses_={CONTAINER:"mdl-layout__container",HEADER:"mdl-layout__header",DRAWER:"mdl-layout__drawer",CONTENT:"mdl-layout__content",DRAWER_BTN:"mdl-layout__drawer-button",ICON:"material-icons",JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_CONTAINER:"mdl-layout__tab-ripple-container",RIPPLE:"mdl-ripple",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",HEADER_SEAMED:"mdl-layout__header--seamed",HEADER_WATERFALL:"mdl-layout__header--waterfall",HEADER_SCROLL:"mdl-layout__header--scroll",FIXED_HEADER:"mdl-layout--fixed-header",OBFUSCATOR:"mdl-layout__obfuscator",TAB_BAR:"mdl-layout__tab-bar",TAB_CONTAINER:"mdl-layout__tab-bar-container",TAB:"mdl-layout__tab",TAB_BAR_BUTTON:"mdl-layout__tab-bar-button",TAB_BAR_LEFT_BUTTON:"mdl-layout__tab-bar-left-button",TAB_BAR_RIGHT_BUTTON:"mdl-layout__tab-bar-right-button",PANEL:"mdl-layout__tab-panel",HAS_DRAWER:"has-drawer",HAS_TABS:"has-tabs",HAS_SCROLLING_HEADER:"has-scrolling-header",CASTING_SHADOW:"is-casting-shadow",IS_COMPACT:"is-compact",IS_SMALL_SCREEN:"is-small-screen",IS_DRAWER_OPEN:"is-visible",IS_ACTIVE:"is-active",IS_UPGRADED:"is-upgraded",IS_ANIMATING:"is-animating",ON_LARGE_SCREEN:"mdl-layout--large-screen-only",ON_SMALL_SCREEN:"mdl-layout--small-screen-only"},f.prototype.contentScrollHandler_=function(){if(!this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)){var e=!this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN)||this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);this.content_.scrollTop>0&&!this.header_.classList.contains(this.CssClasses_.IS_COMPACT)?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.header_.classList.add(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING)):this.content_.scrollTop<=0&&this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.header_.classList.remove(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING))}},f.prototype.keyboardEventHandler_=function(e){e.keyCode===this.Keycodes_.ESCAPE&&this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)&&this.toggleDrawer()},f.prototype.screenSizeHandler_=function(){this.screenSizeMediaQuery_.matches?this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN):(this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN),this.drawer_&&(this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN),this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN)))},f.prototype.drawerToggleHandler_=function(e){if(e&&"keydown"===e.type){if(e.keyCode!==this.Keycodes_.SPACE&&e.keyCode!==this.Keycodes_.ENTER)return;e.preventDefault()}this.toggleDrawer()},f.prototype.headerTransitionEndHandler_=function(){this.header_.classList.remove(this.CssClasses_.IS_ANIMATING)},f.prototype.headerClickHandler_=function(){this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.IS_COMPACT),this.header_.classList.add(this.CssClasses_.IS_ANIMATING))},f.prototype.resetTabState_=function(e){for(var t=0;ta;a++){var l=i[a];l.classList&&l.classList.contains(this.CssClasses_.HEADER)&&(this.header_=l),l.classList&&l.classList.contains(this.CssClasses_.DRAWER)&&(this.drawer_=l),l.classList&&l.classList.contains(this.CssClasses_.CONTENT)&&(this.content_=l)}window.addEventListener("pageshow",function(e){e.persisted&&(this.element_.style.overflowY="hidden",requestAnimationFrame(function(){this.element_.style.overflowY=""}.bind(this)))}.bind(this),!1),this.header_&&(this.tabBar_=this.header_.querySelector("."+this.CssClasses_.TAB_BAR));var o=this.Mode_.STANDARD;if(this.header_&&(this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)?o=this.Mode_.SEAMED:this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)?(o=this.Mode_.WATERFALL,this.header_.addEventListener("transitionend",this.headerTransitionEndHandler_.bind(this)),this.header_.addEventListener("click",this.headerClickHandler_.bind(this))):this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)&&(o=this.Mode_.SCROLL,e.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER)),o===this.Mode_.STANDARD?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.SEAMED||o===this.Mode_.SCROLL?(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.WATERFALL&&(this.content_.addEventListener("scroll",this.contentScrollHandler_.bind(this)),this.contentScrollHandler_())),this.drawer_){var r=this.element_.querySelector("."+this.CssClasses_.DRAWER_BTN);if(!r){r=document.createElement("div"),r.setAttribute("aria-expanded","false"),r.setAttribute("role","button"),r.setAttribute("tabindex","0"),r.classList.add(this.CssClasses_.DRAWER_BTN);var _=document.createElement("i");_.classList.add(this.CssClasses_.ICON),_.innerHTML=this.Constant_.MENU_ICON,r.appendChild(_)}this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)?r.classList.add(this.CssClasses_.ON_LARGE_SCREEN):this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)&&r.classList.add(this.CssClasses_.ON_SMALL_SCREEN),r.addEventListener("click",this.drawerToggleHandler_.bind(this)),r.addEventListener("keydown",this.drawerToggleHandler_.bind(this)),this.element_.classList.add(this.CssClasses_.HAS_DRAWER),this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)?this.header_.insertBefore(r,this.header_.firstChild):this.element_.insertBefore(r,this.content_);var d=document.createElement("div");d.classList.add(this.CssClasses_.OBFUSCATOR),this.element_.appendChild(d),d.addEventListener("click",this.drawerToggleHandler_.bind(this)),this.obfuscator_=d,this.drawer_.addEventListener("keydown",this.keyboardEventHandler_.bind(this)),this.drawer_.setAttribute("aria-hidden","true")}if(this.screenSizeMediaQuery_=window.matchMedia(this.Constant_.MAX_WIDTH),this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)),this.screenSizeHandler_(),this.header_&&this.tabBar_){this.element_.classList.add(this.CssClasses_.HAS_TABS);var h=document.createElement("div");h.classList.add(this.CssClasses_.TAB_CONTAINER),this.header_.insertBefore(h,this.tabBar_),this.header_.removeChild(this.tabBar_);var c=document.createElement("div");c.classList.add(this.CssClasses_.TAB_BAR_BUTTON),c.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);var p=document.createElement("i");p.classList.add(this.CssClasses_.ICON),p.textContent=this.Constant_.CHEVRON_LEFT,c.appendChild(p),c.addEventListener("click",function(){this.tabBar_.scrollLeft-=this.Constant_.TAB_SCROLL_PIXELS}.bind(this));var C=document.createElement("div");C.classList.add(this.CssClasses_.TAB_BAR_BUTTON),C.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);var u=document.createElement("i");u.classList.add(this.CssClasses_.ICON),u.textContent=this.Constant_.CHEVRON_RIGHT,C.appendChild(u),C.addEventListener("click",function(){this.tabBar_.scrollLeft+=this.Constant_.TAB_SCROLL_PIXELS}.bind(this)),h.appendChild(c),h.appendChild(this.tabBar_),h.appendChild(C);var E=function(){this.tabBar_.scrollLeft>0?c.classList.add(this.CssClasses_.IS_ACTIVE):c.classList.remove(this.CssClasses_.IS_ACTIVE),this.tabBar_.scrollLeft0)return;this.setFrameCount(1);var i,n,a=e.currentTarget.getBoundingClientRect();if(0===e.clientX&&0===e.clientY)i=Math.round(a.width/2),n=Math.round(a.height/2);else{var l=e.clientX?e.clientX:e.touches[0].clientX,o=e.clientY?e.clientY:e.touches[0].clientY;i=Math.round(l-a.left),n=Math.round(o-a.top)}this.setRippleXY(i,n),this.setRippleStyles(!0),window.requestAnimationFrame(this.animFrameHandler.bind(this))}},y.prototype.upHandler_=function(e){e&&2!==e.detail&&window.setTimeout(function(){this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE)}.bind(this),0)},y.prototype.init=function(){if(this.element_){var e=this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)||(this.rippleElement_=this.element_.querySelector("."+this.CssClasses_.RIPPLE),this.frameCount_=0,this.rippleSize_=0,this.x_=0,this.y_=0,this.ignoringMouseDown_=!1,this.boundDownHandler=this.downHandler_.bind(this),this.element_.addEventListener("mousedown",this.boundDownHandler),this.element_.addEventListener("touchstart",this.boundDownHandler),this.boundUpHandler=this.upHandler_.bind(this),this.element_.addEventListener("mouseup",this.boundUpHandler),this.element_.addEventListener("mouseleave",this.boundUpHandler),this.element_.addEventListener("touchend",this.boundUpHandler),this.element_.addEventListener("blur",this.boundUpHandler),this.getFrameCount=function(){return this.frameCount_},this.setFrameCount=function(e){this.frameCount_=e},this.getRippleElement=function(){return this.rippleElement_},this.setRippleXY=function(e,t){this.x_=e,this.y_=t},this.setRippleStyles=function(t){if(null!==this.rippleElement_){var s,i,n,a="translate("+this.x_+"px, "+this.y_+"px)";t?(i=this.Constant_.INITIAL_SCALE,n=this.Constant_.INITIAL_SIZE):(i=this.Constant_.FINAL_SCALE,n=this.rippleSize_+"px",e&&(a="translate("+this.boundWidth/2+"px, "+this.boundHeight/2+"px)")),s="translate(-50%, -50%) "+a+i,this.rippleElement_.style.webkitTransform=s,this.rippleElement_.style.msTransform=s,this.rippleElement_.style.transform=s,t?this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING):this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING)}},this.animFrameHandler=function(){this.frameCount_-- >0?window.requestAnimationFrame(this.animFrameHandler.bind(this)):this.setRippleStyles(!1)})}},s.register({constructor:y,classAsString:"MaterialRipple",cssClass:"mdl-js-ripple-effect",widget:!1})}(); -//# sourceMappingURL=material.min.js.map diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala deleted file mode 100644 index cbcc55451540..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/PrintPhase.scala +++ /dev/null @@ -1,30 +0,0 @@ -package dotty.tools -package dottydoc -package core - -import dotc.CompilationUnit -import dotc.core.Contexts.Context -import dotc.core.Phases.Phase -import model.{Package, Entity} - -/** TODO: re-write to `DocMiniPhase` */ -class PrintPhase extends Phase { - def phaseName = "docPrintPhase" - - var currentRun = 0 - override def run(implicit ctx: Context): Unit = () - - override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { - val compUnits = super.runOn(units) - val packages = ctx.docbase.packages[Package].toMap - - val outputDir = { - val out = ctx.settings.DocOutput.value - if (out.last == '/') out.dropRight(1) - else out - } - if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) - - compUnits - } -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala deleted file mode 100644 index 6eee9abf9403..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala +++ /dev/null @@ -1,44 +0,0 @@ -package dotty.tools.dottydoc -package html - -import scalatags.Text.all._ -import model._ - -case class EntityPage(entity: Entity, packages: Map[String, Package]) { - import model.json._ - import util.internal.setters._ - - private def relPath(to: String, from: Entity) = { - val len = (from.path.length - 1) + (from match { - case _: Package => 1 - case _ => 0 - }) - - "../" * len + to - } - - def render = "" + html( - head( - meta(charset := "utf-8"), - meta(name := "viewport", - content := "width=device-width, initial-scale=1, shrink-to-fit=no"), - meta("http-equiv".attr := "x-ua-compatible", content := "ie=edge"), - - script(`type` := "text/javascript", src := relPath("static/material.min.js", entity)), - script(`type` := "text/javascript", src := relPath("static/highlight.pack.js", entity)), - script(`type` := "text/javascript", src := relPath("index.js", entity)), - script(`type` := "text/javascript", src := relPath("static/dottydoc-fastopt.js", entity)), - link(rel := "stylesheet", href := relPath("static/material-icons.css", entity)), - link(rel := "stylesheet", href := relPath("static/material.min.css", entity)), - link(rel := "stylesheet", href := relPath("static/github.css", entity)), - link(rel := "stylesheet", href := relPath("static/index.css", entity)) - ), - body(div(id := "main-container")), - script( - raw(s"""|UnparsedIndex.currentEntity = ${entity.flat.json}; - |dotty.tools.dottydoc.js.DottyDocJS() - | .main(document.getElementById("main-container")); - """.stripMargin) - ) - ) -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala deleted file mode 100644 index fdbcd49cb953..000000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala +++ /dev/null @@ -1,87 +0,0 @@ -package dotty.tools.dottydoc -package util - -import java.io.{File => JFile, BufferedInputStream, FileInputStream, FileOutputStream, BufferedOutputStream} -import html.EntityPage -import model.Package -import model.json._ - -class OutputWriter { - def write(packs: Map[String, Package], outPath: String): Unit = { - // Write all packages to `outPath` - for (pack <- packs.values) { - println(s"""Writing '${pack.path.mkString(".")}'""") - writeFile( - EntityPage(pack, packs).render, - outPath + pack.path.mkString("/", "/", "/"), - "index.html") - - // Write all package children to outPath - for { - child <- pack.children - if child.kind != "package" - } { - println(s"""Writing '${child.path.mkString(".")}'""") - writeFile( - EntityPage(child, packs).render, - outPath + child.path.dropRight(1).mkString("/", "/", "/"), - child.path.last + ".html") - } - } - - // Write full index to outPath - val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + packs.json + ";" - println("Writing index.js...") - writeFile(js, outPath + "/", "index.js") - - // Write resources to outPath - println("Copying CSS/JS resources to destination...") - assert(resources.nonEmpty) - resources.map(copy(_, outPath)) - - println("Done writing static material, building js-app") - } - - def writeFile(str: String, path: String, file: String): Unit = - writeFile(str.map(_.toByte).toArray, path, file) - - def writeFile(bytes: Array[Byte], path: String, file: String): Unit = { - def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) = { - val bos = new BufferedOutputStream(new FileOutputStream(f)) - try { - Stream.continually(bos.write(bytes)) - } finally bos.close() - } - - new java.io.File(path).mkdirs() - printToFile(new java.io.File(path + file))(printer => bytes.foreach(printer.print)) - } - - def copy(src: JFile, path: String): Unit = { - val reader = new BufferedInputStream(new FileInputStream(src)) - try { - val bytes = Stream.continually(reader.read).takeWhile(-1 != _).map(_.toByte) - writeFile(bytes.toArray, path + "/static/", src.getName) - } finally reader.close() - } - - /** All static resources */ - private val resources: Iterable[JFile] = List( - "/MaterialIcons-Regular.eot", - "/MaterialIcons-Regular.ijmap", - "/MaterialIcons-Regular.svg", - "/MaterialIcons-Regular.ttf", - "/MaterialIcons-Regular.woff", - "/MaterialIcons-Regular.woff2", - "/codepoints", - "/github.css", - "/highlight.pack.js", - "/index.css", - "/material-icons.css", - "/material.min.css", - "/material.min.js", - "/dottydoc-fastopt.js" - ).map { f => - new JFile(this.getClass.getResource(f).toURI) - } -} diff --git a/dottydoc/jvm/test/WhitelistedStdLibMain.scala b/dottydoc/jvm/test/WhitelistedStdLibMain.scala deleted file mode 100644 index 49e8f4fc59b8..000000000000 --- a/dottydoc/jvm/test/WhitelistedStdLibMain.scala +++ /dev/null @@ -1,23 +0,0 @@ -package dotty.tools -package dottydoc - -import scala.io.Source - -object WhitelistedStandardLib extends DottyDoc { - val files: List[String] = { - val whitelist = "../../test/dotc/scala-collections.whitelist" - - Source.fromFile(whitelist, "UTF8") - .getLines() - .map(_.trim) // allow identation - .filter(!_.startsWith("#")) // allow comment lines prefixed by # - .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line - .filter(_.nonEmpty) - .filterNot(_.endsWith("package.scala")) - .map("../." + _) - .toList - } - - override def main(args: Array[String]) = - super.main("-language:Scala2" +: "-Ydoc-output" +: "../../build/dottydoc" +: files.toArray) -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala similarity index 78% rename from dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala rename to dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala index 120b743b8c3c..bef9141f2bdb 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala @@ -10,6 +10,10 @@ import dotc.core.Phases.Phase import dotc.typer.FrontEnd import dotc.{ CompilationUnit, Compiler, Driver, Run } import io.PlainFile +import model.Package +import model.json._ + +import _root_.java.util.{ Map => JMap } /** Custom Compiler with phases for the documentation tool * @@ -20,9 +24,7 @@ import io.PlainFile * Example: * 1. Use the existing FrontEnd to typecheck the code being fed to dottydoc * 2. Create an AST that is serializable - * 3. Serialize to JS-Object and write to file - * 4. Deserialize on client side with Scala.js - * 5. Serve content using Scala.js + * 3. Serialize to JS object */ class DottyDocCompiler extends Compiler { override def phases: List[List[Phase]] = List( @@ -32,8 +34,7 @@ class DottyDocCompiler extends Compiler { List(DocMiniTransformations(new LinkReturnTypes, new LinkParamListTypes, new LinkImplicitlyAddedTypes, - new SortMembers)), - List(new PrintPhase) + new SortMembers)) ) override def newRun(implicit ctx: Context): Run = { @@ -66,7 +67,9 @@ class DocRun(comp: Compiler)(implicit ctx: Context) extends Run(comp)(ctx) { ) } -trait DottyDoc extends Driver { +abstract class DottyDocDriver extends Driver { + import scala.collection.JavaConverters._ + override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { val ctx = rootCtx.fresh val summary = CompilerCommand.distill(args)(ctx) @@ -79,6 +82,18 @@ trait DottyDoc extends Driver { } override def newCompiler(implicit ctx: Context): Compiler = new DottyDocCompiler -} -object Main extends DottyDoc + + def compiledDocs(args: Array[String]): collection.Map[String, Package] = { + val (fileNames, ctx) = setup(args, initCtx.fresh) + doCompile(newCompiler(ctx), fileNames)(ctx) + + ctx.docbase.packages[Package] + } + + def compiledDocsJava(args: Array[String]): JMap[String, Package] = + compiledDocs(args).asJava + + def indexToJson(index: JMap[String, Package]): String = + index.asScala.json +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/DocASTPhase.scala rename to dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala rename to dottydoc/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala b/dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala rename to dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala diff --git a/dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala new file mode 100644 index 000000000000..9f8dfdca69a5 --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala @@ -0,0 +1,13 @@ +package dotty.tools +package dottydoc +package core + +import dotc.CompilationUnit +import dotc.core.Contexts.Context +import dotc.core.Phases.Phase +import model.{Package, Entity} + +abstract class JsonOutputPhase extends Phase { + def phaseName = "jsonOutputPhase" + println("wabalubadubdub") +} diff --git a/dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala new file mode 100644 index 000000000000..080687877cdd --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala @@ -0,0 +1,30 @@ +package dotty.tools +package dottydoc +package core + +import dotc.CompilationUnit +import dotc.core.Contexts.Context +import dotc.core.Phases.Phase +import model.{Package, Entity} + +/** TODO: re-write to `DocMiniPhase` */ +//class PrintPhase extends Phase { +// def phaseName = "docPrintPhase" +// +// var currentRun = 0 +// override def run(implicit ctx: Context): Unit = () +// +// override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { +// val compUnits = super.runOn(units) +// val packages = ctx.docbase.packages[Package].toMap +// +// val outputDir = { +// val out = ctx.settings.DocOutput.value +// if (out.last == '/') out.dropRight(1) +// else out +// } +// if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) +// +// compUnits +// } +//} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/SortMembersPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/SortMembersPhase.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/SortMembersPhase.scala rename to dottydoc/src/dotty/tools/dottydoc/core/SortMembersPhase.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala similarity index 98% rename from dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala rename to dottydoc/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 9d29176c2e3e..c2d647290d72 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -7,9 +7,10 @@ import dotc.util.Positions.NoPosition import transform.DocMiniPhase import model._ -import comment._ -import BodyParsers._ import model.internal._ +import model.comment._ +import model.references._ +import BodyParsers._ import util.MemberLookup import util.traversing._ import util.internal.setters._ diff --git a/dottydoc/src/dotty/tools/dottydoc/interface/Dottydoc.java b/dottydoc/src/dotty/tools/dottydoc/interface/Dottydoc.java new file mode 100644 index 000000000000..cc8424f1460c --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/interface/Dottydoc.java @@ -0,0 +1,27 @@ +package dotty.tools.dottydoc.java; + +import dotty.tools.dottydoc.DottyDocDriver; +import dotty.tools.dottydoc.model.Package; +import dotty.tools.dottydoc.util.OutputWriter; +import java.util.Map; +import java.util.List; + +/** FIXME: document me! */ +public class Dottydoc extends DottyDocDriver { + public Map createIndex(String[] args) { + return compiledDocsJava(args); + } + + public String createJsonIndex(String[] args) { + return indexToJson(createIndex(args)); + } + + public void buildDocs( + String outputDir, + String templatePath, + List resources, + Map index + ) { + new OutputWriter().writeJava(index, templatePath, outputDir, resources); + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala similarity index 77% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala index 08da81059bfa..29fe48de3ebc 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala @@ -92,19 +92,3 @@ final case class Tooltip(name: String) extends LinkTo /** Linking directly to entities is not picklable because of cyclic references */ final case class LinkToEntity(entity: Entity) extends LinkTo - -/** Use MaterializableLink for entities that need be picklable */ -sealed trait MaterializableLink { def title: String } -final case class UnsetLink(title: String, query: String) extends MaterializableLink -final case class MaterializedLink(title: String, target: String) extends MaterializableLink -final case class NoLink(title: String, target: String) extends MaterializableLink - -sealed trait Reference -final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[Reference]) extends Reference -final case class OrTypeReference(left: Reference, right: Reference) extends Reference -final case class AndTypeReference(left: Reference, right: Reference) extends Reference -final case class FunctionReference(args: List[Reference], returnValue: Reference) extends Reference -final case class TupleReference(args: List[Reference]) extends Reference -final case class BoundsReference(low: Reference, high: Reference) extends Reference -final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false, isRepeated: Boolean = false) extends Reference -final case class ConstantReference(title: String) extends Reference diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/Comment.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/Comment.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala similarity index 88% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala index 5eb64c6125bf..27b0ff97730e 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentCleaner.scala @@ -18,7 +18,7 @@ trait CommentCleaner { val javadoclessComment = JavadocTags.replaceAllIn(safeComment, { javadocReplacement(_) }) val markedTagComment = SafeTags.replaceAllIn(javadoclessComment, { mtch => - java.util.regex.Matcher.quoteReplacement(safeTagMarker + mtch.matched + safeTagMarker) + _root_.java.util.regex.Matcher.quoteReplacement(safeTagMarker + mtch.matched + safeTagMarker) }) markedTagComment.lines.toList map (cleanLine(_)) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/CommentExpander.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentParser.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/CommentParser.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/CommentRegex.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala rename to dottydoc/src/dotty/tools/dottydoc/model/comment/CommentUtils.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala b/dottydoc/src/dotty/tools/dottydoc/model/entities.scala similarity index 96% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala rename to dottydoc/src/dotty/tools/dottydoc/model/entities.scala index 16d05306e527..1c204662b263 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/entities.scala @@ -1,7 +1,8 @@ package dotty.tools.dottydoc package model -import comment.{ Comment, MaterializableLink, Reference, NamedReference } +import comment._ +import references._ trait Entity { def name: String diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala similarity index 99% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala rename to dottydoc/src/dotty/tools/dottydoc/model/factories.scala index dae8442e8b62..b5cf15148b6f 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala @@ -2,6 +2,7 @@ package dotty.tools.dottydoc package model import comment._ +import references._ import dotty.tools.dotc import dotc.core.Types._ import dotc.core.TypeApplications._ diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala b/dottydoc/src/dotty/tools/dottydoc/model/internal.scala similarity index 96% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala rename to dottydoc/src/dotty/tools/dottydoc/model/internal.scala index a8756c82a694..82185b5aeff3 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/internal.scala @@ -1,7 +1,8 @@ package dotty.tools.dottydoc package model -import comment.{ Comment, MaterializableLink, Reference, NamedReference } +import comment.Comment +import references._ object internal { diff --git a/dottydoc/src/dotty/tools/dottydoc/model/java.scala b/dottydoc/src/dotty/tools/dottydoc/model/java.scala new file mode 100644 index 000000000000..41008506183c --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/model/java.scala @@ -0,0 +1,223 @@ +package dotty.tools.dottydoc +package model + +import comment._ +import references._ + +object java { + import scala.collection.JavaConverters._ + import _root_.java.util.{ Optional => JOptional, Map => JMap } + + implicit class JavaOption[A](val opt: Option[A]) extends AnyVal { + def asJava: JOptional[A] = + opt.map(a => JOptional.of(a)).getOrElse(JOptional.empty[A]) + } + + implicit class JavaComment(val cmt: Comment) extends AnyVal { + def asJava: JMap[String, _] = Map( + "body" -> cmt.body, + "short" -> cmt.short, + "authors" -> cmt.authors.asJava, + "see" -> cmt.see.asJava, + "result" -> cmt.result.asJava, + "throws" -> cmt.throws.asJava, + "valueParams" -> cmt.valueParams.asJava, + "typeParams" -> cmt.typeParams.asJava, + "version" -> cmt.version.asJava, + "since" -> cmt.since.asJava, + "todo" -> cmt.todo.asJava, + "deprecated" -> cmt.deprecated.asJava, + "note" -> cmt.note.asJava, + "example" -> cmt.example.asJava, + "constructor" -> cmt.constructor.asJava, + "group" -> cmt.group.asJava, + "groupDesc" -> cmt.groupDesc.asJava, + "groupNames" -> cmt.groupNames.asJava, + "groupPrio" -> cmt.groupPrio.asJava, + "hideImplicitConversions" -> cmt.hideImplicitConversions.asJava + ).asJava + } + + implicit class JavaPackage(val ent: Package) extends AnyVal { + def asJava(extras: Map[String, _] = Map.empty): JMap[String, _] = (Map( + "kind" -> ent.kind, + "name" -> ent.name, + "path" -> ent.path.asJava, + "members" -> ent.members.map(_.asJava()).asJava, + "comment" -> ent.comment.map(_.asJava).asJava + ) ++ extras).asJava + } + + implicit class JavaCaseClass(val ent: CaseClass) extends AnyVal { + def asJava(extras: Map[String, _] = Map.empty): JMap[String, _] = (Map( + "kind" -> ent.kind, + "name" -> ent.name, + "members" -> ent.members.map(_.asJava()).asJava, + "modifiers" -> ent.modifiers.asJava, + "path" -> ent.path.asJava, + "typeParams" -> ent.typeParams.asJava, + "superTypes" -> ent.superTypes.map(_.asJava).asJava, + "comment" -> ent.comment.map(_.asJava).asJava + ) ++ extras).asJava + } + + implicit class JavaClass(val ent: Class) extends AnyVal { + def asJava(extras: Map[String, _] = Map.empty): JMap[String, _] = (Map( + "kind" -> ent.kind, + "name" -> ent.name, + "members" -> ent.members.map(_.asJava()).asJava, + "modifiers" -> ent.modifiers.asJava, + "path" -> ent.path.asJava, + "typeParams" -> ent.typeParams.asJava, + "superTypes" -> ent.superTypes.map(_.asJava).asJava, + "comment" -> ent.comment.map(_.asJava).asJava + ) ++ extras).asJava + } + + implicit class JavaTrait(val ent: Trait) extends AnyVal { + def asJava(extras: Map[String, _] = Map.empty): JMap[String, _] = (Map( + "kind" -> ent.kind, + "name" -> ent.name, + "members" -> ent.members.map(_.asJava()).asJava, + "modifiers" -> ent.modifiers.asJava, + "path" -> ent.path.asJava, + "typeParams" -> ent.typeParams.asJava, + "superTypes" -> ent.superTypes.map(_.asJava).asJava, + "comment" -> ent.comment.map(_.asJava).asJava + ) ++ extras).asJava + } + + implicit class JavaObject(val ent: Object) extends AnyVal { + def asJava(extras: Map[String, _] = Map.empty): JMap[String, _] = (Map( + "kind" -> ent.kind, + "name" -> ent.name, + "members" -> ent.members.map(_.asJava()).asJava, + "modifiers" -> ent.modifiers.asJava, + "path" -> ent.path.asJava, + "superTypes" -> ent.superTypes.map(_.asJava).asJava, + "comment" -> ent.comment.map(_.asJava).asJava + ) ++ extras).asJava + } + + implicit class JavaDef(val ent: Def) extends AnyVal { + def asJava: JMap[String, _] = Map( + "kind" -> ent.kind, + "name" -> ent.name, + "modifiers" -> ent.modifiers.asJava, + "path" -> ent.path.asJava, + "returnValue" -> ent.returnValue.asJava, + "typeParams" -> ent.typeParams.asJava, + "paramLists" -> ent.paramLists.map(_.asJava).asJava, + "comment" -> ent.comment.map(_.asJava).asJava, + "implicitlyAddedFrom" -> ent.implicitlyAddedFrom.map(_.asJava).asJava + ).asJava + } + + implicit class JavaVal(val ent: Val) extends AnyVal { + def asJava: JMap[String, _] = Map( + "kind" -> ent.kind, + "name" -> ent.name, + "modifiers" -> ent.modifiers.asJava, + "path" -> ent.path.asJava, + "returnValue" -> ent.returnValue.asJava, + "comment" -> ent.comment.map(_.asJava).asJava, + "implicitlyAddedFrom" -> ent.implicitlyAddedFrom.map(_.asJava).asJava + ).asJava + } + + implicit class JavaParamList(val pl: ParamList) extends AnyVal { + def asJava: JMap[String, _] = Map( + "list" -> pl.list.map(_.asJava).asJava, + "isImplicit" -> pl.isImplicit + ).asJava + } + + implicit class JavaReference(val ref: Reference) extends AnyVal { + def asJava: JMap[String, _] = ref match { + case TypeReference(title, tpeLink, paramLinks) => Map( + "kind" -> "TypeReference", + "title" -> title, + "tpeLink" -> tpeLink.asJava, + "paramLinks" -> paramLinks.map(_.asJava).asJava + ).asJava + + case OrTypeReference(left, right) => Map( + "kind" -> "OrTypeReference", + "left" -> left.asJava, + "right" -> right.asJava + ).asJava + + case AndTypeReference(left, right) => Map( + "kind" -> "AndTypeReference", + "left" -> left.asJava, + "right" -> right.asJava + ).asJava + + case FunctionReference(args, returnValue) => Map( + "kind" -> "FunctionReference", + "args" -> args.map(_.asJava).asJava, + "returnValue" -> returnValue + ).asJava + + case TupleReference(args) => Map( + "kind" -> "TupleReference", + "args" -> args.map(_.asJava).asJava + ).asJava + + case BoundsReference(low, high) => Map( + "kind" -> "BoundsReference", + "low" -> low.asJava, + "hight" -> high.asJava + ).asJava + + case NamedReference(title, ref, isByName, isRepeated) => Map( + "kind" -> "NamedReference", + "title" -> title, + "ref" -> ref.asJava, + "isByName" -> isByName, + "isRepeated" -> isRepeated + ).asJava + + case ConstantReference(title) => Map( + "kind" -> "ConstantReference", + "title" -> title + ).asJava + } + } + + implicit class JavaMaterializableLink(val link: MaterializableLink) extends AnyVal { + def asJava: JMap[String, _] = link match { + case UnsetLink(title, query) => Map( + "kind" -> "UnsetLink", + "title" -> title, + "query" -> query + ).asJava + + case MaterializedLink(title, target) => Map( + "kind" -> "MaterializedLink", + "title" -> title, + "target" -> target + ).asJava + + case NoLink(title, target) => Map( + "kind" -> "NoLink", + "title" -> title, + "target" -> target + ).asJava + } + } + + implicit class JavaEntity(val ent: Entity) extends AnyVal { + def asJava(extras: Map[String, _] = Map.empty): JMap[String, _] = parseEntity(ent, extras) + } + + private def parseEntity(ent: Entity, extras: Map[String, _]): JMap[String, _] = ent match { + case ent: Package => ent.asJava(extras) + case ent: CaseClass => ent.asJava(extras) + case ent: Class => ent.asJava(extras) + case ent: Trait => ent.asJava(extras) + case ent: Object => ent.asJava(extras) + case ent: Def => ent.asJava + case ent: Val => ent.asJava + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/src/dotty/tools/dottydoc/model/json.scala similarity index 98% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala rename to dottydoc/src/dotty/tools/dottydoc/model/json.scala index a512ee352bcf..9bf37295c207 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/json.scala @@ -1,7 +1,8 @@ package dotty.tools.dottydoc package model -import model.comment._ +import comment._ +import references._ /** This object provides a protocol for serializing the package AST to JSON * @@ -84,7 +85,7 @@ object json { implicit class EntityJson(val ent: Entity) extends AnyVal { def json: String = entToJson(ent) } implicit class PackageJson(val pack: Package) extends AnyVal { def json: String = (pack: Entity).json } - implicit class PackMapJson(val packs: Map[String, Package]) extends AnyVal { + implicit class PackMapJson(val packs: collection.Map[String, Package]) extends AnyVal { def json: String = packs .map { case (k, v) => s"${k.json}: ${v.json}" } .mkString("{",",","}") diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/src/dotty/tools/dottydoc/model/parsers.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala rename to dottydoc/src/dotty/tools/dottydoc/model/parsers.scala diff --git a/dottydoc/src/dotty/tools/dottydoc/model/references.scala b/dottydoc/src/dotty/tools/dottydoc/model/references.scala new file mode 100644 index 000000000000..a28148fa737b --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/model/references.scala @@ -0,0 +1,20 @@ +package dotty.tools.dottydoc +package model + +object references { + sealed trait Reference + final case class TypeReference(title: String, tpeLink: MaterializableLink, paramLinks: List[Reference]) extends Reference + final case class OrTypeReference(left: Reference, right: Reference) extends Reference + final case class AndTypeReference(left: Reference, right: Reference) extends Reference + final case class FunctionReference(args: List[Reference], returnValue: Reference) extends Reference + final case class TupleReference(args: List[Reference]) extends Reference + final case class BoundsReference(low: Reference, high: Reference) extends Reference + final case class NamedReference(title: String, ref: Reference, isByName: Boolean = false, isRepeated: Boolean = false) extends Reference + final case class ConstantReference(title: String) extends Reference + + /** Use MaterializableLink for entities that need be picklable */ + sealed trait MaterializableLink { def title: String } + final case class UnsetLink(title: String, query: String) extends MaterializableLink + final case class MaterializedLink(title: String, target: String) extends MaterializableLink + final case class NoLink(title: String, target: String) extends MaterializableLink +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala b/dottydoc/src/dotty/tools/dottydoc/util/MemberLookup.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala rename to dottydoc/src/dotty/tools/dottydoc/util/MemberLookup.scala diff --git a/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala new file mode 100644 index 000000000000..2b4c49033ee0 --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -0,0 +1,110 @@ +package dotty.tools.dottydoc +package util + +import dotty.tools.dotc.config.Printers.dottydoc + +import _root_.java.io.{ + File => JFile, + PrintWriter => JPrintWriter, + FileReader => JFileReader, + BufferedInputStream, + FileInputStream, + FileOutputStream, + BufferedOutputStream, + FileNotFoundException +} +import _root_.java.util.{ Map => JMap, List => JList } +import model.{ Entity, Package } +import model.json._ +import com.github.mustachejava.DefaultMustacheFactory + + +class OutputWriter { + + def writeJava(packs: JMap[String, Package], templatePath: String, outPath: String, resources: JList[String]): Unit = { + import scala.collection.JavaConverters._ + write(packs.asScala, templatePath, outPath, resources.asScala) + } + + def write(packs: collection.Map[String, Package], templatePath: String, outPath: String, resources: Iterable[String]): Unit = { + // Write all packages to `outPath` + for (pack <- packs.values) { + println(s"""Writing '${pack.path.mkString(".")}'""") + writeFile( + expandTemplate(templatePath, pack, outPath), + outPath + pack.path.mkString("/", "/", "/"), + "index.html") + + // Write all package children to outPath + for { + child <- pack.children + if child.kind != "package" + } { + println(s"""Writing '${child.path.mkString(".")}'""") + writeFile( + expandTemplate(templatePath, child, outPath), + outPath + child.path.dropRight(1).mkString("/", "/", "/"), + child.path.last + ".html") + } + } + + // Write full index to outPath + val js = "Index = {}; Index.packages = " + packs.json + ";" + println("Writing index.js...") + writeFile(js, outPath + "/docassets/", "index.js") + + // Write resources to outPath + println("Copying CSS/JS resources to destination...") + assert(resources.nonEmpty) + resources.map(s => copy(new JFile(s), outPath)) + + println("Done writing static material, building js-app") + } + + def expandTemplate(templatePath: String, entity: Entity, outPath: String): String = try { + import model.java._ + import scala.collection.JavaConverters._ + val writer = new _root_.java.io.StringWriter() + val mf = new DefaultMustacheFactory() + + def toRoot = "../" * (entity.path.length - 1) + + val entityWithExtras = entity.asJava(Map( + "assets" -> s"${toRoot}docassets", + "index" -> s"${toRoot}docassets/index.js" + )) + + mf.compile(new JFileReader(templatePath), "template") + .execute(writer, entityWithExtras) + + writer.flush() + writer.toString + } catch { + case fnf: FileNotFoundException => + dottydoc.println(s"""Couldn't find the template: "$templatePath"...exiting""") + System.exit(1); "" + } + + def writeFile(str: String, path: String, file: String): Unit = + writeFile(str.map(_.toByte).toArray, path, file) + + def writeFile(bytes: Array[Byte], path: String, file: String): Unit = { + def printToFile(f: JFile)(op: JPrintWriter => Unit) = { + val bos = new BufferedOutputStream(new FileOutputStream(f)) + try { + Stream.continually(bos.write(bytes)) + } finally bos.close() + } + + new JFile(path).mkdirs() + printToFile(new JFile(path + file))(printer => bytes.foreach(printer.print)) + } + + def copy(src: JFile, path: String): Unit = { + val reader = new BufferedInputStream(new FileInputStream(src)) + try { + val bytes = Stream.continually(reader.read).takeWhile(-1 != _).map(_.toByte) + writeFile(bytes.toArray, path + "/docassets/", src.getName) + } finally reader.close() + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/src/dotty/tools/dottydoc/util/Traversing.scala similarity index 100% rename from dottydoc/jvm/src/dotty/tools/dottydoc/util/Traversing.scala rename to dottydoc/src/dotty/tools/dottydoc/util/Traversing.scala diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/src/dotty/tools/dottydoc/util/mutate.scala similarity index 96% rename from dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala rename to dottydoc/src/dotty/tools/dottydoc/util/mutate.scala index 84e3beb5bc98..e02dc60af278 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/src/dotty/tools/dottydoc/util/mutate.scala @@ -4,7 +4,8 @@ package internal object setters { import model._ - import comment.{ Comment, MaterializableLink, Reference, NamedReference } + import comment.Comment + import model.references._ import internal._ def setComment(ent: Entity, to: Option[Comment]) = ent match { diff --git a/dottydoc/jvm/test/BaseTest.scala b/dottydoc/test/BaseTest.scala similarity index 100% rename from dottydoc/jvm/test/BaseTest.scala rename to dottydoc/test/BaseTest.scala diff --git a/dottydoc/jvm/test/PackageStructure.scala b/dottydoc/test/PackageStructure.scala similarity index 100% rename from dottydoc/jvm/test/PackageStructure.scala rename to dottydoc/test/PackageStructure.scala diff --git a/dottydoc/jvm/test/SimpleComments.scala b/dottydoc/test/SimpleComments.scala similarity index 100% rename from dottydoc/jvm/test/SimpleComments.scala rename to dottydoc/test/SimpleComments.scala diff --git a/dottydoc/jvm/test/WhitelistedStdLib.scala b/dottydoc/test/WhitelistedStdLib.scala similarity index 100% rename from dottydoc/jvm/test/WhitelistedStdLib.scala rename to dottydoc/test/WhitelistedStdLib.scala diff --git a/dottydoc/test/WhitelistedStdLibMain.scala b/dottydoc/test/WhitelistedStdLibMain.scala new file mode 100644 index 000000000000..b4ea34d2c194 --- /dev/null +++ b/dottydoc/test/WhitelistedStdLibMain.scala @@ -0,0 +1,47 @@ +package dotty.tools +package dottydoc + +import scala.io.Source + +object WhitelistedStandardLib extends dottydoc.java.Dottydoc { + import scala.collection.JavaConverters._ + + val files: List[String] = { + val whitelist = "../test/dotc/scala-collections.whitelist" + + Source.fromFile(whitelist, "UTF8") + .getLines() + .map(_.trim) // allow identation + .filter(!_.startsWith("#")) // allow comment lines prefixed by # + .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line + .filter(_.nonEmpty) + .filterNot(_.endsWith("package.scala")) + .map("." + _) + .toList + } + + private val resources = List( + "../js-dottydoc/resources/MaterialIcons-Regular.eot", + "../js-dottydoc/resources/MaterialIcons-Regular.ijmap", + "../js-dottydoc/resources/MaterialIcons-Regular.svg", + "../js-dottydoc/resources/MaterialIcons-Regular.ttf", + "../js-dottydoc/resources/MaterialIcons-Regular.woff", + "../js-dottydoc/resources/MaterialIcons-Regular.woff2", + "../js-dottydoc/resources/codepoints", + "../js-dottydoc/resources/github.css", + "../js-dottydoc/resources/highlight.pack.js", + "../js-dottydoc/resources/index.css", + "../js-dottydoc/resources/material-icons.css", + "../js-dottydoc/resources/material.min.css", + "../js-dottydoc/resources/material.min.js"/*, + "resources/dottydoc-fastopt.js"*/ + ) + + override def main(args: Array[String]) = { + val compilerArgs = + "-language:Scala2" +: "-Ydoc-output" +: "../build/dottydoc" +: files.toArray + + val index = createIndex(compilerArgs) + buildDocs("../build/dottydoc", "../js-dottydoc/template.html", resources.asJava, index) + } +} diff --git a/project/Build.scala b/project/Build.scala index ca79167013f4..fa6ebc37ef41 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -264,29 +264,17 @@ object DottyInjectedPlugin extends AutoPlugin { ). settings(publishing) - lazy val dottydoc = crossProject.in(file("dottydoc")) - .jsSettings( - libraryDependencies ++= Seq( - "org.scala-js" %%% "scalajs-dom" % "0.9.0", - "com.lihaoyi" %%% "scalatags" % "0.5.5" - ) - ) - - lazy val dottydocJS = dottydoc.js.dependsOn(dotty).settings( - scalaSource in Compile := baseDirectory.value / "src" - ) - - lazy val dottydocJVM = dottydoc.jvm.dependsOn(dotty).settings( - resources in Compile += (fastOptJS in (dottydocJS, Compile)).value.data, + lazy val dottydoc = project.in(file("dottydoc")).dependsOn(dotty).settings( + //resources in Compile += (fastOptJS in (dottydocJS, Compile)).value.data, resourceDirectory in Compile := baseDirectory.value / "resources", scalaSource in Compile := baseDirectory.value / "src", + javaSource in Compile := baseDirectory.value / "src", scalaSource in Test := baseDirectory.value / "test", javaSource in Test := baseDirectory.value / "test", libraryDependencies ++= Seq( - "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0", - "com.lihaoyi" %% "scalatags" % "0.5.5", - "com.novocode" % "junit-interface" % "0.11" % "test" + "com.novocode" % "junit-interface" % "0.11" % "test", + "com.github.spullara.mustache.java" % "compiler" % "0.9.3" ), // enable improved incremental compilation algorithm @@ -323,7 +311,7 @@ object DottyInjectedPlugin extends AutoPlugin { ("-DpartestParentID=" + pid) :: tuning ::: agentOptions ::: travis_build ::: fullpath } - ) + ).settings(publishing) /** A sandbox to play with the Scala.js back-end of dotty. * From 0d89be8ad7078f51d3d7042c23cae2fe27319218 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 9 Aug 2016 19:32:15 +0200 Subject: [PATCH 090/100] Add `currentEntity` to templating API --- .../tools/dottydoc/util/OutputWriter.scala | 6 ++-- dottydoc/test/WhitelistedStdLibMain.scala | 30 +++++++++---------- project/Build.scala | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala index 2b4c49033ee0..8e288ae7fc91 100644 --- a/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala +++ b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -62,8 +62,9 @@ class OutputWriter { } def expandTemplate(templatePath: String, entity: Entity, outPath: String): String = try { + import model.json._ import model.java._ - import scala.collection.JavaConverters._ + val writer = new _root_.java.io.StringWriter() val mf = new DefaultMustacheFactory() @@ -71,7 +72,8 @@ class OutputWriter { val entityWithExtras = entity.asJava(Map( "assets" -> s"${toRoot}docassets", - "index" -> s"${toRoot}docassets/index.js" + "index" -> s"${toRoot}docassets/index.js", + "currentEntity" -> entity.json )) mf.compile(new JFileReader(templatePath), "template") diff --git a/dottydoc/test/WhitelistedStdLibMain.scala b/dottydoc/test/WhitelistedStdLibMain.scala index b4ea34d2c194..e32b8800cc92 100644 --- a/dottydoc/test/WhitelistedStdLibMain.scala +++ b/dottydoc/test/WhitelistedStdLibMain.scala @@ -21,20 +21,20 @@ object WhitelistedStandardLib extends dottydoc.java.Dottydoc { } private val resources = List( - "../js-dottydoc/resources/MaterialIcons-Regular.eot", - "../js-dottydoc/resources/MaterialIcons-Regular.ijmap", - "../js-dottydoc/resources/MaterialIcons-Regular.svg", - "../js-dottydoc/resources/MaterialIcons-Regular.ttf", - "../js-dottydoc/resources/MaterialIcons-Regular.woff", - "../js-dottydoc/resources/MaterialIcons-Regular.woff2", - "../js-dottydoc/resources/codepoints", - "../js-dottydoc/resources/github.css", - "../js-dottydoc/resources/highlight.pack.js", - "../js-dottydoc/resources/index.css", - "../js-dottydoc/resources/material-icons.css", - "../js-dottydoc/resources/material.min.css", - "../js-dottydoc/resources/material.min.js"/*, - "resources/dottydoc-fastopt.js"*/ + "../../dottydoc-client/resources/MaterialIcons-Regular.eot", + "../../dottydoc-client/resources/MaterialIcons-Regular.ijmap", + "../../dottydoc-client/resources/MaterialIcons-Regular.svg", + "../../dottydoc-client/resources/MaterialIcons-Regular.ttf", + "../../dottydoc-client/resources/MaterialIcons-Regular.woff", + "../../dottydoc-client/resources/MaterialIcons-Regular.woff2", + "../../dottydoc-client/resources/codepoints", + "../../dottydoc-client/resources/github.css", + "../../dottydoc-client/resources/highlight.pack.js", + "../../dottydoc-client/resources/index.css", + "../../dottydoc-client/resources/material-icons.css", + "../../dottydoc-client/resources/material.min.css", + "../../dottydoc-client/resources/material.min.js", + "../../dottydoc-client/target/scala-2.11/dottydoc-client-fastopt.js" ) override def main(args: Array[String]) = { @@ -42,6 +42,6 @@ object WhitelistedStandardLib extends dottydoc.java.Dottydoc { "-language:Scala2" +: "-Ydoc-output" +: "../build/dottydoc" +: files.toArray val index = createIndex(compilerArgs) - buildDocs("../build/dottydoc", "../js-dottydoc/template.html", resources.asJava, index) + buildDocs("../build/dottydoc", "../../dottydoc-client/resources/template.html", resources.asJava, index) } } diff --git a/project/Build.scala b/project/Build.scala index fa6ebc37ef41..29eae1d5e405 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -200,7 +200,7 @@ object DottyBuild extends Build { addCommandAlias("partest", ";test:package;package;test:runMain dotc.build;lockPartestFile;test:test;runPartestRunner") ++ addCommandAlias("partest-only", ";test:package;package;test:runMain dotc.build;lockPartestFile;test:test-only dotc.tests;runPartestRunner") ++ addCommandAlias("partest-only-no-bootstrap", ";test:package;package; lockPartestFile;test:test-only dotc.tests;runPartestRunner") ++ - addCommandAlias("dottydoc", ";dottydocJVM/run") + addCommandAlias("dottydoc", ";dottydoc/run") ). settings(publishing) From b1defa0c080706258b1c2c5859bb10439c394669 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 10 Aug 2016 13:02:10 +0200 Subject: [PATCH 091/100] Add scaladoc interface stub --- .../main/scala/xsbt/ScaladocInterface.scala | 20 +++++++++++++++++++ .../{interface => api/java}/Dottydoc.java | 2 +- .../tools/dottydoc/api/scala/Dottydoc.scala | 15 ++++++++++++++ dottydoc/test/WhitelistedStdLibMain.scala | 2 +- project/Build.scala | 1 + 5 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 bridge/src/main/scala/xsbt/ScaladocInterface.scala rename dottydoc/src/dotty/tools/dottydoc/{interface => api/java}/Dottydoc.java (94%) create mode 100644 dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala diff --git a/bridge/src/main/scala/xsbt/ScaladocInterface.scala b/bridge/src/main/scala/xsbt/ScaladocInterface.scala new file mode 100644 index 000000000000..4990676f196f --- /dev/null +++ b/bridge/src/main/scala/xsbt/ScaladocInterface.scala @@ -0,0 +1,20 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import xsbti.Logger +import dotty.tools.dottydoc.api.scala.Dottydoc + +class ScaladocInterface { + def run(args: Array[String], log: Logger, delegate: xsbti.Reporter) = + (new DottydocRunner(args, log, delegate)).run() +} + +class DottydocRunner(args: Array[String], log: Logger, delegate: xsbti.Reporter) extends Dottydoc { + def run(): Unit = { + println(args.mkString("Args = List (\n ",",\n ",")")) + //val index = createIndex(args) + //buildDocs(outputDir, templatePath, resources, index) + } +} diff --git a/dottydoc/src/dotty/tools/dottydoc/interface/Dottydoc.java b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java similarity index 94% rename from dottydoc/src/dotty/tools/dottydoc/interface/Dottydoc.java rename to dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java index cc8424f1460c..c2ec29395898 100644 --- a/dottydoc/src/dotty/tools/dottydoc/interface/Dottydoc.java +++ b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java @@ -1,4 +1,4 @@ -package dotty.tools.dottydoc.java; +package dotty.tools.dottydoc.api.java; import dotty.tools.dottydoc.DottyDocDriver; import dotty.tools.dottydoc.model.Package; diff --git a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala new file mode 100644 index 000000000000..0b144027b567 --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala @@ -0,0 +1,15 @@ +package dotty.tools.dottydoc.api.scala + +import dotty.tools.dottydoc.DottyDocDriver +import dotty.tools.dottydoc.model.Package +import dotty.tools.dottydoc.util.OutputWriter + +import scala.collection.Map + +trait Dottydoc extends DottyDocDriver { + def createIndex(args: Array[String]): Map[String, Package] = + compiledDocs(args) + + def buildDocs(outDir: String, templatePath: String, resources: List[String], index: Map[String, Package]) = + new OutputWriter().write(index, templatePath, outDir, resources) +} diff --git a/dottydoc/test/WhitelistedStdLibMain.scala b/dottydoc/test/WhitelistedStdLibMain.scala index e32b8800cc92..d1168bf15d8c 100644 --- a/dottydoc/test/WhitelistedStdLibMain.scala +++ b/dottydoc/test/WhitelistedStdLibMain.scala @@ -3,7 +3,7 @@ package dottydoc import scala.io.Source -object WhitelistedStandardLib extends dottydoc.java.Dottydoc { +object WhitelistedStandardLib extends dottydoc.api.java.Dottydoc { import scala.collection.JavaConverters._ val files: List[String] = { diff --git a/project/Build.scala b/project/Build.scala index 29eae1d5e405..cabc9d07d4b9 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -206,6 +206,7 @@ object DottyBuild extends Build { lazy val `dotty-bridge` = project.in(file("bridge")). dependsOn(dotty). + dependsOn(dottydoc). settings( overrideScalaVersionSetting, From a25207472c8b64beeb264f118ed1bb4f9a37418c Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 11 Aug 2016 15:21:25 +0200 Subject: [PATCH 092/100] Implement bridge that generates json on `doc` command --- .../main/scala/xsbt/ScaladocInterface.scala | 19 +++++-- .../tools/dottydoc/api/java/Dottydoc.java | 4 ++ .../tools/dottydoc/api/scala/Dottydoc.scala | 4 ++ .../tools/dottydoc/util/OutputWriter.scala | 9 +++- project/Build.scala | 53 ++----------------- 5 files changed, 33 insertions(+), 56 deletions(-) diff --git a/bridge/src/main/scala/xsbt/ScaladocInterface.scala b/bridge/src/main/scala/xsbt/ScaladocInterface.scala index 4990676f196f..39458bd1d4c8 100644 --- a/bridge/src/main/scala/xsbt/ScaladocInterface.scala +++ b/bridge/src/main/scala/xsbt/ScaladocInterface.scala @@ -12,9 +12,20 @@ class ScaladocInterface { } class DottydocRunner(args: Array[String], log: Logger, delegate: xsbti.Reporter) extends Dottydoc { - def run(): Unit = { - println(args.mkString("Args = List (\n ",",\n ",")")) - //val index = createIndex(args) - //buildDocs(outputDir, templatePath, resources, index) + def run(): Unit = getOutputFolder(args).map { outputFolder => + val index = createIndex(args) + val template = getTemplate(args) + val resources = getResources(args) + + template.fold(writeJson(index, outputFolder)) { tpl => + buildDocs(outputFolder, tpl, resources, index) + } } + + private def getOutputFolder(args: Array[String]): Option[String] = + args sliding(2) find { case Array(x, _) => x == "-d" } map (_.tail.head) + + private def getTemplate(args: Array[String]): Option[String] = None + + private def getResources(args: Array[String]): List[String] = Nil } diff --git a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java index c2ec29395898..c50688c77d44 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java +++ b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java @@ -24,4 +24,8 @@ public void buildDocs( ) { new OutputWriter().writeJava(index, templatePath, outputDir, resources); } + + public void writeJson(Map index, String outputDir) { + new OutputWriter().writeJsonJava(index, outputDir); + } } diff --git a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala index 0b144027b567..373fae39ae8b 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala @@ -6,10 +6,14 @@ import dotty.tools.dottydoc.util.OutputWriter import scala.collection.Map +/** FIXME: document this class plz */ trait Dottydoc extends DottyDocDriver { def createIndex(args: Array[String]): Map[String, Package] = compiledDocs(args) def buildDocs(outDir: String, templatePath: String, resources: List[String], index: Map[String, Package]) = new OutputWriter().write(index, templatePath, outDir, resources) + + def writeJson(index: Map[String, Package], outputDir: String) = + new OutputWriter().writeJson(index, outputDir) } diff --git a/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala index 8e288ae7fc91..d5a48912f79f 100644 --- a/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala +++ b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -17,12 +17,11 @@ import _root_.java.util.{ Map => JMap, List => JList } import model.{ Entity, Package } import model.json._ import com.github.mustachejava.DefaultMustacheFactory - +import scala.collection.JavaConverters._ class OutputWriter { def writeJava(packs: JMap[String, Package], templatePath: String, outPath: String, resources: JList[String]): Unit = { - import scala.collection.JavaConverters._ write(packs.asScala, templatePath, outPath, resources.asScala) } @@ -61,6 +60,12 @@ class OutputWriter { println("Done writing static material, building js-app") } + def writeJsonJava(index: JMap[String, Package], outputDir: String): Unit = + writeJson(index.asScala, outputDir) + + def writeJson(index: collection.Map[String, Package], outputDir: String): Unit = + writeFile(index.json, outputDir + "/", "index.json") + def expandTemplate(templatePath: String, entity: Entity, outPath: String): String = try { import model.json._ import model.java._ diff --git a/project/Build.scala b/project/Build.scala index cabc9d07d4b9..7a9d83a50e71 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -73,7 +73,9 @@ object DottyBuild extends Build { javaSource in Test := baseDirectory.value / "test", resourceDirectory in Compile := baseDirectory.value / "resources", unmanagedSourceDirectories in Compile := Seq((scalaSource in Compile).value), + unmanagedSourceDirectories in Compile += baseDirectory.value / "dottydoc" / "src", unmanagedSourceDirectories in Test := Seq((scalaSource in Test).value), + unmanagedSourceDirectories in Test += baseDirectory.value / "dottydoc" / "test", // set system in/out for repl connectInput in run := true, @@ -100,6 +102,7 @@ object DottyBuild extends Build { "org.scala-lang.modules" %% "scala-partest" % "1.0.11" % "test", "com.novocode" % "junit-interface" % "0.11" % "test", "com.googlecode.java-diff-utils" % "diffutils" % "1.3.0", + "com.github.spullara.mustache.java" % "compiler" % "0.9.3", "com.typesafe.sbt" % "sbt-interface" % sbtVersion.value), // enable improved incremental compilation algorithm incOptions := incOptions.value.withNameHashing(true), @@ -206,7 +209,6 @@ object DottyBuild extends Build { lazy val `dotty-bridge` = project.in(file("bridge")). dependsOn(dotty). - dependsOn(dottydoc). settings( overrideScalaVersionSetting, @@ -265,55 +267,6 @@ object DottyInjectedPlugin extends AutoPlugin { ). settings(publishing) - lazy val dottydoc = project.in(file("dottydoc")).dependsOn(dotty).settings( - //resources in Compile += (fastOptJS in (dottydocJS, Compile)).value.data, - resourceDirectory in Compile := baseDirectory.value / "resources", - scalaSource in Compile := baseDirectory.value / "src", - javaSource in Compile := baseDirectory.value / "src", - scalaSource in Test := baseDirectory.value / "test", - javaSource in Test := baseDirectory.value / "test", - - libraryDependencies ++= Seq( - "com.novocode" % "junit-interface" % "0.11" % "test", - "com.github.spullara.mustache.java" % "compiler" % "0.9.3" - ), - - // enable improved incremental compilation algorithm - incOptions := incOptions.value.withNameHashing(true), - - mainClass in (Compile, run) := Some("dotty.tools.dottydoc.Main"), - fork in run := true, - fork in Test := true, - parallelExecution in Test := false, - - // http://grokbase.com/t/gg/simple-build-tool/135ke5y90p/sbt-setting-jvm-boot-paramaters-for-scala - javaOptions <++= (dependencyClasspath in Runtime, packageBin in Compile) map { (attList, bin) => - // put the Scala {library, reflect} in the classpath - val path = for { - file <- attList.map(_.data) - path = file.getAbsolutePath - } yield "-Xbootclasspath/p:" + path - // dotty itself needs to be in the bootclasspath - val fullpath = ("-Xbootclasspath/a:" + bin) :: path.toList - // System.err.println("BOOTPATH: " + fullpath) - - val travis_build = // propagate if this is a travis build - if (sys.props.isDefinedAt(JENKINS_BUILD)) - List(s"-D$JENKINS_BUILD=${sys.props(JENKINS_BUILD)}") ::: jenkinsMemLimit - else - List() - - val tuning = - if (sys.props.isDefinedAt("Oshort")) - // Optimize for short-running applications, see https://github.com/lampepfl/dotty/issues/222 - List("-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1") - else - List() - - ("-DpartestParentID=" + pid) :: tuning ::: agentOptions ::: travis_build ::: fullpath - } - ).settings(publishing) - /** A sandbox to play with the Scala.js back-end of dotty. * * This sandbox is compiled with dotty with support for Scala.js. It can be From bd7751924d9c145accf04b69e71621347d2b77f6 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 11 Aug 2016 17:18:14 +0200 Subject: [PATCH 093/100] Implement working docs requiring manually specifying resources and template for html docs --- .../main/scala/xsbt/ScaladocInterface.scala | 33 +++++++++++++++++-- .../src/dotty/tools/dottydoc/DottyDoc.scala | 30 ++--------------- .../tools/dottydoc/api/java/Dottydoc.java | 4 +-- .../tools/dottydoc/api/scala/Dottydoc.scala | 4 +-- .../tools/dottydoc/core/OutputJsonPhase.scala | 13 -------- .../tools/dottydoc/core/PrintPhase.scala | 30 ----------------- dottydoc/test/BaseTest.scala | 3 +- dottydoc/test/WhitelistedStdLibMain.scala | 30 ++++++++--------- .../tools/dotc/config/ScalaSettings.scala | 14 +++++--- 9 files changed, 63 insertions(+), 98 deletions(-) delete mode 100644 dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala delete mode 100644 dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala diff --git a/bridge/src/main/scala/xsbt/ScaladocInterface.scala b/bridge/src/main/scala/xsbt/ScaladocInterface.scala index 39458bd1d4c8..42f4296fe893 100644 --- a/bridge/src/main/scala/xsbt/ScaladocInterface.scala +++ b/bridge/src/main/scala/xsbt/ScaladocInterface.scala @@ -20,12 +20,39 @@ class DottydocRunner(args: Array[String], log: Logger, delegate: xsbti.Reporter) template.fold(writeJson(index, outputFolder)) { tpl => buildDocs(outputFolder, tpl, resources, index) } + } getOrElse { + delegate.log( + NoPosition, + "No output folder set for API documentation (\"-d\" parameter should be passed to the documentation tool)", + xsbti.Severity.Error + ) } + private[this] val NoPosition = new xsbti.Position { + val line = xsbti.Maybe.nothing[Integer] + val lineContent = "" + val offset = xsbti.Maybe.nothing[Integer] + val sourcePath = xsbti.Maybe.nothing[String] + val sourceFile = xsbti.Maybe.nothing[java.io.File] + val pointer = xsbti.Maybe.nothing[Integer] + val pointerSpace = xsbti.Maybe.nothing[String] + } + + private def getStringSetting(name: String): Option[String] = + args find (_.startsWith(name)) map (_.drop(name.length)) + private def getOutputFolder(args: Array[String]): Option[String] = - args sliding(2) find { case Array(x, _) => x == "-d" } map (_.tail.head) + args sliding(2) find { case Array(x, _) => x == "-d" } map (_.tail.head.trim) + + private def getTemplate(args: Array[String]): Option[String] = + getStringSetting("-template:") - private def getTemplate(args: Array[String]): Option[String] = None + private def getResources(args: Array[String]): List[String] = + getStringSetting("-resources:").map { path => + val dir = new java.io.File(path) + if (dir.exists && dir.isDirectory) + dir.listFiles.filter(_.isFile).map(_.getAbsolutePath).toList + else Nil + }.getOrElse(Nil) - private def getResources(args: Array[String]): List[String] = Nil } diff --git a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala index bef9141f2bdb..e19805d21561 100644 --- a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala @@ -26,7 +26,7 @@ import _root_.java.util.{ Map => JMap } * 2. Create an AST that is serializable * 3. Serialize to JS object */ -class DottyDocCompiler extends Compiler { +class DocCompiler extends Compiler { override def phases: List[List[Phase]] = List( List(new DocFrontEnd), List(new DocImplicitsPhase), @@ -36,11 +36,6 @@ class DottyDocCompiler extends Compiler { new LinkImplicitlyAddedTypes, new SortMembers)) ) - - override def newRun(implicit ctx: Context): Run = { - reset() - new DocRun(this)(rootContext) - } } class DocFrontEnd extends FrontEnd { @@ -48,26 +43,7 @@ class DocFrontEnd extends FrontEnd { unit.isJava } -class DocRun(comp: Compiler)(implicit ctx: Context) extends Run(comp)(ctx) { - def fromDirectory(f: String): List[String] = { - val file = new PlainFile(f) - - if (!file.isDirectory && f.endsWith(".scala")) List(f) - else if (!file.isDirectory) Nil - else file.iterator.flatMap { - case x if x.isDirectory => fromDirectory(x.canonicalPath) - case x => List(x.canonicalPath) - }.toList - } - - /** If DocRecursive is set, then try to find all scala files! */ - override def compile(fileNames: List[String]): Unit = super.compile( - if (ctx.settings.DocRecursive.value) fileNames flatMap fromDirectory - else fileNames - ) -} - -abstract class DottyDocDriver extends Driver { +abstract class DocDriver extends Driver { import scala.collection.JavaConverters._ override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { @@ -81,7 +57,7 @@ abstract class DottyDocDriver extends Driver { (fileNames, ctx) } - override def newCompiler(implicit ctx: Context): Compiler = new DottyDocCompiler + override def newCompiler(implicit ctx: Context): Compiler = new DocCompiler def compiledDocs(args: Array[String]): collection.Map[String, Package] = { diff --git a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java index c50688c77d44..b461c309661f 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java +++ b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java @@ -1,13 +1,13 @@ package dotty.tools.dottydoc.api.java; -import dotty.tools.dottydoc.DottyDocDriver; +import dotty.tools.dottydoc.DocDriver; import dotty.tools.dottydoc.model.Package; import dotty.tools.dottydoc.util.OutputWriter; import java.util.Map; import java.util.List; /** FIXME: document me! */ -public class Dottydoc extends DottyDocDriver { +public class Dottydoc extends DocDriver { public Map createIndex(String[] args) { return compiledDocsJava(args); } diff --git a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala index 373fae39ae8b..dce994f5d262 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala @@ -1,13 +1,13 @@ package dotty.tools.dottydoc.api.scala -import dotty.tools.dottydoc.DottyDocDriver +import dotty.tools.dottydoc.DocDriver import dotty.tools.dottydoc.model.Package import dotty.tools.dottydoc.util.OutputWriter import scala.collection.Map /** FIXME: document this class plz */ -trait Dottydoc extends DottyDocDriver { +trait Dottydoc extends DocDriver { def createIndex(args: Array[String]): Map[String, Package] = compiledDocs(args) diff --git a/dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala deleted file mode 100644 index 9f8dfdca69a5..000000000000 --- a/dottydoc/src/dotty/tools/dottydoc/core/OutputJsonPhase.scala +++ /dev/null @@ -1,13 +0,0 @@ -package dotty.tools -package dottydoc -package core - -import dotc.CompilationUnit -import dotc.core.Contexts.Context -import dotc.core.Phases.Phase -import model.{Package, Entity} - -abstract class JsonOutputPhase extends Phase { - def phaseName = "jsonOutputPhase" - println("wabalubadubdub") -} diff --git a/dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala deleted file mode 100644 index 080687877cdd..000000000000 --- a/dottydoc/src/dotty/tools/dottydoc/core/PrintPhase.scala +++ /dev/null @@ -1,30 +0,0 @@ -package dotty.tools -package dottydoc -package core - -import dotc.CompilationUnit -import dotc.core.Contexts.Context -import dotc.core.Phases.Phase -import model.{Package, Entity} - -/** TODO: re-write to `DocMiniPhase` */ -//class PrintPhase extends Phase { -// def phaseName = "docPrintPhase" -// -// var currentRun = 0 -// override def run(implicit ctx: Context): Unit = () -// -// override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { -// val compUnits = super.runOn(units) -// val packages = ctx.docbase.packages[Package].toMap -// -// val outputDir = { -// val out = ctx.settings.DocOutput.value -// if (out.last == '/') out.dropRight(1) -// else out -// } -// if (!ctx.settings.YDocNoWrite.value) (new util.OutputWriter).write(packages, outputDir) -// -// compUnits -// } -//} diff --git a/dottydoc/test/BaseTest.scala b/dottydoc/test/BaseTest.scala index 0c6fad1c8e21..7f077d27bc69 100644 --- a/dottydoc/test/BaseTest.scala +++ b/dottydoc/test/BaseTest.scala @@ -17,12 +17,11 @@ trait DottyTest { val ctx = base.initialCtx.fresh ctx.setSetting(ctx.settings.language, List("Scala2")) ctx.setSetting(ctx.settings.YkeepComments, true) - ctx.setSetting(ctx.settings.YDocNoWrite, true) base.initialize()(ctx) ctx } - private def compilerWithChecker(assertion: DocASTPhase => Unit) = new DottyDocCompiler { + private def compilerWithChecker(assertion: DocASTPhase => Unit) = new DocCompiler { private[this] val docPhase = new DocASTPhase override def phases = diff --git a/dottydoc/test/WhitelistedStdLibMain.scala b/dottydoc/test/WhitelistedStdLibMain.scala index d1168bf15d8c..95d4afbae794 100644 --- a/dottydoc/test/WhitelistedStdLibMain.scala +++ b/dottydoc/test/WhitelistedStdLibMain.scala @@ -7,7 +7,7 @@ object WhitelistedStandardLib extends dottydoc.api.java.Dottydoc { import scala.collection.JavaConverters._ val files: List[String] = { - val whitelist = "../test/dotc/scala-collections.whitelist" + val whitelist = "./test/dotc/scala-collections.whitelist" Source.fromFile(whitelist, "UTF8") .getLines() @@ -21,20 +21,20 @@ object WhitelistedStandardLib extends dottydoc.api.java.Dottydoc { } private val resources = List( - "../../dottydoc-client/resources/MaterialIcons-Regular.eot", - "../../dottydoc-client/resources/MaterialIcons-Regular.ijmap", - "../../dottydoc-client/resources/MaterialIcons-Regular.svg", - "../../dottydoc-client/resources/MaterialIcons-Regular.ttf", - "../../dottydoc-client/resources/MaterialIcons-Regular.woff", - "../../dottydoc-client/resources/MaterialIcons-Regular.woff2", - "../../dottydoc-client/resources/codepoints", - "../../dottydoc-client/resources/github.css", - "../../dottydoc-client/resources/highlight.pack.js", - "../../dottydoc-client/resources/index.css", - "../../dottydoc-client/resources/material-icons.css", - "../../dottydoc-client/resources/material.min.css", - "../../dottydoc-client/resources/material.min.js", - "../../dottydoc-client/target/scala-2.11/dottydoc-client-fastopt.js" + "../dottydoc-client/resources/MaterialIcons-Regular.eot", + "../dottydoc-client/resources/MaterialIcons-Regular.ijmap", + "../dottydoc-client/resources/MaterialIcons-Regular.svg", + "../dottydoc-client/resources/MaterialIcons-Regular.ttf", + "../dottydoc-client/resources/MaterialIcons-Regular.woff", + "../dottydoc-client/resources/MaterialIcons-Regular.woff2", + "../dottydoc-client/resources/codepoints", + "../dottydoc-client/resources/github.css", + "../dottydoc-client/resources/highlight.pack.js", + "../dottydoc-client/resources/index.css", + "../dottydoc-client/resources/material-icons.css", + "../dottydoc-client/resources/material.min.css", + "../dottydoc-client/resources/material.min.js", + "../dottydoc-client/target/scala-2.11/dottydoc-client-fastopt.js" ) override def main(args: Array[String]) = { diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala index fa4059a9634d..5d590358452c 100644 --- a/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -197,8 +197,16 @@ class ScalaSettings extends Settings.SettingGroup { val YpresentationReplay = StringSetting("-Ypresentation-replay", "file", "Replay presentation compiler events from file", "") val YpresentationDelay = IntSetting("-Ypresentation-delay", "Wait number of ms after typing before starting typechecking", 0, 0 to 999) - /** Dottydoc specific settings */ - val YDocNoWrite = BooleanSetting("-Ydoc-nowrite", "Doesn't write HTML files if set", false) + /** Doc specific settings */ + val template = OptionSetting[String]( + "-template", + "A mustache template for rendering each top-level entity in the API" + ) + + val resources = OptionSetting[String]( + "-resources", + "A directory containing static resources needed for the API documentation" + ) val DocTitle = StringSetting ( "-Ydoc-title", @@ -235,8 +243,6 @@ class ScalaSettings extends Settings.SettingGroup { "" ) - val DocRecursive = BooleanSetting("-Ydoc-recursive", "Get all files from supplied directory") - //def DocUncompilableFiles(implicit ctx: Context) = DocUncompilable.value match { // case "" => Nil // case path => io.Directory(path).deepFiles.filter(_ hasExtension "scala").toList From d6b5c3e0404b754c2bef432b3227cf8f61bc8896 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 15 Aug 2016 17:58:41 +0200 Subject: [PATCH 094/100] Implement dotty bridge for doc --- .../main/scala/xsbt/ScaladocInterface.scala | 34 ++++++++++++----- .../tools/dottydoc/api/java/Dottydoc.java | 7 ++-- .../tools/dottydoc/api/scala/Dottydoc.scala | 5 ++- .../tools/dottydoc/util/OutputWriter.scala | 38 +++++++++++-------- dottydoc/test/WhitelistedStdLibMain.scala | 5 +-- project/Build.scala | 1 + 6 files changed, 57 insertions(+), 33 deletions(-) diff --git a/bridge/src/main/scala/xsbt/ScaladocInterface.scala b/bridge/src/main/scala/xsbt/ScaladocInterface.scala index 42f4296fe893..3ad9c79416d1 100644 --- a/bridge/src/main/scala/xsbt/ScaladocInterface.scala +++ b/bridge/src/main/scala/xsbt/ScaladocInterface.scala @@ -5,6 +5,7 @@ package xsbt import xsbti.Logger import dotty.tools.dottydoc.api.scala.Dottydoc +import java.net.URL class ScaladocInterface { def run(args: Array[String], log: Logger, delegate: xsbti.Reporter) = @@ -14,8 +15,8 @@ class ScaladocInterface { class DottydocRunner(args: Array[String], log: Logger, delegate: xsbti.Reporter) extends Dottydoc { def run(): Unit = getOutputFolder(args).map { outputFolder => val index = createIndex(args) - val template = getTemplate(args) val resources = getResources(args) + val template = getTemplate(resources) template.fold(writeJson(index, outputFolder)) { tpl => buildDocs(outputFolder, tpl, resources, index) @@ -44,15 +45,28 @@ class DottydocRunner(args: Array[String], log: Logger, delegate: xsbti.Reporter) private def getOutputFolder(args: Array[String]): Option[String] = args sliding(2) find { case Array(x, _) => x == "-d" } map (_.tail.head.trim) - private def getTemplate(args: Array[String]): Option[String] = - getStringSetting("-template:") + private def getTemplate(resources: List[URL]): Option[URL] = + resources.find(_.getFile.endsWith("template.html")) - private def getResources(args: Array[String]): List[String] = - getStringSetting("-resources:").map { path => - val dir = new java.io.File(path) - if (dir.exists && dir.isDirectory) - dir.listFiles.filter(_.isFile).map(_.getAbsolutePath).toList - else Nil - }.getOrElse(Nil) + private def getResources(args: Array[String]): List[URL] = { + val cp = args sliding (2) find { case Array(x, _) => x == "-classpath" } map (_.tail.head.trim) getOrElse "" + cp.split(":").find(_.endsWith("dottydoc-client.jar")).map { resourceJar => + import java.util.jar.JarFile + val jarEntries = (new JarFile(resourceJar)).entries + var entries: List[URL] = Nil + + while (jarEntries.hasMoreElements) { + val entry = jarEntries.nextElement() + + if (!entry.isDirectory()) { + val path = s"jar:file:$resourceJar!/${entry.getName}" + val url = new URL(path) + entries = url :: entries + } + } + + entries + } getOrElse (Nil) + } } diff --git a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java index b461c309661f..dbe3f6f4149e 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java +++ b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java @@ -5,6 +5,7 @@ import dotty.tools.dottydoc.util.OutputWriter; import java.util.Map; import java.util.List; +import java.net.URL; /** FIXME: document me! */ public class Dottydoc extends DocDriver { @@ -18,11 +19,11 @@ public String createJsonIndex(String[] args) { public void buildDocs( String outputDir, - String templatePath, - List resources, + URL template, + List resources, Map index ) { - new OutputWriter().writeJava(index, templatePath, outputDir, resources); + new OutputWriter().writeJava(index, outputDir, template, resources); } public void writeJson(Map index, String outputDir) { diff --git a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala index dce994f5d262..a2c42d38c04c 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala @@ -5,14 +5,15 @@ import dotty.tools.dottydoc.model.Package import dotty.tools.dottydoc.util.OutputWriter import scala.collection.Map +import java.net.URL /** FIXME: document this class plz */ trait Dottydoc extends DocDriver { def createIndex(args: Array[String]): Map[String, Package] = compiledDocs(args) - def buildDocs(outDir: String, templatePath: String, resources: List[String], index: Map[String, Package]) = - new OutputWriter().write(index, templatePath, outDir, resources) + def buildDocs(outDir: String, template: URL, resources: List[URL], index: Map[String, Package]) = + new OutputWriter().write(index, outDir, template, resources) def writeJson(index: Map[String, Package], outputDir: String) = new OutputWriter().writeJson(index, outputDir) diff --git a/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala index d5a48912f79f..2084e0a9788f 100644 --- a/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala +++ b/dottydoc/src/dotty/tools/dottydoc/util/OutputWriter.scala @@ -8,11 +8,13 @@ import _root_.java.io.{ PrintWriter => JPrintWriter, FileReader => JFileReader, BufferedInputStream, - FileInputStream, + InputStream, + InputStreamReader, FileOutputStream, BufferedOutputStream, FileNotFoundException } +import _root_.java.net.URL import _root_.java.util.{ Map => JMap, List => JList } import model.{ Entity, Package } import model.json._ @@ -21,16 +23,16 @@ import scala.collection.JavaConverters._ class OutputWriter { - def writeJava(packs: JMap[String, Package], templatePath: String, outPath: String, resources: JList[String]): Unit = { - write(packs.asScala, templatePath, outPath, resources.asScala) + def writeJava(packs: JMap[String, Package], outPath: String, template: URL, resources: JList[URL]): Unit = { + write(packs.asScala, outPath, template, resources.asScala) } - def write(packs: collection.Map[String, Package], templatePath: String, outPath: String, resources: Iterable[String]): Unit = { + def write(packs: collection.Map[String, Package], outPath: String, template: URL, resources: Traversable[URL]): Unit = { // Write all packages to `outPath` for (pack <- packs.values) { println(s"""Writing '${pack.path.mkString(".")}'""") writeFile( - expandTemplate(templatePath, pack, outPath), + expandTemplate(template, pack, outPath), outPath + pack.path.mkString("/", "/", "/"), "index.html") @@ -41,7 +43,7 @@ class OutputWriter { } { println(s"""Writing '${child.path.mkString(".")}'""") writeFile( - expandTemplate(templatePath, child, outPath), + expandTemplate(template, child, outPath), outPath + child.path.dropRight(1).mkString("/", "/", "/"), child.path.last + ".html") } @@ -55,7 +57,10 @@ class OutputWriter { // Write resources to outPath println("Copying CSS/JS resources to destination...") assert(resources.nonEmpty) - resources.map(s => copy(new JFile(s), outPath)) + + // TODO: splitting the URL by '/' and taking the last means that we don't + // allow folders among the resources + resources.foreach(url => copy(url.openStream, outPath, url.getFile.split("/").last)) println("Done writing static material, building js-app") } @@ -66,14 +71,15 @@ class OutputWriter { def writeJson(index: collection.Map[String, Package], outputDir: String): Unit = writeFile(index.json, outputDir + "/", "index.json") - def expandTemplate(templatePath: String, entity: Entity, outPath: String): String = try { + def expandTemplate(template: URL, entity: Entity, outPath: String): String = try { import model.json._ import model.java._ + val inputStream = template.openStream val writer = new _root_.java.io.StringWriter() val mf = new DefaultMustacheFactory() - def toRoot = "../" * (entity.path.length - 1) + def toRoot = "../" * (entity.path.length - { if (entity.isInstanceOf[Package]) 0 else 1 }) val entityWithExtras = entity.asJava(Map( "assets" -> s"${toRoot}docassets", @@ -81,14 +87,15 @@ class OutputWriter { "currentEntity" -> entity.json )) - mf.compile(new JFileReader(templatePath), "template") + mf.compile(new InputStreamReader(inputStream), "template") .execute(writer, entityWithExtras) + inputStream.close() writer.flush() writer.toString } catch { case fnf: FileNotFoundException => - dottydoc.println(s"""Couldn't find the template: "$templatePath"...exiting""") + dottydoc.println(s"""Couldn't find the template: "${template.getFile}"...exiting""") System.exit(1); "" } @@ -107,11 +114,12 @@ class OutputWriter { printToFile(new JFile(path + file))(printer => bytes.foreach(printer.print)) } - def copy(src: JFile, path: String): Unit = { - val reader = new BufferedInputStream(new FileInputStream(src)) + def copy(src: InputStream, path: String, name: String): Unit = { + val reader = new BufferedInputStream(src) try { - val bytes = Stream.continually(reader.read).takeWhile(-1 != _).map(_.toByte) - writeFile(bytes.toArray, path + "/docassets/", src.getName) + val bytes = Stream.continually(reader.read).takeWhile(-1 != _).map(_.toByte) + writeFile(bytes.toArray, path + "/docassets/", name) + src.close() } finally reader.close() } } diff --git a/dottydoc/test/WhitelistedStdLibMain.scala b/dottydoc/test/WhitelistedStdLibMain.scala index 95d4afbae794..fcd08e50dd3e 100644 --- a/dottydoc/test/WhitelistedStdLibMain.scala +++ b/dottydoc/test/WhitelistedStdLibMain.scala @@ -3,7 +3,7 @@ package dottydoc import scala.io.Source -object WhitelistedStandardLib extends dottydoc.api.java.Dottydoc { +object WhitelistedStandardLib extends dottydoc.api.scala.Dottydoc { import scala.collection.JavaConverters._ val files: List[String] = { @@ -16,7 +16,6 @@ object WhitelistedStandardLib extends dottydoc.api.java.Dottydoc { .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line .filter(_.nonEmpty) .filterNot(_.endsWith("package.scala")) - .map("." + _) .toList } @@ -42,6 +41,6 @@ object WhitelistedStandardLib extends dottydoc.api.java.Dottydoc { "-language:Scala2" +: "-Ydoc-output" +: "../build/dottydoc" +: files.toArray val index = createIndex(compilerArgs) - buildDocs("../build/dottydoc", "../../dottydoc-client/resources/template.html", resources.asJava, index) + buildDocs("../build/dottydoc", "../../dottydoc-client/resources/template.html", resources, index) } } diff --git a/project/Build.scala b/project/Build.scala index 7a9d83a50e71..cd17f2d079c2 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -100,6 +100,7 @@ object DottyBuild extends Build { libraryDependencies ++= partestDeps.value, libraryDependencies ++= Seq("org.scala-lang.modules" %% "scala-xml" % "1.0.1", "org.scala-lang.modules" %% "scala-partest" % "1.0.11" % "test", + "ch.epfl.lamp" % "dottydoc-client" % "0.1-SNAPSHOT", "com.novocode" % "junit-interface" % "0.11" % "test", "com.googlecode.java-diff-utils" % "diffutils" % "1.3.0", "com.github.spullara.mustache.java" % "compiler" % "0.9.3", From abf16325cb8909b8c856d2a83ad7c9b05f49130b Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 15 Aug 2016 18:22:14 +0200 Subject: [PATCH 095/100] Add documentation to dottydoc API --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 7 ++-- .../tools/dottydoc/api/java/Dottydoc.java | 35 +++++++++++++++++-- .../tools/dottydoc/api/scala/Dottydoc.scala | 31 +++++++++++++++- .../model/comment/CommentParser.scala | 2 +- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala index e19805d21561..a05cd8c25ad7 100644 --- a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala @@ -70,6 +70,9 @@ abstract class DocDriver extends Driver { def compiledDocsJava(args: Array[String]): JMap[String, Package] = compiledDocs(args).asJava - def indexToJson(index: JMap[String, Package]): String = - index.asScala.json + def indexToJson(index: collection.Map[String, Package]): String = + index.json + + def indexToJsonJava(index: JMap[String, Package]): String = + indexToJson(index.asScala) } diff --git a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java index dbe3f6f4149e..1bdfe0488e34 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java +++ b/dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java @@ -7,16 +7,46 @@ import java.util.List; import java.net.URL; -/** FIXME: document me! */ +/** + * The Dottydoc API is fairly simple. The tool creates an index by calling: + * "createIndex" with the same argument list as you would the compiler - e.g: + * + * {{{ + * String[] array = { + * "-language:Scala2" + * }; + * + * Map index = createIndex(array); + * }}} + * + * Once the index has been generated, the tool can also build a documentation + * API given a Mustache template and a flat resources structure (i.e. absolute + * paths to each resource, which will be put in the same directory). + * + * {{{ + * buildDocs("path/to/output/dir", templateURL, resources, index); + * }}} + * + * The tool can also generate JSON from the created index using "toJson(index)" + * or directly using "createJsonIndex" + */ public class Dottydoc extends DocDriver { + + /** Creates index from compiler arguments */ public Map createIndex(String[] args) { return compiledDocsJava(args); } + /** Creates JSON from compiler arguments */ public String createJsonIndex(String[] args) { - return indexToJson(createIndex(args)); + return indexToJsonJava(createIndex(args)); + } + + public String toJson(Map index) { + return indexToJsonJava(index); } + /** Creates a documentation from the given parameters */ public void buildDocs( String outputDir, URL template, @@ -26,6 +56,7 @@ public void buildDocs( new OutputWriter().writeJava(index, outputDir, template, resources); } + /** Writes JSON to an output directory as "index.json" */ public void writeJson(Map index, String outputDir) { new OutputWriter().writeJsonJava(index, outputDir); } diff --git a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala index a2c42d38c04c..15db81a9559f 100644 --- a/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala @@ -7,14 +7,43 @@ import dotty.tools.dottydoc.util.OutputWriter import scala.collection.Map import java.net.URL -/** FIXME: document this class plz */ +/** + * The Dottydoc API is fairly simple. The tool creates an index by calling: + * "createIndex" with the same argument list as you would the compiler - e.g: + * + * {{{ + * val array: Array[String] = Array( + * "-language:Scala2" + * ) + * + * val index: Map[String, Package] = createIndex(array) + * }}} + * + * Once the index has been generated, the tool can also build a documentation + * API given a Mustache template and a flat resources structure (i.e. absolute + * paths to each resource, which will be put in the same directory). + * + * {{{ + * buildDocs("path/to/output/dir", templateURL, resources, index) + * }}} + * + * The tool can also generate JSON from the created index using "indexToJson" + * or directly using "createJsonIndex" + */ trait Dottydoc extends DocDriver { + /** Creates index from compiler arguments */ def createIndex(args: Array[String]): Map[String, Package] = compiledDocs(args) + /** Creates JSON from compiler arguments */ + def createJsonIndex(args: Array[String]): String = + indexToJson(compiledDocs(args)) + + /** Creates a documentation from the given parameters */ def buildDocs(outDir: String, template: URL, resources: List[URL], index: Map[String, Package]) = new OutputWriter().write(index, outDir, template, resources) + /** Writes JSON to an output directory as "index.json" */ def writeJson(index: Map[String, Package], outputDir: String) = new OutputWriter().writeJson(index, outputDir) } diff --git a/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentParser.scala index 589e2ebe21a2..9685b69341b7 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentParser.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/comment/CommentParser.scala @@ -347,7 +347,7 @@ trait CommentParser extends util.MemberLookup { /** listStyle ::= '-' spc | '1.' spc | 'I.' spc | 'i.' spc | 'A.' spc | 'a.' spc * Characters used to build lists and their constructors */ - protected val listStyles = Map[String, (Seq[Block] => Block)]( // TODO Should this be defined at some list companion? + protected val listStyles = Map[String, (Seq[Block] => Block)]( "- " -> ( UnorderedList(_) ), "1. " -> ( OrderedList(_,"decimal") ), "I. " -> ( OrderedList(_,"upperRoman") ), From 0a9003d7b018ad179b0a6b8630e1bdb99be06627 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 15 Aug 2016 18:30:48 +0200 Subject: [PATCH 096/100] Move client test to client repo --- dottydoc/test/WhitelistedStdLib.scala | 17 ++++++++- dottydoc/test/WhitelistedStdLibMain.scala | 46 ----------------------- 2 files changed, 15 insertions(+), 48 deletions(-) delete mode 100644 dottydoc/test/WhitelistedStdLibMain.scala diff --git a/dottydoc/test/WhitelistedStdLib.scala b/dottydoc/test/WhitelistedStdLib.scala index 88dc67e995e7..0225ba218cec 100644 --- a/dottydoc/test/WhitelistedStdLib.scala +++ b/dottydoc/test/WhitelistedStdLib.scala @@ -5,8 +5,21 @@ import org.junit.Test import org.junit.Assert._ class TestWhitelistedCollections extends DottyTest { + val files: List[String] = { + val whitelist = "./test/dotc/scala-collections.whitelist" + + scala.io.Source.fromFile(whitelist, "UTF8") + .getLines() + .map(_.trim) // allow identation + .filter(!_.startsWith("#")) // allow comment lines prefixed by # + .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line + .filter(_.nonEmpty) + .filterNot(_.endsWith("package.scala")) + .toList + } + @Test def arrayHasDocumentation = - checkFiles(WhitelistedStandardLib.files) { doc => + checkFiles(files) { doc => val array = doc .packages("scala") .children.find(_.path.mkString(".") == "scala.Array") @@ -16,7 +29,7 @@ class TestWhitelistedCollections extends DottyTest { } @Test def traitImmutableHasDocumentation = - checkFiles(WhitelistedStandardLib.files) { doc => + checkFiles(files) { doc => val imm = doc .packages("scala") .children.find(_.path.mkString(".") == "scala.Immutable") diff --git a/dottydoc/test/WhitelistedStdLibMain.scala b/dottydoc/test/WhitelistedStdLibMain.scala deleted file mode 100644 index fcd08e50dd3e..000000000000 --- a/dottydoc/test/WhitelistedStdLibMain.scala +++ /dev/null @@ -1,46 +0,0 @@ -package dotty.tools -package dottydoc - -import scala.io.Source - -object WhitelistedStandardLib extends dottydoc.api.scala.Dottydoc { - import scala.collection.JavaConverters._ - - val files: List[String] = { - val whitelist = "./test/dotc/scala-collections.whitelist" - - Source.fromFile(whitelist, "UTF8") - .getLines() - .map(_.trim) // allow identation - .filter(!_.startsWith("#")) // allow comment lines prefixed by # - .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line - .filter(_.nonEmpty) - .filterNot(_.endsWith("package.scala")) - .toList - } - - private val resources = List( - "../dottydoc-client/resources/MaterialIcons-Regular.eot", - "../dottydoc-client/resources/MaterialIcons-Regular.ijmap", - "../dottydoc-client/resources/MaterialIcons-Regular.svg", - "../dottydoc-client/resources/MaterialIcons-Regular.ttf", - "../dottydoc-client/resources/MaterialIcons-Regular.woff", - "../dottydoc-client/resources/MaterialIcons-Regular.woff2", - "../dottydoc-client/resources/codepoints", - "../dottydoc-client/resources/github.css", - "../dottydoc-client/resources/highlight.pack.js", - "../dottydoc-client/resources/index.css", - "../dottydoc-client/resources/material-icons.css", - "../dottydoc-client/resources/material.min.css", - "../dottydoc-client/resources/material.min.js", - "../dottydoc-client/target/scala-2.11/dottydoc-client-fastopt.js" - ) - - override def main(args: Array[String]) = { - val compilerArgs = - "-language:Scala2" +: "-Ydoc-output" +: "../build/dottydoc" +: files.toArray - - val index = createIndex(compilerArgs) - buildDocs("../build/dottydoc", "../../dottydoc-client/resources/template.html", resources, index) - } -} From 9879b906772ff24dbe3da53c4dc6c9700935c483 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 15 Aug 2016 19:51:25 +0200 Subject: [PATCH 097/100] Add snapshots resolver --- project/Build.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/project/Build.scala b/project/Build.scala index cd17f2d079c2..8157147d218e 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -93,6 +93,8 @@ object DottyBuild extends Build { //http://stackoverflow.com/questions/10472840/how-to-attach-sources-to-sbt-managed-dependencies-in-scala-ide#answer-11683728 com.typesafe.sbteclipse.plugin.EclipsePlugin.EclipseKeys.withSource := true, + resolvers += Resolver.sonatypeRepo("snapshots"), + // get libraries onboard partestDeps := Seq(scalaCompiler, "org.scala-lang" % "scala-reflect" % scalaVersion.value, From 59c6c0d1bb1e889ee728931576a461e3014e3cf3 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 17 Aug 2016 09:52:04 +0200 Subject: [PATCH 098/100] Properly materialize supertype links --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 2 +- .../dottydoc/core/TypeLinkingPhases.scala | 40 +++++++++++++++---- .../dotty/tools/dottydoc/model/internal.scala | 22 +++++----- .../dotty/tools/dottydoc/util/mutate.scala | 12 ------ 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala index a05cd8c25ad7..61de1cfd849d 100644 --- a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala @@ -34,6 +34,7 @@ class DocCompiler extends Compiler { List(DocMiniTransformations(new LinkReturnTypes, new LinkParamListTypes, new LinkImplicitlyAddedTypes, + new LinkSuperTypes, new SortMembers)) ) } @@ -59,7 +60,6 @@ abstract class DocDriver extends Driver { override def newCompiler(implicit ctx: Context): Compiler = new DocCompiler - def compiledDocs(args: Array[String]): collection.Map[String, Package] = { val (fileNames, ctx) = setup(args, initCtx.fresh) doCompile(newCompiler(ctx), fileNames)(ctx) diff --git a/dottydoc/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/dottydoc/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index c2d647290d72..ae07effa9ed9 100644 --- a/dottydoc/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/dottydoc/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -38,6 +38,32 @@ class LinkParamListTypes extends DocMiniPhase with TypeLinker { } } +class LinkSuperTypes extends DocMiniPhase with TypeLinker { + def linkSuperTypes(ent: Entity with SuperTypes)(implicit ctx: Context): List[MaterializableLink] = + ent.superTypes.collect { + case UnsetLink(title, query) => + val packages = ctx.docbase.packages[Package].toMap + val entityLink = makeEntityLink(ent, packages, Text(title), NoPosition, query).link + handleEntityLink(title, entityLink, ent) + } + + override def transformClass(implicit ctx: Context) = { case cls: ClassImpl => + cls.copy(superTypes = linkSuperTypes(cls)) + } + + override def transformCaseClass(implicit ctx: Context) = { case cc: CaseClassImpl => + cc.copy(superTypes = linkSuperTypes(cc)) + } + + override def transformTrait(implicit ctx: Context) = { case trt: TraitImpl => + trt.copy(superTypes = linkSuperTypes(trt)) + } + + override def transformObject(implicit ctx: Context) = { case obj: ObjectImpl => + obj.copy(superTypes = linkSuperTypes(obj)) + } +} + class LinkImplicitlyAddedTypes extends DocMiniPhase with TypeLinker { override def transformDef(implicit ctx: Context) = { case df: DefImpl if df.implicitlyAddedFrom.isDefined => @@ -53,6 +79,12 @@ class LinkImplicitlyAddedTypes extends DocMiniPhase with TypeLinker { } trait TypeLinker extends MemberLookup { + def handleEntityLink(title: String, lt: LinkTo, ent: Entity): MaterializableLink = lt match { + case Tooltip(str) => NoLink(title, str) + case LinkToExternal(_, url) => MaterializedLink(title, url) + case LinkToEntity(target) => MaterializedLink(title, util.traversing.relativePath(ent, target)) + } + def linkReference(ent: Entity, ref: Reference, packs: Map[String, Package]): Reference = { def linkRef(ref: Reference) = linkReference(ent, ref, packs) @@ -61,13 +93,7 @@ trait TypeLinker extends MemberLookup { val inlineToHtml = InlineToHtml(ent) val title = t - def handleEntityLink(title: String, lt: LinkTo): MaterializableLink = lt match { - case Tooltip(str) => NoLink(title, str) - case LinkToExternal(_, url) => MaterializedLink(title, url) - case LinkToEntity(target) => MaterializedLink(title, util.traversing.relativePath(ent, target)) - } - - val target = handleEntityLink(title, makeEntityLink(ent, packs, Text(t), NoPosition, query).link) + val target = handleEntityLink(title, makeEntityLink(ent, packs, Text(t), NoPosition, query).link, ent) val tpTargets = tps.map(linkReference(ent, _, packs)) ref.copy(tpeLink = target, paramLinks = tpTargets) case ref @ OrTypeReference(left, right) => diff --git a/dottydoc/src/dotty/tools/dottydoc/model/internal.scala b/dottydoc/src/dotty/tools/dottydoc/model/internal.scala index 82185b5aeff3..63e97743d8f1 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/internal.scala @@ -25,8 +25,8 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], - var typeParams: List[String] = Nil, - var superTypes: List[MaterializableLink] = Nil, + typeParams: List[String] = Nil, + superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Class with Impl @@ -35,8 +35,8 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], - var typeParams: List[String] = Nil, - var superTypes: List[MaterializableLink] = Nil, + typeParams: List[String] = Nil, + superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends CaseClass with Impl @@ -45,8 +45,8 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], - var typeParams: List[String] = Nil, - var superTypes: List[MaterializableLink] = Nil, + typeParams: List[String] = Nil, + superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Trait with Impl @@ -55,7 +55,7 @@ object internal { members: List[Entity], modifiers: List[String], path: List[String], - var superTypes: List[MaterializableLink] = Nil, + superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Object with Impl @@ -63,9 +63,9 @@ object internal { name: String, modifiers: List[String], path: List[String], - var returnValue: Reference, - var typeParams: List[String] = Nil, - var paramLists: List[ParamList] = Nil, + returnValue: Reference, + typeParams: List[String] = Nil, + paramLists: List[ParamList] = Nil, var comment: Option[Comment] = None, implicitlyAddedFrom: Option[Reference] = None ) extends Def with Impl @@ -74,7 +74,7 @@ object internal { name: String, modifiers: List[String], path: List[String], - var returnValue: Reference, + returnValue: Reference, var comment: Option[Comment] = None, implicitlyAddedFrom: Option[Reference] = None ) extends Val with Impl diff --git a/dottydoc/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/src/dotty/tools/dottydoc/util/mutate.scala index e02dc60af278..a5a4dfec6422 100644 --- a/dottydoc/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/src/dotty/tools/dottydoc/util/mutate.scala @@ -18,18 +18,6 @@ object setters { case x: ValImpl => x.comment = to } - - def setReturnValue(ent: Entity, ref: Reference) = ent match { - case x: DefImpl => x.returnValue = ref - case x: ValImpl => x.returnValue = ref - case _ => () - } - - def setParamLists(ent: Entity, refs: List[ParamList]) = ent match { - case x: DefImpl => x.paramLists = refs - case _ => () - } - def setParent(ent: Entity, to: Entity): Unit = ent match { case e: ClassImpl => e.parent = to From d8c02ec2f8ef225fde2be5324bbf46958132d865 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 17 Aug 2016 14:53:32 +0200 Subject: [PATCH 099/100] Add `ImplicitlyAddedEntity` as a common trait for implicitly added members --- dottydoc/src/dotty/tools/dottydoc/model/entities.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dottydoc/src/dotty/tools/dottydoc/model/entities.scala b/dottydoc/src/dotty/tools/dottydoc/model/entities.scala index 1c204662b263..4d3a33b33ee6 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/entities.scala @@ -57,6 +57,10 @@ trait ParamList { def isImplicit: Boolean } +trait ImplicitlyAddedEntity extends Entity { + def implicitlyAddedFrom: Option[Reference] +} + trait Package extends Entity with Members { val kind = "package" @@ -79,15 +83,13 @@ trait Object extends Entity with Modifiers with SuperTypes with Members { override val kind = "object" } -trait Def extends Entity with Modifiers with TypeParams with ReturnValue { +trait Def extends Entity with Modifiers with TypeParams with ReturnValue with ImplicitlyAddedEntity { val kind = "def" def paramLists: List[ParamList] - def implicitlyAddedFrom: Option[Reference] } -trait Val extends Entity with Modifiers with ReturnValue { +trait Val extends Entity with Modifiers with ReturnValue with ImplicitlyAddedEntity { val kind = "val" - def implicitlyAddedFrom: Option[Reference] } trait Var extends Entity with Modifiers with ReturnValue { From 0b69be68d3100103ebfd636bbc36f9cdcbd6fb28 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 19 Aug 2016 15:28:39 +0200 Subject: [PATCH 100/100] Add phase to deal with constructors --- .../src/dotty/tools/dottydoc/DottyDoc.scala | 1 + .../core/AlternateConstructorsPhase.scala | 34 +++ .../tools/dottydoc/core/DocASTPhase.scala | 4 +- .../dottydoc/core/MiniPhaseTransform.scala | 19 +- .../dotty/tools/dottydoc/model/entities.scala | 9 +- .../tools/dottydoc/model/factories.scala | 21 +- .../dotty/tools/dottydoc/model/internal.scala | 3 + .../src/dotty/tools/dottydoc/model/json.scala | 8 +- dottydoc/test/BaseTest.scala | 24 +- dottydoc/test/ConstructorTest.scala | 211 ++++++++++++++++++ dottydoc/test/PackageStructure.scala | 20 +- dottydoc/test/SimpleComments.scala | 6 +- dottydoc/test/WhitelistedStdLib.scala | 12 +- 13 files changed, 318 insertions(+), 54 deletions(-) create mode 100644 dottydoc/src/dotty/tools/dottydoc/core/AlternateConstructorsPhase.scala create mode 100644 dottydoc/test/ConstructorTest.scala diff --git a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala index 61de1cfd849d..2d4c7abcf3ee 100644 --- a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala @@ -35,6 +35,7 @@ class DocCompiler extends Compiler { new LinkParamListTypes, new LinkImplicitlyAddedTypes, new LinkSuperTypes, + new AlternateConstructors, new SortMembers)) ) } diff --git a/dottydoc/src/dotty/tools/dottydoc/core/AlternateConstructorsPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/AlternateConstructorsPhase.scala new file mode 100644 index 000000000000..53c96fc87487 --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/core/AlternateConstructorsPhase.scala @@ -0,0 +1,34 @@ +package dotty.tools +package dottydoc +package core + +import dotc.core.Contexts.Context + +import transform.DocMiniPhase +import model._ +import model.internal._ + +/** This DocMiniPhase adds the alternate constructors, currently defined as + * methods with the name ``, to the Entity#constructors list + */ +class AlternateConstructors extends DocMiniPhase { + def partitionMembers(ent: Entity with Constructors with Members): (List[List[ParamList]], List[Entity]) = { + val (constructors, members) = ent.members.partition(x => x.name == "") + + val paramLists: List[List[ParamList]] = constructors.collect { + case df: Def => df.paramLists + } + + (ent.constructors ++ paramLists, members) + } + + override def transformClass(implicit ctx: Context) = { case cls: ClassImpl => + val (constructors, members) = partitionMembers(cls) + cls.copy(members = members, constructors = constructors) + } + + override def transformCaseClass(implicit ctx: Context) = { case cc: CaseClassImpl => + val (constructors, members) = partitionMembers(cc) + cc.copy(members = members, constructors = constructors) + } +} diff --git a/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala index 01301097194d..7744752ce530 100644 --- a/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -97,7 +97,7 @@ class DocASTPhase extends Phase { val name = n.decode.toString val newPath = prev :+ name //TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well - TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), superTypes(t)) + TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), traitParameters(t.symbol), superTypes(t)) /** objects, on the format "Object$" so drop the last letter */ case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => @@ -110,7 +110,7 @@ class DocASTPhase extends Phase { val name = n.decode.toString val newPath = prev :+ name //TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well - (name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), superTypes(c), None) match { + (name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), constructors(c.symbol), superTypes(c), None) match { case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x) case x => ClassImpl.tupled(x) } diff --git a/dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala b/dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala index 7bdb2bf4e177..2690ac7b77c9 100644 --- a/dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala +++ b/dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala @@ -88,15 +88,16 @@ object transform { newPackage } - case c: Class => transformEntity(c, _.classTransformation) { newClass => + case c: Class => transformEntity(c, _.classTransformation) { cls => ClassImpl( - newClass.name, - newClass.members.map(traverse), - newClass.modifiers, - newClass.path, - newClass.typeParams, - newClass.superTypes, - newClass.comment + cls.name, + cls.members.map(traverse), + cls.modifiers, + cls.path, + cls.typeParams, + cls.constructors, + cls.superTypes, + cls.comment ) } case cc: CaseClass => transformEntity(cc, _.caseClassTransformation) { cc => @@ -106,6 +107,7 @@ object transform { cc.modifiers, cc.path, cc.typeParams, + cc.constructors, cc.superTypes, cc.comment ) @@ -117,6 +119,7 @@ object transform { trt.modifiers, trt.path, trt.typeParams, + trt.traitParams, trt.superTypes, trt.comment ) diff --git a/dottydoc/src/dotty/tools/dottydoc/model/entities.scala b/dottydoc/src/dotty/tools/dottydoc/model/entities.scala index 4d3a33b33ee6..76792070cf5b 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/entities.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/entities.scala @@ -57,6 +57,10 @@ trait ParamList { def isImplicit: Boolean } +trait Constructors { + def constructors: List[List[ParamList]] +} + trait ImplicitlyAddedEntity extends Entity { def implicitlyAddedFrom: Option[Reference] } @@ -67,15 +71,16 @@ trait Package extends Entity with Members { def children: List[Entity with Members] } -trait Class extends Entity with Modifiers with TypeParams with SuperTypes with Members { +trait Class extends Entity with Modifiers with TypeParams with Constructors with SuperTypes with Members { val kind = "class" } -trait CaseClass extends Entity with Modifiers with TypeParams with SuperTypes with Members { +trait CaseClass extends Entity with Modifiers with TypeParams with Constructors with SuperTypes with Members { override val kind = "case class" } trait Trait extends Entity with Modifiers with TypeParams with SuperTypes with Members { + def traitParams: List[ParamList] override val kind = "trait" } diff --git a/dottydoc/src/dotty/tools/dottydoc/model/factories.scala b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala index b5cf15148b6f..b19b836eee2b 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala @@ -6,19 +6,17 @@ import references._ import dotty.tools.dotc import dotc.core.Types._ import dotc.core.TypeApplications._ -import dotc.core.Flags import dotc.core.Contexts.Context -import dotc.core.Symbols.Symbol +import dotc.core.Symbols.{ Symbol, ClassSymbol } import dotty.tools.dotc.core.SymDenotations._ import dotty.tools.dotc.core.Names.TypeName -import dotc.core.{ Flags => DottyFlags } import dotc.ast.Trees._ object factories { import dotty.tools.dotc.ast.tpd._ import dotty.tools.dottydoc.model.internal.ParamListImpl - import DottyFlags._ + import dotc.core.Flags._ type TypeTree = dotty.tools.dotc.ast.Trees.Tree[Type] @@ -118,11 +116,11 @@ object factories { pt.paramNames.map(_.show.split("\\$").last) case ClassInfo(_, _, _, decls, _) => decls.iterator - .filter(_.flags is Flags.TypeParam) + .filter(_.flags is TypeParam) .map { tp => val prefix = - if (tp.flags is Flags.Covariant) "+" - else if (tp.flags is Flags.Contravariant) "-" + if (tp.flags is Covariant) "+" + else if (tp.flags is Contravariant) "-" else "" prefix + tp.name.show.split("\\$").last } @@ -131,6 +129,15 @@ object factories { Nil } + def constructors(sym: Symbol)(implicit ctx: Context): List[List[ParamList]] = sym match { + case sym: ClassSymbol => + paramLists(sym.primaryConstructor.info) :: Nil + case _ => Nil + } + + def traitParameters(sym: Symbol)(implicit ctx: Context): List[ParamList] = + constructors(sym).head + def paramLists(tpe: Type)(implicit ctx: Context): List[ParamList] = tpe match { case pt: PolyType => paramLists(pt.resultType) diff --git a/dottydoc/src/dotty/tools/dottydoc/model/internal.scala b/dottydoc/src/dotty/tools/dottydoc/model/internal.scala index 63e97743d8f1..6afb1ec9b33b 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/internal.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/internal.scala @@ -26,6 +26,7 @@ object internal { modifiers: List[String], path: List[String], typeParams: List[String] = Nil, + constructors: List[List[ParamList]] = Nil, superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Class with Impl @@ -36,6 +37,7 @@ object internal { modifiers: List[String], path: List[String], typeParams: List[String] = Nil, + constructors: List[List[ParamList]] = Nil, superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends CaseClass with Impl @@ -46,6 +48,7 @@ object internal { modifiers: List[String], path: List[String], typeParams: List[String] = Nil, + traitParams: List[ParamList] = Nil, superTypes: List[MaterializableLink] = Nil, var comment: Option[Comment] = None ) extends Trait with Impl diff --git a/dottydoc/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/src/dotty/tools/dottydoc/model/json.scala index 9bf37295c207..145728f8a592 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/json.scala @@ -34,7 +34,7 @@ object json { def json: String = { val (secondTitle, secondValue, kind) = link match { case ul: UnsetLink => ("query".json, ul.query.json, "UnsetLink".json) - case ml: MaterializedLink => ("target", ml.target.json, "MaterializedLink".json) + case ml: MaterializedLink => ("target".json, ml.target.json, "MaterializedLink".json) case nl: NoLink => ("target".json, nl.target.json, "NoLink".json) } s"""{"title":${link.title.json},$secondTitle:${secondValue},"kind":$kind}""" @@ -70,11 +70,11 @@ object json { case ent: Package => s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"package"}""" case ent: Class => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"constructors":${ent.constructors.map(xs => xs.map(_.json).mkString("[",",","]")).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}""" case ent: CaseClass => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"constructors":${ent.constructors.map(xs => xs.map(_.json).mkString("[",",","]")).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}""" case ent: Trait => - s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}""" + s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"traitParams":${ent.traitParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}""" case ent: Object => s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}""" case ent: Def => diff --git a/dottydoc/test/BaseTest.scala b/dottydoc/test/BaseTest.scala index 7f077d27bc69..2233d03c8b53 100644 --- a/dottydoc/test/BaseTest.scala +++ b/dottydoc/test/BaseTest.scala @@ -7,6 +7,7 @@ import dotc.util.SourceFile import dotc.core.Phases.Phase import dotc.typer.FrontEnd import dottydoc.core.DocASTPhase +import model.Package trait DottyTest { dotty.tools.dotc.parsing.Scanners // initialize keywords @@ -21,34 +22,33 @@ trait DottyTest { ctx } - private def compilerWithChecker(assertion: DocASTPhase => Unit) = new DocCompiler { - private[this] val docPhase = new DocASTPhase - - override def phases = - List(new FrontEnd) :: - List(docPhase) :: + private def compilerWithChecker(assertion: Map[String, Package] => Unit) = new DocCompiler { + private[this] val assertionPhase: List[List[Phase]] = List(new Phase { def phaseName = "assertionPhase" - override def run(implicit ctx: Context): Unit = assertion(docPhase) - }) :: - Nil + override def run(implicit ctx: Context): Unit = + assertion(ctx.docbase.packages[Package].toMap) + }) :: Nil + + override def phases = + super.phases ++ assertionPhase } - def checkSource(source: String)(assertion: DocASTPhase => Unit): Unit = { + def checkSource(source: String)(assertion: Map[String, Package] => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun run.compile(source) } - def checkFiles(sources: List[String])(assertion: DocASTPhase => Unit): Unit = { + def checkFiles(sources: List[String])(assertion: Map[String, Package] => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun run.compile(sources) } - def checkSources(sourceFiles: List[SourceFile])(assertion: DocASTPhase => Unit): Unit = { + def checkSources(sourceFiles: List[SourceFile])(assertion: Map[String, Package] => Unit): Unit = { val c = compilerWithChecker(assertion) c.rootContext(ctx) val run = c.newRun diff --git a/dottydoc/test/ConstructorTest.scala b/dottydoc/test/ConstructorTest.scala new file mode 100644 index 000000000000..8aa8830223ef --- /dev/null +++ b/dottydoc/test/ConstructorTest.scala @@ -0,0 +1,211 @@ +package dotty.tools +package dottydoc + +import org.junit.Test +import org.junit.Assert._ + +import dotc.util.SourceFile +import model._ +import model.internal._ +import model.references._ + +class Constructors extends DottyTest { + @Test def singleClassConstructor = { + val source = new SourceFile ( + "Class.scala", + """ + |package scala + | + |class Class(val str: String) + """.stripMargin + ) + + checkSources(source :: Nil) { packages => + packages("scala") match { + case PackageImpl(_, List(cls: Class), _, _) => + cls.constructors.headOption match { + case Some(ParamListImpl(NamedReference("str", _, false, false) :: Nil, false) :: Nil) => + // success! + case _ => assert(false, s"Incorrect constructor found: ${cls.constructors}") + } + } + } + } + + @Test def constructorPlusImplicitArgList = { + val source = new SourceFile ( + "Class.scala", + """ + |package scala + | + |class Class(val str1: String)(implicit str2: String) + """.stripMargin + ) + + checkSources(source :: Nil) { packages => + packages("scala") match { + case PackageImpl(_, List(cls: Class), _, _) => + cls.constructors match { + case ( + ParamListImpl(NamedReference("str1", _, false, false) :: Nil, false) :: + ParamListImpl(NamedReference("str2", _, false, false) :: Nil, true) :: Nil + ) :: Nil => + // success! + case _ => assert(false, s"Incorrect constructor found: ${cls.constructors}") + } + } + } + } + + @Test def multipleArgumentListsForConstructor = { + val source = new SourceFile ( + "Class.scala", + """ + |package scala + | + |class Class(val str1: String)(val str2: String)(implicit str3: String) + """.stripMargin + ) + + checkSources(source :: Nil) { packages => + packages("scala") match { + case PackageImpl(_, List(cls: Class), _, _) => + cls.constructors match { + case ( + ParamListImpl(NamedReference("str1", _, false, false) :: Nil, false) :: + ParamListImpl(NamedReference("str2", _, false, false) :: Nil, false) :: + ParamListImpl(NamedReference("str3", _, false, false) :: Nil, true) :: Nil + ) :: Nil => + // success! + case _ => assert(false, s"Incorrect constructor found: ${cls.constructors}") + } + } + } + } + + @Test def multipleConstructors = { + val source = new SourceFile ( + "Class.scala", + """ + |package scala + | + |class Class(val main: String) { + | def this(alt1: Int) = + | this("String") + | + | def this(alt2: List[String]) = + | this(alt2.head) + |} + """.stripMargin + ) + + checkSources(source :: Nil) { packages => + packages("scala") match { + case PackageImpl(_, List(cls: Class), _, _) => + cls.constructors match { + case ( + ParamListImpl(NamedReference("main", _, false, false) :: Nil, false) :: Nil + ) :: ( + ParamListImpl(NamedReference("alt1", _, false, false) :: Nil, false) :: Nil + ) :: ( + ParamListImpl(NamedReference("alt2", _, false, false) :: Nil, false) :: Nil + ) :: Nil => + // success! + case _ => + assert( + false, + s"""Incorrect constructor found:\n${cls.constructors.mkString("\n")}""" + ) + } + } + } + } + + @Test def multipleConstructorsCC = { + val source = new SourceFile ( + "Class.scala", + """ + |package scala + | + |case class Class(val main: String) { + | def this(alt1: Int) = + | this("String") + | + | def this(alt2: List[String]) = + | this(alt2.head) + |} + """.stripMargin + ) + + checkSources(source :: Nil) { packages => + packages("scala") match { + case PackageImpl(_, List(cls: CaseClass, obj: Object), _, _) => + cls.constructors match { + case ( + ParamListImpl(NamedReference("main", _, false, false) :: Nil, false) :: Nil + ) :: ( + ParamListImpl(NamedReference("alt1", _, false, false) :: Nil, false) :: Nil + ) :: ( + ParamListImpl(NamedReference("alt2", _, false, false) :: Nil, false) :: Nil + ) :: Nil => + // success! + case _ => + println(obj.members.map(x => x.kind + " " + x.name)) + assert( + false, + s"""Incorrect constructor found:\n${cls.constructors.mkString("\n")}""" + ) + } + } + } + } + + @Test def traitParameters = { + val source = new SourceFile ( + "Trait.scala", + """ + |package scala + | + |trait Trait(val main: String) + """.stripMargin + ) + + checkSources(source :: Nil) { packages => + packages("scala") match { + case PackageImpl(_, List(trt: Trait), _, _) => + trt.traitParams match { + case ParamListImpl(NamedReference("main", _, false, false) :: Nil, false) :: Nil => + case _ => + assert( + false, + s"""Incorrect constructor found:\n${trt.traitParams.mkString("\n")}""" + ) + } + } + } + } + + @Test def testJson = { + val actualSource = + """ + |package scala + | + |trait Trait(val main: String) + |class Class(val main: String) + |case class CaseClass(main: String) + """.stripMargin + + val source = new SourceFile ("JsonTest.scala", actualSource) + + checkSources(source :: Nil) { packages => + packages("scala") match { + case PackageImpl(_, List(cc: CaseClass, _, cls: Class, trt: Trait), _, _) => + import model.json._ + lazy val incorrectJson = s"The json generated for:\n$actualSource\n\nIs not correct" + assert(cc.json.contains(s""""constructors":[[{"list":[{"title":"main""""), incorrectJson) + assert(cls.json.contains(s""""constructors":[[{"list":[{"title":"main""""), incorrectJson) + assert(trt.json.contains(s""""traitParams":[{"list":[{"title":"main""""), incorrectJson) + } + } + } +} diff --git a/dottydoc/test/PackageStructure.scala b/dottydoc/test/PackageStructure.scala index af6e52184e8b..00caaa2c0e0f 100644 --- a/dottydoc/test/PackageStructure.scala +++ b/dottydoc/test/PackageStructure.scala @@ -10,7 +10,7 @@ import model.internal._ class PackageStructure extends DottyTest { @Test def multipleCompilationUnits = { val source1 = new SourceFile( - "", + "TraitA.scala", """ |package scala | @@ -19,7 +19,7 @@ class PackageStructure extends DottyTest { ) val source2 = new SourceFile( - "", + "TraitB.scala", """ |package scala | @@ -27,8 +27,8 @@ class PackageStructure extends DottyTest { """.stripMargin ) - checkSources(source1 :: source2 :: Nil) { doc => - doc.packages("scala") match { + checkSources(source1 :: source2 :: Nil) { packages => + packages("scala") match { case PackageImpl(_, List(tA, tB), _, _) => assert( tA.name == "A" && tB.name == "B", @@ -42,7 +42,7 @@ class PackageStructure extends DottyTest { @Test def multiplePackages = { val source1 = new SourceFile( - "", + "TraitA.scala", """ |package scala |package collection @@ -51,7 +51,7 @@ class PackageStructure extends DottyTest { """.stripMargin) val source2 = new SourceFile( - "", + "TraitB.scala", """ |package scala |package collection @@ -59,8 +59,8 @@ class PackageStructure extends DottyTest { |trait B """.stripMargin) - checkSources(source1 :: source2 :: Nil) { doc => - doc.packages("scala") match { + checkSources(source1 :: source2 :: Nil) { packages => + packages("scala") match { case PackageImpl( "scala", List(PackageImpl("scala.collection", List(tA, tB), _, _)), @@ -72,10 +72,10 @@ class PackageStructure extends DottyTest { ) case _ => - fail(s"""Incorrect package structure for 'scala' package: ${doc.packages("scala")}""") + fail(s"""Incorrect package structure for 'scala' package: ${packages("scala")}""") } - doc.packages("scala.collection") match { + packages("scala.collection") match { case PackageImpl("scala.collection", List(tA, tB), _, _) => assert( tA.name == "A" && tB.name == "B", diff --git a/dottydoc/test/SimpleComments.scala b/dottydoc/test/SimpleComments.scala index ad9b7b1a6962..959eb1745b3f 100644 --- a/dottydoc/test/SimpleComments.scala +++ b/dottydoc/test/SimpleComments.scala @@ -15,9 +15,9 @@ class TestSimpleComments extends DottyTest { |trait HelloWorld """.stripMargin - checkSource(source) { doc => - val traitCmt = doc - .packages("scala") + checkSource(source) { packages => + val traitCmt = + packages("scala") .children.find(_.path.mkString(".") == "scala.HelloWorld") .flatMap(_.comment.map(_.body)) .get diff --git a/dottydoc/test/WhitelistedStdLib.scala b/dottydoc/test/WhitelistedStdLib.scala index 0225ba218cec..48697ea7f17b 100644 --- a/dottydoc/test/WhitelistedStdLib.scala +++ b/dottydoc/test/WhitelistedStdLib.scala @@ -19,9 +19,9 @@ class TestWhitelistedCollections extends DottyTest { } @Test def arrayHasDocumentation = - checkFiles(files) { doc => - val array = doc - .packages("scala") + checkFiles(files) { packages => + val array = + packages("scala") .children.find(_.path.mkString(".") == "scala.Array") .get @@ -29,9 +29,9 @@ class TestWhitelistedCollections extends DottyTest { } @Test def traitImmutableHasDocumentation = - checkFiles(files) { doc => - val imm = doc - .packages("scala") + checkFiles(files) { packages => + val imm = + packages("scala") .children.find(_.path.mkString(".") == "scala.Immutable") .get