more work on Q&A

pull/90/head
Thibault Duplessis 2014-07-05 16:50:04 +02:00
parent f82abcace7
commit 6ee267e01b
51 changed files with 1745 additions and 204 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "scalachess"]
path = modules/chess
url = git://github.com/ornicar/scalachess.git
[submodule "public/vendor/tagmanager"]
path = public/vendor/tagmanager
url = https://github.com/max-favilli/tagmanager

View File

@ -0,0 +1,70 @@
package controllers
import play.api.data.Form
import play.api.mvc._
import lila.api.Context
import lila.app._
import lila.qa.{ QuestionId, Question, AnswerId, Answer, QuestionWithUsers, QaAuth }
import views._
object QaAnswer extends QaController {
def create(id: QuestionId) = AuthBody { implicit ctx =>
me =>
WithQuestion(id) { q =>
implicit val req = ctx.body
forms.answer.bindFromRequest.fold(
err => renderQuestion(q, Some(err)),
data => api.answer.create(data, q, me) map { answer =>
Redirect(routes.QaQuestion.show(q.id, q.slug) + "#answer-" + answer.id)
}
)
}
}
def accept(questionId: QuestionId, answerId: AnswerId) = AuthBody { implicit ctx =>
me =>
(api.question findById questionId) zip (api.answer findById answerId) flatMap {
case (Some(q), Some(a)) if (QaAuth canEdit q) =>
api.answer.accept(q, a) inject Redirect(routes.QaQuestion.show(q.id, q.slug) + "#answer-" + a.id)
case _ => notFound
}
}
def vote(questionId: QuestionId, answerId: AnswerId) = AuthBody { implicit ctx =>
me =>
implicit val req = ctx.body
forms.vote.bindFromRequest.fold(
err => fuccess(BadRequest),
v => api.answer.vote(answerId, me, v == 1) map {
case Some(vote) => Ok(html.qa.vote(routes.QaAnswer.vote(questionId, answerId).url, vote))
case None => NotFound
}
)
}
def doEdit(questionId: QuestionId, answerId: AnswerId) = AuthBody { implicit ctx =>
me =>
WithOwnAnswer(questionId, answerId) { q =>
a =>
implicit val req = ctx.body
forms.answer.bindFromRequest.fold(
err => renderQuestion(q),
data => api.answer.edit(data, a.id) map {
case None => NotFound
case Some(a2) => Redirect(routes.QaQuestion.show(q.id, q.slug) + "#answer-" + a2.id)
}
)
}
}
def remove(questionId: QuestionId, answerId: AnswerId) = Secure(_.ModerateQa) { implicit ctx =>
me =>
OptionFuRedirect(api.answer findById answerId) { a =>
(api.answer remove a.id) >>
Env.mod.logApi.deleteQaAnswer(me.id, a.userId, a.body) inject
routes.QaQuestion.show(questionId, "redirect")
}
}
}

View File

@ -0,0 +1,46 @@
package controllers
import play.api.data.Form
import play.api.mvc._
import lila.api.Context
import lila.app._
import lila.qa.{ QuestionId, Question, AnswerId, Answer, QuestionWithUsers, QaAuth }
import views._
object QaComment extends QaController {
def question(id: QuestionId) = AuthBody { implicit ctx =>
me =>
WithQuestion(id) { q =>
implicit val req = ctx.body
forms.comment.bindFromRequest.fold(
err => renderQuestion(q, None),
data => api.comment.create(data, Left(q), me) map { comment =>
Redirect(routes.QaQuestion.show(q.id, q.slug) + "#comment-" + comment.id)
}
)
}
}
def answer(questionId: QuestionId, answerId: AnswerId) = AuthBody { implicit ctx =>
me =>
(api.question findById questionId) zip (api.answer findById answerId) flatMap {
case (Some(q), Some(a)) =>
implicit val req = ctx.body
forms.comment.bindFromRequest.fold(
err => renderQuestion(q, None),
data => api.comment.create(data, Right(a), me) map { comment =>
Redirect(routes.QaQuestion.show(q.id, q.slug) + "#comment-" + comment.id)
}
)
case _ => notFound
}
}
def remove(questionId: QuestionId, commentId: String) = Secure(_.ModerateQa) { implicit ctx =>
me =>
api.comment.remove(questionId, commentId) inject
Redirect(routes.QaQuestion.show(questionId, "redirect"))
}
}

View File

@ -25,14 +25,22 @@ trait QaController extends LilaController {
case _ => notFound
}
protected def WithQuestion(id: QuestionId)(block: Question => Fu[Result])(implicit ctx: Context): Fu[Result] =
OptionFuResult(api.question findById id)(block)
protected def WithQuestion(id: QuestionId, slug: String)(block: Question => Fu[Result])(implicit ctx: Context): Fu[Result] =
OptionFuResult(api.question findById id) { q =>
WithQuestion(id) { q =>
if (slug != q.slug) fuccess(Redirect {
controllers.routes.QaQuestion.show(id, q.slug)
})
else block(q)
}
protected def WithOwnQuestion(id: QuestionId)(block: Question => Fu[Result])(implicit ctx: Context): Fu[Result] =
WithQuestion(id) { q =>
if (QaAuth canEdit q) block(q)
else fuccess(Unauthorized)
}
protected def WithOwnQuestion(id: QuestionId, slug: String)(block: Question => Fu[Result])(implicit ctx: Context): Fu[Result] =
WithQuestion(id, slug) { q =>
if (QaAuth canEdit q) block(q)

View File

@ -13,7 +13,7 @@ object QaQuestion extends QaController {
def index(page: Option[Int] = None) = Open { implicit ctx =>
api.question.paginatorWithUsers(page getOrElse 1, 20) zip
(api.question popular 10) map {
case (questions, popular) => Ok(views.html.qa.index(questions, popular))
case (questions, popular) => Ok(html.qa.index(questions, popular))
}
}
@ -23,14 +23,14 @@ object QaQuestion extends QaController {
case "" => (api.question recent 20 flatMap api.question.zipWithUsers)
case _ => Env.qa search query flatMap api.question.zipWithUsers
}) zip (api.question popular 10) map {
case (questions, popular) => Ok(views.html.qa.search(query, questions, popular))
case (questions, popular) => Ok(html.qa.search(query, questions, popular))
}
}
def byTag(tag: String) = Open { implicit ctx =>
(api.question.byTag(tag, 20) flatMap api.question.zipWithUsers) zip
(api.question popular 10) map {
case (questions, popular) => Ok(views.html.qa.byTag(tag, questions, popular))
case (questions, popular) => Ok(html.qa.byTag(tag, questions, popular))
}
}
@ -42,7 +42,7 @@ object QaQuestion extends QaController {
private def renderAsk(form: Form[_], status: Results.Status)(implicit ctx: Context) =
api.question popular 10 zip api.tag.all map {
case (popular, tags) => status(views.html.qa.ask(form, tags, popular))
case (popular, tags) => status(html.qa.ask(form, tags, popular))
}
def ask = Auth { implicit ctx =>
@ -60,4 +60,51 @@ object QaQuestion extends QaController {
}
)
}
def edit(id: QuestionId, slug: String) = Auth { implicit ctx =>
me =>
WithOwnQuestion(id, slug) { q =>
renderEdit(forms editQuestion q, q, Results.Ok)
}
}
def doEdit(id: QuestionId) = AuthBody { implicit ctx =>
me =>
WithOwnQuestion(id) { q =>
implicit val req = ctx.body
forms.question.bindFromRequest.fold(
err => renderEdit(err, q, Results.BadRequest),
data => api.question.edit(data, q.id) map {
case None => NotFound
case Some(q2) => Redirect(routes.QaQuestion.show(q2.id, q2.slug))
}
)
}
}
private def renderEdit(form: Form[_], q: Question, status: Results.Status)(implicit ctx: Context) =
api.question popular 10 zip api.tag.all map {
case (popular, tags) => status(html.qa.edit(form, q, tags, popular))
}
def vote(id: QuestionId) = AuthBody { implicit ctx =>
me =>
implicit val req = ctx.body
forms.vote.bindFromRequest.fold(
err => fuccess(BadRequest),
v => api.question.vote(id, me, v == 1) map {
case Some(vote) => Ok(html.qa.vote(routes.QaQuestion.vote(id).url, vote))
case None => NotFound
}
)
}
def remove(questionId: QuestionId) = Secure(_.ModerateQa) { implicit ctx =>
me =>
WithQuestion(questionId) { q =>
(api.question remove q.id) >>
Env.mod.logApi.deleteQaQuestion(me.id, q.userId, q.title) inject
Redirect(routes.QaQuestion.index())
}
}
}

View File

@ -18,7 +18,6 @@ trait AssetHelper {
def cssTag(name: String, staticDomain: Boolean = true) = cssAt("stylesheets/" + name, staticDomain)
def cssVendorTag(name: String, staticDomain: Boolean = true) = cssAt("vendor/" + name, staticDomain)
def cssAt(path: String, staticDomain: Boolean = true) = Html {
@ -60,6 +59,16 @@ trait AssetHelper {
test = "window._",
local = staticUrl("vendor/underscorejs.min.js"))
val tagmanagerTag = cdnOrLocal(
cdn = "http://cdnjs.cloudflare.com/ajax/libs/tagmanager/3.0.0/tagmanager.js",
test = "$.tagsManager",
local = staticUrl("vendor/tagmanager/tagmanager.js"))
val typeaheadTag = cdnOrLocal(
cdn = "http://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.2/typeahead.bundle.min.js",
test = "$.typeahead",
local = staticUrl("vendor/typeahead.bundle.min.js"))
private def cdnOrLocal(cdn: String, test: String, local: String) = Html {
if (isProd)
s"""<script src="$cdn"></script><script>$test || document.write('<script src="$local">\\x3C/script>')</script>"""

View File

@ -1,19 +1,10 @@
@(title: String, searchText: String = "", goodies: Option[Html] = None, moreJs: Html = Html(""))(body: Html)(implicit ctx: Context)
@moreCss = {
@cssTag("forum.css")
}
@forumJs = {
@moreJs
@jsTag("forum.js")
}
@base.layout(
title = title,
goodies = goodies,
moreCss = moreCss,
moreJs = forumJs,
moreCss = cssTag("forum.css"),
moreJs = moreJs,
active = siteMenu.forum.some) {
<div id="lichess_forum" class="content_box no_padding">
@forum.searchForm(searchText.trim)

View File

@ -29,10 +29,10 @@ title = topic.name) {
@momentFromNow(post.createdAt)
<a class="anchor" href="@routes.ForumTopic.show(categ.slug, topic.slug, posts.currentPage)#@post.number">#@post.number</a>
@if(isGranted(_.IpBan)) {
<span class="postip">@post.ip</span>
<span class="mod postip">@post.ip</span>
}
@if(isGrantedMod(categ.slug)) {
<a class="delete" href="@routes.ForumPost.delete(categ.slug, post.id)">Delete</a>
<a class="mod thin delete button" href="@routes.ForumPost.delete(categ.slug, post.id)" data-icon="q"> Delete</a>
}
</div>
<p class="message">@autoLink(post.text)</p>

View File

@ -0,0 +1,59 @@
@(q: lila.qa.Question, as: List[lila.qa.AnswerWithUserAndComments])(implicit ctx: Context)
<div class="answers-header">
@as.size match {
case 0 => {
Be the first to answer!
}
case 1 => {
One answer
}
case n => {
@n Answers
}
}
</div>
<div class="answers">
@as.map { a =>
<div class="answer-wrap" id="answer-@a.answer.id">
<div class="votecol">
@views.html.qa.vote(routes.QaAnswer.vote(q.id, a.answer.id).url, a.answer.vote)
@if(a.answer.accepted) {
<span title="The question owner accepted this as the best answer" class="count accept accepted">&#10004;</span>
} else {
@if(lila.qa.QaAuth canEdit q) {
<form class="accept-form" action="@routes.QaAnswer.accept(q.id, a.answer.id)" method="POST">
<button type="submit"
title="Accept this as the best answer"
class="count accept @if(a.answer.accepted) {accepted}" data-icon="E"></button>
</form>
}
}
</div>
<div class="postcol">
<div class="body">
<div class="answer">
@autoLink(a.answer.body)
@if(lila.qa.QaAuth canEdit a.answer) {
<form class="edit-answer" action="@routes.QaAnswer.doEdit(q.id, a.answer.id)" method="post">
<textarea class="answer-body" name="body">@a.answer.body</textarea>
<button class="pure button" type="submit">Update answer</button>
</form>
}
<div class="metadata">
Answered @momentFromNow(a.answer.createdAt)
by @userLink(a.user)
@if(lila.qa.QaAuth canEdit a.answer) {
<a title="Edit answer" class="icon toggle-edit-answer" data-icon="m"> Edit the answer</a>
}
@nope("Remove the answer", routes.QaAnswer.remove(q.id, a.answer.id))
</div>
</div>
<div class="comments" id="answer-@a.answer.id-comments">
@views.html.qa.commentList(q, a.comments, routes.QaComment.answer(q.id, a.answer.id).url)
</div>
</div>
</div>
</div>
}
</div>

View File

@ -3,13 +3,16 @@
@title = @{ "Q&A - Ask a new question" }
@layout(
title = title,
title = "Ask a new question" ,
goodies = popularBox(popular).some) {
<h1>@title</h1>
<h1>
<a href="@routes.QaQuestion.index()" data-icon="&"></a>
Ask a new question
</h1>
<form action="@routes.QaQuestion.ask()" method="post">
<form class="wide question" action="@routes.QaQuestion.ask()" method="post">
@questionForm(form, tags)
<button type="submit" class="pure button">Post your question</button>
<button type="submit" class="pure submit button">Post your question</button>
</form>
}

View File

@ -0,0 +1,20 @@
@(q: lila.qa.Question, comments: List[lila.qa.CommentWithUser], action: String)(implicit ctx: Context)
@comments.map { c =>
<div class="comment" id="comment-@c.comment.id">
<div class="metadata">
@userLink(c.user) commented @momentFromNow(c.comment.createdAt):
@nope("Remove", routes.QaComment.remove(q.id, c.comment.id))
</div>
@autoLink(c.comment.body)
</div>
}
@ctx.me.map { user =>
<div class="your-comment @if(comments.isEmpty) {no-comment}">
<a class="thin toggle">Add comment</a>
<form action="@action" method="post">
<textarea name="body"></textarea>
<button class="pure button" type="submit">Post your comment</button>
</form>
</div>
}

View File

@ -0,0 +1,15 @@
@(form: Form[_], q: lila.qa.Question, tags: List[String], popular: List[lila.qa.Question])(implicit ctx: Context)
@title = @{ s"""Edit question "${q.title}"""" }
@layout(
title = title,
goodies = popularBox(popular).some) {
<h1>@title</h1>
<form class="wide question" action="@routes.QaQuestion.doEdit(q.id)" method="post">
@questionForm(form, tags)
<button type="submit" class="pure submit button">Update your question</button>
</form>
}

View File

@ -5,7 +5,7 @@
}
@layout(
title = "Questions & answers",
title = "Questions & Answers",
goodies = goodies.some) {
<h1 data-icon="&" class="is4"> Questions &amp; Answers</h1>

View File

@ -6,12 +6,19 @@
@goodies
}
@moreJs = {
@tagmanagerTag
@typeaheadTag
@jsTag("qa.js")
}
@base.layout(
title = title,
title = s"Q&A - $title",
moreCss = cssTag("qa.css"),
moreJs = moreJs,
goodies = side.some,
openGraph = openGraph) {
<div id="lichess_qa" class="content_box">
<div id="qa" class="content_box">
@body
</div>
}

View File

@ -0,0 +1,6 @@
@(title: String, url: Call)(implicit ctx: Context)
@if(isGranted(_.ModerateQa)) {
<form class="mod" action="@url" method="post">
<button type="submit" title="@title" class="thin confirm button" data-icon="q"> @title</button>
</form>
}

View File

@ -1,15 +1,16 @@
@(form: Form[_], tags: List[String])(implicit ctx: Context)
<input class="title" name="@form("title").name" value="@form("title").value" placeholder="What's your question? Be specific." />
<input hint="What's your question?" class="title" name="@form("title").name" value="@form("title").value" placeholder="What's your question? Be specific." />
@errMsg(form("title"))
<textarea name="@form("body").name">@form("body").value</textarea>
@errMsg(form("body"))
<div class="tags-wrap">
<div class="tags_wrap">
<input
type="text"
name="tags"
data-tags="@tags.mkString(",")"
data-prefill="@form("hidden-tags").value"
placeholder="Add a tag"
placeholder="Add a tag and press Enter"
class="tags tm-input"/>
<div class="tags"></div>
</div>

View File

@ -1 +1,63 @@
@(q: lila.qa.Question, user: User, answers: List[lila.qa.AnswerWithUserAndComments], comments: List[lila.qa.CommentWithUser], popular: List[lila.qa.Question], related: List[lila.qa.Question], answerForm: Option[Form[_]])(implicit ctx: Context)
@goodies = {
@relatedBox(related)
@popularBox(popular)
}
@layout(
title = q.title,
goodies = goodies.some) {
<div class="question">
<h1>
<a href="@routes.QaQuestion.index()" data-icon="&"></a>@q.title
</h1>
<table class="meta">
<tbody>
<tr>
<th>Asked</th>
<td>@momentFromNow(q.createdAt) by @userLink(user)</td>
</tr>
@if(q.tags.nonEmpty) {
<tr>
<th>Tags</th>
<td>@tags(q.tags)</td>
</tr>
}
<tr>
<th>Activity</th>
<td>Viewed @q.views times, last updated @momentFromNow(q.updatedAt)</td>
</tr>
<tr>
<th>Actions</th>
<td>
@if(lila.qa.QaAuth canEdit q) {
<a class="thin button" data-icon="m" href="@routes.QaQuestion.edit(q.id, q.slug)"> Edit question</a>
}
@nope("Remove question", routes.QaQuestion.remove(q.id))
</td>
</tr>
</tbody>
</table>
<div class="body">
@autoLink(q.body)
</div>
<div class="comments" id="question-@q.id-comments">
@views.html.qa.commentList(q, comments, routes.QaComment.question(q.id).url)
</div>
@answerList(q, answers)
@answerForm.map { form =>
<div class="your-answer">
@if(answers.nonEmpty) {
<p class="title answers-header">Your answer</p>
}
<form class="wide" action="@routes.QaAnswer.create(q.id).url#your-answer" method="post">
<textarea class="answer-body" name="@form("body").name">@form("body").value</textarea>
@errMsg(form("body"))
<button class="pure submit button" type="submit">Post your answer</button>
</form>
</div>
</div>
}
}

View File

@ -0,0 +1,13 @@
@(qs: List[lila.qa.Question])(implicit ctx: Context)
<div class="related box">
<p class="title">Related questions</p>
<div class="questions">
@qs.map { q =>
<a href="@routes.QaQuestion.show(q.id, q.slug)">
<span class="number">@q.vote.score</span>
<span class="name">@q.title</span>
</a>
}
</div>
</div>

View File

@ -1,13 +1,8 @@
@(tags: Seq[String])
<div class="tags">
@defining(tags.size - 1) { last =>
@tags.zipWithIndex.map {
case (tag, i) => {
<a href="@routes.QaQuestion.byTag(tag)">@tag</a>@if(i != last) {,}
}
}
}
@if(tags.isEmpty) {
&nbsp;
}
</div>
@defining(tags.size - 1) { last =>
@tags.zipWithIndex.map {
case (tag, i) => {
<a href="@routes.QaQuestion.byTag(tag)" class="tag" data-icon="o">@tag</a>@if(i != last) {,}
}
}
}

View File

@ -0,0 +1,17 @@
@(url: String, vote: lila.qa.Vote)(implicit ctx: Context)
@defining(ctx.userId.flatMap(vote.of)) { myVote =>
<div class="upvote @if(ctx.isAuth) {enabled}" data-post-url="url">
<a
title="This question shows research effort; it is useful and clear"
data-vote="1"
data-icon="S"
class="upvote @if(myVote == Some(true)) {active}"></a>
<span data-hint="Popularity" class="count hint--bottom">@vote.score</span>
<a
title="This question does not show any research effort; it is unclear or not useful"
data-vote="0"
data-icon="R"
class="downvote @if(myVote == Some(true)) {active}"></a>
</div>
}

View File

@ -22,6 +22,15 @@ case NoteCreate(fromId, toId) => {
case TourJoin(userId, tourId, tourName) => {
@userIdLink(userId.some, withOnline = false) competes in <a href="@routes.Tournament.show(tourId)">@trans.xTournament(tourName)</a>
}
case QaQuestion(userId, id, title) => {
@userIdLink(userId.some, withOnline = false) asked <a href="@routes.QaQuestion.show(id, "redirect")">@title</a>
}
case QaAnswer(userId, id, title, answerId) => {
@userIdLink(userId.some, withOnline = false) answered <a href="@routes.QaQuestion.show(id, "redirect")#answer-@answerId">@title</a>
}
case QaComment(userId, id, title, commentId) => {
@userIdLink(userId.some, withOnline = false) commented <a href="@routes.QaQuestion.show(id, "redirect")#comment-@commentId">@title</a>
}
}
@momentFromNow(e.date)
}

View File

@ -260,19 +260,18 @@ GET /qa/ask controllers.QaQuestion.ask
POST /qa/ask controllers.QaQuestion.doAsk
GET /qa/tag/:slug controllers.QaQuestion.byTag(slug: String)
GET /qa/:id/:slug controllers.QaQuestion.show(id: Int, slug: String)
# GET /qa/:id/:slug/edit controllers.QaQuestion.edit(id: Int, slug: String)
# POST /qa/:id/:slug/edit controllers.QaQuestion.doEdit(id: Int, slug: String)
# POST /qa/:id/vote controllers.QaQuestion.vote(id: Int)
# POST /qa/:id/favorite controllers.QaQuestion.favorite(id: Int)
# POST /qa/:id/rm controllers.QaQuestion.remove(id: Int)
# POST /qa/:id/answer controllers.QaAnswer.create(id: Int)
# POST /qa/:id/:a/vote controllers.QaAnswer.vote(id: Int, a: Int)
# POST /qa/:id/:a/accept controllers.QaAnswer.accept(id: Int, a: Int)
# POST /qa/:id/:a/edit-answer controllers.QaAnswer.doEdit(id: Int, a: Int)
# POST /qa/:id/:a/rm-answer controllers.QaAnswer.remove(id: Int, a: Int)
# POST /qa/:id/comment controllers.QaComment.question(id: Int)
# POST /qa/:id/:a/comment controllers.QaComment.answer(id: Int, a: Int)
# POST /qa/:id/:c/rm-comment controllers.QaComment.remove(id: Int, c: String)
GET /qa/:id/:slug/edit controllers.QaQuestion.edit(id: Int, slug: String)
POST /qa/:id/edit controllers.QaQuestion.doEdit(id: Int)
POST /qa/:id/vote controllers.QaQuestion.vote(id: Int)
POST /qa/:id/rm controllers.QaQuestion.remove(id: Int)
POST /qa/:id/answer controllers.QaAnswer.create(id: Int)
POST /qa/:id/:a/vote controllers.QaAnswer.vote(id: Int, a: Int)
POST /qa/:id/:a/accept controllers.QaAnswer.accept(id: Int, a: Int)
POST /qa/:id/:a/edit-answer controllers.QaAnswer.doEdit(id: Int, a: Int)
POST /qa/:id/:a/rm-answer controllers.QaAnswer.remove(id: Int, a: Int)
POST /qa/:id/comment controllers.QaComment.question(id: Int)
POST /qa/:id/:a/comment controllers.QaComment.answer(id: Int, a: Int)
POST /qa/:id/:c/rm-comment controllers.QaComment.remove(id: Int, c: String)
# API
GET /api/user controllers.Api.users

View File

@ -20,7 +20,7 @@ private[blog] final class Notifier(
(ThreadRepo reallyDeleteByCreatorId lichessUserId) >> {
val thread = makeThread(post)
val futures = userIds.toStream map { userId =>
messageApi.lichessThread(thread.copy(to = userId), lichessUserId)
messageApi.lichessThread(thread.copy(to = userId))
}
lila.common.Future.lazyFold(futures)(())((_, _) => ()) >>- lastPostCache.clear
}
@ -33,6 +33,7 @@ private[blog] final class Notifier(
private def makeThread(doc: io.prismic.Document) =
lila.hub.actorApi.message.LichessThread(
from = lichessUserId,
to = "",
subject = s"New blog post: ${~doc.getText("blog.title")}",
message = s"""${~doc.getText("blog.shortlede")}

View File

@ -76,6 +76,9 @@ case class TeamCreate(userId: String, teamId: String) extends Atom
case class ForumPost(userId: String, topicName: String, postId: String) extends Atom
case class NoteCreate(from: String, to: String) extends Atom
case class TourJoin(userId: String, tourId: String, tourName: String) extends Atom
case class QaQuestion(userId: String, id: Int, title: String) extends Atom
case class QaAnswer(userId: String, id: Int, title: String, answerId: Int) extends Atom
case class QaComment(userId: String, id: Int, title: String, commentId: String) extends Atom
object atomFormat {
implicit val followFormat = Json.format[Follow]
@ -84,6 +87,9 @@ object atomFormat {
implicit val forumPostFormat = Json.format[ForumPost]
implicit val noteCreateFormat = Json.format[NoteCreate]
implicit val tourJoinFormat = Json.format[TourJoin]
implicit val qaQuestionFormat = Json.format[QaQuestion]
implicit val qaAnswerFormat = Json.format[QaAnswer]
implicit val qaCommentFormat = Json.format[QaComment]
}
object propagation {
@ -99,6 +105,7 @@ import propagation._
case class Propagate(data: Atom, propagations: List[Propagation] = Nil) {
def toUsers(ids: List[String]) = add(Users(ids))
def toUser(id: String) = add(Users(List(id)))
def toFollowersOf(id: String) = add(Followers(id))
def toFriendsOf(id: String) = add(Friends(id))
def toStaffFriendsOf(id: String) = add(StaffFriends(id))
@ -113,7 +120,7 @@ case object Count
}
package message {
case class LichessThread(to: String, subject: String, message: String)
case class LichessThread(from: String, to: String, subject: String, message: String)
}
package router {

View File

@ -55,11 +55,11 @@ final class Api(
}
}
def lichessThread(lt: LichessThread, creatorId: String = "lichess"): Funit =
def lichessThread(lt: LichessThread): Funit =
$insert(Thread.make(
name = lt.subject,
text = lt.message,
creatorId = creatorId,
creatorId = lt.from,
invitedId = lt.to)) >> unreadCache.clear(lt.to)
def makePost(thread: Thread, text: String, me: User) = {

View File

@ -11,21 +11,24 @@ case class Modlog(
date: DateTime = DateTime.now) {
def showAction = action match {
case Modlog.engine => "mark as engine"
case Modlog.unengine => "un-mark as engine"
case Modlog.deletePost => "delete forum post"
case Modlog.ban => "ban user"
case Modlog.ipban => "ban IPs"
case Modlog.ipunban => "unban IPs"
case Modlog.closeAccount => "close account"
case Modlog.reopenAccount => "reopen account"
case Modlog.openTopic => "reopen topic"
case Modlog.closeTopic => "close topic"
case Modlog.showTopic => "show topic"
case Modlog.hideTopic => "hide topic"
case Modlog.setTitle => "set FIDE title"
case Modlog.removeTitle => "remove FIDE title"
case a => a
case Modlog.engine => "mark as engine"
case Modlog.unengine => "un-mark as engine"
case Modlog.deletePost => "delete forum post"
case Modlog.ban => "ban user"
case Modlog.ipban => "ban IPs"
case Modlog.ipunban => "unban IPs"
case Modlog.closeAccount => "close account"
case Modlog.reopenAccount => "reopen account"
case Modlog.openTopic => "reopen topic"
case Modlog.closeTopic => "close topic"
case Modlog.showTopic => "show topic"
case Modlog.hideTopic => "hide topic"
case Modlog.setTitle => "set FIDE title"
case Modlog.removeTitle => "remove FIDE title"
case Modlog.deleteQaQuestion => "delete Q&A question"
case Modlog.deleteQaAnswer => "delete Q&A answer"
case Modlog.deleteQaComment => "delete Q&A comment"
case a => a
}
override def toString = s"$mod $showAction ${~user}"
@ -49,6 +52,9 @@ object Modlog {
val hideTopic = "hideTopic"
val setTitle = "setTitle"
val removeTitle = "removeTitle"
val deleteQaQuestion = "deleteQaQuestion"
val deleteQaAnswer = "deleteQaAnswer"
val deleteQaComment = "deleteQaComment"
import lila.db.JsTube
import JsTube.Helpers._

View File

@ -53,6 +53,18 @@ final class ModlogApi {
))
}
def deleteQaQuestion(mod: String, user: String, title: String) = add {
Modlog(mod, user.some, Modlog.deleteQaQuestion, details = Some(title take 140))
}
def deleteQaAnswer(mod: String, user: String, text: String) = add {
Modlog(mod, user.some, Modlog.deleteQaAnswer, details = Some(text take 140))
}
def deleteQaComment(mod: String, user: String, text: String) = add {
Modlog(mod, user.some, Modlog.deleteQaComment, details = Some(text take 140))
}
def recent = $find($query($select.all) sort $sort.naturalDesc, 100)
private def add(m: Modlog): Funit = {

View File

@ -42,8 +42,4 @@ object DataForms {
val vote = Form(single(
"vote" -> number
))
val favorite = Form(single(
"favorite" -> number
))
}

View File

@ -5,18 +5,24 @@ import lila.common.PimpedConfig._
final class Env(
config: Config,
hub: lila.hub.Env,
db: lila.db.Env) {
private val CollectionQuestion = config getString "collection.question"
private val CollectionAnswer = config getString "collection.answer"
private val NotifyUserId = config getString "notify.user_id"
private val NotifierSender = config getString "notifier.sender"
private lazy val questionColl = db(CollectionQuestion)
lazy val api = new QaApi(
questionColl = questionColl,
answerColl = db(CollectionAnswer),
mailer = new Mailer(NotifyUserId))
notifier = notifier)
private lazy val notifier = new Notifier(
sender = NotifierSender,
messenger = hub.actor.messenger,
timeline = hub.actor.timeline)
lazy val search = new Search(questionColl)
@ -27,5 +33,6 @@ object Env {
lazy val current = "[boot] qa" describes new Env(
config = lila.common.PlayApp loadConfig "qa",
hub = lila.hub.Env.current,
db = lila.db.Env.current)
}

View File

@ -1,68 +0,0 @@
package lila.qa
import lila.common.String._
import lila.user.User
private[qa] final class Mailer(sender: String) {
private[qa] def createAnswer(q: Question, a: Answer, u: User, favoriters: List[User]): Funit = ???
// send(
// to = (rudyEmail :: user.email :: favoriters.map(_.email)) filterNot (u.email.==),
// subject = s"""${u.displaynameOrFullname} answered your question""",
// content = s"""New answer on prismic.io Q&A: ${questionUrl(q)}#answer-${a.id}
// By ${u.displaynameOrFullname}
// On question <b>${q.title}</b>
// ${a.body}
// URL: ${questionUrl(q)}#answer-${a.id}""")
private[qa] def createQuestionComment(q: Question, c: Comment, u: User): Funit = ???
// send(
// to = List(rudyEmail, questionAuthor.email) filterNot (u.email.==),
// subject = s"""${u.displaynameOrFullname} commented your question""",
// content = s"""New comment on prismic.io Q&A: ${questionUrl(question)}#comment-${c.id}
// By ${u.displaynameOrFullname}
// On question <b>${question.title}</b>
// ${c.body}
// URL: ${questionUrl(question)}#comment-${c.id}""")
// case _ => Future successful ()
private[qa] def createAnswerComment(q: Question, a: Answer, c: Comment, u: User): Funit =
???
// QaApi.answer.withUser(a) flatMap {
// case Some(AnswerWithUser(answer, answerAuthor)) => send(
// to = List(rudyEmail, answerAuthor.email) filterNot (u.email.==),
// subject = s"""${u.displaynameOrFullname} commented your answer""",
// content = s"""New comment on prismic.io Q&A: ${questionUrl(q)}#comment-${c.id}
// By ${u.displaynameOrFullname}
// On question <b>${q.title}</b>
// ${c.body}
// URL: ${questionUrl(q)}#comment-${c.id}""")
private def questionUrl(q: Question) =
s"http://lichess.org/qa/${q.id}/${q.slug}"
private def send(to: List[String], subject: String, content: String) = {
to foreach { recipient =>
// common.utils.Mailer.send(
// to = recipient,
// from = Some(sender),
// fromname = Some(common.Wroom.domain),
// subject = s"[Q&A] $subject",
// content = Html(nl2br(content)))
}
fuccess(())
}
}

View File

@ -0,0 +1,44 @@
package lila.qa
import lila.common.String._
import lila.hub.actorApi.message.LichessThread
import lila.hub.actorApi.timeline.{ Propagate, QaQuestion, QaAnswer, QaComment }
import lila.user.User
import akka.actor.ActorSelection
private[qa] final class Notifier(
sender: String,
messenger: ActorSelection,
timeline: ActorSelection) {
private[qa] def createQuestion(q: Question, u: User) {
val msg = Propagate(QaQuestion(u.id, q.id, q.title))
timeline ! (msg toFollowersOf u.id)
}
private[qa] def createAnswer(q: Question, a: Answer, u: User) {
val msg = Propagate(QaAnswer(u.id, q.id, q.title, a.id))
timeline ! (msg toFollowersOf u.id toUser q.userId exceptUser u.id)
messenger ! LichessThread(
from = sender,
to = q.userId,
subject = s"""${u.username} replied to your question""",
message = s"""Your question "${q.title}" got a new answer from ${u.username}!
Check it out on ${questionUrl(q)}#answer-${a.id}""")
}
private[qa] def createQuestionComment(q: Question, c: Comment, u: User) {
val msg = Propagate(QaComment(u.id, q.id, q.title, c.id))
timeline ! (msg toFollowersOf u.id toUser q.userId exceptUser u.id)
}
private[qa] def createAnswerComment(q: Question, a: Answer, c: Comment, u: User) {
val msg = Propagate(QaComment(u.id, q.id, q.title, c.id))
timeline ! (msg toFollowersOf u.id toUser a.userId exceptUser u.id)
}
private def questionUrl(q: Question) =
s"http://lichess.org/qa/${q.id}/${q.slug}"
}

View File

@ -14,7 +14,7 @@ import lila.db.paginator._
import lila.db.Types.Coll
import lila.user.{ User, UserRepo }
final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
final class QaApi(questionColl: Coll, answerColl: Coll, notifier: Notifier) {
object question {
@ -31,7 +31,6 @@ final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
body = data.body,
tags = data.tags,
vote = Vote(Set.empty, Set.empty, 0),
favoriters = Set.empty,
comments = Nil,
views = 0,
answers = 0,
@ -42,7 +41,8 @@ final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
(questionColl insert q) >>
tag.clearCache >>
relation.clearCache inject q
relation.clearCache >>-
notifier.createQuestion(q, user) inject q
}
def edit(data: DataForms.QuestionData, id: QuestionId): Fu[Option[Question]] = findById(id) flatMap {
@ -89,13 +89,6 @@ final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
.sort(BSONDocument("createdAt" -> -1))
.cursor[Question].collect[List](max)
def favoriteByUser(u: User, max: Int): Fu[List[Question]] =
questionColl.find(BSONDocument("favoriters" -> u.id))
.sort(BSONDocument("createdAt" -> -1))
.cursor[Question].collect[List](max)
def favoriters(q: Question): Fu[List[User]] = UserRepo byIds q.favoriters.toList
def popular(max: Int): Fu[List[Question]] =
questionColl.find(BSONDocument())
.sort(BSONDocument("vote.score" -> -1))
@ -147,17 +140,6 @@ final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
case None => fuccess(none)
}
def favorite(id: QuestionId, user: User, v: Boolean): Fu[Option[Question]] =
question findById id flatMap {
case Some(q) =>
val newFavs = q.setFavorite(user.id, v)
questionColl.update(
BSONDocument("_id" -> q.id),
BSONDocument("$set" -> BSONDocument("favoriters" -> newFavs.favoriters, "updatedAt" -> DateTime.now))
) >> profile.clearCache inject Some(newFavs)
case None => fuccess(none)
}
def incViews(q: Question) = questionColl.update(
BSONDocument("_id" -> q.id),
BSONDocument("$inc" -> BSONDocument("views" -> BSONInteger(1))))
@ -208,11 +190,8 @@ final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
editedAt = None)
(answerColl insert a) >>
(question recountAnswers q.id) >> {
question favoriters q flatMap {
mailer.createAnswer(q, a, user, _)
}
} inject a
(question recountAnswers q.id) >>-
notifier.createAnswer(q, a, user) inject a
}
def edit(data: DataForms.AnswerData, id: AnswerId): Fu[Option[Answer]] = findById(id) flatMap {
@ -315,12 +294,13 @@ final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
userId = user.id,
body = data.body,
createdAt = DateTime.now)
subject.fold(question addComment c, answer addComment c) >> {
subject.fold(question addComment c, answer addComment c) >>- {
subject match {
case Left(q) => funit
case Right(a) => question findById a.questionId flatMap {
case None => funit
case Some(q) => mailer.createAnswerComment(q, a, c, user)
case Left(q) => notifier.createQuestionComment(q, c, user)
case Right(a) => question findById a.questionId foreach {
_ foreach { q =>
notifier.createAnswerComment(q, a, c, user)
}
}
}
} inject c
@ -365,7 +345,7 @@ final class QaApi(questionColl: Coll, answerColl: Coll, mailer: Mailer) {
question.recentByUser(u, 300) zip answer.recentByUser(u, 500) map {
case (qs, as) => Profile(
reputation = math.max(0, qs.map { q =>
q.vote.score + q.favoriters.size
q.vote.score
}.sum + as.map { a =>
a.vote.score + (if (a.accepted && !qs.exists(_.userId == a.userId)) 5 else 0)
}.sum),

View File

@ -11,7 +11,6 @@ case class Question(
body: String, // markdown
tags: List[String],
vote: Vote,
favoriters: Set[String],
comments: List[Comment],
views: Int,
answers: Int,
@ -39,12 +38,6 @@ case class Question(
def editNow = copy(editedAt = Some(DateTime.now)).updateNow
def accepted = acceptedAt.isDefined
def favorite(user: User): Boolean = favoriters(user.id)
def setFavorite(userId: String, v: Boolean) = copy(
favoriters = if (v) favoriters + userId else favoriters - userId
)
}
case class QuestionWithUser(question: Question, user: User)

View File

@ -7,6 +7,9 @@ trait SecurityHelper {
def isGranted(permission: Permission)(implicit ctx: UserContext): Boolean =
ctx.me ?? Granter(permission)
def isGranted(permission: Permission.type => Permission)(implicit ctx: UserContext): Boolean =
isGranted(permission(Permission))
def isGranted(permission: Permission, user: User): Boolean =
Granter(permission)(user)
}

View File

@ -12,6 +12,7 @@ final class Env(config: Config, hub: lila.hub.Env, db: lila.db.Env) {
val CollectionRequest = config getString "collection.request"
val PaginatorMaxPerPage = config getInt "paginator.max_per_page"
val PaginatorMaxUserPerPage = config getInt "paginator.max_user_per_page"
val NotifierSender = config getString "notifier.sender"
}
import settings._
@ -37,6 +38,7 @@ final class Env(config: Config, hub: lila.hub.Env, db: lila.db.Env) {
private[team] lazy val memberColl = db(CollectionMember)
private lazy val notifier = new Notifier(
sender = NotifierSender,
messenger = hub.actor.messenger,
router = hub.actor.router)
}

View File

@ -7,6 +7,7 @@ import lila.hub.actorApi.message.LichessThread
import lila.hub.actorApi.router._
private[team] final class Notifier(
sender: String,
messenger: ActorSelection,
router: ActorSelection) {
@ -15,6 +16,7 @@ private[team] final class Notifier(
def acceptRequest(team: Team, request: Request) {
teamUrl(team.id) foreach { url =>
messenger ! LichessThread(
from = sender,
to = request.user,
subject = """You have joined the team %s""".format(team.name),
message = """Congratulation, your request to join the team was accepted!

View File

@ -24,6 +24,9 @@ case class Entry(
case "forum-post" => Json.fromJson[ForumPost](data)
case "note-create" => Json.fromJson[NoteCreate](data)
case "tour-join" => Json.fromJson[TourJoin](data)
case "qa-question" => Json.fromJson[QaQuestion](data)
case "qa-answer" => Json.fromJson[QaAnswer](data)
case "qa-comment" => Json.fromJson[QaComment](data)
}).asOpt
}
@ -36,6 +39,9 @@ object Entry {
case d: ForumPost => "forum-post" -> Json.toJson(d)
case d: NoteCreate => "note-create" -> Json.toJson(d)
case d: TourJoin => "tour-join" -> Json.toJson(d)
case d: QaQuestion => "qa-question" -> Json.toJson(d)
case d: QaAnswer => "qa-answer" -> Json.toJson(d)
case d: QaComment => "qa-comment" -> Json.toJson(d)
}) match {
case (typ, json) => json.asOpt[JsObject] map { new Entry(users, typ, _, DateTime.now) }
}

Binary file not shown.

View File

@ -0,0 +1,81 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by Fontastic.me</metadata>
<defs>
<font id="lichess" horiz-adv-x="512">
<font-face font-family="lichess" units-per-em="512" ascent="480" descent="-32"/>
<missing-glyph horiz-adv-x="512" />
<glyph unicode="&#97;" d="M393 293c8 0 14-3 20-8 5-6 8-12 8-20l0-164c0-8-3-15-8-20-6-5-12-8-20-8l-274 0c-8 0-14 3-20 8-5 5-8 12-8 20l0 164c0 8 3 14 8 20 6 5 12 8 20 8l9 0 0 91c0 35 13 65 38 90 25 25 55 38 90 38 35 0 65-13 90-38 25-25 38-55 38-90 0-5-2-9-5-13-4-3-8-5-13-5l-19 0c-5 0-9 2-12 5-4 4-6 8-6 13 0 20-7 37-21 52-15 14-32 21-52 21-20 0-37-7-52-21-14-15-21-32-21-52l0-91z"/>
<glyph unicode="&#98;" d="M475 213l0 176c-32-17-61-26-87-26-16 0-29 3-41 10-19 9-37 16-53 21-16 6-33 8-51 8-33 0-71-12-115-36l0-171c47 21 88 32 124 32 10 0 20-1 29-2 10-1 19-4 28-7 10-4 17-7 22-9 6-3 13-6 24-12l8-4c8-4 18-6 29-6 23 0 50 9 83 26z m-384 226c0-7-1-13-5-18-3-6-7-10-13-14l0-361c0-3-1-5-2-7-2-2-4-2-7-2l-18 0c-3 0-5 0-7 2-2 2-2 4-2 7l0 361c-6 4-10 8-14 14-3 5-5 11-5 18 0 10 4 19 11 26 7 7 16 10 26 10 10 0 19-3 26-10 7-7 10-16 10-26z m421-18l0-218c0-8-3-13-10-17-2-1-4-2-5-2-41-22-77-33-105-33-17 0-32 3-45 10l-8 4c-13 6-22 10-29 13-6 3-15 6-26 9-10 2-21 4-32 4-20 0-42-5-68-13-25-8-47-18-65-29-3-2-6-3-9-3-3 0-6 1-9 3-7 3-10 9-10 16l0 212c0 6 3 11 9 15 7 4 14 8 23 12 8 5 19 9 32 15 14 6 28 11 44 14 15 4 30 6 44 6 21 0 41-3 60-9 18-6 38-14 60-25 7-3 15-5 25-5 23 0 53 11 89 32 4 2 7 4 8 5 6 3 12 3 18-1 6-4 9-9 9-15z"/>
<glyph unicode="&#99;" d="M256 402c-39 0-75-6-109-20-34-13-61-31-81-53-19-23-29-47-29-73 0-21 6-42 20-61 14-19 33-36 58-50l24-14-7-28c-5-17-12-34-20-49 29 12 55 28 78 49l13 11 16-2c13-2 25-2 37-2 39 0 75 6 109 20 34 13 61 31 81 53 19 23 29 47 29 73 0 26-10 50-29 73-20 22-47 40-81 53-34 14-70 20-109 20z m256-146c0-33-11-64-34-92-23-28-54-50-93-66-40-17-83-25-129-25-13 0-27 1-41 2-38-33-82-56-132-69-9-2-20-4-32-6l-2 0c-3 0-5 1-8 3-2 2-3 5-4 8l0 0c-1 1-1 2 0 4 0 1 0 2 0 2 0 1 1 2 2 3l1 3c0 0 1 1 2 2 2 2 2 3 3 3 1 1 4 5 8 10 5 5 8 8 10 10 2 3 5 6 9 12 4 5 7 10 9 14 3 5 5 10 8 17 3 7 5 14 8 22-30 17-54 38-71 63-17 25-26 51-26 80 0 33 11 64 34 92 23 28 54 50 93 66 40 17 83 25 129 25 46 0 89-8 129-25 39-16 70-38 93-66 23-28 34-59 34-92z"/>
<glyph unicode="&#100;" d="M201 402c-29 0-56-5-82-15-25-9-45-23-60-40-15-17-22-35-22-54 0-16 5-31 15-46 10-14 24-27 42-37l28-16-10-24c6 4 12 7 18 11l12 9 15-3c15-3 30-4 44-4 29 0 57 5 82 15 25 10 45 23 60 40 15 17 23 35 23 55 0 19-8 37-23 54-15 17-35 31-60 40-25 10-53 15-82 15z m0 37c37 0 70-7 101-20 31-13 56-31 73-53 18-22 27-47 27-73 0-27-9-51-27-74-17-22-42-40-73-53-31-13-64-20-101-20-16 0-33 2-50 5-24-17-50-29-80-37-6-1-15-3-24-4l-1 0c-2 0-4 0-6 2-2 2-3 4-3 6 0 1 0 1 0 2 0 1 0 1 0 2 0 0 0 1 0 1l1 2c0 0 0 0 1 1 1 1 1 2 1 2 0 0 1 0 1 1 1 1 2 2 2 2 1 1 3 3 6 7 4 3 6 6 8 8 1 2 3 5 6 8 3 4 5 8 7 11 2 4 4 8 6 13-24 14-42 31-56 51-13 20-20 41-20 64 0 26 9 51 27 73 18 22 42 40 73 53 31 13 65 20 101 20z m235-334c2-5 4-9 6-13 2-4 4-7 7-11 3-3 5-6 6-8 2-2 4-5 8-8 3-4 5-6 6-8 1 0 1 0 2-1 0-1 1-1 1-1 0-1 1-1 1-2 0 0 1-1 1-1l1-2c0 0 0 0 0-1 1-2 1-2 0-2 0 0 0-1 0-2 0-3-2-5-4-6-1-2-4-3-6-2-9 1-18 2-24 4-30 8-56 20-80 37-17-3-34-5-50-5-52 0-97 13-135 38 11-1 19-1 25-1 31 0 60 4 88 13 29 8 54 20 76 36 24 18 42 38 55 61 12 23 19 47 19 73 0 14-2 29-7 43 25-14 44-30 59-51 14-20 21-42 21-66 0-22-7-44-20-64-14-20-32-36-56-50z"/>
<glyph unicode="&#101;" d="M512 309l0-227c0-12-4-23-13-32-9-9-20-13-33-13l-420 0c-13 0-24 4-33 13-9 9-13 20-13 32l0 227c8-9 18-17 29-25 69-47 116-79 142-98 11-8 20-15 26-19 7-4 16-9 27-14 12-4 22-7 32-7l0 0c10 0 20 3 32 7 11 5 20 10 27 14 6 4 15 11 26 19 33 23 80 56 142 98 11 8 21 16 29 25z m0 84c0-15-5-29-14-43-9-14-21-25-35-35-71-50-116-81-134-93-1-1-6-4-12-9-6-4-11-8-15-11-4-2-9-5-15-9-6-3-11-6-16-8-6-1-10-2-15-2l0 0c-5 0-9 1-15 2-5 2-10 5-16 8-6 4-11 7-15 9-4 3-9 7-15 11-6 5-11 8-12 9-18 12-43 30-75 52-33 23-52 36-59 41-12 8-23 19-33 33-11 14-16 27-16 39 0 15 4 27 12 37 8 10 19 15 34 15l420 0c13 0 23-5 32-14 9-9 14-19 14-32z"/>
<glyph unicode="&#102;" d="M158 256c-29-1-52-12-71-34l-35 0c-15 0-27 3-37 11-10 7-15 17-15 31 0 63 11 94 33 94 1 0 5-1 12-5 6-4 15-8 26-12 10-3 21-5 31-5 12 0 24 2 36 6-1-7-1-13-1-18 0-24 7-47 21-68z m286-170c0-21-7-38-20-50-13-13-30-19-51-19l-234 0c-21 0-38 6-51 19-13 12-20 29-20 50 0 10 1 19 1 28 1 9 2 18 4 29 2 10 4 20 7 29 3 9 7 17 11 26 5 8 11 15 17 21 6 6 14 11 23 15 9 3 19 5 30 5 1 0 5-2 11-6 6-4 12-8 19-13 8-4 17-9 29-12 12-4 24-6 36-6 12 0 24 2 36 6 12 3 21 8 29 12 7 5 13 9 19 13 6 4 10 6 11 6 11 0 21-2 30-5 9-4 17-9 23-15 6-6 12-13 17-21 4-9 8-17 11-26 3-9 5-19 7-29 2-11 3-20 4-29 0-9 1-18 1-28z m-273 341c0-19-7-35-20-49-14-13-30-20-49-20-18 0-35 7-48 20-13 14-20 30-20 49 0 19 7 35 20 48 13 13 30 20 48 20 19 0 35-7 49-20 13-13 20-29 20-48z m187-103c0-28-10-52-30-72-20-20-44-30-72-30-28 0-52 10-72 30-20 20-30 44-30 72 0 29 10 53 30 73 20 20 44 30 72 30 28 0 52-10 72-30 20-20 30-44 30-73z m154-60c0-14-5-24-15-31-10-8-22-11-37-11l-35 0c-19 22-42 33-71 34 14 21 21 44 21 68 0 5 0 11-1 18 12-4 24-6 36-6 10 0 21 2 31 5 11 4 20 8 26 12 7 4 11 5 12 5 22 0 33-31 33-94z m-34 163c0-19-7-35-20-49-13-13-30-20-48-20-19 0-35 7-49 20-13 14-20 30-20 49 0 19 7 35 20 48 14 13 30 20 49 20 18 0 35-7 48-20 13-13 20-29 20-48z"/>
<glyph unicode="&#103;" d="M149 260c-14 31-21 66-21 106l-73 0 0-28c0-15 9-30 27-46 18-16 40-27 67-32z m308 78l0 28-73 0c0-40-7-75-21-106 27 5 49 16 67 32 18 16 27 31 27 46z m37 37l0-37c0-13-4-27-12-41-8-13-19-26-32-37-14-11-30-20-50-28-19-7-40-11-61-12-8-11-17-20-27-27-8-7-13-14-15-21-3-7-4-16-4-26 0-10 2-19 8-26 6-7 15-10 28-10 14 0 27-5 38-13 11-9 17-20 17-33l0-18c0-3-1-5-3-7-1-2-3-2-6-2l-238 0c-3 0-5 0-6 2-2 2-3 4-3 7l0 18c0 13 6 24 17 33 11 8 24 13 38 13 13 0 22 3 28 10 6 7 8 16 8 26 0 10-1 19-4 26-2 7-7 14-15 21-10 7-19 16-27 27-21 1-42 5-61 12-20 8-36 17-50 28-13 11-24 24-32 37-8 14-12 28-12 41l0 37c0 7 3 14 8 19 6 6 12 8 20 8l82 0 0 28c0 12 4 23 13 32 9 9 20 13 33 13l164 0c13 0 24-4 33-13 9-9 13-20 13-32l0-28 82 0c8 0 14-2 20-8 5-5 8-12 8-19z"/>
<glyph unicode="&#104;" d="M110 128c0 5-2 9-6 13-3 3-8 5-13 5-5 0-9-2-12-5-4-4-6-8-6-13 0-5 2-9 6-13 3-3 7-5 12-5 5 0 10 2 13 5 4 4 6 8 6 13z m329 165c0 9-4 18-11 25-8 7-16 11-26 11l-100 0c0 11 4 26 13 46 10 19 14 34 14 46 0 18-3 32-9 41-6 9-18 13-37 13-5-5-8-13-10-24-3-11-6-23-9-36-4-12-9-23-17-31-4-4-12-13-22-26-1-1-3-4-7-9-3-4-6-8-9-11-2-3-5-7-10-12-4-5-8-10-11-13-3-3-7-7-11-10-4-4-8-6-11-8-4-2-8-2-11-2l-9 0 0-183 9 0c3 0 6-1 9-1 4-1 7-1 10-2 3-1 6-2 11-3 4-2 8-3 10-3 2-1 5-2 10-4 4-2 7-3 8-3 40-14 73-21 98-21l34 0c37 0 55 16 55 48 0 5 0 10-1 16 6 3 10 8 13 15 4 7 5 14 5 21 0 7-1 13-5 20 10 9 15 20 15 34 0 4-1 10-2 15-2 6-5 11-8 14 7 0 12 5 16 13 4 9 6 17 6 24z m36 0c0-17-4-33-14-47 2-6 3-13 3-19 0-15-4-29-11-42 1-4 1-8 1-12 0-19-6-36-17-51 0-26-8-47-24-62-17-16-38-23-65-23l-37 0c-18 0-36 2-54 6-18 4-39 11-62 19-22 7-35 11-40 11l-82 0c-10 0-19 4-26 11-7 7-10 16-10 26l0 183c0 10 3 18 10 25 7 8 16 11 26 11l78 0c7 5 20 19 40 44 11 15 21 27 30 37 5 5 8 13 10 24 2 12 5 24 9 37 4 12 10 22 18 30 7 7 16 11 25 11 16 0 31-3 44-9 12-6 22-16 29-29 6-13 10-31 10-53 0-18-5-36-14-55l50 0c20 0 37-8 52-22 14-14 21-32 21-51z"/>
<glyph unicode="&#106;" d="M256 475c40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110 0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29z m37-356l0 54c0 3-1 5-3 7-2 2-4 3-6 3l-55 0c-3 0-5-1-7-3-2-2-3-4-3-7l0-54c0-2 1-5 3-6 2-2 4-3 7-3l55 0c2 0 4 1 6 2 2 2 3 4 3 7z m-1 98l5 178c0 2-1 4-3 5-2 2-4 2-7 2l-62 0c-3 0-5 0-7-2-2-1-3-3-3-5l5-178c0-1 1-3 3-5 1-1 4-2 6-2l53 0c3 0 5 1 7 2 2 2 3 4 3 5z"/>
<glyph unicode="&#107;" d="M411 257c0 31-8 59-24 84l-216-215c26-17 55-25 85-25 21 0 41 4 60 12 20 8 36 19 50 33 14 14 25 31 33 50 8 19 12 40 12 61z m-285-86l216 216c-26 17-55 26-86 26-28 0-54-7-78-21-24-14-43-33-57-57-13-24-20-50-20-78 0-31 8-59 25-86z m349 86c0-30-5-59-17-86-12-27-27-51-47-70-19-20-43-35-70-47-27-12-55-17-85-17-30 0-58 5-85 17-27 12-51 27-70 47-20 19-35 43-47 70-12 27-17 56-17 86 0 30 5 58 17 85 12 28 27 51 47 71 19 19 43 35 70 46 27 12 55 18 85 18 30 0 58-6 85-18 27-11 51-27 70-46 20-20 35-43 47-71 12-27 17-55 17-85z"/>
<glyph unicode="&#108;" d="M256 101l0 310c-28 0-54-7-78-20-24-14-43-33-57-57-13-24-20-50-20-78 0-28 7-54 20-78 14-24 33-43 57-57 24-13 50-20 78-20z m219 155c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#109;" d="M140 73l26 26-67 67-26-26 0-30 37 0 0-37z m150 265c0 4-2 7-7 7-1 0-3-1-4-2l-155-155c-2-2-2-3-2-5 0-4 2-6 6-6 2 0 4 0 5 2l155 154c1 2 2 3 2 5z m-16 55l119-119-238-237-118 0 0 118z m195-27c0-10-3-19-10-26l-48-47-118 118 47 48c7 7 15 10 26 10 10 0 18-3 26-10l67-67c7-8 10-16 10-26z"/>
<glyph unicode="&#112;" d="M293 357l0-128c0-3-1-5-3-7-2-2-4-3-7-3l-91 0c-3 0-5 1-7 3-1 2-2 4-2 7l0 18c0 3 1 5 2 6 2 2 4 3 7 3l64 0 0 101c0 2 1 4 3 6 1 2 3 3 6 3l18 0c3 0 5-1 7-3 2-2 3-4 3-6z m118-101c0 28-7 54-20 78-14 24-33 43-57 57-24 13-50 20-78 20-28 0-54-7-78-20-24-14-43-33-57-57-13-24-20-50-20-78 0-28 7-54 20-78 14-24 33-43 57-57 24-13 50-20 78-20 28 0 54 7 78 20 24 14 43 33 57 57 13 24 20 50 20 78z m64 0c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#114;" d="M457 111c0-23-7-41-21-55-14-13-32-19-55-19l-250 0c-23 0-41 6-55 19-14 14-21 32-21 55 0 10 0 20 1 29 1 10 2 20 4 31 2 11 4 22 7 31 3 10 8 19 13 28 5 9 11 17 17 23 7 7 15 12 25 16 9 3 20 5 32 5 1 0 5-2 12-6 6-4 13-9 21-14 8-5 18-9 31-13 13-4 25-6 38-6 13 0 25 2 38 6 13 4 23 8 31 13 8 5 15 10 21 14 7 4 11 6 12 6 12 0 23-2 32-5 10-4 18-9 25-16 6-6 12-14 17-23 5-9 10-18 13-28 3-9 5-20 7-31 2-11 3-21 4-31 1-9 1-19 1-29z m-91 255c0-31-11-56-32-78-22-21-48-32-78-32-30 0-56 11-78 32-21 22-32 47-32 78 0 30 11 56 32 77 22 22 48 32 78 32 30 0 56-10 78-32 21-21 32-47 32-77z"/>
<glyph unicode="&#115;" d="M343 225l88 85-121 18-54 109-54-109-121-18 88-85-21-120 108 57 108-57z m151 102c0-4-3-9-8-14l-103-101 24-143c0-1 0-3 0-5 0-10-3-15-11-15-4 0-8 2-12 4l-128 67-128-67c-4-2-8-4-12-4-4 0-7 2-9 5-2 2-3 6-3 10 0 1 0 3 1 5l24 143-104 101c-4 6-7 10-7 14 0 7 6 12 16 13l144 21 64 130c4 8 8 12 14 12 6 0 10-4 14-12l64-130 144-21c10-1 16-6 16-13z"/>
<glyph unicode="&#116;" d="M494 327c0-4-3-9-8-14l-103-101 24-143c0-1 0-3 0-5 0-4-1-8-3-10-2-3-4-5-8-5-4 0-8 2-12 4l-128 67-128-67c-4-2-8-4-12-4-4 0-7 2-9 5-2 2-3 6-3 10 0 1 0 3 1 5l24 143-104 101c-4 6-7 10-7 14 0 7 6 12 16 13l144 21 64 130c4 8 8 12 14 12 6 0 10-4 14-12l64-130 144-21c10-1 16-6 16-13z"/>
<glyph unicode="&#117;" d="M402 311c0-5-2-9-5-13l-128-128c-4-4-8-5-13-5-5 0-9 1-13 5l-128 128c-3 4-5 8-5 13 0 5 2 9 5 13 4 3 8 5 13 5l256 0c5 0 9-2 13-5 3-4 5-8 5-13z"/>
<glyph unicode="&#118;" d="M0 281l-2-19c101-203 381-224 512-40l2 19c-100 202-381 224-512 40m251-145c-64 5-112 61-107 125 5 64 61 112 125 106 64-5 112-61 107-125-5-64-61-112-125-106m9 174c-32 0-58-26-58-58 0-33 26-59 58-59 32 0 58 26 58 59 0 32-26 58-58 58"/>
<glyph unicode="&#119;" d="M475 256c0-30-5-58-17-85-12-27-27-51-47-70-19-20-43-35-70-47-27-12-55-17-85-17-30 0-58 5-85 17-27 12-51 27-70 47-20 19-35 43-47 70-12 27-17 55-17 85 0 35 7 67 23 98 15 31 36 56 64 77 8 6 18 9 28 7 10-1 18-6 23-14 7-8 9-17 7-27-1-10-6-18-14-24-18-14-33-31-43-52-10-20-15-42-15-65 0-20 4-39 11-57 8-18 18-33 32-46 13-14 28-24 46-32 18-7 37-11 57-11 20 0 39 4 57 11 18 8 33 18 46 32 14 13 24 28 32 46 7 18 11 37 11 57 0 23-5 45-15 65-10 21-25 38-43 52-8 6-13 14-14 24-2 10 0 19 7 27 5 8 13 13 24 14 10 2 19-1 27-7 28-21 49-46 64-77 16-31 23-63 23-98z m-182 219l0-182c0-10-4-19-11-26-8-7-16-11-26-11-10 0-18 4-26 11-7 7-11 16-11 26l0 182c0 10 4 19 11 26 8 7 16 11 26 11 10 0 18-4 26-11 7-7 11-16 11-26z"/>
<glyph unicode="&#120;" d="M384 128c0 5-2 9-5 13-4 3-8 5-13 5-5 0-10-2-13-5-4-4-6-8-6-13 0-5 2-9 6-13 3-3 8-5 13-5 5 0 9 2 13 5 3 4 5 8 5 13z m73 0c0 5-2 9-5 13-4 3-8 5-13 5-5 0-9-2-13-5-4-4-5-8-5-13 0-5 1-9 5-13 4-3 8-5 13-5 5 0 9 2 13 5 3 4 5 8 5 13z m37 64l0-91c0-8-3-15-8-20-6-5-12-8-20-8l-420 0c-8 0-14 3-20 8-5 5-8 12-8 20l0 91c0 8 3 14 8 19 6 6 12 8 20 8l133 0 38-38c11-11 24-16 39-16 15 0 28 5 39 16l39 38 132 0c8 0 14-2 20-8 5-5 8-11 8-19z m-93 163c3-8 2-15-4-20l-128-128c-4-4-8-6-13-6-5 0-9 2-13 6l-128 128c-6 5-7 12-4 20 3 7 9 11 17 11l73 0 0 128c0 5 2 9 6 13 3 3 7 5 12 5l74 0c5 0 9-2 12-5 4-4 6-8 6-13l0-128 73 0c8 0 14-4 17-11z"/>
<glyph unicode="&#122;" d="M512 329c0-5-2-9-5-13l-147-146c-3-4-8-5-13-5-5 0-9 1-12 5-4 4-6 8-6 13l0 73-64 0c-19 0-35-1-50-2-15-1-29-3-44-6-15-3-27-7-38-12-11-5-21-12-30-20-9-8-17-18-23-29-6-11-11-24-14-39-3-16-5-33-5-52 0-10 1-22 2-35 0-1 0-4 0-7 1-3 1-6 1-7 0-3-1-6-2-8-2-1-4-2-7-2-3 0-6 1-8 4-1 2-3 4-4 7-1 2-2 5-4 8-1 4-2 6-3 7-24 54-36 97-36 129 0 38 5 70 15 95 31 77 114 115 250 115l64 0 0 73c0 5 2 10 6 13 3 4 7 6 12 6 5 0 10-2 13-6l147-146c3-4 5-8 5-13z"/>
<glyph unicode="&#65;" d="M416 32l-22 0c52 34 86 93 86 160 0 90-62 165-145 186l36 68c4 9 1 19-7 23l-86 41c-4 2-8 2-13 1-4-2-7-5-9-9l-102-194c-8-17-2-37 14-44l-14-29 57-28 14 29c16-8 36 0 44 17l35 65c63-7 112-61 112-126 0-71-57-128-128-128-32 0-74 12-96 32l0 16c0 9 7 16 16 16l80 0 0 32-256 0 0-32 80 0c9 0 16-7 16-16l0-80c-35 0-64 3-64-32l416 0c0 35-29 32-64 32m-112 437c-4-2-8-5-10-10l-74-139-28 14c1 2 1 4 2 6l70 130c2 4 5 7 9 9 5 1 9 1 13-1l18-9c0 0 0 0 0 0"/>
<glyph unicode="&#67;" d="M410 64l-340 0c-3 0-6-3-6-6l0-52c0-3 3-6 6-6l340 0c3 0 6 3 6 6l0 52c0 3-3 6-6 6m70 336c0 27-22 48-48 48-26 0-48-21-48-48 0-16 8-30 20-39l-84-169-56 167c14 8 24 23 24 41 0 27-22 48-48 48-26 0-48-21-48-48 0-18 10-33 24-41l-56-167-84 169c12 9 20 23 20 39 0 27-22 48-48 48-26 0-48-21-48-48 0-22 15-41 35-46l29-258 352 0 29 258c20 5 35 24 35 46"/>
<glyph unicode="&#68;" d="M456 428c3-8 2-15-4-20l-141-141 0-212c0-8-4-14-11-17-3-1-5-1-7-1-6 0-10 1-13 5l-73 73c-4 4-6 8-6 13l0 139-141 141c-6 5-7 12-4 20 4 7 9 11 17 11l366 0c8 0 13-4 17-11z"/>
<glyph unicode="&#69;" d="M477 350c0-7-2-14-8-19l-206-207-39-39c-6-5-12-8-20-8-7 0-14 3-19 8l-142 142c-6 6-8 12-8 20 0 7 2 14 8 19l38 39c6 5 12 8 20 8 7 0 14-3 19-8l84-84 188 188c5 5 12 8 19 8 8 0 14-3 20-8l38-39c6-6 8-12 8-20z"/>
<glyph unicode="&#70;" d="M375 256c0-5-2-9-6-13l-155-155c-4-4-8-6-13-6-5 0-9 2-13 6-3 3-5 8-5 13l0 82-128 0c-5 0-9 2-13 5-4 4-5 8-5 13l0 110c0 5 1 9 5 13 4 3 8 5 13 5l128 0 0 82c0 5 2 10 5 13 4 4 8 6 13 6 5 0 9-2 13-6l155-155c4-4 6-8 6-13z m100 101l0-202c0-22-8-42-24-58-16-16-35-24-58-24l-91 0c-3 0-5 1-7 3-2 2-2 4-2 6 0 1-1 3-1 6 0 3 0 6 0 8 0 2 1 4 1 6 0 3 1 5 3 6 1 1 3 2 6 2l91 0c13 0 23 4 32 13 9 9 14 20 14 32l0 202c0 12-5 23-14 32-9 9-19 13-32 13l-89 0c0 0-1 0-3 1-2 0-4 0-4 0 0 1 0 1-2 2-1 1-2 2-2 3 0 1 0 2 0 3 0 1-1 3-1 6 0 3 0 6 0 8 0 2 1 4 1 6 0 3 1 5 3 6 1 1 3 2 6 2l91 0c23 0 42-8 58-24 16-16 24-36 24-58z"/>
<glyph unicode="&#71;" d="M450 247l-379-211c-5-2-8-2-11-1-4 2-5 6-5 11l0 420c0 5 1 9 5 11 3 1 6 1 11-1l379-211c5-3 7-6 7-9 0-3-2-6-7-9z"/>
<glyph unicode="&#72;" d="M405 274c0-10-3-18-10-26l-186-186c-7-7-16-10-26-10-10 0-19 3-26 10l-22 22c-7 7-10 16-10 26 0 10 3 18 10 25l139 139-139 139c-7 7-10 16-10 26 0 10 3 19 10 26l22 21c7 7 16 11 26 11 10 0 19-4 26-11l186-186c7-7 10-16 10-26z"/>
<glyph unicode="&#73;" d="M303 63l-186 186c-7 7-10 15-10 25 0 11 3 19 10 26l186 186c7 7 16 11 26 11 10 0 19-4 26-11l22-21c7-7 10-16 10-26 0-10-3-19-10-26l-139-139 139-138c7-8 10-16 10-26 0-10-3-19-10-26l-22-21c-7-7-16-11-26-11-10 0-19 4-26 11z"/>
<glyph unicode="&#74;" d="M475 256c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#75;" d="M256 411c-28 0-54-7-78-20-24-14-43-33-57-57-13-24-20-50-20-78 0-28 7-54 20-78 14-24 33-43 57-57 24-13 50-20 78-20 28 0 54 7 78 20 24 14 43 33 57 57 13 24 20 50 20 78 0 28-7 54-20 78-14 24-33 43-57 57-24 13-50 20-78 20z m219-155c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#66;" d="M319 160l96 128 97-128-64 0 0-32c0-53-43-96-96-96l-192 0c-53 0-96 43-96 96l0 32 64 0 0-32c0-18 14-32 32-32l192 0c18 0 32 14 32 32l0 32z m-126 192l-96-128-97 128 64 0 0 32c0 53 43 96 96 96l192 0c53 0 96-43 96-96l0-32-64 0 0 32c0 18-14 32-32 32l-192 0c-18 0-32-14-32-32l0-32z"/>
<glyph unicode="&#77;" d="M448 384l-96-96-160 160-128-128 160-160-96-96 320 0z"/>
<glyph unicode="&#78;" d="M448 128l-96 96-160-160-128 128 160 160-96 96 320 0z"/>
<glyph unicode="&#76;" d="M426 134c0-7-3-14-8-19l-39-39c-5-5-12-8-20-8-7 0-14 3-19 8l-84 84-84-84c-5-5-12-8-19-8-8 0-15 3-20 8l-39 39c-5 5-8 12-8 19 0 8 3 14 8 20l84 84-84 84c-5 5-8 12-8 19 0 8 3 14 8 20l39 38c5 6 12 8 20 8 7 0 14-2 19-8l84-84 84 84c5 6 12 8 19 8 8 0 15-2 20-8l39-38c5-6 8-12 8-20 0-7-3-14-8-19l-84-84 84-84c5-6 8-12 8-20z"/>
<glyph unicode="&#79;" d="M410 461c14 0 26-5 36-15 10-10 15-22 15-36 0 0 0-308 0-308 0-13-5-25-15-35-10-11-22-16-36-16 0 0-308 0-308 0-13 0-25 5-35 16-11 10-16 22-16 35 0 0 0 308 0 308 0 14 5 26 16 36 10 10 22 15 35 15 0 0 308 0 308 0m-26-231c0 0 0 52 0 52 0 0-102 0-102 0 0 0 0 102 0 102 0 0-52 0-52 0 0 0 0-102 0-102 0 0-102 0-102 0 0 0 0-52 0-52 0 0 102 0 102 0 0 0 0-102 0-102 0 0 52 0 52 0 0 0 0 102 0 102 0 0 102 0 102 0"/>
<glyph unicode="&#79;" d="M256 471c59 0 110-21 152-63 42-42 63-93 63-152 0-59-21-110-63-152-42-42-93-63-152-63-59 0-110 21-152 63-42 42-63 93-63 152 0 59 21 110 63 152 42 42 93 63 152 63m27-241c0 0 102 0 102 0 0 0 0 53 0 53 0 0-102 0-102 0 0 0 0 103 0 103 0 0-53 0-53 0 0 0 0-103 0-103 0 0-103 0-103 0 0 0 0-53 0-53 0 0 103 0 103 0 0 0 0-103 0-103 0 0 53 0 53 0 0 0 0 103 0 103"/>
<glyph unicode="&#79;" d="M402 238l0 36c0 5-2 10-5 13-4 4-8 6-13 6l-91 0 0 91c0 5-2 9-6 13-3 3-8 5-13 5l-36 0c-5 0-10-2-13-5-4-4-6-8-6-13l0-91-91 0c-5 0-9-2-13-6-3-3-5-8-5-13l0-36c0-5 2-10 5-13 4-4 8-6 13-6l91 0 0-91c0-5 2-9 6-13 3-3 8-5 13-5l36 0c5 0 10 2 13 5 4 4 6 8 6 13l0 91 91 0c5 0 9 2 13 6 3 3 5 8 5 13z m73 155l0-274c0-23-8-42-24-58-16-16-35-24-58-24l-274 0c-23 0-42 8-58 24-16 16-24 35-24 58l0 274c0 23 8 42 24 58 16 16 35 24 58 24l274 0c23 0 42-8 58-24 16-16 24-35 24-58z"/>
<glyph unicode="&#81;" d="M475 274l0-36c0-39-9-73-28-104-18-30-45-54-78-72-33-17-71-25-113-25-42 0-80 8-113 25-33 18-60 42-78 72-19 31-28 65-28 104l0 36c0 5 1 10 5 13 4 4 8 6 13 6l110 0c5 0 9-2 12-6 4-3 6-8 6-13l0-36c0-10 2-19 7-26 4-7 9-13 15-16 6-4 12-7 20-9 8-2 14-3 18-4 5 0 9 0 13 0 4 0 8 0 13 0 4 1 10 2 18 4 8 2 14 5 20 9 6 3 11 9 15 16 5 7 7 16 7 26l0 36c0 5 2 10 6 13 3 4 7 6 12 6l110 0c5 0 9-2 13-6 4-3 5-8 5-13z m-292 183l0-110c0-5-2-9-6-12-3-4-7-6-12-6l-110 0c-5 0-9 2-13 6-4 3-5 7-5 12l0 110c0 5 1 9 5 13 4 4 8 5 13 5l110 0c5 0 9-1 12-5 4-4 6-8 6-13z m292 0l0-110c0-5-1-9-5-12-4-4-8-6-13-6l-110 0c-5 0-9 2-12 6-4 3-6 7-6 12l0 110c0 5 2 9 6 13 3 4 7 5 12 5l110 0c5 0 9-1 13-5 4-4 5-8 5-13z"/>
<glyph unicode="&#81;" d="M373 395l-42-64-75 106-75-106-42 64c-14-25-64-86-64-150 0-94 87-170 181-170 94 0 181 76 181 170 0 64-50 125-64 150z m-117-278c-43 0-75 22-75 43 0 48 75 107 75 107 0 0 75-58 75-107 0-21-32-43-75-43z"/>
<glyph unicode="&#81;" d="M384 320c0 0-23-1-78-32l-4 5c2 42 6 92 18 123-7-4-32-25-62-47-15 36-20 105-2 143-141-101-224-245-224-336 0-70-10-176 160-176 265 0 128 192 192 320m-173-270c-192-5-69 182-89 144-3-5-17-49 51-85-34 42 27 92 49 115 0-59 24-115 24-115 0 0 39 23 67 105 24-105 5-160-102-164"/>
<glyph unicode="&#82;" d="M32 352l224-224 224 224z"/>
<glyph unicode="&#83;" d="M480 160l-224 224-224-224z"/>
<glyph unicode="&#84;" d="M381 350c3-4 4-8 2-12l-154-331c-3-5-7-7-12-7-1 0-3 0-4 1-4 1-6 2-8 5-1 3-2 6-1 9l56 230-116-28c0-1-2-1-3-1-4 0-7 1-9 3-3 3-5 7-4 12l58 235c0 3 2 5 4 7 3 2 5 2 8 2l94 0c4 0 7-1 9-3 3-3 4-5 4-9 0-1-1-3-2-5l-48-132 113 28c1 0 2 1 3 1 4 0 7-2 10-5z"/>
<glyph unicode="&#85;" d="M281 240l96-104c17 13 29 27 35 41l31 0c-6-27-19-49-40-65l53-63c14-1 21-8 22-23-1-9-6-16-12-20-7-4-16-6-25-6-17 1-25 10-26 28l-54 58c-24-13-46-20-66-22l-14 23c23 3 43 11 58 22l-84 100-83-100c15-11 34-19 57-22l-13-23c-21 2-43 9-67 22l-53-58c-1-16-8-26-22-28-9 0-18 1-27 5-8 3-13 9-14 17 0 17 7 26 22 27l53 63c-21 16-35 38-40 65l31 0c6-14 18-28 35-41l95 104-185 221-11 51 222-243 223 243-11-51z"/>
<glyph unicode="&#86;" d="M13 40c-4-3-7-5-9-3-3 1-4 4-4 9l0 420c0 5 1 8 4 9 2 2 5 0 9-3l203-203c1-2 2-3 3-6l0 203c0 5 2 8 4 9 3 2 6 0 9-3l203-203c2-2 3-3 4-6l0 194c0 5 2 9 5 13 4 4 8 5 13 5l37 0c5 0 9-1 13-5 3-4 5-8 5-13l0-402c0-5-2-9-5-13-4-4-8-5-13-5l-37 0c-5 0-9 1-13 5-3 4-5 8-5 13l0 194c-1-2-2-4-4-6l-203-203c-3-3-6-5-9-3-2 1-4 4-4 9l0 203c-1-2-2-4-3-6z"/>
<glyph unicode="&#87;" d="M499 472c4 3 7 5 9 3 3-1 4-4 4-9l0-420c0-5-1-8-4-9-2-2-5 0-9 3l-203 203c-1 2-3 4-3 6l0-203c0-5-2-8-4-9-3-2-6 0-9 3l-203 203c-2 2-3 4-4 6l0-194c0-5-2-9-5-13-4-4-8-5-13-5l-37 0c-5 0-9 1-13 5-3 4-5 8-5 13l0 402c0 5 2 9 5 13 4 4 8 5 13 5l37 0c5 0 9-1 13-5 3-4 5-8 5-13l0-194c1 3 2 4 4 6l203 203c3 3 6 5 9 3 2-1 4-4 4-9l0-203c0 3 2 4 3 6z"/>
<glyph unicode="&#88;" d="M123 40c-4-3-7-5-10-3-2 1-3 4-3 9l0 420c0 5 1 8 3 9 3 2 6 0 10-3l202-203c2-2 3-3 4-6l0 194c0 5 2 9 6 13 3 4 7 5 12 5l37 0c5 0 9-1 13-5 3-4 5-8 5-13l0-402c0-5-2-9-5-13-4-4-8-5-13-5l-37 0c-5 0-9 1-12 5-4 4-6 8-6 13l0 194c-1-2-2-4-4-6z"/>
<glyph unicode="&#89;" d="M389 472c4 3 7 5 10 3 2-1 3-4 3-9l0-420c0-5-1-8-3-9-3-2-6 0-10 3l-202 203c-2 2-3 4-4 6l0-194c0-5-2-9-6-13-3-4-7-5-12-5l-37 0c-5 0-9 1-13 5-3 4-5 8-5 13l0 402c0 5 2 9 5 13 4 4 8 5 13 5l37 0c5 0 9-1 12-5 4-4 6-8 6-13l0-194c1 3 2 4 4 6z"/>
<glyph unicode="&#90;" d="M475 457l0-402c0-5-1-9-5-13-4-4-8-5-13-5l-146 0c-5 0-9 1-13 5-4 4-5 8-5 13l0 402c0 5 1 9 5 13 4 4 8 5 13 5l146 0c5 0 9-1 13-5 4-4 5-8 5-13z m-256 0l0-402c0-5-1-9-5-13-4-4-8-5-13-5l-146 0c-5 0-9 1-13 5-4 4-5 8-5 13l0 402c0 5 1 9 5 13 4 4 8 5 13 5l146 0c5 0 9-1 13-5 4-4 5-8 5-13z"/>
<glyph unicode="&#33;" d="M293 119l0 54c0 3-1 5-3 7-2 2-4 3-7 3l-54 0c-3 0-5-1-7-3-2-2-3-4-3-7l0-54c0-3 1-5 3-7 2-1 4-2 7-2l54 0c3 0 5 1 7 2 2 2 3 4 3 7z m-1 107l5 131c0 2-1 4-3 6-2 2-4 3-7 3l-62 0c-3 0-5-1-7-3-2-2-3-4-3-6l5-131c0-2 1-3 3-5 1-1 4-2 6-2l53 0c3 0 5 1 7 2 2 2 3 3 3 5z m-4 267l219-402c7-12 7-24 0-36-3-6-8-10-13-14-6-3-12-4-19-4l-438 0c-7 0-13 1-19 4-5 4-10 8-13 14-7 12-7 24 0 36l219 402c3 6 8 10 13 14 6 3 12 5 19 5 7 0 13-2 19-5 5-4 10-8 13-14z"/>
<glyph unicode="&#80;" d="M475 256c0-30-5-58-17-85-12-27-27-51-47-70-19-20-43-35-70-47-27-12-55-17-85-17-33 0-64 6-93 20-30 14-55 34-76 59-1 2-2 4-2 6 0 3 1 4 3 6l39 39c2 2 4 3 7 3 3 0 5-2 7-3 13-19 31-33 51-42 20-10 41-15 64-15 20 0 39 4 57 11 18 8 33 18 46 32 14 13 24 28 32 46 7 18 11 37 11 57 0 20-4 39-11 57-8 18-18 33-32 46-13 14-28 24-46 32-18 7-37 11-57 11-19 0-37-3-54-10-17-7-32-16-45-29l39-39c6-6 7-13 4-20-4-8-9-11-17-11l-128 0c-5 0-9 1-13 5-4 4-5 8-5 13l0 128c0 8 3 13 11 17 7 3 14 2 20-4l37-37c20 19 44 34 70 45 26 10 53 15 81 15 30 0 58-5 85-17 27-12 51-27 70-47 20-19 35-43 47-70 12-27 17-55 17-85z"/>
<glyph unicode="&#105;" d="M512 192c0-32-12-75-36-129-1-1-2-3-3-7-2-3-3-6-4-8-1-3-3-5-4-7-2-3-5-4-8-4-3 0-5 1-7 2-1 2-2 5-2 8 0 1 0 4 1 7 0 3 0 6 0 7 1 13 2 25 2 35 0 19-2 36-5 52-3 15-8 28-14 39-6 11-14 21-23 29-9 8-19 15-30 20-11 5-23 9-38 12-15 3-29 5-44 6-15 1-31 2-50 2l-64 0 0-73c0-5-2-9-6-13-3-4-7-5-12-5-5 0-10 1-13 5l-147 146c-3 4-5 8-5 13 0 5 2 9 5 13l147 146c3 4 8 6 13 6 5 0 9-2 12-6 4-3 6-8 6-13l0-73 64 0c136 0 219-38 250-115 10-25 15-57 15-95z"/>
<glyph unicode="&#50;" d="M32 384l0-256c0-60 0-128 96-128l128 0c72 0 90 39 94 83l123 153c10 13 9 31-2 43-4 3-26 23-56 23-14 0-34-4-54-23l-41-42 0 211c0 18-14 32-32 32l-32 0c0 18-14 32-32 32l-32 0c-18 0-32-14-32-32l-32 0c-18 0-32-14-32-32l0-32-32 0c-18 0-32-14-32-32m32 0l32 0 0-128 32 0 0 192 32 0 0-192 32 0 0 224 32 0 0-224 32 0 0 192 32 0 0-256 32 0 0 0 64 64c11 11 21 14 31 14 19 0 33-14 33-14l-128-159 0-1-1 0c-1-42-11-64-63-64l-128 0c-64 0-64 32-64 96z"/>
<glyph unicode="&#51;" d="M120 176c31 0 56-25 56-56 0-31-25-56-56-56-31 0-56 25-56 56 0 31 25 56 56 56z m-56 144c140 0 256-116 256-256l-80 0c0 48-14 94-48 128-34 34-80 48-128 48z m0 128c212 0 384-172 384-384l-80 0c0 171-133 304-304 304z"/>
<glyph unicode="&#48;" d="M201 101c0-1 0-3 0-6 1-3 1-6 1-8-1-2-1-4-1-6-1-3-2-5-3-6-2-1-4-2-6-2l-91 0c-23 0-42 8-59 24-16 16-24 36-24 58l0 202c0 22 8 42 24 58 17 16 36 24 59 24l91 0c2 0 5-1 6-3 2-2 3-4 3-6 0-1 0-3 0-6 1-3 1-6 1-8-1-2-1-4-1-6-1-3-2-5-3-6-2-1-4-2-6-2l-91 0c-13 0-24-4-33-13-9-9-13-20-13-32l0-202c0-12 4-23 13-32 9-9 20-13 33-13l89 0c0 0 1 0 3-1 2 0 3 0 3 0 0-1 1-1 3-2 1-1 2-2 2-3-1-1 0-2 0-3z m265 155c0-5-2-9-5-13l-156-155c-3-4-7-6-12-6-5 0-10 2-13 6-4 3-6 8-6 13l0 82-128 0c-5 0-9 2-13 5-3 4-5 8-5 13l0 110c0 5 2 9 5 13 4 3 8 5 13 5l128 0 0 82c0 5 2 10 6 13 3 4 8 6 13 6 5 0 9-2 12-6l156-155c3-4 5-8 5-13z"/>
<glyph unicode="&#49;" d="M480 384l-177 0 70 70c6 6 6 16 0 22-7 7-17 7-23 0l-92-92-19 0-93 92c-6 7-16 7-22 0-6-6-6-16 0-22l70-70-162 0c-18 0-32-14-32-32l0-288c0-18 14-32 32-32l448 0c18 0 32 14 32 32l0 288c0 18-14 32-32 32m-128-288l-288 0 0 224 288 0z m96 96l-32 0 0 32 32 0z m0 64l-32 0 0 32 32 0z"/>
<glyph unicode="&#52;" d="M232 382c-14-4-19-5-30-11-28-14-50-39-59-68-8-24-7-57 1-78 1-2-2-4-8-5-10-2-22-11-33-24l-5-6-9 0c-11 0-24-2-35-7-13-5-24-17-31-32-7-13-7-20-2-25l3-4 293 0 4 3c3 3 4 7 4 14l1 4 67 0c71 0 73 0 77 7 4 7 1 14-12 27-13 12-27 18-44 19-7 0-8 1-13 5-9 8-15 11-26 14-5 1-10 3-10 3-1 0 0 1 2 9 5 15 6 22 6 37 0 27-5 46-19 67-17 25-42 43-72 50-2 0-5 1-6 1-2 1-10 1-19 1-11 1-18 0-25-1z m43-13c37-7 67-32 80-68 4-13 5-19 5-38 0-16-1-24-7-38-4-8-4-8-10-10-9-2-16-6-24-12-6-5-7-6-11-5-12 2-27 0-40-7-8-3-8-3-22 4-11 5-25 8-35 8-6-1-7-1-13 5-8 8-19 13-31 15l-9 2-4 11c-9 29-3 62 14 88 14 22 40 40 64 45 4 0 8 1 9 1 5 2 26 1 34-1z m-101-161c7-3 16-9 21-15l5-6 6 2c11 3 20 1 36-6 6-3 11-6 12-9 1-1 3-3 3-4 0 0 3 2 6 4 10 7 25 4 38-9 8-8 10-12 11-23l0-8-282 0 1 5c4 11 12 21 21 28 13 9 34 13 48 8 5-1 5-1 9 7 9 14 24 25 38 28 8 1 20 1 27-2z m206-8c5-3 11-7 15-11l6-6 12-1c10 0 14 0 19-3 8-3 17-10 25-19l3-4-68 0-69 0-5 8c-5 7-18 20-21 20-2 0-2 1 0 1 1 1 11 0 18-2 3-1 4-1 6 2 3 6 11 12 17 15 4 2 6 3 6 3 0-1 1 0 2 0 2 1 8 1 14 1 9 0 12 0 20-4z"/>
<glyph unicode="&#53;" d="M251 500c-2-3-2-5-2-40 0-38 0-38 3-40 4-3 7-3 9 0 2 2 3 7 3 40 0 35 0 38-3 40-3 3-6 3-10 0z m-118-31c-1-1-1-4-1-5 0-3 15-32 23-44 1-2 4-6 6-10 5-10 10-15 14-14 9 3 8 7-12 41-10 17-18 31-19 32-2 3-9 2-11 0z m238 1c-2-1-6-8-12-17-5-8-9-15-9-15 0-1-10-18-12-22-7-10-8-16-2-20 4-3 8 0 13 8 2 4 10 19 18 32 15 27 16 31 10 33-1 1-4 1-6 1z m-137-85c-26-5-48-16-68-35-56-56-47-151 20-195 21-14 41-20 67-21 13-1 19 0 29 2 35 8 61 25 80 54 21 32 26 70 16 107-3 10-12 29-15 33-1 1-3 4-5 6-8 11-22 24-36 33-23 15-60 22-88 16z m41-13c66-11 109-80 89-145-10-33-38-62-71-74-12-4-16-5-33-5-49-3-93 27-110 75-6 13-6 20-6 40 0 17 2 28 9 43 14 32 44 57 76 64 6 1 11 3 12 3 4 1 27 0 34-1z m-227 12c-3-2-4-5-2-9 1-3 36-24 58-36 8-4 12-4 15 1 3 5 0 8-18 19-10 5-18 10-19 10-1 1-3 2-5 3-4 3-20 12-23 13-2 0-4 0-6-1z m402-4c-4-2-8-5-9-5-9-4-46-27-48-30-2-4-1-8 3-10 4-1 7 0 45 22 27 16 31 20 23 26-3 3-5 2-14-3z m-435-115c-3-3-3-7 0-10 2-2 7-2 39-2 32 0 38 0 40 2 4 2 4 7 1 10-2 3-7 3-40 3-35 0-38 0-40-3z m401 1c-1-1-3-4-3-6 0-7 3-7 44-7 20 0 37 0 38 1 3 2 4 8 1 11-2 3-4 3-39 3-32 0-38 0-41-2z m-20-82c-4-2-6-8-3-11 3-3 57-35 64-37 7-3 13 5 8 11-1 1-12 9-26 16-14 8-26 15-28 16-6 4-12 6-15 5z m-295-6c-5-3-12-6-14-8-3-1-12-7-21-12-9-5-17-10-18-11-3-2-4-9-1-11 5-4 4-4 61 29 11 6 14 10 11 15-3 5-7 5-18-2z m234-56c-2-1-3-3-3-5 0-2 7-15 15-29 8-14 16-28 17-31 4-7 8-9 13-8 3 2 4 4 4 9 0 2-27 49-34 60-4 6-8 8-12 4z m-166 0c-1-1-8-11-14-23-7-11-14-23-15-26-3-4-5-9-7-12-3-6-3-6 0-10 1-2 3-3 6-3 4 1 5 2 20 28 23 40 24 41 18 46-2 2-4 2-8 0z m82-23c-2-2-2-7-2-40 0-38 0-38 3-40 4-3 7-3 9 0 2 2 3 7 3 40 0 31-1 37-3 40-2 3-7 4-10 0z"/>
<glyph unicode="&#54;" d="M121 264l-85-68 35-7 75 63c145 2 233 58 233 58l-51 44c0 0 90 7 113-4 21 11 59 47 71 156-263 38-329-107-391-242m38 15l-2 1c25 26 169 173 320 205-83-29-278-176-318-206m31-148l-32 0c0 18-15 32-32 32l-32 0c-18 0-32-14-32-32l-32 0c-18 0-32-14-32-32l0-64c0-17 14-32 32-32l160 0c17 0 32 15 32 32l0 64c0 18-15 32-32 32"/>
<glyph unicode="&#56;" d="M314 198c3-17 4-31 5-42 0-10-1-20-5-30-3-10-5-16-6-21-1-4-7-9-18-16-11-7-19-11-23-13-5-2-17-8-36-16-19-9-34-15-43-19-11-4-19-3-24 2-4 5-4 13-1 23 0 0 20 56 20 56 0 0-66 67-66 67 0 0-54-20-54-20-10-4-17-4-22 1-6 5-6 13-2 24 4 10 9 23 16 40 6 17 11 28 14 33 2 6 6 13 11 23 5 10 9 16 13 19 4 2 9 6 15 10 6 4 13 7 21 7 0 0 26 0 26 0 0 0 12-1 37-3 3 4 8 11 14 20 7 8 20 23 40 43 20 21 40 38 60 53 21 15 46 28 75 39 29 10 57 14 84 9 3 0 5-1 7-3 2-1 3-3 3-7 4-28 1-56-9-86-10-29-22-55-39-77-16-22-33-42-50-61-17-18-32-31-44-41 0 0-19-14-19-14m26 151c8-7 17-11 28-11 11 0 20 4 27 11 8 8 12 18 12 29 0 11-4 20-12 29-7 7-16 11-27 11-11 0-20-4-28-11-7-9-11-18-11-29 0-11 4-21 11-29"/>
<glyph unicode="&#57;" d="M17 222c-14 4-20 13-16 29 3 14 12 20 27 16 0 0 50-12 50-12 0 0-26-41-26-41 0 0-35 8-35 8m455-6c4 4 10 6 16 6 7-1 12-3 16-8 11-11 11-22-1-33 0 0-128-115-128-115-5-4-10-6-16-6-5 0-9 2-14 5 0 0-146 112-146 112 0 0-28 8-28 8 0 0 26 40 26 40 0 0 18-4 18-4 4-1 7-2 8-4 0 0 135-104 135-104 0 0 114 103 114 103m-251 112c0 0-178-280-178-280-4-8-11-12-20-12-4 0-8 2-12 5-5 3-9 8-10 14-1 7 0 12 3 17 0 0 191 300 191 300 3 6 7 9 14 11 6 2 12 1 19-3 0 0 125-80 125-80 0 0 115 166 115 166 4 6 9 9 15 10 6 1 12-1 17-5 13-8 15-18 6-31 0 0-128-185-128-185-9-12-19-14-32-6 0 0-125 79-125 79"/>
<glyph unicode="&#34;" d="M202 136c5 5 10 7 17 7 7 0 13-2 19-7 10-11 10-23 0-36 0 0-22-20-22-20-19-19-42-29-68-29-26 0-49 10-68 29-19 19-29 42-29 67 0 27 10 50 29 69 0 0 76 76 76 76 24 23 48 36 73 39 26 3 47-4 66-22 5-5 8-11 8-18 0-7-3-13-8-19-12-11-24-11-36 0-17 17-40 11-68-17 0 0-75-75-75-75-9-9-14-20-14-33 0-13 5-23 14-31 9-9 19-14 32-14 13 0 23 5 32 14 0 0 22 20 22 20m230 294c19-19 29-42 29-68 0-26-10-49-29-68 0 0-81-81-81-81-25-25-51-37-77-37-21 0-40 9-57 26-5 5-7 10-7 17 0 7 2 13 7 19 5 4 11 7 18 7 7 0 13-3 18-7 17-17 38-13 62 12 0 0 81 80 81 80 10 9 15 20 15 32 0 13-5 24-15 32-8 9-17 14-28 16-11 2-22-2-31-11 0 0-26-25-26-25-5-5-11-7-18-7-7 0-13 2-18 7-11 11-11 23 0 36 0 0 26 25 26 25 18 19 40 27 65 26 25-1 47-11 66-31"/>
<glyph unicode="&#55;" d="M160 256c0 64 32 96 96 96 64 0 96-32 96-96 0-64-32-96-96-96-64 0-96 32-96 96z m352 16l0-32-65 0c-4-47-22-87-55-120-33-33-73-51-120-55l0-65-32 0 0 65c-47 4-87 22-120 55-33 33-51 73-55 120l-65 0 0 32 65 0c1 13 3 26 7 39 4 13 9 24 15 35 6 11 13 22 21 32 8 10 16 18 26 26 10 8 21 15 32 21 11 6 22 11 35 15 13 4 26 6 39 7l0 65 32 0 0-65c47-4 87-22 120-55 33-33 51-73 55-120z m-256-159c39 0 73 14 101 42 28 28 42 62 42 101 0 39-14 73-42 101-28 28-62 42-101 42-39 0-73-14-101-42-28-28-42-62-42-101 0-39 14-73 42-101 28-28 62-42 101-42z"/>
<glyph unicode="&#35;" d="M96 320l-64 0 0-128 64 0 128-96 32 0 0 320-32 0z m205-19c-6 7-16 7-22 0-7-6-7-16 0-22 12-13 12-33 0-46-7-6-7-16 0-22 6-7 16-7 22 0 25 25 25 65 0 90z m46 46c-7 6-17 6-23 0-6-7-6-17 0-23 37-38 37-98 0-136-6-6-6-16 0-23 6-6 16-6 23 0 49 50 49 132 0 182z m45 45c-6 6-17 6-23 0-6-6-6-17 0-23 63-62 63-164 0-226-6-6-6-17 0-23 6-6 17-6 23 0 75 75 75 197 0 272z"/>
<glyph unicode="&#36;" d="M96 320l-64 0 0-128 64 0 128-96 32 0 0 320-32 0z m368-16l-32 32-48-48-48 48-31-32 47-48-48-48 32-32 48 48 48-48 32 32-48 48z"/>
<glyph unicode="&#37;" d="M256 337c-45 0-81-36-81-81 0-45 36-81 81-81 45 0 81 36 81 81 0 45-36 81-81 81z m162-128l-14-35 26-51 3-7-36-36-59 28-35-14-18-55-2-7-51 0-22 62-36 14-51-26-7-3-36 36 28 59-14 35-55 18-7 2 0 51 62 22 14 36-26 51-3 7 36 36 59-28 35 14 18 55 2 7 51 0 22-62 36-14 51 26 7 3 36-36-28-59 14-35 55-18 7-2 0-51z"/>
<glyph unicode="&#38;" d="M224 384l-32 0 0-32 32 0z m0 64l-32 0 0-32 32 0z m192 64c-16 0-304 0-320 0-16 0-32-16-32-32 0-16 0-368 0-384 0-16 16-32 32-32 16 0 64 0 64 0l0-64 48 48 48-48 0 64c0 0 144 0 160 0 16 0 32 16 32 32 0 16 0 368 0 384 0 16-16 32-32 32z m0-400c0-8-7-16-16-16-8 0-144 0-144 0l0 32-96 0 0-32c0 0-39 0-48 0-8 0-16 8-16 16 0 7 0 48 0 48l320 0c0 0 0-40 0-48z m0 80l-256 0 0 288 257 0z m-192 64l-32 0 0-32 32 0z m0 64l-32 0 0-32 32 0z"/>
<glyph unicode="&#110;" d="M257 416c17 0 31 14 31 31 1 18-14 33-33 33-17-1-30-14-31-31 0-19 15-34 33-33z m232-192l-9 0-63 123c9 1 18 4 26 8 12 5 14 21 5 31l0 0c-6 6-14 8-22 4-7-3-17-6-26-6-28 0-41 32-144 32-103 0-115-32-143-32-10 0-20 3-27 6-7 3-16 2-21-4l-1 0c-9-10-6-25 6-31 8-4 17-7 26-8l-64-123-9 0c-4 0-7-4-6-8 5-32 46-56 95-56 50 0 90 24 96 56 0 4-3 8-7 8l-9 0-63 122c41 4 63 25 95 25l0-243c-17 0-32-15-32-32l-35 0c-14 0-29-15-29-32l256 0c0 17-14 32-35 32l-29 0c0 17-14 32-32 32l0 243c32 0 54-21 96-25l-64-122-9 0c-4 0-7-4-6-8 5-32 46-56 95-56 50 0 90 24 96 56 0 4-3 8-7 8z m-329 0l-96 0 48 90z m192 0l48 90 48-90z"/>
<glyph unicode="&#111;" d="M224 480l-128 0-64-64 0-128 256-256 192 192z m-160-176l0 96 48 48 96 0 224-224-144-144z m192 48l-96-96 128-128 96 96z m-48-96l48 48 80-80-48-48z m-16 112c0 26-21 48-48 48-26 0-48-22-48-48 0-27 22-48 48-48 27 0 48 21 48 48z m-48-16c-9 0-16 7-16 16 0 9 7 16 16 16 9 0 16-7 16-16 0-9-7-16-16-16z"/>
<glyph unicode="&#113;" d="M201 302l0-165c0-3-1-5-2-6-2-2-4-3-7-3l-18 0c-3 0-5 1-7 3-2 1-2 3-2 6l0 165c0 2 0 5 2 6 2 2 4 3 7 3l18 0c3 0 5-1 7-3 1-1 2-4 2-6z m73 0l0-165c0-3-1-5-2-6-2-2-4-3-7-3l-18 0c-3 0-5 1-7 3-1 1-2 3-2 6l0 165c0 2 1 5 2 6 2 2 4 3 7 3l18 0c3 0 5-1 7-3 1-1 2-4 2-6z m73 0l0-165c0-3 0-5-2-6-2-2-4-3-7-3l-18 0c-3 0-5 1-7 3-1 1-2 3-2 6l0 165c0 2 1 5 2 6 2 2 4 3 7 3l18 0c3 0 5-1 7-3 2-1 2-4 2-6z m37-207l0 271-256 0 0-271c0-4 1-8 2-12 1-3 3-6 4-7 2-2 3-3 3-3l238 0c0 0 1 1 3 3 1 1 3 4 4 7 1 4 2 8 2 12z m-192 307l128 0-14 34c-1 1-3 2-5 3l-90 0c-2-1-4-2-5-3z m265-9l0-18c0-3-1-5-2-7-2-1-4-2-7-2l-27 0 0-271c0-16-5-30-14-41-9-12-20-17-32-17l-238 0c-12 0-23 5-32 16-9 11-14 25-14 41l0 272-27 0c-3 0-5 1-7 2-1 2-2 4-2 7l0 18c0 3 1 5 2 7 2 1 4 2 7 2l88 0 20 48c3 7 8 13 16 18 7 5 15 7 22 7l92 0c7 0 15-2 22-7 8-5 13-11 16-18l20-48 88 0c3 0 5-1 7-2 1-2 2-4 2-7z"/>
</font></defs></svg>

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,637 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Font Reference - lichess</title>
<link href="http://fonts.googleapis.com/css?family=Dosis:400,500,700" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="styles.css">
<style type="text/css">
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-weight:inherit;font-style:inherit;font-family:inherit;font-size:100%;vertical-align:baseline}
body{line-height:1;color:#000;background:#fff}
ol,ul{list-style:none}
table{border-collapse:separate;border-spacing:0;vertical-align:middle}
caption,th,td{text-align:left;font-weight:normal;vertical-align:middle}
a img{border:none}
*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
body{font-family:'Dosis','Tahoma',sans-serif}
.container{margin:15px auto;width:80%}
h1{margin:40px 0 20px;font-weight:700;font-size:38px;line-height:32px;color:#fb565e}
h2{font-size:18px;padding:0 0 21px 5px;margin:45px 0 0 0;text-transform:uppercase;font-weight:500}
.small{font-size:14px;color:#a5adb4;}
.small a{color:#a5adb4;}
.small a:hover{color:#fb565e}
.glyphs.character-mapping{margin:0 0 20px 0;padding:20px 0 20px 30px;color:rgba(0,0,0,0.5);border:1px solid #d8e0e5;-webkit-border-radius:3px;border-radius:3px;}
.glyphs.character-mapping li{margin:0 30px 20px 0;display:inline-block;width:90px}
.glyphs.character-mapping .icon{margin:10px 0 10px 15px;padding:15px;position:relative;width:55px;height:55px;color:#162a36 !important;overflow:hidden;-webkit-border-radius:3px;border-radius:3px;font-size:32px;}
.glyphs.character-mapping .icon svg{fill:#000}
.glyphs.character-mapping input{margin:0;padding:5px 0;line-height:12px;font-size:12px;display:block;width:100%;border:1px solid #d8e0e5;-webkit-border-radius:5px;border-radius:5px;text-align:center;outline:0;}
.glyphs.character-mapping input:focus{border:1px solid #fbde4a;-webkit-box-shadow:inset 0 0 3px #fbde4a;box-shadow:inset 0 0 3px #fbde4a}
.glyphs.character-mapping input:hover{-webkit-box-shadow:inset 0 0 3px #fbde4a;box-shadow:inset 0 0 3px #fbde4a}
.glyphs.css-mapping{margin:0 0 60px 0;padding:30px 0 20px 30px;color:rgba(0,0,0,0.5);border:1px solid #d8e0e5;-webkit-border-radius:3px;border-radius:3px;}
.glyphs.css-mapping li{margin:0 30px 20px 0;padding:0;display:inline-block;overflow:hidden}
.glyphs.css-mapping .icon{margin:0;margin-right:10px;padding:13px;height:50px;width:50px;color:#162a36 !important;overflow:hidden;float:left;font-size:24px}
.glyphs.css-mapping input{margin:0;margin-top:5px;padding:8px;line-height:16px;font-size:16px;display:block;width:150px;height:40px;border:1px solid #d8e0e5;-webkit-border-radius:5px;border-radius:5px;background:#fff;outline:0;float:right;}
.glyphs.css-mapping input:focus{border:1px solid #fbde4a;-webkit-box-shadow:inset 0 0 3px #fbde4a;box-shadow:inset 0 0 3px #fbde4a}
.glyphs.css-mapping input:hover{-webkit-box-shadow:inset 0 0 3px #fbde4a;box-shadow:inset 0 0 3px #fbde4a}
</style>
</head>
<body>
<div class="container">
<h1>lichess</h1>
<p class="small">This font was created with<a href="http://fontastic.me/">Fontastic</a></p>
<h2>Character mapping</h2>
<ul class="glyphs character-mapping">
<li>
<div data-icon="a" class="icon"></div>
<input type="text" readonly="readonly" value="a">
</li>
<li>
<div data-icon="b" class="icon"></div>
<input type="text" readonly="readonly" value="b">
</li>
<li>
<div data-icon="c" class="icon"></div>
<input type="text" readonly="readonly" value="c">
</li>
<li>
<div data-icon="d" class="icon"></div>
<input type="text" readonly="readonly" value="d">
</li>
<li>
<div data-icon="e" class="icon"></div>
<input type="text" readonly="readonly" value="e">
</li>
<li>
<div data-icon="f" class="icon"></div>
<input type="text" readonly="readonly" value="f">
</li>
<li>
<div data-icon="g" class="icon"></div>
<input type="text" readonly="readonly" value="g">
</li>
<li>
<div data-icon="h" class="icon"></div>
<input type="text" readonly="readonly" value="h">
</li>
<li>
<div data-icon="j" class="icon"></div>
<input type="text" readonly="readonly" value="j">
</li>
<li>
<div data-icon="k" class="icon"></div>
<input type="text" readonly="readonly" value="k">
</li>
<li>
<div data-icon="l" class="icon"></div>
<input type="text" readonly="readonly" value="l">
</li>
<li>
<div data-icon="m" class="icon"></div>
<input type="text" readonly="readonly" value="m">
</li>
<li>
<div data-icon="p" class="icon"></div>
<input type="text" readonly="readonly" value="p">
</li>
<li>
<div data-icon="r" class="icon"></div>
<input type="text" readonly="readonly" value="r">
</li>
<li>
<div data-icon="s" class="icon"></div>
<input type="text" readonly="readonly" value="s">
</li>
<li>
<div data-icon="t" class="icon"></div>
<input type="text" readonly="readonly" value="t">
</li>
<li>
<div data-icon="u" class="icon"></div>
<input type="text" readonly="readonly" value="u">
</li>
<li>
<div data-icon="v" class="icon"></div>
<input type="text" readonly="readonly" value="v">
</li>
<li>
<div data-icon="w" class="icon"></div>
<input type="text" readonly="readonly" value="w">
</li>
<li>
<div data-icon="x" class="icon"></div>
<input type="text" readonly="readonly" value="x">
</li>
<li>
<div data-icon="z" class="icon"></div>
<input type="text" readonly="readonly" value="z">
</li>
<li>
<div data-icon="A" class="icon"></div>
<input type="text" readonly="readonly" value="A">
</li>
<li>
<div data-icon="C" class="icon"></div>
<input type="text" readonly="readonly" value="C">
</li>
<li>
<div data-icon="D" class="icon"></div>
<input type="text" readonly="readonly" value="D">
</li>
<li>
<div data-icon="E" class="icon"></div>
<input type="text" readonly="readonly" value="E">
</li>
<li>
<div data-icon="F" class="icon"></div>
<input type="text" readonly="readonly" value="F">
</li>
<li>
<div data-icon="G" class="icon"></div>
<input type="text" readonly="readonly" value="G">
</li>
<li>
<div data-icon="H" class="icon"></div>
<input type="text" readonly="readonly" value="H">
</li>
<li>
<div data-icon="I" class="icon"></div>
<input type="text" readonly="readonly" value="I">
</li>
<li>
<div data-icon="J" class="icon"></div>
<input type="text" readonly="readonly" value="J">
</li>
<li>
<div data-icon="K" class="icon"></div>
<input type="text" readonly="readonly" value="K">
</li>
<li>
<div data-icon="B" class="icon"></div>
<input type="text" readonly="readonly" value="B">
</li>
<li>
<div data-icon="M" class="icon"></div>
<input type="text" readonly="readonly" value="M">
</li>
<li>
<div data-icon="N" class="icon"></div>
<input type="text" readonly="readonly" value="N">
</li>
<li>
<div data-icon="L" class="icon"></div>
<input type="text" readonly="readonly" value="L">
</li>
<li>
<div data-icon="O" class="icon"></div>
<input type="text" readonly="readonly" value="O">
</li>
<li>
<div data-icon="O" class="icon"></div>
<input type="text" readonly="readonly" value="O">
</li>
<li>
<div data-icon="O" class="icon"></div>
<input type="text" readonly="readonly" value="O">
</li>
<li>
<div data-icon="Q" class="icon"></div>
<input type="text" readonly="readonly" value="Q">
</li>
<li>
<div data-icon="Q" class="icon"></div>
<input type="text" readonly="readonly" value="Q">
</li>
<li>
<div data-icon="Q" class="icon"></div>
<input type="text" readonly="readonly" value="Q">
</li>
<li>
<div data-icon="R" class="icon"></div>
<input type="text" readonly="readonly" value="R">
</li>
<li>
<div data-icon="S" class="icon"></div>
<input type="text" readonly="readonly" value="S">
</li>
<li>
<div data-icon="T" class="icon"></div>
<input type="text" readonly="readonly" value="T">
</li>
<li>
<div data-icon="U" class="icon"></div>
<input type="text" readonly="readonly" value="U">
</li>
<li>
<div data-icon="V" class="icon"></div>
<input type="text" readonly="readonly" value="V">
</li>
<li>
<div data-icon="W" class="icon"></div>
<input type="text" readonly="readonly" value="W">
</li>
<li>
<div data-icon="X" class="icon"></div>
<input type="text" readonly="readonly" value="X">
</li>
<li>
<div data-icon="Y" class="icon"></div>
<input type="text" readonly="readonly" value="Y">
</li>
<li>
<div data-icon="Z" class="icon"></div>
<input type="text" readonly="readonly" value="Z">
</li>
<li>
<div data-icon="!" class="icon"></div>
<input type="text" readonly="readonly" value="!">
</li>
<li>
<div data-icon="P" class="icon"></div>
<input type="text" readonly="readonly" value="P">
</li>
<li>
<div data-icon="i" class="icon"></div>
<input type="text" readonly="readonly" value="i">
</li>
<li>
<div data-icon="2" class="icon"></div>
<input type="text" readonly="readonly" value="2">
</li>
<li>
<div data-icon="3" class="icon"></div>
<input type="text" readonly="readonly" value="3">
</li>
<li>
<div data-icon="0" class="icon"></div>
<input type="text" readonly="readonly" value="0">
</li>
<li>
<div data-icon="1" class="icon"></div>
<input type="text" readonly="readonly" value="1">
</li>
<li>
<div data-icon="4" class="icon"></div>
<input type="text" readonly="readonly" value="4">
</li>
<li>
<div data-icon="5" class="icon"></div>
<input type="text" readonly="readonly" value="5">
</li>
<li>
<div data-icon="6" class="icon"></div>
<input type="text" readonly="readonly" value="6">
</li>
<li>
<div data-icon="8" class="icon"></div>
<input type="text" readonly="readonly" value="8">
</li>
<li>
<div data-icon="9" class="icon"></div>
<input type="text" readonly="readonly" value="9">
</li>
<li>
<div data-icon="&#34;" class="icon"></div>
<input type="text" readonly="readonly" value="&quot;">
</li>
<li>
<div data-icon="7" class="icon"></div>
<input type="text" readonly="readonly" value="7">
</li>
<li>
<div data-icon="#" class="icon"></div>
<input type="text" readonly="readonly" value="#">
</li>
<li>
<div data-icon="$" class="icon"></div>
<input type="text" readonly="readonly" value="$">
</li>
<li>
<div data-icon="%" class="icon"></div>
<input type="text" readonly="readonly" value="%">
</li>
<li>
<div data-icon="&" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;">
</li>
<li>
<div data-icon="n" class="icon"></div>
<input type="text" readonly="readonly" value="n">
</li>
<li>
<div data-icon="o" class="icon"></div>
<input type="text" readonly="readonly" value="o">
</li>
<li>
<div data-icon="q" class="icon"></div>
<input type="text" readonly="readonly" value="q">
</li>
</ul>
<h2>CSS mapping</h2>
<ul class="glyphs css-mapping">
<li>
<div class="icon icon-fontawesome-webfont-1"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-1">
</li>
<li>
<div class="icon icon-fontawesome-webfont-2"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-2">
</li>
<li>
<div class="icon icon-fontawesome-webfont-3"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-3">
</li>
<li>
<div class="icon icon-fontawesome-webfont-4"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-4">
</li>
<li>
<div class="icon icon-fontawesome-webfont-5"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-5">
</li>
<li>
<div class="icon icon-fontawesome-webfont-6"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-6">
</li>
<li>
<div class="icon icon-fontawesome-webfont-7"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-7">
</li>
<li>
<div class="icon icon-fontawesome-webfont-8"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-8">
</li>
<li>
<div class="icon icon-fontawesome-webfont-9"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-9">
</li>
<li>
<div class="icon icon-fontawesome-webfont-10"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-10">
</li>
<li>
<div class="icon icon-fontawesome-webfont-11"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-11">
</li>
<li>
<div class="icon icon-fontawesome-webfont-12"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-12">
</li>
<li>
<div class="icon icon-fontawesome-webfont-15"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-15">
</li>
<li>
<div class="icon icon-fontawesome-webfont-17"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-17">
</li>
<li>
<div class="icon icon-fontawesome-webfont-18"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-18">
</li>
<li>
<div class="icon icon-fontawesome-webfont-19"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-19">
</li>
<li>
<div class="icon icon-fontawesome-webfont-20"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-20">
</li>
<li>
<div class="icon icon-eye-view-1"></div>
<input type="text" readonly="readonly" value="eye-view-1">
</li>
<li>
<div class="icon icon-fontawesome-webfont-21"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-21">
</li>
<li>
<div class="icon icon-fontawesome-webfont-22"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-22">
</li>
<li>
<div class="icon icon-fontawesome-webfont-23"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-23">
</li>
<li>
<div class="icon icon-microscope"></div>
<input type="text" readonly="readonly" value="microscope">
</li>
<li>
<div class="icon icon-crown-king-1"></div>
<input type="text" readonly="readonly" value="crown-king-1">
</li>
<li>
<div class="icon icon-fontawesome-webfont-24"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-24">
</li>
<li>
<div class="icon icon-fontawesome-webfont-25"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-25">
</li>
<li>
<div class="icon icon-fontawesome-webfont-26"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-26">
</li>
<li>
<div class="icon icon-fontawesome-webfont-27"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-27">
</li>
<li>
<div class="icon icon-fontawesome-webfont-28"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-28">
</li>
<li>
<div class="icon icon-fontawesome-webfont-29"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-29">
</li>
<li>
<div class="icon icon-fontawesome-webfont-30"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-30">
</li>
<li>
<div class="icon icon-fontawesome-webfont-31"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-31">
</li>
<li>
<div class="icon icon-loop-alt2"></div>
<input type="text" readonly="readonly" value="loop-alt2">
</li>
<li>
<div class="icon icon-arrow-full-lowerright"></div>
<input type="text" readonly="readonly" value="arrow-full-lowerright">
</li>
<li>
<div class="icon icon-arrow-full-upperright"></div>
<input type="text" readonly="readonly" value="arrow-full-upperright">
</li>
<li>
<div class="icon icon-fontawesome-webfont-32"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-32">
</li>
<li>
<div class="icon icon-plus-squared"></div>
<input type="text" readonly="readonly" value="plus-squared">
</li>
<li>
<div class="icon icon-plus-circled"></div>
<input type="text" readonly="readonly" value="plus-circled">
</li>
<li>
<div class="icon icon-fontawesome-webfont-33"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-33">
</li>
<li>
<div class="icon icon-fontawesome-webfont-34"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-34">
</li>
<li>
<div class="icon icon-fire-station-24"></div>
<input type="text" readonly="readonly" value="fire-station-24">
</li>
<li>
<div class="icon icon-burning-fire"></div>
<input type="text" readonly="readonly" value="burning-fire">
</li>
<li>
<div class="icon icon-arrow-sans-down"></div>
<input type="text" readonly="readonly" value="arrow-sans-down">
</li>
<li>
<div class="icon icon-arrow-sans-up"></div>
<input type="text" readonly="readonly" value="arrow-sans-up">
</li>
<li>
<div class="icon icon-fontawesome-webfont-34"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-34">
</li>
<li>
<div class="icon icon-crossed-swords-small"></div>
<input type="text" readonly="readonly" value="crossed-swords-small">
</li>
<li>
<div class="icon icon-fontawesome-webfont-35"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-35">
</li>
<li>
<div class="icon icon-fontawesome-webfont-36"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-36">
</li>
<li>
<div class="icon icon-fontawesome-webfont-37"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-37">
</li>
<li>
<div class="icon icon-fontawesome-webfont-38"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-38">
</li>
<li>
<div class="icon icon-fontawesome-webfont-39"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-39">
</li>
<li>
<div class="icon icon-fontawesome-webfont-40"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-40">
</li>
<li>
<div class="icon icon-fontawesome-webfont-41"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-41">
</li>
<li>
<div class="icon icon-fontawesome-webfont"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont">
</li>
<li>
<div class="icon icon-hand-stop"></div>
<input type="text" readonly="readonly" value="hand-stop">
</li>
<li>
<div class="icon icon-ionicons"></div>
<input type="text" readonly="readonly" value="ionicons">
</li>
<li>
<div class="icon icon-fontawesome-webfont-42"></div>
<input type="text" readonly="readonly" value="fontawesome-webfont-42">
</li>
<li>
<div class="icon icon-television-tv"></div>
<input type="text" readonly="readonly" value="television-tv">
</li>
<li>
<div class="icon icon-moon"></div>
<input type="text" readonly="readonly" value="moon">
</li>
<li>
<div class="icon icon-sun"></div>
<input type="text" readonly="readonly" value="sun">
</li>
<li>
<div class="icon icon-ink-pen"></div>
<input type="text" readonly="readonly" value="ink-pen">
</li>
<li>
<div class="icon icon-rocket"></div>
<input type="text" readonly="readonly" value="rocket">
</li>
<li>
<div class="icon icon-chart-line"></div>
<input type="text" readonly="readonly" value="chart-line">
</li>
<li>
<div class="icon icon-link"></div>
<input type="text" readonly="readonly" value="link">
</li>
<li>
<div class="icon icon-ionicons-1"></div>
<input type="text" readonly="readonly" value="ionicons-1">
</li>
<li>
<div class="icon icon-unmute"></div>
<input type="text" readonly="readonly" value="unmute">
</li>
<li>
<div class="icon icon-mute"></div>
<input type="text" readonly="readonly" value="mute">
</li>
<li>
<div class="icon icon-gear"></div>
<input type="text" readonly="readonly" value="gear">
</li>
<li>
<div class="icon icon-repo"></div>
<input type="text" readonly="readonly" value="repo">
</li>
<li>
<div class="icon icon-law"></div>
<input type="text" readonly="readonly" value="law">
</li>
<li>
<div class="icon icon-tag"></div>
<input type="text" readonly="readonly" value="tag">
</li>
<li>
<div class="icon icon-trash-bin"></div>
<input type="text" readonly="readonly" value="trash-bin">
</li>
</ul>
</div><script type="text/javascript">
(function() {
var glyphs, _i, _len, _ref;
_ref = document.getElementsByClassName('glyphs');
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
glyphs = _ref[_i];
glyphs.addEventListener('click', function(event) {
if (event.target.tagName === 'INPUT') {
return event.target.select();
}
});
}
}).call(this);
</script>
</body>
</html>

View File

@ -0,0 +1,253 @@
@charset "UTF-8";
@font-face {
font-family: "lichess";
src:url("fonts/lichess.eot");
src:url("fonts/lichess.eot?#iefix") format("embedded-opentype"),
url("fonts/lichess.woff") format("woff"),
url("fonts/lichess.ttf") format("truetype"),
url("fonts/lichess.svg#lichess") format("svg");
font-weight: normal;
font-style: normal;
}
[data-icon]:before {
font-family: "lichess" !important;
content: attr(data-icon);
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
[class^="icon-"]:before,
[class*=" icon-"]:before {
font-family: "lichess" !important;
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-fontawesome-webfont-1:before {
content: "a";
}
.icon-fontawesome-webfont-2:before {
content: "b";
}
.icon-fontawesome-webfont-3:before {
content: "c";
}
.icon-fontawesome-webfont-4:before {
content: "d";
}
.icon-fontawesome-webfont-5:before {
content: "e";
}
.icon-fontawesome-webfont-6:before {
content: "f";
}
.icon-fontawesome-webfont-7:before {
content: "g";
}
.icon-fontawesome-webfont-8:before {
content: "h";
}
.icon-fontawesome-webfont-9:before {
content: "j";
}
.icon-fontawesome-webfont-10:before {
content: "k";
}
.icon-fontawesome-webfont-11:before {
content: "l";
}
.icon-fontawesome-webfont-12:before {
content: "m";
}
.icon-fontawesome-webfont-15:before {
content: "p";
}
.icon-fontawesome-webfont-17:before {
content: "r";
}
.icon-fontawesome-webfont-18:before {
content: "s";
}
.icon-fontawesome-webfont-19:before {
content: "t";
}
.icon-fontawesome-webfont-20:before {
content: "u";
}
.icon-eye-view-1:before {
content: "v";
}
.icon-fontawesome-webfont-21:before {
content: "w";
}
.icon-fontawesome-webfont-22:before {
content: "x";
}
.icon-fontawesome-webfont-23:before {
content: "z";
}
.icon-microscope:before {
content: "A";
}
.icon-crown-king-1:before {
content: "C";
}
.icon-fontawesome-webfont-24:before {
content: "D";
}
.icon-fontawesome-webfont-25:before {
content: "E";
}
.icon-fontawesome-webfont-26:before {
content: "F";
}
.icon-fontawesome-webfont-27:before {
content: "G";
}
.icon-fontawesome-webfont-28:before {
content: "H";
}
.icon-fontawesome-webfont-29:before {
content: "I";
}
.icon-fontawesome-webfont-30:before {
content: "J";
}
.icon-fontawesome-webfont-31:before {
content: "K";
}
.icon-loop-alt2:before {
content: "B";
}
.icon-arrow-full-lowerright:before {
content: "M";
}
.icon-arrow-full-upperright:before {
content: "N";
}
.icon-fontawesome-webfont-32:before {
content: "L";
}
.icon-plus-squared:before {
content: "O";
}
.icon-plus-circled:before {
content: "O";
}
.icon-fontawesome-webfont-33:before {
content: "O";
}
.icon-fontawesome-webfont-34:before {
content: "Q";
}
.icon-fire-station-24:before {
content: "Q";
}
.icon-burning-fire:before {
content: "Q";
}
.icon-arrow-sans-down:before {
content: "R";
}
.icon-arrow-sans-up:before {
content: "S";
}
.icon-fontawesome-webfont-34:before {
content: "T";
}
.icon-crossed-swords-small:before {
content: "U";
}
.icon-fontawesome-webfont-35:before {
content: "V";
}
.icon-fontawesome-webfont-36:before {
content: "W";
}
.icon-fontawesome-webfont-37:before {
content: "X";
}
.icon-fontawesome-webfont-38:before {
content: "Y";
}
.icon-fontawesome-webfont-39:before {
content: "Z";
}
.icon-fontawesome-webfont-40:before {
content: "!";
}
.icon-fontawesome-webfont-41:before {
content: "P";
}
.icon-fontawesome-webfont:before {
content: "i";
}
.icon-hand-stop:before {
content: "2";
}
.icon-ionicons:before {
content: "3";
}
.icon-fontawesome-webfont-42:before {
content: "0";
}
.icon-television-tv:before {
content: "1";
}
.icon-moon:before {
content: "4";
}
.icon-sun:before {
content: "5";
}
.icon-ink-pen:before {
content: "6";
}
.icon-rocket:before {
content: "8";
}
.icon-chart-line:before {
content: "9";
}
.icon-link:before {
content: "\"";
}
.icon-ionicons-1:before {
content: "7";
}
.icon-unmute:before {
content: "#";
}
.icon-mute:before {
content: "$";
}
.icon-gear:before {
content: "%";
}
.icon-repo:before {
content: "&";
}
.icon-law:before {
content: "n";
}
.icon-tag:before {
content: "o";
}
.icon-trash-bin:before {
content: "q";
}

View File

@ -2929,6 +2929,14 @@ var storage = {
}));
});
/////////////// forum.js ////////////////////
$('#lichess_forum').on('click', 'a.delete', function() {
$.post($(this).attr("href"));
$(this).closest(".post").slideUp(100);
return false;
});
$.fn.sortable = function(sortFns) {
return this.each(function() {
var $table = $(this);

View File

@ -1,11 +0,0 @@
$(function() {
$("#lichess_forum a.delete").unbind("click").click(function() {
if (confirm("Delete?")) {
var $this = $(this)
$.post($this.attr("href"), function(d) {
$this.closest(".post").slideUp(500);
});
}
return false;
});
});

View File

@ -0,0 +1,50 @@
$(function() {
var $qa = $('#qa');
$qa.find('form.question').each(function() {
var $form = $(this);
$form.find('input.tm-input').each(function() {
var $input = $(this);
var tagApi;
tagApi = $input.tagsManager({
prefilled: $input.data('prefill'),
backspace: [],
delimiters: [13, 44],
tagsContainer: $form.find('.tags')
});
var tagSource = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: $.map($input.data('tags').split(','), function(t) {
return {
value: t
};
})
});
tagSource.initialize();
$input.typeahead({
minLength: 1,
highlight: true
}, {
source: tagSource.ttAdapter(),
name: 'tags',
displayKey: 'value',
limit: 15
}).on('typeahead:selected', function(e, d) {
tagApi.tagsManager("pushTag", d.value);
$input.val('');
});
});
});
$qa.on('click', '.your-comment .toggle', function() {
var $form = $(this).siblings('form');
$form.toggle(200, function() {
if ($form.is(':visible')) $form.find('textarea').focus();
});
});
$qa.find('.your-comment form').submit(function() {
if ($(this).find('textarea').val().length < 20) {
alert("Comment must be longer than 20 characters");
return false;
}
});
});

View File

@ -70,8 +70,8 @@ time {
}
@font-face {
font-family: "lichess";
src: url("../font14/fonts/lichess.eot");
src: url("../font14/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font14/fonts/lichess.woff") format("woff"), url("../font14/fonts/lichess.ttf") format("truetype"), url("../font14/fonts/lichess.svg#lichess") format("svg");
src: url("../font15/fonts/lichess.eot");
src: url("../font15/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font15/fonts/lichess.woff") format("woff"), url("../font15/fonts/lichess.ttf") format("truetype"), url("../font15/fonts/lichess.svg#lichess") format("svg");
font-weight: normal;
font-style: normal;
}

View File

@ -1,17 +1,16 @@
.metas .delete,
.metas .postip {
div.post .metas .mod {
margin-left: 1em;
font-size: 0.9em;
visibility: hidden;
}
.forum_topics_list .delete {
margin-right: 1em;
div.post:hover .metas .mod {
visibility: visible;
}
ol.crumbs {
padding: 20px 24px 0 24px;
}
ol.crumbs li {
display: inline;
margin-left: 1em;

View File

@ -0,0 +1,145 @@
#qa form.wide {
font-size: 1.2em;
}
#qa form.wide input.title {
width: 500px;
padding: 5px 10px;
margin-top: 20px;
}
#qa form.wide textarea {
width: 500px;
height: 150px;
padding: 5px 10px;
margin-top: 20px;
}
#qa form.wide .tags_wrap {
margin-top: 20px;
}
#qa form.wide .tags_wrap input {
display: block;
}
#qa form.wide .submit {
margin-top: 20px;
}
#qa form.wide p.error {
margin-left: 110px;
margin-bottom: 10px;
color: red;
}
#qa form.mod {
display: inline;
}
#qa table.meta {
margin-top: 20px;
}
#qa table.meta th {
width: 80px;
font-weight: bold;
padding: 2px 0;
}
#qa .tag {
white-space: nowrap;
text-decoration: none;
font-weight: bold;
}
#qa .tag:hover {
text-decoration: underline;
}
#qa .question h1 a {
display: inline-block;
width: 80px;
text-decoration: none;
}
#qa .question > .body {
font-size: 1.2em;
margin: 40px 0 40px 80px;
}
#qa .comments {
margin: 0 0 20px 80px;
border-top: 1px dotted #ccc;
}
#qa .comments .comment {
border-bottom: 1px dotted #ccc;
padding: 10px 0;
}
#qa .question .your-comment {
margin-top: 10px;
}
#qa .question .your-comment form {
/* display: none; */
}
#qa .comment .mod {
visibility: hidden;
}
#qa .question .your-comment textarea {
width: 500px;
height: 50px;
margin-bottom: 10px;
padding: 5px 10px;
display: block;
}
#qa .comment:hover .mod {
visibility: visible;
}
#qa .answers-header {
margin: 40px 0 0 80px;
font-size: 1.4em;
}
#qa .your-answer {
margin: 0 0 0 80px;
}
.tt-hint {
display: none;
}
.tt-dropdown-menu {
width: 422px;
margin-top: 12px;
padding: 8px 0;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
}
.tt-suggestion {
padding: 3px 20px;
font-size: 18px;
line-height: 24px;
}
.tt-suggestion.tt-cursor {
color: #fff;
background-color: #0097cf;
}
.tt-suggestion p {
margin: 0;
}
.tm-tag {
background-color: #f5f5f5;
border: #bbbbbb 1px solid;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
display: inline-block;
border-radius: 3px;
margin: 0 5px 5px 0;
padding: 7px;
text-decoration: none;
transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s;
-moz-transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s;
-webkit-transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s;
vertical-align: middle;
}
.tm-tag .tm-tag-remove {
color: #000000;
font-weight: bold;
margin-left: 4px;
opacity: 0.2;
text-decoration: none;
}
.tm-tag .tm-tag-remove:hover {
color: #000000;
text-decoration: none;
opacity: 0.4;
}

1
public/vendor/tagmanager vendored 160000

@ -0,0 +1 @@
Subproject commit be5d4100ec3ff755bb380452a8824d56d7a517c9

File diff suppressed because one or more lines are too long