first commit
This commit is contained in:
commit
91f70ed69c
|
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
die();
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
require_once '../config/config.php';
|
||||
require_login();
|
||||
|
||||
// Проверяем права администратора (простая проверка - первый пользователь считается администратором)
|
||||
if ($_SESSION['user_id'] != 1) {
|
||||
$_SESSION['error'] = "У вас нет доступа к этой странице";
|
||||
redirect('../dashboard.php');
|
||||
}
|
||||
|
||||
$userModel = new User($pdo);
|
||||
$users = $userModel->findAll();
|
||||
|
||||
// Обработка действий
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$_SESSION['error'] = "Ошибка безопасности";
|
||||
} else {
|
||||
$action = $_POST['action'] ?? '';
|
||||
$user_id = $_POST['user_id'] ?? null;
|
||||
|
||||
if ($user_id && $user_id != $_SESSION['user_id']) { // Нельзя изменять себя
|
||||
switch ($action) {
|
||||
case 'toggle_active':
|
||||
$user = $userModel->findById($user_id);
|
||||
if ($user) {
|
||||
$new_status = $user['is_active'] ? 0 : 1;
|
||||
if ($userModel->updateStatus($user_id, $new_status)) {
|
||||
$_SESSION['success'] = 'Статус пользователя обновлен';
|
||||
} else {
|
||||
$_SESSION['error'] = 'Ошибка при обновлении статуса';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if ($userModel->delete($user_id)) {
|
||||
$_SESSION['success'] = 'Пользователь удален';
|
||||
} else {
|
||||
$_SESSION['error'] = 'Ошибка при удалении пользователя';
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$_SESSION['error'] = 'Нельзя изменить собственный аккаунт';
|
||||
}
|
||||
|
||||
redirect('users.php');
|
||||
}
|
||||
}
|
||||
|
||||
$page_title = "Управление пользователями";
|
||||
include '../views/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1>Управление пользователями</h1>
|
||||
|
||||
<?php if (isset($_SESSION['success'])): ?>
|
||||
<div class="alert alert-success">
|
||||
<?= e($_SESSION['success']) ?>
|
||||
<?php unset($_SESSION['success']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION['error'])): ?>
|
||||
<div class="alert alert-error">
|
||||
<?= e($_SESSION['error']) ?>
|
||||
<?php unset($_SESSION['error']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
|
||||
<h2 style="margin: 0;">Всего пользователей: <?= count($users) ?></h2>
|
||||
<a href="../register.php" role="button">➕ Добавить пользователя</a>
|
||||
</div>
|
||||
|
||||
<?php if (empty($users)): ?>
|
||||
<article style="text-align: center; padding: 2rem;">
|
||||
<h3>Пользователи не найдены</h3>
|
||||
<p>Зарегистрируйте первого пользователя</p>
|
||||
<a href="../register.php" role="button">📝 Добавить пользователя</a>
|
||||
</article>
|
||||
<?php else: ?>
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="compact-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">ID</th>
|
||||
<th style="width: 15%;">Имя пользователя</th>
|
||||
<th style="width: 20%;">Отображаемое имя</th>
|
||||
<th style="width: 20%;">Email</th>
|
||||
<th style="width: 15%;">Дата регистрации</th>
|
||||
<th style="width: 10%;">Статус</th>
|
||||
<th style="width: 15%;">Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($users as $user): ?>
|
||||
<tr>
|
||||
<td><?= $user['id'] ?></td>
|
||||
<td>
|
||||
<strong><?= e($user['username']) ?></strong>
|
||||
<?php if ($user['id'] == $_SESSION['user_id']): ?>
|
||||
<br><small style="color: #666;">(Вы)</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= e($user['display_name']) ?></td>
|
||||
<td><?= e($user['email']) ?></td>
|
||||
<td>
|
||||
<small><?= date('d.m.Y H:i', strtotime($user['created_at'])) ?></small>
|
||||
<?php if ($user['last_login']): ?>
|
||||
<br><small style="color: #666;">Вход: <?= date('d.m.Y H:i', strtotime($user['last_login'])) ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span style="color: <?= $user['is_active'] ? 'green' : 'red' ?>">
|
||||
<?= $user['is_active'] ? '✅ Активен' : '❌ Неактивен' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
||||
<div style="display: flex; gap: 3px; flex-wrap: wrap;">
|
||||
<form method="post" style="display: inline;">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<input type="hidden" name="user_id" value="<?= $user['id'] ?>">
|
||||
<input type="hidden" name="action" value="toggle_active">
|
||||
<button type="submit" class="compact-button secondary" title="<?= $user['is_active'] ? 'Деактивировать' : 'Активировать' ?>">
|
||||
<?= $user['is_active'] ? '⏸️' : '▶️' ?>
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" style="display: inline;" onsubmit="return confirm('Вы уверены, что хотите удалить пользователя «<?= e($user['username']) ?>»? Все его книги и главы также будут удалены.');">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<input type="hidden" name="user_id" value="<?= $user['id'] ?>">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<button type="submit" class="compact-button secondary" style="background: #ff4444; border-color: #ff4444; color: white;" title="Удалить">
|
||||
🗑️
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<small style="color: #666;">Текущий пользователь</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php include '../views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,594 @@
|
|||
/*
|
||||
* Foundation Icons v 3.0
|
||||
* Made by ZURB 2013 http://zurb.com/playground/foundation-icon-fonts-3
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
@font-face {
|
||||
font-family: "foundation-icons";
|
||||
src: url("foundation-icons.eot");
|
||||
src: url("foundation-icons.eot?#iefix") format("embedded-opentype"),
|
||||
url("foundation-icons.woff") format("woff"),
|
||||
url("foundation-icons.ttf") format("truetype"),
|
||||
url("foundation-icons.svg#fontcustom") format("svg");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.fi-address-book:before,
|
||||
.fi-alert:before,
|
||||
.fi-align-center:before,
|
||||
.fi-align-justify:before,
|
||||
.fi-align-left:before,
|
||||
.fi-align-right:before,
|
||||
.fi-anchor:before,
|
||||
.fi-annotate:before,
|
||||
.fi-archive:before,
|
||||
.fi-arrow-down:before,
|
||||
.fi-arrow-left:before,
|
||||
.fi-arrow-right:before,
|
||||
.fi-arrow-up:before,
|
||||
.fi-arrows-compress:before,
|
||||
.fi-arrows-expand:before,
|
||||
.fi-arrows-in:before,
|
||||
.fi-arrows-out:before,
|
||||
.fi-asl:before,
|
||||
.fi-asterisk:before,
|
||||
.fi-at-sign:before,
|
||||
.fi-background-color:before,
|
||||
.fi-battery-empty:before,
|
||||
.fi-battery-full:before,
|
||||
.fi-battery-half:before,
|
||||
.fi-bitcoin-circle:before,
|
||||
.fi-bitcoin:before,
|
||||
.fi-blind:before,
|
||||
.fi-bluetooth:before,
|
||||
.fi-bold:before,
|
||||
.fi-book-bookmark:before,
|
||||
.fi-book:before,
|
||||
.fi-bookmark:before,
|
||||
.fi-braille:before,
|
||||
.fi-burst-new:before,
|
||||
.fi-burst-sale:before,
|
||||
.fi-burst:before,
|
||||
.fi-calendar:before,
|
||||
.fi-camera:before,
|
||||
.fi-check:before,
|
||||
.fi-checkbox:before,
|
||||
.fi-clipboard-notes:before,
|
||||
.fi-clipboard-pencil:before,
|
||||
.fi-clipboard:before,
|
||||
.fi-clock:before,
|
||||
.fi-closed-caption:before,
|
||||
.fi-cloud:before,
|
||||
.fi-comment-minus:before,
|
||||
.fi-comment-quotes:before,
|
||||
.fi-comment-video:before,
|
||||
.fi-comment:before,
|
||||
.fi-comments:before,
|
||||
.fi-compass:before,
|
||||
.fi-contrast:before,
|
||||
.fi-credit-card:before,
|
||||
.fi-crop:before,
|
||||
.fi-crown:before,
|
||||
.fi-css3:before,
|
||||
.fi-database:before,
|
||||
.fi-die-five:before,
|
||||
.fi-die-four:before,
|
||||
.fi-die-one:before,
|
||||
.fi-die-six:before,
|
||||
.fi-die-three:before,
|
||||
.fi-die-two:before,
|
||||
.fi-dislike:before,
|
||||
.fi-dollar-bill:before,
|
||||
.fi-dollar:before,
|
||||
.fi-download:before,
|
||||
.fi-eject:before,
|
||||
.fi-elevator:before,
|
||||
.fi-euro:before,
|
||||
.fi-eye:before,
|
||||
.fi-fast-forward:before,
|
||||
.fi-female-symbol:before,
|
||||
.fi-female:before,
|
||||
.fi-filter:before,
|
||||
.fi-first-aid:before,
|
||||
.fi-flag:before,
|
||||
.fi-folder-add:before,
|
||||
.fi-folder-lock:before,
|
||||
.fi-folder:before,
|
||||
.fi-foot:before,
|
||||
.fi-foundation:before,
|
||||
.fi-graph-bar:before,
|
||||
.fi-graph-horizontal:before,
|
||||
.fi-graph-pie:before,
|
||||
.fi-graph-trend:before,
|
||||
.fi-guide-dog:before,
|
||||
.fi-hearing-aid:before,
|
||||
.fi-heart:before,
|
||||
.fi-home:before,
|
||||
.fi-html5:before,
|
||||
.fi-indent-less:before,
|
||||
.fi-indent-more:before,
|
||||
.fi-info:before,
|
||||
.fi-italic:before,
|
||||
.fi-key:before,
|
||||
.fi-laptop:before,
|
||||
.fi-layout:before,
|
||||
.fi-lightbulb:before,
|
||||
.fi-like:before,
|
||||
.fi-link:before,
|
||||
.fi-list-bullet:before,
|
||||
.fi-list-number:before,
|
||||
.fi-list-thumbnails:before,
|
||||
.fi-list:before,
|
||||
.fi-lock:before,
|
||||
.fi-loop:before,
|
||||
.fi-magnifying-glass:before,
|
||||
.fi-mail:before,
|
||||
.fi-male-female:before,
|
||||
.fi-male-symbol:before,
|
||||
.fi-male:before,
|
||||
.fi-map:before,
|
||||
.fi-marker:before,
|
||||
.fi-megaphone:before,
|
||||
.fi-microphone:before,
|
||||
.fi-minus-circle:before,
|
||||
.fi-minus:before,
|
||||
.fi-mobile-signal:before,
|
||||
.fi-mobile:before,
|
||||
.fi-monitor:before,
|
||||
.fi-mountains:before,
|
||||
.fi-music:before,
|
||||
.fi-next:before,
|
||||
.fi-no-dogs:before,
|
||||
.fi-no-smoking:before,
|
||||
.fi-page-add:before,
|
||||
.fi-page-copy:before,
|
||||
.fi-page-csv:before,
|
||||
.fi-page-delete:before,
|
||||
.fi-page-doc:before,
|
||||
.fi-page-edit:before,
|
||||
.fi-page-export-csv:before,
|
||||
.fi-page-export-doc:before,
|
||||
.fi-page-export-pdf:before,
|
||||
.fi-page-export:before,
|
||||
.fi-page-filled:before,
|
||||
.fi-page-multiple:before,
|
||||
.fi-page-pdf:before,
|
||||
.fi-page-remove:before,
|
||||
.fi-page-search:before,
|
||||
.fi-page:before,
|
||||
.fi-paint-bucket:before,
|
||||
.fi-paperclip:before,
|
||||
.fi-pause:before,
|
||||
.fi-paw:before,
|
||||
.fi-paypal:before,
|
||||
.fi-pencil:before,
|
||||
.fi-photo:before,
|
||||
.fi-play-circle:before,
|
||||
.fi-play-video:before,
|
||||
.fi-play:before,
|
||||
.fi-plus:before,
|
||||
.fi-pound:before,
|
||||
.fi-power:before,
|
||||
.fi-previous:before,
|
||||
.fi-price-tag:before,
|
||||
.fi-pricetag-multiple:before,
|
||||
.fi-print:before,
|
||||
.fi-prohibited:before,
|
||||
.fi-projection-screen:before,
|
||||
.fi-puzzle:before,
|
||||
.fi-quote:before,
|
||||
.fi-record:before,
|
||||
.fi-refresh:before,
|
||||
.fi-results-demographics:before,
|
||||
.fi-results:before,
|
||||
.fi-rewind-ten:before,
|
||||
.fi-rewind:before,
|
||||
.fi-rss:before,
|
||||
.fi-safety-cone:before,
|
||||
.fi-save:before,
|
||||
.fi-share:before,
|
||||
.fi-sheriff-badge:before,
|
||||
.fi-shield:before,
|
||||
.fi-shopping-bag:before,
|
||||
.fi-shopping-cart:before,
|
||||
.fi-shuffle:before,
|
||||
.fi-skull:before,
|
||||
.fi-social-500px:before,
|
||||
.fi-social-adobe:before,
|
||||
.fi-social-amazon:before,
|
||||
.fi-social-android:before,
|
||||
.fi-social-apple:before,
|
||||
.fi-social-behance:before,
|
||||
.fi-social-bing:before,
|
||||
.fi-social-blogger:before,
|
||||
.fi-social-delicious:before,
|
||||
.fi-social-designer-news:before,
|
||||
.fi-social-deviant-art:before,
|
||||
.fi-social-digg:before,
|
||||
.fi-social-dribbble:before,
|
||||
.fi-social-drive:before,
|
||||
.fi-social-dropbox:before,
|
||||
.fi-social-evernote:before,
|
||||
.fi-social-facebook:before,
|
||||
.fi-social-flickr:before,
|
||||
.fi-social-forrst:before,
|
||||
.fi-social-foursquare:before,
|
||||
.fi-social-game-center:before,
|
||||
.fi-social-github:before,
|
||||
.fi-social-google-plus:before,
|
||||
.fi-social-hacker-news:before,
|
||||
.fi-social-hi5:before,
|
||||
.fi-social-instagram:before,
|
||||
.fi-social-joomla:before,
|
||||
.fi-social-lastfm:before,
|
||||
.fi-social-linkedin:before,
|
||||
.fi-social-medium:before,
|
||||
.fi-social-myspace:before,
|
||||
.fi-social-orkut:before,
|
||||
.fi-social-path:before,
|
||||
.fi-social-picasa:before,
|
||||
.fi-social-pinterest:before,
|
||||
.fi-social-rdio:before,
|
||||
.fi-social-reddit:before,
|
||||
.fi-social-skillshare:before,
|
||||
.fi-social-skype:before,
|
||||
.fi-social-smashing-mag:before,
|
||||
.fi-social-snapchat:before,
|
||||
.fi-social-spotify:before,
|
||||
.fi-social-squidoo:before,
|
||||
.fi-social-stack-overflow:before,
|
||||
.fi-social-steam:before,
|
||||
.fi-social-stumbleupon:before,
|
||||
.fi-social-treehouse:before,
|
||||
.fi-social-tumblr:before,
|
||||
.fi-social-twitter:before,
|
||||
.fi-social-vimeo:before,
|
||||
.fi-social-windows:before,
|
||||
.fi-social-xbox:before,
|
||||
.fi-social-yahoo:before,
|
||||
.fi-social-yelp:before,
|
||||
.fi-social-youtube:before,
|
||||
.fi-social-zerply:before,
|
||||
.fi-social-zurb:before,
|
||||
.fi-sound:before,
|
||||
.fi-star:before,
|
||||
.fi-stop:before,
|
||||
.fi-strikethrough:before,
|
||||
.fi-subscript:before,
|
||||
.fi-superscript:before,
|
||||
.fi-tablet-landscape:before,
|
||||
.fi-tablet-portrait:before,
|
||||
.fi-target-two:before,
|
||||
.fi-target:before,
|
||||
.fi-telephone-accessible:before,
|
||||
.fi-telephone:before,
|
||||
.fi-text-color:before,
|
||||
.fi-thumbnails:before,
|
||||
.fi-ticket:before,
|
||||
.fi-torso-business:before,
|
||||
.fi-torso-female:before,
|
||||
.fi-torso:before,
|
||||
.fi-torsos-all-female:before,
|
||||
.fi-torsos-all:before,
|
||||
.fi-torsos-female-male:before,
|
||||
.fi-torsos-male-female:before,
|
||||
.fi-torsos:before,
|
||||
.fi-trash:before,
|
||||
.fi-trees:before,
|
||||
.fi-trophy:before,
|
||||
.fi-underline:before,
|
||||
.fi-universal-access:before,
|
||||
.fi-unlink:before,
|
||||
.fi-unlock:before,
|
||||
.fi-upload-cloud:before,
|
||||
.fi-upload:before,
|
||||
.fi-usb:before,
|
||||
.fi-video:before,
|
||||
.fi-volume-none:before,
|
||||
.fi-volume-strike:before,
|
||||
.fi-volume:before,
|
||||
.fi-web:before,
|
||||
.fi-wheelchair:before,
|
||||
.fi-widget:before,
|
||||
.fi-wrench:before,
|
||||
.fi-x-circle:before,
|
||||
.fi-x:before,
|
||||
.fi-yen:before,
|
||||
.fi-zoom-in:before,
|
||||
.fi-zoom-out:before {
|
||||
font-family: "foundation-icons";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.fi-address-book:before { content: "\f100"; }
|
||||
.fi-alert:before { content: "\f101"; }
|
||||
.fi-align-center:before { content: "\f102"; }
|
||||
.fi-align-justify:before { content: "\f103"; }
|
||||
.fi-align-left:before { content: "\f104"; }
|
||||
.fi-align-right:before { content: "\f105"; }
|
||||
.fi-anchor:before { content: "\f106"; }
|
||||
.fi-annotate:before { content: "\f107"; }
|
||||
.fi-archive:before { content: "\f108"; }
|
||||
.fi-arrow-down:before { content: "\f109"; }
|
||||
.fi-arrow-left:before { content: "\f10a"; }
|
||||
.fi-arrow-right:before { content: "\f10b"; }
|
||||
.fi-arrow-up:before { content: "\f10c"; }
|
||||
.fi-arrows-compress:before { content: "\f10d"; }
|
||||
.fi-arrows-expand:before { content: "\f10e"; }
|
||||
.fi-arrows-in:before { content: "\f10f"; }
|
||||
.fi-arrows-out:before { content: "\f110"; }
|
||||
.fi-asl:before { content: "\f111"; }
|
||||
.fi-asterisk:before { content: "\f112"; }
|
||||
.fi-at-sign:before { content: "\f113"; }
|
||||
.fi-background-color:before { content: "\f114"; }
|
||||
.fi-battery-empty:before { content: "\f115"; }
|
||||
.fi-battery-full:before { content: "\f116"; }
|
||||
.fi-battery-half:before { content: "\f117"; }
|
||||
.fi-bitcoin-circle:before { content: "\f118"; }
|
||||
.fi-bitcoin:before { content: "\f119"; }
|
||||
.fi-blind:before { content: "\f11a"; }
|
||||
.fi-bluetooth:before { content: "\f11b"; }
|
||||
.fi-bold:before { content: "\f11c"; }
|
||||
.fi-book-bookmark:before { content: "\f11d"; }
|
||||
.fi-book:before { content: "\f11e"; }
|
||||
.fi-bookmark:before { content: "\f11f"; }
|
||||
.fi-braille:before { content: "\f120"; }
|
||||
.fi-burst-new:before { content: "\f121"; }
|
||||
.fi-burst-sale:before { content: "\f122"; }
|
||||
.fi-burst:before { content: "\f123"; }
|
||||
.fi-calendar:before { content: "\f124"; }
|
||||
.fi-camera:before { content: "\f125"; }
|
||||
.fi-check:before { content: "\f126"; }
|
||||
.fi-checkbox:before { content: "\f127"; }
|
||||
.fi-clipboard-notes:before { content: "\f128"; }
|
||||
.fi-clipboard-pencil:before { content: "\f129"; }
|
||||
.fi-clipboard:before { content: "\f12a"; }
|
||||
.fi-clock:before { content: "\f12b"; }
|
||||
.fi-closed-caption:before { content: "\f12c"; }
|
||||
.fi-cloud:before { content: "\f12d"; }
|
||||
.fi-comment-minus:before { content: "\f12e"; }
|
||||
.fi-comment-quotes:before { content: "\f12f"; }
|
||||
.fi-comment-video:before { content: "\f130"; }
|
||||
.fi-comment:before { content: "\f131"; }
|
||||
.fi-comments:before { content: "\f132"; }
|
||||
.fi-compass:before { content: "\f133"; }
|
||||
.fi-contrast:before { content: "\f134"; }
|
||||
.fi-credit-card:before { content: "\f135"; }
|
||||
.fi-crop:before { content: "\f136"; }
|
||||
.fi-crown:before { content: "\f137"; }
|
||||
.fi-css3:before { content: "\f138"; }
|
||||
.fi-database:before { content: "\f139"; }
|
||||
.fi-die-five:before { content: "\f13a"; }
|
||||
.fi-die-four:before { content: "\f13b"; }
|
||||
.fi-die-one:before { content: "\f13c"; }
|
||||
.fi-die-six:before { content: "\f13d"; }
|
||||
.fi-die-three:before { content: "\f13e"; }
|
||||
.fi-die-two:before { content: "\f13f"; }
|
||||
.fi-dislike:before { content: "\f140"; }
|
||||
.fi-dollar-bill:before { content: "\f141"; }
|
||||
.fi-dollar:before { content: "\f142"; }
|
||||
.fi-download:before { content: "\f143"; }
|
||||
.fi-eject:before { content: "\f144"; }
|
||||
.fi-elevator:before { content: "\f145"; }
|
||||
.fi-euro:before { content: "\f146"; }
|
||||
.fi-eye:before { content: "\f147"; }
|
||||
.fi-fast-forward:before { content: "\f148"; }
|
||||
.fi-female-symbol:before { content: "\f149"; }
|
||||
.fi-female:before { content: "\f14a"; }
|
||||
.fi-filter:before { content: "\f14b"; }
|
||||
.fi-first-aid:before { content: "\f14c"; }
|
||||
.fi-flag:before { content: "\f14d"; }
|
||||
.fi-folder-add:before { content: "\f14e"; }
|
||||
.fi-folder-lock:before { content: "\f14f"; }
|
||||
.fi-folder:before { content: "\f150"; }
|
||||
.fi-foot:before { content: "\f151"; }
|
||||
.fi-foundation:before { content: "\f152"; }
|
||||
.fi-graph-bar:before { content: "\f153"; }
|
||||
.fi-graph-horizontal:before { content: "\f154"; }
|
||||
.fi-graph-pie:before { content: "\f155"; }
|
||||
.fi-graph-trend:before { content: "\f156"; }
|
||||
.fi-guide-dog:before { content: "\f157"; }
|
||||
.fi-hearing-aid:before { content: "\f158"; }
|
||||
.fi-heart:before { content: "\f159"; }
|
||||
.fi-home:before { content: "\f15a"; }
|
||||
.fi-html5:before { content: "\f15b"; }
|
||||
.fi-indent-less:before { content: "\f15c"; }
|
||||
.fi-indent-more:before { content: "\f15d"; }
|
||||
.fi-info:before { content: "\f15e"; }
|
||||
.fi-italic:before { content: "\f15f"; }
|
||||
.fi-key:before { content: "\f160"; }
|
||||
.fi-laptop:before { content: "\f161"; }
|
||||
.fi-layout:before { content: "\f162"; }
|
||||
.fi-lightbulb:before { content: "\f163"; }
|
||||
.fi-like:before { content: "\f164"; }
|
||||
.fi-link:before { content: "\f165"; }
|
||||
.fi-list-bullet:before { content: "\f166"; }
|
||||
.fi-list-number:before { content: "\f167"; }
|
||||
.fi-list-thumbnails:before { content: "\f168"; }
|
||||
.fi-list:before { content: "\f169"; }
|
||||
.fi-lock:before { content: "\f16a"; }
|
||||
.fi-loop:before { content: "\f16b"; }
|
||||
.fi-magnifying-glass:before { content: "\f16c"; }
|
||||
.fi-mail:before { content: "\f16d"; }
|
||||
.fi-male-female:before { content: "\f16e"; }
|
||||
.fi-male-symbol:before { content: "\f16f"; }
|
||||
.fi-male:before { content: "\f170"; }
|
||||
.fi-map:before { content: "\f171"; }
|
||||
.fi-marker:before { content: "\f172"; }
|
||||
.fi-megaphone:before { content: "\f173"; }
|
||||
.fi-microphone:before { content: "\f174"; }
|
||||
.fi-minus-circle:before { content: "\f175"; }
|
||||
.fi-minus:before { content: "\f176"; }
|
||||
.fi-mobile-signal:before { content: "\f177"; }
|
||||
.fi-mobile:before { content: "\f178"; }
|
||||
.fi-monitor:before { content: "\f179"; }
|
||||
.fi-mountains:before { content: "\f17a"; }
|
||||
.fi-music:before { content: "\f17b"; }
|
||||
.fi-next:before { content: "\f17c"; }
|
||||
.fi-no-dogs:before { content: "\f17d"; }
|
||||
.fi-no-smoking:before { content: "\f17e"; }
|
||||
.fi-page-add:before { content: "\f17f"; }
|
||||
.fi-page-copy:before { content: "\f180"; }
|
||||
.fi-page-csv:before { content: "\f181"; }
|
||||
.fi-page-delete:before { content: "\f182"; }
|
||||
.fi-page-doc:before { content: "\f183"; }
|
||||
.fi-page-edit:before { content: "\f184"; }
|
||||
.fi-page-export-csv:before { content: "\f185"; }
|
||||
.fi-page-export-doc:before { content: "\f186"; }
|
||||
.fi-page-export-pdf:before { content: "\f187"; }
|
||||
.fi-page-export:before { content: "\f188"; }
|
||||
.fi-page-filled:before { content: "\f189"; }
|
||||
.fi-page-multiple:before { content: "\f18a"; }
|
||||
.fi-page-pdf:before { content: "\f18b"; }
|
||||
.fi-page-remove:before { content: "\f18c"; }
|
||||
.fi-page-search:before { content: "\f18d"; }
|
||||
.fi-page:before { content: "\f18e"; }
|
||||
.fi-paint-bucket:before { content: "\f18f"; }
|
||||
.fi-paperclip:before { content: "\f190"; }
|
||||
.fi-pause:before { content: "\f191"; }
|
||||
.fi-paw:before { content: "\f192"; }
|
||||
.fi-paypal:before { content: "\f193"; }
|
||||
.fi-pencil:before { content: "\f194"; }
|
||||
.fi-photo:before { content: "\f195"; }
|
||||
.fi-play-circle:before { content: "\f196"; }
|
||||
.fi-play-video:before { content: "\f197"; }
|
||||
.fi-play:before { content: "\f198"; }
|
||||
.fi-plus:before { content: "\f199"; }
|
||||
.fi-pound:before { content: "\f19a"; }
|
||||
.fi-power:before { content: "\f19b"; }
|
||||
.fi-previous:before { content: "\f19c"; }
|
||||
.fi-price-tag:before { content: "\f19d"; }
|
||||
.fi-pricetag-multiple:before { content: "\f19e"; }
|
||||
.fi-print:before { content: "\f19f"; }
|
||||
.fi-prohibited:before { content: "\f1a0"; }
|
||||
.fi-projection-screen:before { content: "\f1a1"; }
|
||||
.fi-puzzle:before { content: "\f1a2"; }
|
||||
.fi-quote:before { content: "\f1a3"; }
|
||||
.fi-record:before { content: "\f1a4"; }
|
||||
.fi-refresh:before { content: "\f1a5"; }
|
||||
.fi-results-demographics:before { content: "\f1a6"; }
|
||||
.fi-results:before { content: "\f1a7"; }
|
||||
.fi-rewind-ten:before { content: "\f1a8"; }
|
||||
.fi-rewind:before { content: "\f1a9"; }
|
||||
.fi-rss:before { content: "\f1aa"; }
|
||||
.fi-safety-cone:before { content: "\f1ab"; }
|
||||
.fi-save:before { content: "\f1ac"; }
|
||||
.fi-share:before { content: "\f1ad"; }
|
||||
.fi-sheriff-badge:before { content: "\f1ae"; }
|
||||
.fi-shield:before { content: "\f1af"; }
|
||||
.fi-shopping-bag:before { content: "\f1b0"; }
|
||||
.fi-shopping-cart:before { content: "\f1b1"; }
|
||||
.fi-shuffle:before { content: "\f1b2"; }
|
||||
.fi-skull:before { content: "\f1b3"; }
|
||||
.fi-social-500px:before { content: "\f1b4"; }
|
||||
.fi-social-adobe:before { content: "\f1b5"; }
|
||||
.fi-social-amazon:before { content: "\f1b6"; }
|
||||
.fi-social-android:before { content: "\f1b7"; }
|
||||
.fi-social-apple:before { content: "\f1b8"; }
|
||||
.fi-social-behance:before { content: "\f1b9"; }
|
||||
.fi-social-bing:before { content: "\f1ba"; }
|
||||
.fi-social-blogger:before { content: "\f1bb"; }
|
||||
.fi-social-delicious:before { content: "\f1bc"; }
|
||||
.fi-social-designer-news:before { content: "\f1bd"; }
|
||||
.fi-social-deviant-art:before { content: "\f1be"; }
|
||||
.fi-social-digg:before { content: "\f1bf"; }
|
||||
.fi-social-dribbble:before { content: "\f1c0"; }
|
||||
.fi-social-drive:before { content: "\f1c1"; }
|
||||
.fi-social-dropbox:before { content: "\f1c2"; }
|
||||
.fi-social-evernote:before { content: "\f1c3"; }
|
||||
.fi-social-facebook:before { content: "\f1c4"; }
|
||||
.fi-social-flickr:before { content: "\f1c5"; }
|
||||
.fi-social-forrst:before { content: "\f1c6"; }
|
||||
.fi-social-foursquare:before { content: "\f1c7"; }
|
||||
.fi-social-game-center:before { content: "\f1c8"; }
|
||||
.fi-social-github:before { content: "\f1c9"; }
|
||||
.fi-social-google-plus:before { content: "\f1ca"; }
|
||||
.fi-social-hacker-news:before { content: "\f1cb"; }
|
||||
.fi-social-hi5:before { content: "\f1cc"; }
|
||||
.fi-social-instagram:before { content: "\f1cd"; }
|
||||
.fi-social-joomla:before { content: "\f1ce"; }
|
||||
.fi-social-lastfm:before { content: "\f1cf"; }
|
||||
.fi-social-linkedin:before { content: "\f1d0"; }
|
||||
.fi-social-medium:before { content: "\f1d1"; }
|
||||
.fi-social-myspace:before { content: "\f1d2"; }
|
||||
.fi-social-orkut:before { content: "\f1d3"; }
|
||||
.fi-social-path:before { content: "\f1d4"; }
|
||||
.fi-social-picasa:before { content: "\f1d5"; }
|
||||
.fi-social-pinterest:before { content: "\f1d6"; }
|
||||
.fi-social-rdio:before { content: "\f1d7"; }
|
||||
.fi-social-reddit:before { content: "\f1d8"; }
|
||||
.fi-social-skillshare:before { content: "\f1d9"; }
|
||||
.fi-social-skype:before { content: "\f1da"; }
|
||||
.fi-social-smashing-mag:before { content: "\f1db"; }
|
||||
.fi-social-snapchat:before { content: "\f1dc"; }
|
||||
.fi-social-spotify:before { content: "\f1dd"; }
|
||||
.fi-social-squidoo:before { content: "\f1de"; }
|
||||
.fi-social-stack-overflow:before { content: "\f1df"; }
|
||||
.fi-social-steam:before { content: "\f1e0"; }
|
||||
.fi-social-stumbleupon:before { content: "\f1e1"; }
|
||||
.fi-social-treehouse:before { content: "\f1e2"; }
|
||||
.fi-social-tumblr:before { content: "\f1e3"; }
|
||||
.fi-social-twitter:before { content: "\f1e4"; }
|
||||
.fi-social-vimeo:before { content: "\f1e5"; }
|
||||
.fi-social-windows:before { content: "\f1e6"; }
|
||||
.fi-social-xbox:before { content: "\f1e7"; }
|
||||
.fi-social-yahoo:before { content: "\f1e8"; }
|
||||
.fi-social-yelp:before { content: "\f1e9"; }
|
||||
.fi-social-youtube:before { content: "\f1ea"; }
|
||||
.fi-social-zerply:before { content: "\f1eb"; }
|
||||
.fi-social-zurb:before { content: "\f1ec"; }
|
||||
.fi-sound:before { content: "\f1ed"; }
|
||||
.fi-star:before { content: "\f1ee"; }
|
||||
.fi-stop:before { content: "\f1ef"; }
|
||||
.fi-strikethrough:before { content: "\f1f0"; }
|
||||
.fi-subscript:before { content: "\f1f1"; }
|
||||
.fi-superscript:before { content: "\f1f2"; }
|
||||
.fi-tablet-landscape:before { content: "\f1f3"; }
|
||||
.fi-tablet-portrait:before { content: "\f1f4"; }
|
||||
.fi-target-two:before { content: "\f1f5"; }
|
||||
.fi-target:before { content: "\f1f6"; }
|
||||
.fi-telephone-accessible:before { content: "\f1f7"; }
|
||||
.fi-telephone:before { content: "\f1f8"; }
|
||||
.fi-text-color:before { content: "\f1f9"; }
|
||||
.fi-thumbnails:before { content: "\f1fa"; }
|
||||
.fi-ticket:before { content: "\f1fb"; }
|
||||
.fi-torso-business:before { content: "\f1fc"; }
|
||||
.fi-torso-female:before { content: "\f1fd"; }
|
||||
.fi-torso:before { content: "\f1fe"; }
|
||||
.fi-torsos-all-female:before { content: "\f1ff"; }
|
||||
.fi-torsos-all:before { content: "\f200"; }
|
||||
.fi-torsos-female-male:before { content: "\f201"; }
|
||||
.fi-torsos-male-female:before { content: "\f202"; }
|
||||
.fi-torsos:before { content: "\f203"; }
|
||||
.fi-trash:before { content: "\f204"; }
|
||||
.fi-trees:before { content: "\f205"; }
|
||||
.fi-trophy:before { content: "\f206"; }
|
||||
.fi-underline:before { content: "\f207"; }
|
||||
.fi-universal-access:before { content: "\f208"; }
|
||||
.fi-unlink:before { content: "\f209"; }
|
||||
.fi-unlock:before { content: "\f20a"; }
|
||||
.fi-upload-cloud:before { content: "\f20b"; }
|
||||
.fi-upload:before { content: "\f20c"; }
|
||||
.fi-usb:before { content: "\f20d"; }
|
||||
.fi-video:before { content: "\f20e"; }
|
||||
.fi-volume-none:before { content: "\f20f"; }
|
||||
.fi-volume-strike:before { content: "\f210"; }
|
||||
.fi-volume:before { content: "\f211"; }
|
||||
.fi-web:before { content: "\f212"; }
|
||||
.fi-wheelchair:before { content: "\f213"; }
|
||||
.fi-widget:before { content: "\f214"; }
|
||||
.fi-wrench:before { content: "\f215"; }
|
||||
.fi-x-circle:before { content: "\f216"; }
|
||||
.fi-x:before { content: "\f217"; }
|
||||
.fi-yen:before { content: "\f218"; }
|
||||
.fi-zoom-in:before { content: "\f219"; }
|
||||
.fi-zoom-out:before { content: "\f21a"; }
|
||||
Binary file not shown.
|
|
@ -0,0 +1,970 @@
|
|||
<?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" >
|
||||
<!--
|
||||
2013-8-23: Created.
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>
|
||||
Created by FontForge 20120731 at Fri Aug 23 09:25:55 2013
|
||||
By Jordan Humphreys
|
||||
Created by Jordan Humphreys with FontForge 2.0 (http://fontforge.sf.net)
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="fontcustom" horiz-adv-x="369" >
|
||||
<font-face
|
||||
font-family="fontcustom"
|
||||
font-weight="500"
|
||||
font-stretch="normal"
|
||||
units-per-em="512"
|
||||
panose-1="2 0 6 3 0 0 0 0 0 0"
|
||||
ascent="448"
|
||||
descent="-64"
|
||||
bbox="-0.584459 -64.25 512.25 448.25"
|
||||
underline-thickness="25.6"
|
||||
underline-position="-51.2"
|
||||
unicode-range="U+F100-F21A"
|
||||
/>
|
||||
<missing-glyph />
|
||||
<glyph glyph-name="uniF100" unicode="" horiz-adv-x="340"
|
||||
d="M330 287v0h-24v-30h24c6 0 10 -4 10 -10v-30c0 -6 -4 -10 -10 -10h-24v-29h24c6 0 10 -5 10 -11v-30c0 -6 -4 -10 -10 -10h-24v-29h24c6 0 10 -5 10 -11v-30c0 -6 -4 -10 -10 -10h-24v-9c0 -9 -7 -16 -16 -16h-274c-9 0 -16 7 -16 16v308c0 9 7 16 16 16h274
|
||||
c9 0 16 -7 16 -16v-9h24c6 0 10 -4 10 -10v-30c0 -6 -4 -10 -10 -10zM234 122v0v44c0 4 -3 8 -6 10l-55 26c13 8 21 24 21 42c0 26 -18 48 -41 48s-41 -22 -41 -48c0 -19 9 -34 22 -42l-56 -26c-3 -2 -5 -6 -5 -10v-44c0 -6 4 -11 9 -11h142c5 0 10 5 10 11z" />
|
||||
<glyph glyph-name="uniF101" unicode="" horiz-adv-x="425"
|
||||
d="M423 31c1 -2 2 -4 2 -7c0 -10 -9 -18 -19 -18v0h-388v0c-10 0 -18 8 -18 18c0 4 1 9 4 12v0l191 331h1c3 6 8 11 16 11c7 0 13 -3 16 -9l193 -334c0 -1 1 -1 1 -2l1 -2v0zM213 40c14 0 26 12 26 27s-12 26 -26 26c-15 0 -27 -11 -27 -26s12 -27 27 -27zM239 273v0v0v0v0
|
||||
c0 6 -5 10 -11 10v0h-32v0c-5 0 -10 -4 -10 -10v-1v-144v0v0c0 -6 5 -11 11 -11h31v0v0c6 0 11 5 11 11v0v0v145z" />
|
||||
<glyph glyph-name="uniF102" unicode="" horiz-adv-x="355"
|
||||
d="M337 370c10 0 18 -7 18 -17v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM312 235c0 -10 -8 -17 -18 -17v0h-233c-10 0 -18 7 -18 17v16c0 10 8 17 18 17h233v0c10 0 18 -7 18 -17v0v-16v0zM320 64c10 0 17 -7 17 -17v0v-16v0
|
||||
c0 -10 -7 -17 -17 -17v0h-285c-10 0 -18 7 -18 17v16c0 10 8 17 18 17h285v0zM294 149v0v-16v0c0 -10 -7 -17 -17 -17v0v0h-199c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h199v0v0c10 0 17 -7 17 -17z" />
|
||||
<glyph glyph-name="uniF103" unicode="" horiz-adv-x="355"
|
||||
d="M337 369c10 0 18 -7 18 -17v-16c0 -10 -8 -18 -18 -18h-320c-10 0 -17 8 -17 18v16c0 10 7 17 17 17h320zM337 268c10 0 18 -7 18 -17v-16c0 -10 -8 -18 -18 -18h-320c-10 0 -17 8 -17 18v16c0 10 7 17 17 17h320zM337 167c10 0 18 -8 18 -18v-16c0 -10 -8 -17 -18 -17
|
||||
h-320c-10 0 -17 7 -17 17v16c0 10 7 18 17 18h320zM337 66c10 0 18 -8 18 -18v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 18 17 18h320z" />
|
||||
<glyph glyph-name="uniF104" unicode="" horiz-adv-x="355"
|
||||
d="M337 370c10 0 18 -7 18 -17v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM17 218c-10 0 -17 7 -17 17v16c0 10 7 18 17 18h234v0c10 0 18 -8 18 -18v0v-16v0c0 -10 -8 -17 -18 -17v0h-234zM302 64c10 0 18 -7 18 -17v0v-16v0
|
||||
c0 -10 -8 -17 -18 -17v0h-285c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h285v0zM17 116c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h199v0v0c10 0 18 -7 18 -17v0v-16v0c0 -10 -8 -17 -18 -17v0v0h-199z" />
|
||||
<glyph glyph-name="uniF105" unicode="" horiz-adv-x="355"
|
||||
d="M337 370c10 0 18 -7 18 -17v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM337 268c10 0 18 -7 18 -17v0v-16v0c0 -10 -8 -17 -18 -17v0h-233c-10 0 -18 7 -18 17v16c0 10 8 17 18 17h233v0zM337 64c10 0 18 -7 18 -17v0v-16v0
|
||||
c0 -10 -8 -17 -18 -17v0h-285c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h285v0v0zM355 149v0v-16v0c0 -10 -8 -17 -18 -17v0v0h-199c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h199v0v0c10 0 18 -7 18 -17z" />
|
||||
<glyph glyph-name="uniF106" unicode="" horiz-adv-x="393"
|
||||
d="M392 104c1 -1 1 -3 1 -4c0 -4 -4 -8 -8 -8h-21c-33 -58 -95 -97 -167 -97s-134 39 -167 97h-22c-4 0 -8 4 -8 8c0 2 1 4 2 5l47 82c1 3 4 5 7 5s6 -2 7 -4v0l48 -84v0c1 -1 2 -3 2 -4c0 -4 -5 -8 -9 -8h-12c20 -22 48 -38 79 -44v150h-46c-4 0 -8 4 -8 8v0v35v0
|
||||
c0 4 4 8 8 8v0h46v27c-20 10 -34 30 -34 54c0 33 27 59 60 59s59 -26 59 -59c0 -24 -14 -44 -34 -54v-27h47v0c4 0 8 -4 8 -8v0v-35v0c0 -4 -4 -8 -8 -8h-47v-150c31 6 59 22 79 44h-12c-4 0 -8 4 -8 8c0 2 1 4 2 5l46 82c1 3 5 5 8 5s6 -2 7 -4v0l48 -84v0zM197 296
|
||||
c18 0 33 16 33 34s-15 33 -33 33s-34 -15 -34 -33s16 -34 34 -34z" />
|
||||
<glyph glyph-name="uniF107" unicode="" horiz-adv-x="388"
|
||||
d="M360 98c17 -9 28 -27 28 -47c0 -29 -24 -54 -53 -54c-22 0 -42 14 -50 34h-182c-8 -20 -28 -34 -50 -34c-29 0 -53 25 -53 54c0 20 11 38 28 47v188c-17 9 -28 27 -28 47c0 29 24 54 53 54c18 0 34 -10 44 -24h194c10 14 26 24 44 24c29 0 53 -25 53 -54
|
||||
c0 -20 -11 -38 -28 -47v-188zM79 98c7 -4 13 -10 18 -16h195c5 6 10 12 17 16v188c-11 6 -18 15 -23 26h-184c-5 -11 -12 -20 -23 -26v-188z" />
|
||||
<glyph glyph-name="uniF108" unicode="" horiz-adv-x="401"
|
||||
d="M401 279v0v-247v0c0 -12 -9 -21 -21 -21h-1h-357h-1c-12 0 -21 9 -21 21v0v247v1c0 5 2 10 5 14v0l42 72v0c2 4 6 7 11 7v0v0h284v0h1c6 0 12 -4 13 -10l40 -69v-1c3 -4 5 -8 5 -13v-1zM269 154c1 2 2 4 1 6s-4 3 -6 3h-30v81c0 3 -3 6 -6 6h-55c-3 0 -6 -3 -6 -6v-81
|
||||
h-30c-2 0 -5 -1 -6 -3s0 -4 1 -6l64 -90c1 -2 3 -2 5 -2v0c2 0 4 0 5 2zM39 301h323l-27 47h-269z" />
|
||||
<glyph glyph-name="uniF109" unicode="" horiz-adv-x="292"
|
||||
d="M2 188c-3 4 -3 9 -1 13s7 7 12 7h62v167c0 7 6 13 13 13h116c7 0 12 -6 12 -13v-167h63c5 0 9 -3 11 -7s2 -9 -1 -13l-132 -187c-2 -3 -7 -5 -11 -5v0c-4 0 -8 2 -10 5z" />
|
||||
<glyph glyph-name="uniF10A" unicode="" horiz-adv-x="393"
|
||||
d="M192 335c4 3 9 3 13 1s7 -6 7 -11v-62h168c7 0 13 -6 13 -13v-116c0 -7 -6 -13 -13 -13h-168v-62c0 -5 -3 -9 -7 -11s-9 -2 -13 1l-187 132c-3 2 -5 7 -5 11v0c0 4 2 8 5 10z" />
|
||||
<glyph glyph-name="uniF10B" unicode="" horiz-adv-x="393"
|
||||
d="M201 49c-4 -3 -10 -3 -14 -1s-7 6 -7 11v62h-167c-7 0 -13 6 -13 13v116c0 7 6 13 13 13h167v62c0 5 3 9 7 11s10 2 14 -1l186 -132c3 -2 6 -7 6 -11v0c0 -4 -3 -8 -6 -10z" />
|
||||
<glyph glyph-name="uniF10C" unicode="" horiz-adv-x="292"
|
||||
d="M289 196c3 -4 3 -9 1 -13s-6 -7 -11 -7h-63v-167c0 -7 -5 -13 -12 -13h-116c-7 0 -13 6 -13 13v167h-62c-5 0 -10 3 -12 7s-2 9 1 13l133 187c2 3 6 5 10 5v0c4 0 9 -2 11 -5z" />
|
||||
<glyph glyph-name="uniF10D" unicode="" horiz-adv-x="512"
|
||||
d="M201 -5c-1 -3 -4 -6 -7 -7s-7 0 -9 2l-30 31l-83 -82c-4 -4 -9 -4 -13 0l-56 56c-4 4 -4 9 0 13l82 83l-31 30c-2 2 -3 6 -2 9s4 6 7 7l157 26c3 0 6 0 8 -2v0c2 -2 3 -5 3 -8zM311 389c1 3 4 6 7 7s7 0 9 -2l30 -31l83 82c4 4 9 4 13 0l56 -56c4 -4 4 -9 0 -13l-82 -83
|
||||
l31 -30c2 -2 3 -6 2 -9s-4 -6 -7 -7l-157 -26c-3 0 -6 0 -8 2v0c-2 2 -3 5 -3 8z" />
|
||||
<glyph glyph-name="uniF10E" unicode="" horiz-adv-x="512"
|
||||
d="M26 104c1 3 3 6 6 7s7 0 9 -2l31 -31l83 83c4 4 8 4 12 0l57 -57c4 -4 4 -9 0 -13l-82 -82l30 -31c2 -2 4 -6 3 -9s-4 -5 -7 -6l-158 -27c-3 0 -5 1 -7 3v0c-2 2 -3 4 -3 7zM486 280c-1 -3 -3 -6 -6 -7s-7 0 -9 2l-31 31l-83 -83c-4 -4 -8 -4 -12 0l-57 57
|
||||
c-4 4 -4 9 0 13l82 82l-30 31c-2 2 -4 6 -3 9s4 5 7 6l158 27c3 0 5 -1 7 -3v0c2 -2 3 -4 3 -7z" />
|
||||
<glyph glyph-name="uniF10F" unicode="" horiz-adv-x="512"
|
||||
d="M184 -10c-1 -3 -2 -5 -5 -6s-7 0 -9 2l-28 28l-76 -76c-3 -3 -8 -3 -11 0l-53 53c-3 3 -3 8 0 11l76 76l-28 28c-2 2 -3 6 -2 9s3 4 6 5l145 25c3 0 5 -1 7 -3v0c2 -2 2 -4 2 -7zM328 394c1 3 2 5 5 6s7 0 9 -2l28 -28l76 76c3 3 8 3 11 0l53 -53c3 -3 3 -8 0 -11
|
||||
l-76 -76l28 -28c2 -2 3 -6 2 -9s-3 -4 -6 -5l-145 -25c-3 0 -5 1 -7 3v0c-2 2 -2 4 -2 7zM458 120c3 -1 5 -2 6 -5s0 -7 -2 -9l-28 -28l76 -76c3 -3 3 -8 0 -11l-53 -53c-3 -3 -8 -3 -11 0l-76 76l-28 -28c-2 -2 -6 -3 -9 -2s-4 3 -5 6l-25 145c0 3 1 5 3 7v0c2 2 4 2 7 2z
|
||||
M54 264c-3 1 -5 2 -6 5s0 7 2 9l28 28l-76 76c-3 3 -3 8 0 11l53 53c3 3 8 3 11 0l76 -76l28 28c2 2 6 3 9 2s4 -3 5 -6l25 -145c0 -3 -1 -5 -3 -7v0c-2 -2 -4 -2 -7 -2z" />
|
||||
<glyph glyph-name="uniF110" unicode="" horiz-adv-x="512"
|
||||
d="M24 90c1 3 3 6 6 7s6 0 8 -2l28 -28l76 75c3 3 9 3 12 0l52 -52c3 -3 3 -9 0 -12l-76 -75l28 -29c2 -2 3 -5 2 -8s-3 -4 -6 -5l-144 -25c-3 0 -6 0 -8 2v0c-2 2 -2 5 -2 8zM488 294c-1 -3 -3 -6 -6 -7s-6 0 -8 2l-28 28l-76 -75c-3 -3 -9 -3 -12 0l-52 52c-3 3 -3 9 0 12
|
||||
l76 75l-28 29c-2 2 -3 5 -2 8s3 4 6 5l144 25c3 0 6 0 8 -2v0c2 -2 2 -5 2 -8zM358 -40c-3 1 -6 3 -7 6s0 6 2 8l28 28l-75 76c-3 3 -3 9 0 12l52 52c3 3 9 3 12 0l75 -76l29 28c2 2 5 3 8 2s4 -3 5 -6l25 -144c0 -3 0 -6 -2 -8v0c-2 -2 -5 -2 -8 -2zM154 424
|
||||
c3 -1 6 -3 7 -6s0 -6 -2 -8l-28 -28l75 -76c3 -3 3 -9 0 -12l-52 -52c-3 -3 -9 -3 -12 0l-75 76l-29 -28c-2 -2 -5 -3 -8 -2s-4 3 -5 6l-25 144c0 3 0 6 2 8v0c2 2 5 2 8 2z" />
|
||||
<glyph glyph-name="uniF111" unicode="" horiz-adv-x="440"
|
||||
d="M94 315c2 1 3 2 5 3c17 15 37 27 59 34c11 3 23 4 35 5c2 0 6 -2 7 -4s0 -6 -2 -8c-3 -3 -6 -5 -10 -6c-15 -5 -29 -9 -44 -14c-3 -1 -6 -6 -9 -8c-7 -6 -14 -10 -21 -16l-3 -3v-1c4 2 7 3 11 4c12 4 23 9 35 11c10 2 21 -1 32 -2c2 0 5 -2 7 -4c8 -6 15 -13 23 -19
|
||||
c3 -2 3 -4 1 -7c-5 -7 -11 -8 -18 -4c-6 3 -10 7 -15 11c-3 2 -5 4 -9 3c-7 -1 -15 -1 -22 -2c-3 0 -5 -1 -7 -2c-10 -7 -20 -15 -30 -22c-2 -1 -3 -4 -3 -7c1 0 2 0 3 1c8 5 17 6 26 7c3 0 6 1 9 1c12 2 20 -3 29 -10c7 -5 14 -10 21 -16c4 -3 6 -8 6 -13
|
||||
c0 -9 0 -18 -3 -27c0 -1 -1 -3 0 -3c6 -4 2 -9 1 -13c-3 -9 -7 -18 -10 -27c-3 -8 -9 -13 -18 -16c-21 -6 -41 -13 -62 -20c-8 -3 -17 -4 -26 -2c-17 4 -33 2 -49 -5c-7 -3 -15 -7 -23 -11c-9 13 -14 27 -17 41c-4 17 -4 35 -2 52c0 1 2 3 3 4c17 7 25 21 31 37
|
||||
c7 19 9 40 21 57c13 19 23 39 40 55c8 8 16 18 23 27c3 4 5 4 8 -1s3 -11 -1 -16c-10 -13 -21 -26 -31 -39c-1 -1 -1 -2 -2 -4zM167 170c4 0 8 -1 10 3c4 9 11 16 18 22c2 2 2 3 1 5c-4 7 -6 14 -10 21c-1 2 -3 4 -5 5c-6 4 -12 8 -19 12c-2 1 -4 2 -6 1
|
||||
c-5 -2 -10 -5 -15 -7c-4 -2 -9 -3 -13 -5c-11 -4 -14 -13 -17 -23c-2 -6 -1 -11 4 -16c6 -6 12 -13 17 -20c2 -2 3 -2 6 -1c10 3 19 5 29 3zM346 69c-3 -3 -7 -4 -10 -7c-15 -14 -34 -24 -53 -30c-11 -4 -23 -5 -35 -6c-7 -1 -10 7 -6 12c3 3 7 7 11 8c12 4 25 7 37 11
|
||||
c5 2 9 5 13 8c8 6 16 13 24 19c1 1 2 2 2 4c-4 -2 -9 -4 -13 -6c-11 -4 -21 -9 -32 -10s-22 1 -33 2c-2 0 -5 2 -7 4c-7 5 -13 11 -20 16s-6 12 3 15c3 1 8 1 11 -1c6 -3 11 -8 17 -12c2 -1 4 -2 6 -2c8 0 15 1 22 2c3 0 7 1 10 3c9 7 19 14 28 21c2 1 2 4 3 7
|
||||
c-12 -8 -26 -8 -39 -9c-9 -1 -16 1 -23 7c-9 7 -19 14 -28 21c-2 2 -4 5 -4 8c0 9 1 18 2 27c0 3 2 6 -1 9c-1 1 0 3 0 4c1 4 3 7 4 11c3 7 5 13 7 20c3 9 9 15 19 18c21 6 42 13 62 20c9 3 17 4 26 2c18 -5 35 -2 52 6c6 3 12 7 19 10c8 -9 12 -21 15 -32
|
||||
c6 -20 6 -40 4 -61c0 -5 -4 -5 -7 -6c-10 -4 -17 -13 -21 -22c-5 -10 -8 -21 -11 -32c-5 -15 -10 -30 -19 -43c-7 -10 -13 -20 -20 -30c-6 -8 -13 -15 -19 -23l-21 -24c-4 -4 -5 -4 -8 1s-2 10 2 16c10 13 20 25 30 38c1 1 1 3 2 5c-1 0 -1 1 -1 1zM245 186
|
||||
c3 -8 6 -16 10 -24c1 -2 2 -3 4 -4c6 -4 13 -8 19 -12c2 -1 4 -2 7 -1c8 3 15 7 23 10s14 6 17 14c2 4 3 9 4 13c1 5 1 9 -3 13c-7 7 -13 14 -19 21c-1 1 -3 1 -4 1c-11 -3 -22 -5 -33 -3c-2 0 -6 -1 -7 -3c-7 -8 -12 -17 -18 -25z" />
|
||||
<glyph glyph-name="uniF112" unicode="" horiz-adv-x="343"
|
||||
d="M338 140c4 -3 6 -7 4 -12v0v-2v0h-1l-28 -49v0c-3 -5 -9 -6 -14 -3c-1 0 -1 0 -2 1l-87 50v-103v0v0c0 -5 -4 -9 -9 -10v0h-58v0c-6 0 -10 4 -10 10v3v100l-89 -51v0v0c-4 -3 -10 -2 -13 2v0l-30 51v0c-3 5 -1 11 4 14c1 0 1 1 2 1l88 50l-90 51v1v0v0v0c-5 3 -7 8 -4 13
|
||||
v0l29 49v0v1c3 5 9 7 14 4v0l89 -52v103v0c0 5 5 10 10 10v0h57v0v0c6 0 10 -4 10 -10v0v-103l90 51v0c5 3 10 2 13 -3v0l28 -49v0l1 -1c3 -5 1 -11 -4 -14v0l-89 -51l89 -51v0v-1z" />
|
||||
<glyph glyph-name="uniF113" unicode="" horiz-adv-x="384"
|
||||
d="M384 192v-9v0c0 -76 -46 -102 -85 -102c-27 0 -75 22 -78 39v3c-16 -22 -41 -36 -65 -36c-44 0 -70 31 -70 75c0 60 50 111 102 111c27 0 47 -13 56 -30l4 18v0c1 3 4 5 7 5h37c4 0 7 -2 7 -6l-1 -2h1l-22 -101c0 -2 -1 -8 -1 -11c0 -14 8 -21 17 -21c18 0 39 29 39 80
|
||||
c-7 72 -67 128 -140 128c-78 0 -141 -63 -141 -141s63 -141 141 -141c19 0 37 3 53 10v0c1 0 2 1 3 1c2 0 4 -1 5 -2v0l34 -21v0c3 -1 4 -4 4 -7c0 -4 -2 -6 -5 -7c-28 -16 -60 -25 -94 -25c-106 0 -192 86 -192 192s86 192 192 192s192 -86 192 -192zM226 157l11 52
|
||||
c-5 10 -16 23 -36 23c-36 0 -62 -32 -62 -65c0 -23 14 -40 37 -40c24 0 40 16 50 30z" />
|
||||
<glyph glyph-name="uniF114" unicode=""
|
||||
d="M122 53h133l17 -45h-167zM136 98l52 138l53 -138h-105zM333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-3l-106 270v0c-2 5 -7 9 -13 9h-45c-6 0 -11 -4 -13 -9v0l-106 -270h-11c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297z" />
|
||||
<glyph glyph-name="uniF115" unicode="" horiz-adv-x="484"
|
||||
d="M476 236c5 0 8 -4 8 -9v-62c0 -5 -3 -9 -8 -9h-40v-95v0v0c0 -5 -4 -9 -9 -9h-418c-5 0 -9 4 -9 9v0v0v262v0v0c0 5 4 9 9 9h418c5 0 9 -4 9 -9v0v0v-87h40zM385 103v177h-333v-177h333z" />
|
||||
<glyph glyph-name="uniF116" unicode="" horiz-adv-x="484"
|
||||
d="M476 236c5 0 8 -4 8 -9v-62c0 -5 -3 -9 -8 -9h-40v-95v0v0c0 -5 -4 -9 -9 -9h-418c-5 0 -9 4 -9 9v0v0v262v0v0c0 5 4 9 9 9h418c5 0 9 -4 9 -9v0v0v-87h40zM385 103v177h-333v-177h333zM78 128v129h281v-129h-281z" />
|
||||
<glyph glyph-name="uniF117" unicode="" horiz-adv-x="484"
|
||||
d="M476 236c5 0 8 -4 8 -9v-62c0 -5 -3 -9 -8 -9h-40v-95v0v0c0 -5 -4 -9 -9 -9h-418c-5 0 -9 4 -9 9v0v0v262v0v0c0 5 4 9 9 9h418c5 0 9 -4 9 -9v0v0v-87h40zM385 103v177h-333v-177h333zM276 255l-50 -126h-149v126h199z" />
|
||||
<glyph glyph-name="uniF118" unicode="" horiz-adv-x="384"
|
||||
d="M191 253c12 -3 50 -8 44 -33c-6 -24 -43 -12 -55 -9zM175 190c14 -4 60 -11 53 -38c-7 -26 -50 -13 -64 -9zM238 378c103 -26 166 -129 140 -232s-129 -166 -232 -140s-166 129 -140 232s129 166 232 140zM277 219c4 26 -16 40 -43 49l9 34l-21 6l-8 -34
|
||||
c-6 1 -11 3 -17 4l8 34l-21 5l-9 -34c-5 1 -9 2 -13 3v0l-29 7l-6 -22l16 -4c9 -2 9 -9 9 -13l-9 -39c1 0 1 -1 2 -1c-1 0 -1 1 -2 1l-14 -55c-1 -3 -4 -6 -10 -5l-15 3l-11 -24l28 -6c5 -1 10 -3 15 -4l-9 -35l21 -6l9 35c6 -2 12 -3 17 -4l-9 -35l21 -5l9 35
|
||||
c36 -7 63 -4 74 28c9 26 0 41 -19 51c14 3 24 12 27 31z" />
|
||||
<glyph glyph-name="uniF119" unicode="" horiz-adv-x="260"
|
||||
d="M213 205c31 -7 51 -26 47 -67c-5 -51 -44 -65 -98 -68v-47v0v0c0 -4 -2 -7 -6 -7v0v0v0h-20v0v0c-4 0 -6 3 -6 7v0v46c-8 0 -17 1 -26 1v-47v0v0c0 -4 -2 -7 -6 -7v0v0v0h-20v0v0c-4 0 -6 3 -6 7v0v47h-23h-42v0c-3 0 -6 4 -6 7v0v0l5 27h1c1 3 3 5 6 5v0v0h23
|
||||
c9 0 12 7 13 11v85v0v61c-1 7 -6 14 -19 14h-24v0v0c-4 0 -6 2 -6 6v22c0 4 2 6 6 6v0h45v0h21v47v0v0c0 4 2 7 6 7v0v0v0v0h20v0v0c4 0 6 -3 6 -7v0v-46c9 0 17 1 26 1v45v0v0c0 4 2 7 6 7v0v0v0v0h20v0v0c4 0 6 -3 6 -7v0v-47c42 -4 75 -16 79 -54c3 -28 -9 -45 -28 -55z
|
||||
M105 277v-64c18 0 76 -5 76 32c0 38 -58 32 -76 32zM105 109c22 0 91 -5 91 35c0 42 -69 36 -91 36v-71z" />
|
||||
<glyph glyph-name="uniF11A" unicode="" horiz-adv-x="342"
|
||||
d="M91 347c0 24 12 36 36 36s37 -12 37 -36s-13 -37 -37 -37s-36 13 -36 37zM341 15c1 -1 1 -2 1 -3c0 -4 -2 -6 -6 -6c-2 0 -4 1 -5 3v0v0v1l-107 184h-3c-3 0 -6 1 -8 2v0v0v1h-1l-35 20v0v0v0v0l-23 23v-76l45 -44v0l49 -85c3 -4 4 -8 4 -13c0 -6 -2 -11 -6 -15
|
||||
s-9 -6 -15 -6c-8 0 -15 4 -19 11v0l-47 81l-37 37l-41 -72v0l-49 -49c-4 -5 -10 -8 -17 -8c-6 0 -11 2 -15 6s-6 9 -6 15s2 12 7 16v0l45 45l36 62v0v96l-19 -18v-52v0c0 -4 -1 -8 -4 -11s-7 -4 -11 -4c-3 0 -6 1 -8 2s-5 4 -6 6s-2 4 -2 7v0v62h1h-1c0 1 1 2 2 3v0l54 55
|
||||
c7 8 17 11 27 11c12 0 21 -4 28 -13l47 -47l31 -18c6 -3 9 -7 9 -14c0 -3 0 -6 -2 -9l107 -186v0z" />
|
||||
<glyph glyph-name="uniF11B" unicode="" horiz-adv-x="239"
|
||||
d="M231 120c5 -4 8 -10 8 -17c0 -5 -3 -10 -6 -14v0l-1 -1v0l-102 -102v0c-4 -4 -10 -7 -16 -7c-12 0 -21 9 -21 21v0v0v1v0v124l-55 -55c-4 -5 -9 -7 -16 -7c-12 0 -22 10 -22 22c0 6 2 11 6 15v0v0v0l87 86v11l-86 86c-4 4 -7 9 -7 15c0 12 10 22 22 22c6 0 12 -3 16 -7
|
||||
l55 -55v119c-1 2 -1 4 -1 6c0 12 9 22 21 22c7 0 13 -3 17 -8l101 -101c5 -4 8 -9 8 -16c0 -5 -3 -10 -6 -14v0v0c-1 -1 -1 -2 -2 -3l-72 -71zM186 103l-50 51v-101zM136 230l50 50l-50 50v-100z" />
|
||||
<glyph glyph-name="uniF11C" unicode="" horiz-adv-x="242"
|
||||
d="M186 197c31 -5 56 -35 56 -71c0 -44 -29 -79 -85 -79h-144c-7 0 -13 6 -13 13v264c0 7 6 13 13 13h140c55 0 83 -35 83 -74c0 -36 -23 -60 -50 -66zM62 283v-61h77c21 0 34 11 34 30c0 18 -13 31 -34 31h-77zM142 101c23 0 37 12 37 33c0 18 -13 33 -37 33h-80v-66h80z
|
||||
" />
|
||||
<glyph glyph-name="uniF11D" unicode="" horiz-adv-x="328"
|
||||
d="M328 334v-327v0c0 -5 -3 -8 -8 -8v0v0h-312v0c-4 0 -8 4 -8 8v0v0v0v1v65v303v1c0 5 3 8 8 8h153v-66v-84v-29c0 -2 2 -4 4 -4c1 0 2 0 3 1v0l29 30h1c1 1 1 1 2 1s2 0 3 -1v0l29 -29c1 -1 2 -2 3 -2c2 0 4 2 4 4v29v84v66h29v0h1c5 0 8 -3 8 -8v-319v0c0 -5 -3 -8 -8 -8
|
||||
h-1v0h-242v-19c1 -4 4 -7 8 -7h261v0c5 0 8 4 8 9v0v309h17v0c4 0 8 -4 8 -8v0z" />
|
||||
<glyph glyph-name="uniF11E" unicode="" horiz-adv-x="328"
|
||||
d="M328 334v-327v0c0 -5 -3 -8 -8 -8v0v0h-312v0c-4 0 -8 4 -8 8v0v0v0v1v65v303v1c0 5 3 8 8 8h260v0h1c5 0 8 -3 8 -8v-319v0c0 -5 -3 -8 -8 -8h-1v0h-242v-19c1 -4 4 -7 8 -7h261v0c5 0 8 4 8 9v0v309h17v0c4 0 8 -4 8 -8v0zM25 326v0v-64c0 -5 4 -8 9 -8h209v0
|
||||
c5 0 8 3 8 8v0v64v0c0 5 -3 8 -8 8h-209c-5 0 -9 -3 -9 -8z" />
|
||||
<glyph glyph-name="uniF11F" unicode="" horiz-adv-x="218"
|
||||
d="M203 381c9 0 15 -7 15 -16v-34v-235v-82c0 -6 -5 -11 -11 -11c-3 0 -7 2 -9 4l-81 82v0c-2 2 -5 3 -8 3s-5 -1 -7 -3v0l-83 -83v0c-2 -2 -5 -3 -8 -3c-6 0 -11 5 -11 11v82v235v34c0 9 6 16 15 16h188z" />
|
||||
<glyph glyph-name="uniF120" unicode="" horiz-adv-x="265"
|
||||
d="M0 325c0 24 12 36 36 36s35 -12 35 -36s-11 -35 -35 -35s-36 11 -36 35zM194 325c0 24 11 36 35 36s36 -12 36 -36s-12 -35 -36 -35s-35 11 -35 35zM0 192c0 24 12 36 36 36s35 -12 35 -36s-11 -36 -35 -36s-36 12 -36 36zM194 192c0 24 11 36 35 36s36 -12 36 -36
|
||||
s-12 -36 -36 -36s-35 12 -35 36zM0 59c0 24 12 36 36 36s35 -12 35 -36s-11 -36 -35 -36s-36 12 -36 36zM194 59c0 24 11 36 35 36s36 -12 36 -36s-12 -36 -36 -36s-35 12 -35 36z" />
|
||||
<glyph glyph-name="uniF121" unicode="" horiz-adv-x="395"
|
||||
d="M395 192c0 -5 -3 -9 -6 -11v0l-48 -28l27 -46v0c2 -4 1 -9 -1 -13s-6 -6 -10 -6v0h-54v-55h-1c0 -4 -2 -8 -6 -10s-9 -3 -13 -1v0l-47 27l-27 -47v0c-2 -3 -6 -6 -11 -6s-9 3 -11 6v0l-27 46l-49 -28v0c-4 -2 -8 -1 -12 1s-7 6 -7 10v0v55h-55v0c-4 0 -8 3 -10 7
|
||||
s-3 8 -1 12v0l27 48l-47 28v0c-3 2 -6 6 -6 11s3 9 6 11v0l48 28l-27 46v0c-2 4 -1 9 1 13s6 6 10 6v0h54v55v0c0 4 3 8 7 10s8 3 12 1v0l48 -27l27 47v0c2 3 6 6 11 6s9 -3 11 -6v0l27 -46l49 28v0c4 2 8 1 12 -1s7 -6 7 -10v0v-55h55v0c4 0 8 -3 10 -7s3 -8 1 -12v-1
|
||||
l-27 -47l47 -28v0c3 -2 6 -6 6 -11zM165 134l12 7l-34 59l-12 -7l21 -37l-49 21l-13 -8l34 -59l13 8l-22 38zM189 148l42 24l-7 11l-29 -17l-8 13l29 17l-6 11l-29 -17l-7 13l29 17l-6 11l-42 -24zM286 204l13 7l-17 69l-14 -8l14 -49l-36 36l-9 -5l13 -49l-35 36l-14 -8
|
||||
l51 -49l13 8l-13 46z" />
|
||||
<glyph glyph-name="uniF122" unicode="" horiz-adv-x="395"
|
||||
d="M167 163l-5 31l24 -20zM395 192c0 -5 -3 -9 -6 -11v0l-48 -28l27 -46v0c2 -4 1 -9 -1 -13s-6 -6 -10 -6v0h-54v-55h-1c0 -4 -2 -8 -6 -10s-9 -3 -13 -1v0l-47 27l-27 -47v0c-2 -3 -6 -6 -11 -6s-9 3 -11 6v0l-27 46l-49 -28v0c-4 -2 -8 -1 -12 1s-7 6 -7 10v0v55h-55v0
|
||||
c-4 0 -8 3 -10 7s-3 8 -1 12v0l27 48l-47 28v0c-3 2 -6 6 -6 11s3 9 6 11v0l48 28l-27 46v0c-2 4 -1 9 1 13s6 6 10 6v0h54v55v0c0 4 3 8 7 10s8 3 12 1v0l48 -27l27 47v0c2 3 6 6 11 6s9 -3 11 -6v0l27 -46l49 28v0c4 2 8 1 12 -1s7 -6 7 -10v0v-55h55v0c4 0 8 -3 10 -7
|
||||
s3 -8 1 -12v-1l-27 -47l47 -28v0c3 -2 6 -6 6 -11zM134 114c16 9 18 22 12 33c-13 22 -43 -4 -48 5c-2 4 0 8 5 11c6 3 14 5 21 3l1 14c-9 2 -18 0 -27 -5c-14 -8 -18 -21 -12 -31c13 -22 42 4 48 -6c2 -3 1 -8 -6 -12c-8 -5 -17 -5 -24 -3l-1 -14c9 -2 20 -2 31 5zM205 157
|
||||
l14 8l-57 46l-15 -9l11 -72l14 8l-2 12l25 15zM224 168l38 22l-7 11l-25 -15l-27 48l-13 -7zM270 195l42 24l-6 11l-29 -17l-8 13l28 17l-6 11l-29 -17l-7 13l29 17l-6 11l-42 -24z" />
|
||||
<glyph glyph-name="uniF123" unicode="" horiz-adv-x="395"
|
||||
d="M395 192c0 -5 -3 -9 -6 -11v0l-48 -28l27 -46v0c2 -4 1 -9 -1 -13s-6 -6 -10 -6v0h-54v-55h-1c0 -4 -2 -8 -6 -10s-9 -3 -13 -1v0l-47 27l-27 -47v0c-2 -3 -6 -6 -11 -6s-9 3 -11 6v0l-27 46l-49 -28v0c-4 -2 -8 -1 -12 1s-7 6 -7 10v0v55h-55v0c-4 0 -8 3 -10 7
|
||||
s-3 8 -1 12v0l27 48l-47 28v0c-3 2 -6 6 -6 11s3 9 6 11v0l48 28l-27 46v0c-2 4 -1 9 1 13s6 6 10 6v0h54v55v0c0 4 3 8 7 10s8 3 12 1v0l48 -27l27 47v0c2 3 6 6 11 6s9 -3 11 -6v0l27 -46l49 28v0c4 2 8 1 12 -1s7 -6 7 -10v0v-55h55v0c4 0 8 -3 10 -7s3 -8 1 -12v-1
|
||||
l-27 -47l47 -28v0c3 -2 6 -6 6 -11z" />
|
||||
<glyph glyph-name="uniF124" unicode="" horiz-adv-x="326"
|
||||
d="M320 246c4 0 6 -3 6 -7v-225c0 -4 -2 -6 -6 -6h-314c-4 0 -6 2 -6 6v225c0 4 2 7 6 7h314zM109 55c34 0 56 18 56 44c0 18 -13 26 -25 31c14 7 21 17 21 31c0 18 -18 30 -44 30c-15 0 -27 -2 -37 -7c-1 -1 -2 -2 -2 -3l3 -22c0 -1 1 -2 2 -2h3c8 4 16 6 24 6
|
||||
c15 0 15 -6 15 -9c0 -5 -3 -11 -24 -13c-2 0 -3 -1 -3 -3v-22c0 -2 1 -3 3 -3c25 -1 30 -7 30 -16c0 -8 -9 -13 -20 -13s-19 1 -29 5c-1 0 -2 1 -3 0s-1 -1 -1 -2l-3 -22c0 -1 1 -3 2 -4c9 -4 21 -6 32 -6zM245 61v0v125c0 2 -1 3 -3 3h-13h-2l-38 -19c-1 -1 -2 -2 -2 -3
|
||||
l3 -22c0 -1 1 -3 2 -3c1 -1 2 0 3 0l17 7v-88c0 -2 1 -4 3 -4h27c2 0 3 2 3 4zM320 347c4 0 6 -2 6 -6v-66c0 -4 -2 -7 -6 -7h-314c-4 0 -6 3 -6 7v66c0 4 2 6 6 6h34v-16c0 -17 9 -34 36 -34s36 17 36 34v16h102v-16c0 -17 9 -34 36 -34s36 17 36 34v16h34zM76 318
|
||||
c-11 0 -15 4 -15 13v16v16c0 9 4 13 15 13s15 -4 15 -13v-16v-16c0 -9 -4 -13 -15 -13zM250 318c-11 0 -15 4 -15 13v16v16c0 9 4 13 15 13s15 -4 15 -13v-16v-16c0 -9 -4 -13 -15 -13z" />
|
||||
<glyph glyph-name="uniF125" unicode="" horiz-adv-x="415"
|
||||
d="M159 175c0 32 17 49 49 49s48 -17 48 -49s-16 -48 -48 -48s-49 16 -49 48zM396 324c5 0 9 -1 13 -5s6 -9 6 -14v-259c0 -5 -2 -10 -6 -14s-8 -5 -13 -5v-1h-377v1c-5 0 -9 1 -13 5s-6 9 -6 14v259c0 5 2 10 6 14s8 5 13 5v0h85v15c0 5 2 9 6 13s8 6 13 6h168
|
||||
c5 0 10 -2 14 -6s5 -8 5 -13v-15h86v0zM209 77c18 0 34 4 49 13s27 21 36 36s13 31 13 49c0 27 -10 51 -29 70s-42 29 -69 29s-51 -10 -70 -29s-29 -43 -29 -70s10 -50 29 -69s43 -29 70 -29zM389 248v0v51h-75v-51h75z" />
|
||||
<glyph glyph-name="uniF126" unicode="" horiz-adv-x="397"
|
||||
d="M393 293c5 -5 5 -13 0 -18l-250 -250c-2 -2 -6 -4 -9 -4v1l-1 -1c-3 0 -6 2 -8 4l-121 121c-2 2 -4 6 -4 9s2 7 4 9l66 66c5 5 12 5 17 0l47 -47l176 176c2 2 5 4 8 4s7 -2 9 -4z" />
|
||||
<glyph glyph-name="uniF127" unicode="" horiz-adv-x="381"
|
||||
d="M379 323c3 -3 3 -8 0 -11l-209 -209c-2 -2 -4 -3 -6 -3v0v0c-2 0 -4 1 -6 3l-81 80c-2 2 -3 4 -3 6s1 4 3 6l44 44c3 3 9 3 12 0l31 -31l159 160c2 2 4 2 6 2s4 0 6 -2zM277 173l51 52v-185v0c0 -14 -12 -26 -26 -26v0h-1v0v0h-275v0v0v0v0c-14 0 -26 12 -26 26v0v276v0
|
||||
c0 14 12 26 26 26h1v0h234l-51 -51h-159v-226h226v108z" />
|
||||
<glyph glyph-name="uniF128" unicode="" horiz-adv-x="315"
|
||||
d="M315 360v0v-362v0v0c0 -15 -12 -27 -27 -27h-1h-259v0h-1c-15 0 -27 12 -27 27v0v0v362v0v0c0 15 12 27 27 27v0h75v17v1c0 5 3 8 8 8v0v0h95v0c5 0 8 -3 8 -8v0v0v-18h75v0c15 0 27 -12 27 -27v0v0zM264 22v0v314h-25v-16v0c0 -5 -5 -9 -10 -9h-143v0v0
|
||||
c-5 0 -10 4 -10 9v1v15h-25v-314h213zM102 237v0v0v-13v0v0c0 -3 -3 -6 -6 -6h-1v0h-12v0c-3 0 -7 3 -7 6v0v0v13c0 3 4 7 7 7h12v-1l1 1c3 0 6 -4 6 -7zM239 237v0v0v-13v0v0c0 -3 -4 -6 -7 -6h-98v0c-3 0 -7 3 -7 6v0v0v13c0 3 4 7 7 7h98v0c3 0 7 -4 7 -7zM102 186v0v0
|
||||
v-13v0v0c0 -3 -3 -6 -6 -6h-1v0h-12v0c-3 0 -7 3 -7 6v0v0v13c0 3 4 7 7 7h12v-1l1 1c3 0 6 -4 6 -7zM239 186v0v0v-13v0v0c0 -3 -4 -6 -7 -6h-98v0c-3 0 -7 3 -7 6v0v0v13c0 3 4 7 7 7h98v0c3 0 7 -4 7 -7zM102 135v0v0v-13v0v0c0 -3 -3 -6 -6 -6h-1v0h-12v0
|
||||
c-3 0 -7 3 -7 6v0v0v13c0 3 4 6 7 6h12v0h1c3 0 6 -3 6 -6zM239 135v0v0v-13v0v0c0 -3 -4 -6 -7 -6h-98v0c-3 0 -7 3 -7 6v0v0v13c0 3 4 6 7 6h98v0c3 0 7 -3 7 -6z" />
|
||||
<glyph glyph-name="uniF129" unicode="" horiz-adv-x="392"
|
||||
d="M391 228c2 -2 2 -7 0 -9l-116 -116v0v0l-59 -16v0c-2 -1 -5 0 -7 2s-2 4 -1 6v0l16 59v0v0l115 116c2 2 7 2 9 0zM227 107l35 9l-25 26zM309 73c3 0 6 -3 6 -6v0v0v-69v0v0c0 -15 -12 -27 -27 -27h-1h-259v0h-1c-15 0 -27 12 -27 27v0v0v362v0v0c0 15 12 27 27 27v0h75
|
||||
v17v1c0 5 3 8 8 8v0v0h95v0c4 0 8 -3 8 -8v0v0v-18h75v0c15 0 27 -12 27 -27v0v0v-68v0c0 -3 -3 -7 -6 -7v0h-39c-3 0 -6 4 -6 7v0v44h-25v-16v0c0 -5 -5 -9 -10 -9h-143v0v0c-5 0 -10 4 -10 9v1v15h-25v-314h213v45v0c0 3 3 6 6 6v0v0h39v0z" />
|
||||
<glyph glyph-name="uniF12A" unicode="" horiz-adv-x="315"
|
||||
d="M315 360v0v-362v0v0c0 -15 -12 -27 -27 -27h-1h-259v0h-1c-15 0 -27 12 -27 27v0v0v362v0v0c0 15 12 27 27 27v0h75v17v1c0 5 3 8 8 8v0v0h95v0c5 0 8 -3 8 -8v0v0v-18h75v0c15 0 27 -12 27 -27v0v0zM264 22v0v314h-25v-16v0c0 -5 -5 -9 -10 -9h-143v0v0
|
||||
c-5 0 -10 4 -10 9v1v15h-25v-314h213z" />
|
||||
<glyph glyph-name="uniF12B" unicode="" horiz-adv-x="384"
|
||||
d="M192 333c-78 0 -141 -63 -141 -141s63 -141 141 -141s141 63 141 141s-63 141 -141 141zM192 384v0c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM290 263c4 -4 4 -10 0 -14l-91 -91c-2 -2 -4 -3 -7 -3v0c-3 0 -5 1 -7 3l-62 62
|
||||
c-2 2 -3 4 -3 7s1 6 3 8l20 20c4 4 10 4 14 0l35 -36l64 64c4 4 10 4 14 0z" />
|
||||
<glyph glyph-name="uniF12C" unicode="" horiz-adv-x="342"
|
||||
d="M333 300c5 -1 9 -6 9 -11v-94v-6v-94c0 -5 -4 -10 -9 -11l-160 -32h-4l-160 32c-5 1 -9 6 -9 11v94v6v94c0 5 4 10 9 11l160 32h4zM149 150c1 2 1 5 0 7s-3 4 -5 5l-19 8c-2 1 -4 1 -6 0s-4 -3 -5 -5c-2 -4 -7 -14 -17 -14c-14 0 -24 17 -24 41s10 41 24 41
|
||||
c9 0 14 -7 17 -13c2 -4 8 -6 12 -4l18 8c2 1 4 3 5 5s0 4 -1 6c-11 23 -28 35 -51 35c-38 0 -64 -31 -64 -78s26 -78 64 -78c23 0 41 12 52 36zM308 150c1 2 1 5 0 7s-3 4 -5 5l-18 8c-2 1 -5 1 -7 0s-4 -3 -5 -5c-2 -4 -6 -14 -16 -14c-14 0 -25 17 -25 41s11 41 25 41
|
||||
c9 0 14 -7 17 -13c2 -4 7 -6 11 -4l18 8c2 1 4 3 5 5s0 4 -1 6c-11 23 -27 35 -50 35c-38 0 -65 -31 -65 -78s27 -78 65 -78c23 0 40 12 51 36z" />
|
||||
<glyph glyph-name="uniF12D" unicode="" horiz-adv-x="473"
|
||||
d="M387 206c46 6 86 -35 86 -84c0 -18 -6 -35 -16 -50c-3 -4 -7 -7 -12 -7h-414c-5 0 -10 3 -13 8c-12 20 -18 42 -18 66c0 66 49 121 110 121c8 0 15 -1 23 -3c27 39 70 62 115 62c65 0 121 -47 139 -113z" />
|
||||
<glyph glyph-name="uniF12E" unicode="" horiz-adv-x="470"
|
||||
d="M302 166h92v-93v0c-2 -8 -9 -14 -17 -14h-225l-44 -44c-3 -5 -9 -8 -15 -8c-10 0 -17 7 -17 17v35h-59v0c-8 0 -15 6 -17 14v0v288v0c1 9 8 16 17 16v0h360c9 0 16 -7 17 -16v0v-91h-92c-5 0 -9 -4 -9 -9v0v-86v0c0 -5 4 -9 9 -9zM461 245c5 0 9 -4 9 -9v-36
|
||||
c0 -5 -4 -8 -9 -8h-133c-5 0 -9 3 -9 8v36c0 5 4 9 9 9h133z" />
|
||||
<glyph glyph-name="uniF12F" unicode="" horiz-adv-x="394"
|
||||
d="M394 361v0v-288v0c-2 -8 -9 -14 -17 -14h-225l-44 -44c-3 -5 -9 -8 -15 -8c-10 0 -17 7 -17 17v35h-59v0c-8 0 -15 6 -17 14v0v288v0c1 9 8 16 17 16v0h360c9 0 16 -7 17 -16zM87 189c14 0 26 12 26 26s-10 24 -23 24c-3 0 -5 0 -6 -1c3 12 13 25 24 31v0h1v0
|
||||
c1 1 2 2 2 3s-1 2 -2 3v0l-14 9v0c-1 0 -1 1 -2 1s-1 -1 -2 -1v0c-21 -15 -34 -36 -34 -61c0 -22 14 -34 30 -34zM154 189c14 0 27 12 27 26s-10 24 -23 24c-3 0 -6 0 -7 -1c3 12 14 25 25 31v0v0v0c1 1 2 2 2 3s0 2 -1 3v0l-14 9v0c-1 0 -1 1 -2 1s-1 -1 -2 -1v0
|
||||
c-21 -15 -34 -36 -34 -61c0 -22 13 -34 29 -34zM235 152c21 15 35 37 35 62c0 22 -14 34 -30 34c-14 0 -26 -13 -26 -27s9 -24 22 -24c3 0 6 0 7 1c-3 -12 -14 -25 -25 -31v0v0v0c-1 -1 -2 -2 -2 -3s1 -2 2 -3h-1l14 -9v0c1 0 2 -1 3 -1s0 1 1 1v0zM303 152
|
||||
c21 15 34 37 34 62c0 22 -13 34 -29 34c-14 0 -27 -13 -27 -27s10 -24 23 -24c3 0 6 0 7 1c-3 -12 -14 -25 -25 -31v0v0v0c-1 -1 -2 -2 -2 -3s0 -2 1 -3v0l14 -9v0c1 0 1 -1 2 -1s1 1 2 1v0z" />
|
||||
<glyph glyph-name="uniF130" unicode="" horiz-adv-x="394"
|
||||
d="M394 361v0v-288v0c-2 -8 -9 -14 -17 -14h-225l-44 -44c-3 -5 -9 -8 -15 -8c-10 0 -17 7 -17 17v35h-59v0c-8 0 -15 6 -17 14v0v288v0c1 9 8 16 17 16v0h360c9 0 16 -7 17 -16zM305 155v124l-65 -30v28c0 7 -6 12 -13 12h-110c-7 0 -12 -5 -12 -12v-120c0 -7 5 -12 12 -12
|
||||
h110c7 0 13 5 13 12v29z" />
|
||||
<glyph glyph-name="uniF131" unicode="" horiz-adv-x="394"
|
||||
d="M394 361v0v-288v0c-2 -8 -9 -14 -17 -14h-225l-44 -44c-3 -5 -9 -8 -15 -8c-10 0 -17 7 -17 17v35h-59v0c-8 0 -15 6 -17 14v0v288v0c1 9 8 16 17 16v0h360c9 0 16 -7 17 -16z" />
|
||||
<glyph glyph-name="uniF132" unicode="" horiz-adv-x="461"
|
||||
d="M461 357v0v-217v0c-1 -6 -7 -11 -13 -11v0h-44v-26c0 -7 -6 -13 -13 -13c-4 0 -9 3 -11 6l-33 33h-57v150v0c-1 6 -5 10 -11 10h-115v68v0c1 7 6 11 13 11h271v0c7 0 12 -5 13 -11zM253 264c6 0 11 -5 12 -11v0v-193h-1c-1 -5 -5 -10 -11 -10h-151l-30 -29
|
||||
c-2 -3 -5 -5 -9 -5c-6 0 -12 5 -12 11v23h-40v0c-5 0 -10 5 -11 10v0v193v0c1 6 5 11 11 11v0h242z" />
|
||||
<glyph glyph-name="uniF133" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM192 51c78 0 141 63 141 141s-63 141 -141 141s-141 -63 -141 -141s63 -141 141 -141zM267 281c4 2 9 1 12 -2s4 -8 2 -12l-60 -100l-3 -3l-101 -61c-2 -1 -3 -1 -5 -1s-5 1 -7 3v0
|
||||
c-3 3 -4 8 -2 12l61 101l3 3z" />
|
||||
<glyph glyph-name="uniF134" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM193 333v-282c78 0 140 63 140 141s-62 141 -140 141z" />
|
||||
<glyph glyph-name="uniF135" unicode="" horiz-adv-x="378"
|
||||
d="M378 314v-1v0v-37h-378v36v2c0 8 6 13 14 13h1h349h1c8 0 13 -5 13 -13zM0 70v155h378v-155v0c0 -7 -6 -13 -13 -13v0h-350v0h-1c-8 0 -14 5 -14 13v0v0z" />
|
||||
<glyph glyph-name="uniF136" unicode="" horiz-adv-x="419"
|
||||
d="M405 84c8 0 14 -6 14 -14v-23c0 -8 -6 -14 -14 -14v0h-37v-36c0 -8 -6 -14 -14 -14h-23c-8 0 -14 6 -14 14v36h-241v0c-13 0 -25 12 -25 25v1v0v241h-37v0c-8 0 -14 6 -14 14v23c0 8 6 14 14 14v0h37v36v0c0 8 6 14 14 14h23c8 0 14 -6 14 -14v0v-36h241v0
|
||||
c13 0 25 -12 25 -25v-1v0v-241h37v0zM102 84v0h215v216h-215v-216z" />
|
||||
<glyph glyph-name="uniF137" unicode="" horiz-adv-x="348"
|
||||
d="M348 38v-19v0v0c0 -9 -6 -16 -15 -16h-317v0c-9 0 -16 7 -16 16v0v0v19v0c0 9 7 16 16 16v0h317c9 0 15 -7 15 -16v0zM44 251c1 -1 1 0 2 -1l34 -35l82 81v0c3 3 7 5 12 5s9 -2 12 -5v0l82 -81l35 35c0 1 0 2 1 2h1v0c3 2 6 4 10 4c9 0 17 -8 17 -17v-3v-145v0v0v-2v0
|
||||
c-1 -8 -8 -14 -17 -14v0v-1h-282v0v0c-9 0 -15 7 -16 15h-1v150h1c0 9 7 16 16 16c4 0 8 -1 11 -4v0v0zM292 208v0h-1h1zM2 309c0 21 10 31 31 31s30 -10 30 -31s-9 -31 -30 -31s-31 10 -31 31zM283 309c0 21 10 31 31 31s31 -10 31 -31s-10 -31 -31 -31s-31 10 -31 31z
|
||||
M145 350c0 21 10 31 31 31s31 -10 31 -31s-10 -31 -31 -31s-31 10 -31 31z" />
|
||||
<glyph glyph-name="uniF138" unicode="" horiz-adv-x="325"
|
||||
d="M0 375h325l-30 -330l-132 -36l-133 36zM260 268l4 40h-102h-103l5 -40h98h6l-6 -2l-94 -40l3 -39h91h49l-3 -52l-46 -13v0v0l-44 11l-3 32v0h-41v0l5 -62l83 -25v0h1l82 25l11 123h-94v0v0z" />
|
||||
<glyph glyph-name="uniF139" unicode="" horiz-adv-x="422"
|
||||
d="M124 323v-262v0v0c0 -12 -11 -22 -23 -22v0h-80v1c-12 0 -21 9 -21 21v0v262v0c0 12 9 22 21 22v0h80v0c12 0 22 -10 22 -22h1zM62 65c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM98 180v139h-72v-139h72zM273 323v-262v0v0c0 -12 -10 -22 -22 -22
|
||||
v0h-81v1c-12 0 -21 9 -21 21v0v262v0c0 12 9 22 21 22v0h81v0c12 0 22 -10 22 -22v0zM211 65c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM247 180v0v139h-72v-139h72zM422 323v-262v0v0c0 -12 -10 -22 -22 -22v0h-81v1c-12 0 -21 9 -21 21v0v262v0
|
||||
c0 12 9 22 21 22v0h81v0c12 0 22 -10 22 -22v0zM360 65c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM396 180v139h-72v-139h72z" />
|
||||
<glyph glyph-name="uniF13A" unicode="" horiz-adv-x="348"
|
||||
d="M348 329v0v-274v0c0 -20 -17 -37 -37 -37v0h-274v0c-20 0 -37 17 -37 37v0v274v0c0 20 17 37 37 37v0h274v0c20 -1 37 -17 37 -37zM87 71c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM87 243c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36
|
||||
s16 -36 36 -36zM174 156c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM261 69c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM261 243c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36z" />
|
||||
<glyph glyph-name="uniF13B" unicode="" horiz-adv-x="348"
|
||||
d="M348 329v0v-274v0c0 -20 -17 -37 -37 -37v0h-274v0c-20 0 -37 17 -37 37v0v274v0c0 20 17 37 37 37v0h274v0c20 -1 37 -17 37 -37zM87 71c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM87 243c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36
|
||||
s16 -36 36 -36zM261 69c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM261 243c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36z" />
|
||||
<glyph glyph-name="uniF13C" unicode="" horiz-adv-x="348"
|
||||
d="M348 329v0v-274v0c0 -20 -17 -37 -37 -37v0h-274v0c-20 0 -37 17 -37 37v0v274v0c0 20 17 37 37 37v0h274v0c20 -1 37 -17 37 -37zM174 153c22 0 39 17 39 39s-17 39 -39 39s-39 -17 -39 -39s17 -39 39 -39z" />
|
||||
<glyph glyph-name="uniF13D" unicode="" horiz-adv-x="348"
|
||||
d="M348 329v0v-274v0c0 -20 -17 -37 -37 -37v0h-274v0c-20 0 -37 17 -37 37v0v274v0c0 20 17 37 37 37v0h274v0c20 -1 37 -17 37 -37zM87 71c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM87 156c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36
|
||||
s16 -36 36 -36zM87 243c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM261 69c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM261 156c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM261 243c20 0 36 16 36 36
|
||||
s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36z" />
|
||||
<glyph glyph-name="uniF13E" unicode="" horiz-adv-x="348"
|
||||
d="M348 329v0v-274v0c0 -20 -17 -37 -37 -37v0h-274v0c-20 0 -37 17 -37 37v0v274v0c0 20 17 37 37 37v0h274v0c20 -1 37 -17 37 -37zM87 243c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM174 156c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36
|
||||
s16 -36 36 -36zM261 69c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36z" />
|
||||
<glyph glyph-name="uniF13F" unicode="" horiz-adv-x="348"
|
||||
d="M348 329v0v-274v0c0 -20 -17 -37 -37 -37v0h-274v0c-20 0 -37 17 -37 37v0v274v0c0 20 17 37 37 37v0h274v0c20 -1 37 -17 37 -37zM87 243c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36zM261 69c20 0 36 16 36 36s-16 36 -36 36s-36 -16 -36 -36
|
||||
s16 -36 36 -36z" />
|
||||
<glyph glyph-name="uniF140" unicode="" horiz-adv-x="333"
|
||||
d="M333 295v0v-144v0c0 -7 -5 -13 -12 -13v0h-71v-58v-1v-17v0c0 -16 -13 -29 -29 -29c-11 0 -21 6 -26 15v0l-50 86v0v0v1l-3 3h-51h-1c-7 0 -13 6 -13 13v0v0v144v0v43v0v1v0v0c0 7 6 12 13 12h1h185c2 0 4 0 5 -1v0l50 -50v0c1 -1 2 -3 2 -5v0zM51 316v-138v-2
|
||||
c0 -7 -6 -13 -13 -13v0v0v0v0h-25v0c-7 0 -12 6 -13 12v0v141v0c0 7 6 12 13 12v0h24l1 1c7 0 13 -6 13 -13v0v0z" />
|
||||
<glyph glyph-name="uniF141" unicode="" horiz-adv-x="447"
|
||||
d="M447 294v-204v0v0c0 -11 -9 -20 -20 -20v0v0h-407c-11 0 -20 9 -20 20v0v0v204v0c0 11 9 20 20 20h407v0v0c11 0 20 -9 20 -20v0zM371 266v0v0c0 -2 2 -4 4 -4v0v0h21v-21v0c0 -2 2 -4 4 -4v0h17v0h1c2 0 4 2 4 4v0v43c0 2 -2 4 -4 4h-1v0h-42v0v0c-2 0 -4 -2 -4 -4v-18z
|
||||
M77 118v0v0c0 2 -2 4 -4 4h-1v0h-21v21v0c0 2 -2 4 -4 4v0h-17v0v0c-2 0 -4 -2 -4 -4v0v-43c0 -2 2 -4 4 -4v0v0h42v0h1c2 0 4 2 4 4v18zM77 284v0v0c0 2 -2 4 -4 4h-43c-2 0 -4 -2 -4 -4v0v0v-43v0v0c0 -2 2 -4 4 -4h17v0v0c2 0 4 2 4 4v0v0v21h22v0c2 0 4 3 4 5v0v17z
|
||||
M224 96c53 0 96 43 96 96s-43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96zM422 143v0v0c0 2 -2 4 -4 4h-18v0c-2 0 -4 -2 -4 -4v0v0v-21h-21v0c-2 0 -4 -3 -4 -5v0v-17v0v0c0 -2 2 -4 4 -4h43c2 0 4 2 4 4v0v0v43zM224 263c39 0 70 -32 70 -71c0 -15 -4 -29 -12 -40v0
|
||||
c0 3 -2 7 -4 8l-28 13l-12 6c5 3 9 8 12 14c2 5 3 10 3 16c0 3 0 6 -1 9c-4 14 -14 25 -28 25c-13 0 -25 -10 -29 -24c-1 -3 -1 -6 -1 -10c0 -6 2 -12 4 -17c3 -6 7 -11 12 -14l-11 -5l-29 -13c-3 -1 -4 -5 -4 -8v0c-8 11 -13 25 -13 40c0 39 32 71 71 71z" />
|
||||
<glyph glyph-name="uniF142" unicode="" horiz-adv-x="209"
|
||||
d="M126 219c39 -10 83 -26 83 -77c0 -42 -28 -73 -83 -79v-28v0c0 -3 -3 -6 -6 -6h-23v0c-3 0 -6 3 -6 6v28c-39 3 -68 18 -89 39v0c-1 1 -2 3 -2 5c0 1 0 2 1 3v0l22 32v0c1 2 3 3 5 3c1 0 2 0 3 -1v0l1 -1v0c14 -14 34 -28 59 -32v58c-39 9 -81 25 -81 76
|
||||
c0 38 30 70 81 75v29c0 3 3 6 6 6h23c3 0 6 -3 6 -6v0v-30c30 -3 57 -14 77 -33c1 -1 2 -2 2 -4c0 -1 -1 -3 -2 -4v0l-21 -31h-1c-1 -1 -2 -2 -4 -2c-1 0 -3 0 -4 1v0c-14 12 -30 20 -47 24v-51zM91 227v46c-17 -2 -26 -11 -26 -24c0 -11 11 -17 26 -22zM126 111
|
||||
c19 4 29 14 29 26s-12 19 -29 24v-50z" />
|
||||
<glyph glyph-name="uniF143" unicode="" horiz-adv-x="404"
|
||||
d="M379 194c14 0 25 -11 25 -25v-144c0 -14 -11 -25 -25 -25h-354c-14 0 -25 11 -25 25v144c0 14 11 25 25 25h90c11 0 21 -7 24 -17c9 -28 34 -46 63 -46s54 18 63 46c3 10 13 17 24 17h90zM197 181l-70 98c-1 2 -2 5 -1 7s3 3 6 3h33v88c0 4 3 7 7 7h60c4 0 7 -3 7 -7v-88
|
||||
h33c3 0 5 -1 6 -3s0 -5 -1 -7l-69 -98c-1 -2 -4 -3 -6 -3v0c-2 0 -4 1 -5 3z" />
|
||||
<glyph glyph-name="uniF144" unicode="" horiz-adv-x="382"
|
||||
d="M13 141c-7 0 -13 6 -13 13c0 4 2 7 4 9l176 177c2 3 7 5 11 5s7 -2 9 -5v0l178 -177c3 -2 4 -5 4 -9c0 -7 -5 -13 -12 -13v0h-357v0zM382 52v0c0 -7 -6 -13 -13 -13v0h-357v0c-7 1 -12 6 -12 13v1v49v0c0 7 5 12 12 13v0l357 1v0c7 0 13 -6 13 -13v0v0v-51z" />
|
||||
<glyph glyph-name="uniF145" unicode="" horiz-adv-x="493"
|
||||
d="M389 393c7 0 13 -6 13 -13v-376c0 -7 -6 -13 -13 -13v0v0h-376v0v0v0v0c-7 0 -13 6 -13 13v376c0 7 6 13 13 13v0h376v0v0zM51 341v-298h299v298h-299zM490 120c1 0 2 0 3 -1s0 -2 -1 -3l-31 -44c-1 -1 -1 -2 -2 -2v0c-1 0 -2 1 -3 2l-31 44c-1 1 -2 2 -1 3s2 1 3 1h15
|
||||
v40c0 2 1 3 3 3h27c2 0 3 -1 3 -3v-40h15zM427 264c-1 0 -2 0 -3 1s0 2 1 3l31 44c1 1 2 2 3 2v0c1 0 1 -1 2 -2l32 -44c1 -1 1 -2 0 -3s-2 -1 -3 -1h-15v-40c0 -2 -1 -3 -3 -3h-27c-2 0 -3 1 -3 3v40h-15zM109 284c0 17 8 26 25 26s25 -9 25 -26s-8 -25 -25 -25
|
||||
s-25 8 -25 25zM182 252c6 -1 11 -6 11 -12v-72v0c0 -3 -1 -5 -3 -7c-4 -4 -12 -4 -16 0c-2 2 -3 4 -3 7v0v50v0c0 2 -1 4 -3 4s-4 -2 -4 -4v0v-32v-33v-66c0 -7 -5 -13 -12 -13s-13 6 -13 13v66v0c0 2 -1 4 -3 4s-4 -2 -4 -4v0v-66c0 -7 -5 -13 -12 -13s-13 6 -13 13v99v32
|
||||
v0v0c0 2 -1 4 -3 4s-3 -2 -3 -4v0v0v-50v0c0 -3 -2 -5 -4 -7c-4 -4 -11 -4 -15 0c-2 2 -3 4 -3 7v0v72v0c0 7 5 12 12 12v0h91v0zM238 284c0 17 9 26 26 26s25 -9 25 -26s-8 -25 -25 -25s-26 8 -26 25zM312 252c6 -1 10 -6 10 -12v-72v0c0 -3 -1 -5 -3 -7
|
||||
c-4 -4 -11 -4 -15 0c-2 2 -3 4 -3 7v0v50v0c0 2 -1 4 -3 4s-4 -2 -4 -4v0v-32v-33v-66c0 -7 -5 -13 -12 -13s-13 6 -13 13v66v0c0 2 -1 4 -3 4s-4 -2 -4 -4v0v-66c0 -7 -5 -13 -12 -13s-13 6 -13 13v99v32v0v0c0 2 -1 4 -3 4s-4 -2 -4 -4v0v0v-50v0c0 -3 -1 -5 -3 -7
|
||||
c-4 -4 -11 -4 -15 0c-2 2 -3 4 -3 7v0v72v0c0 7 5 12 12 12v0h91v0z" />
|
||||
<glyph glyph-name="uniF146" unicode="" horiz-adv-x="283"
|
||||
d="M280 125c3 -2 3 -5 2 -8v0v0v0v0c-19 -34 -55 -67 -115 -67c-68 0 -122 38 -140 98h-21v-1c-3 0 -6 3 -6 6v21c0 3 3 6 6 6v0h15v12v13h-15v0c-3 0 -6 3 -6 6v21c0 3 3 6 6 6v0h21c19 59 73 96 140 96c60 0 96 -33 115 -67v0v0v0v0c1 -3 1 -6 -2 -8h-1v0l-40 -19v0
|
||||
c-3 -1 -5 -1 -7 2v0c-12 22 -37 40 -65 40c-34 0 -61 -17 -75 -44h100v0c3 0 6 -3 6 -6v-21c0 -3 -3 -6 -6 -6v0v0v0v0h-110c-1 -5 -1 -8 -1 -13v-12h111v0c3 0 6 -3 6 -6v-21c0 -3 -3 -6 -6 -6v0h-101c14 -28 41 -45 76 -45c28 0 52 17 64 39l1 1c2 3 4 3 7 2v0l40 -19v0h1
|
||||
z" />
|
||||
<glyph glyph-name="uniF147" unicode="" horiz-adv-x="365"
|
||||
d="M359 204c4 -2 6 -6 6 -11c0 -4 -2 -8 -4 -10v0v0l-1 -1l-79 -79v0c-24 -27 -60 -44 -99 -44c-35 0 -66 14 -90 36v-1l-87 87c-3 3 -5 7 -5 11c0 3 1 7 3 9v0l80 79c24 27 60 45 99 45c35 0 67 -14 91 -36v1zM182 102c50 0 90 40 90 90s-40 90 -90 90s-90 -40 -90 -90
|
||||
s40 -90 90 -90zM139 192c0 29 14 43 43 43s44 -14 44 -43s-15 -44 -44 -44s-43 15 -43 44z" />
|
||||
<glyph glyph-name="uniF148" unicode="" horiz-adv-x="372"
|
||||
d="M372 192c0 -3 -1 -5 -4 -7v-1l-192 -111c-2 -2 -5 -2 -7 -2c-5 0 -8 3 -8 8v78l-146 -84c-2 -2 -4 -2 -6 -2c-5 0 -9 3 -9 8v226v0c0 5 4 8 9 8c2 0 4 0 6 -2l146 -84v78v0c0 5 3 8 8 8c2 0 5 0 7 -2l191 -111v0c3 -1 5 -4 5 -8z" />
|
||||
<glyph glyph-name="uniF149" unicode="" horiz-adv-x="268"
|
||||
d="M229 163c-20 -20 -44 -32 -70 -37v-41h28v0c2 0 4 0 6 -2s2 -4 2 -6v-35c0 -4 -4 -8 -8 -8v0h-28v-34v0c0 -4 -4 -8 -8 -8v0h-35v0v0h-2v0c-4 1 -6 4 -6 8v0v34h-27v0c-4 0 -8 4 -8 8v0v35v0c0 2 0 4 2 6s4 2 6 2v0h27v41c-25 5 -50 18 -69 37c-52 52 -52 138 0 190
|
||||
s138 52 190 0s52 -138 0 -190zM134 175c46 0 83 37 83 83s-37 83 -83 83s-83 -37 -83 -83s37 -83 83 -83z" />
|
||||
<glyph glyph-name="uniF14A" unicode="" horiz-adv-x="227"
|
||||
d="M68 345c0 28 14 42 42 42s42 -14 42 -42s-14 -42 -42 -42s-42 14 -42 42zM227 171v0v-3c0 -3 -1 -6 -3 -9s-3 -4 -6 -6s-6 -3 -9 -3c-8 0 -14 4 -17 12v0l-20 76v0c-1 3 -3 5 -6 5c-4 0 -5 -2 -5 -6v-2v0l32 -122c1 -1 1 -2 1 -3l1 -1h-1h1c0 -6 -4 -10 -10 -10h-24v-81
|
||||
c0 -4 -1 -7 -3 -10s-5 -6 -8 -8s-6 -3 -10 -3c-6 0 -11 3 -15 7s-6 8 -6 14v81h-12v-81c0 -6 -2 -10 -6 -14s-8 -7 -14 -7s-11 3 -15 7s-6 8 -6 14v81h-24c-6 0 -10 4 -10 10v0v0v1c0 1 0 2 1 3l33 123v1v0v0v1v0c-1 3 -2 5 -5 5s-5 -2 -6 -5v0v0l-20 -76h-1
|
||||
c-3 -8 -8 -12 -16 -12c-5 0 -10 3 -13 6s-5 7 -5 12v3v0l28 105v0l1 2v0c3 9 8 13 18 13v1h132v-1v0c10 0 16 -4 19 -13v0l1 -2v0z" />
|
||||
<glyph glyph-name="uniF14B" unicode="" horiz-adv-x="410"
|
||||
d="M410 334c0 -10 -4 -19 -11 -25v0l-156 -155v-118v0v-2c0 -10 -7 -17 -17 -17c-3 0 -6 1 -9 2v0v0l-1 1l-40 23v0c-5 3 -9 9 -9 15v0v0v96l-155 154c-8 6 -12 16 -12 26c0 18 15 33 33 33h2v0h343v0c18 -1 32 -15 32 -33zM114 301v0v0v0z" />
|
||||
<glyph glyph-name="uniF14C" unicode="" horiz-adv-x="411"
|
||||
d="M100 308v45v1c0 7 6 12 13 12v0v0h185v0c7 0 12 -5 12 -12v0v-47h-31v27h-148v-26h-31zM76 18v262h259v-262h-259zM128 167v-37c0 -1 0 -1 1 -2s2 -1 3 -1h52v-53c0 -1 0 -2 1 -3s2 -1 3 -1h37c1 0 1 0 2 1s2 2 2 3v53h52c1 0 2 0 3 1s1 1 1 2v37c0 2 -2 4 -4 4h-52v52
|
||||
c0 2 -2 4 -4 4h-37c-2 0 -4 -2 -4 -4v-52h-52c-2 0 -4 -2 -4 -4zM20 280v0h31v-262h-31v0c-11 0 -20 9 -20 20v1v220v0c0 11 9 21 20 21zM411 38v0c0 -11 -9 -20 -20 -20v0v0h-31v262h31c11 0 20 -9 20 -20v0v-222z" />
|
||||
<glyph glyph-name="uniF14D" unicode="" horiz-adv-x="372"
|
||||
d="M364 325c4 0 8 -4 8 -8v-169c0 -2 -1 -5 -3 -6c-21 -22 -51 -36 -84 -36c-31 0 -58 11 -79 31c-23 27 -57 45 -96 45c-20 0 -39 -4 -56 -13v-145c0 -15 -12 -27 -27 -27s-27 12 -27 27v322c0 15 12 27 27 27c11 0 20 -6 24 -15c20 18 47 29 77 29c31 0 59 -11 80 -31
|
||||
c23 -27 56 -45 95 -45c21 0 41 5 58 14v0h3z" />
|
||||
<glyph glyph-name="uniF14E" unicode="" horiz-adv-x="425"
|
||||
d="M397 325c15 0 28 -13 28 -28v-248c0 -15 -13 -28 -28 -28h-369c-15 0 -28 13 -28 28v248c0 15 13 28 28 28h30l26 32c3 4 8 6 13 6h74c6 0 12 -5 15 -10c3 -4 13 -16 23 -28h188zM374 124v31c0 2 -1 4 -3 4h-45v45c0 2 -2 3 -4 3h-31c-2 0 -4 -1 -4 -3v-45h-45
|
||||
c-2 0 -3 -2 -3 -4v-31c0 -1 0 -1 1 -2s1 -1 2 -1h45v-45c0 -1 0 -2 1 -3s2 -1 3 -1h31c1 0 2 0 3 1s1 2 1 3v45h45c1 0 1 0 2 1s1 1 1 2z" />
|
||||
<glyph glyph-name="uniF14F" unicode="" horiz-adv-x="425"
|
||||
d="M312 181c9 0 17 -8 17 -17v0v0v0v-15h-34v15c0 9 8 17 17 17zM397 325c15 0 28 -13 28 -28v-248c0 -15 -13 -28 -28 -28h-369c-15 0 -28 13 -28 28v248c0 15 13 28 28 28h30l26 32c3 4 8 6 13 6h74c6 0 12 -5 15 -10c3 -4 13 -16 23 -28h188zM374 77v0v67c0 3 -2 5 -5 5
|
||||
h-6h-9v15v0c0 23 -19 42 -42 42s-41 -19 -41 -42v-15h-8h-6c-3 0 -5 -2 -5 -5v-67c0 -3 2 -5 5 -5h112c3 0 5 2 5 5z" />
|
||||
<glyph glyph-name="uniF150" unicode="" horiz-adv-x="425"
|
||||
d="M397 325c15 0 28 -13 28 -28v-248c0 -15 -13 -28 -28 -28h-369c-15 0 -28 13 -28 28v248c0 15 13 28 28 28h30l26 32c3 4 8 6 13 6h74c6 0 12 -5 15 -10c3 -4 13 -16 23 -28h188z" />
|
||||
<glyph glyph-name="uniF151" unicode="" horiz-adv-x="264"
|
||||
d="M0 264c0 15 7 22 22 22s22 -7 22 -22s-7 -22 -22 -22s-22 7 -22 22zM168 368c0 30 15 45 45 45s45 -15 45 -45s-15 -44 -45 -44s-45 14 -45 44zM92 354c0 19 9 28 28 28s28 -9 28 -28s-9 -28 -28 -28s-28 9 -28 28zM249 69v0c9 -11 13 -24 13 -38c0 -17 -5 -31 -17 -43
|
||||
s-26 -17 -43 -17c-13 0 -25 3 -35 11s-18 18 -22 30l-76 131l1 1c-5 8 -9 16 -11 25c-3 11 -5 22 -5 33c0 29 10 53 31 74s45 31 74 31c19 0 37 -5 53 -14s29 -23 38 -39s14 -33 14 -52c0 -21 -5 -41 -17 -59v0c-6 -11 -9 -23 -9 -35c0 -14 3 -27 11 -39zM39 311
|
||||
c0 15 7 23 22 23s22 -8 22 -23s-7 -22 -22 -22s-22 7 -22 22z" />
|
||||
<glyph glyph-name="uniF152" unicode="" horiz-adv-x="356"
|
||||
d="M325 59c1 0 1 -1 1 -2v-1l-6 -12c0 -1 -1 -1 -2 -1h-1l-16 8c-1 0 -1 1 -1 2s1 0 1 1l6 12c1 1 2 2 3 1zM325 328c1 0 1 -1 1 -2v-1l-7 -11c0 -1 0 -2 -1 -2l-2 1l-15 9c-1 0 -1 0 -1 1v2l7 11c1 1 2 2 3 1zM295 75c1 -1 2 -2 1 -3l-7 -12c0 -1 -1 -1 -2 -1h-1l-4 3l-5 2
|
||||
l-62 -34v0v0c-1 -1 -4 -1 -5 -1s-3 0 -4 1v0v0l-63 34l-62 -34v0h-1c-1 -1 -3 -1 -4 -1s-3 0 -4 1h-1v0l-67 37c-3 1 -4 3 -4 6v274c0 3 2 6 5 7s6 0 9 -1l62 -34l62 34h1v1h2h2h2h2l1 -1v0l62 -34l62 34c2 2 6 3 9 1l7 -5l7 -3c1 0 1 -1 1 -2s-1 0 -1 -1l-6 -12
|
||||
c0 -1 -1 -1 -2 -1l-1 1l-9 5v-252zM76 46v256l-58 31v-256zM210 46v256l-67 36v-256zM354 160c1 0 2 -2 2 -3v-27c0 -1 -1 -2 -2 -2h-13c-1 0 -3 1 -3 2v27c0 1 2 3 3 3h13zM354 52c1 0 2 -1 2 -2v-10c0 -8 -5 -11 -10 -11c-2 0 -4 1 -6 2l-8 4c-1 0 -1 1 -1 2v1l6 12l1 1
|
||||
l2 1h1h13zM349 314c0 0 7 -4 7 -12v-10c0 -1 -1 -2 -2 -2h-13c-1 0 -3 1 -3 2v8l-6 4c-1 0 -1 0 -1 1v2l6 11c1 1 2 2 3 1zM354 267c1 0 2 -1 2 -2v-27c0 -1 -1 -2 -2 -2h-13c-1 0 -3 1 -3 2v27c0 1 2 2 3 2h13zM354 106c1 0 2 -1 2 -2v-27c0 -1 -1 -3 -2 -3h-13
|
||||
c-1 0 -3 2 -3 3v27c0 1 2 2 3 2h13zM354 213c1 0 2 -1 2 -2v-27c0 -1 -1 -2 -2 -2h-13c-1 0 -3 1 -3 2v27c0 1 2 2 3 2h13z" />
|
||||
<glyph glyph-name="uniF153" unicode="" horiz-adv-x="427"
|
||||
d="M193 140c4 0 8 -4 8 -8v-112c0 -4 -4 -8 -8 -8h-72c-4 0 -8 4 -8 8v112c0 4 4 8 8 8h72zM306 372c4 0 8 -4 8 -8v-344c0 -4 -4 -8 -8 -8h-72c-4 0 -8 4 -8 8v344c0 4 4 8 8 8h72zM420 267c4 0 7 -3 7 -7v-240c0 -4 -3 -8 -7 -8h-73c-4 0 -8 4 -8 8v240c0 4 4 7 8 7h73z
|
||||
M80 267c4 0 8 -3 8 -7v-240c0 -4 -4 -8 -8 -8h-72c-4 0 -8 4 -8 8v240c0 4 4 7 8 7h72z" />
|
||||
<glyph glyph-name="uniF154" unicode="" horiz-adv-x="387"
|
||||
d="M380 238c4 0 7 -4 7 -8v-77c0 -4 -3 -8 -7 -8h-372c-4 0 -8 4 -8 8v77c0 4 4 8 8 8h372zM226 357c3 -1 5 -4 5 -8v-77c0 -4 -2 -7 -5 -8v0h-218c-4 0 -8 4 -8 8v77c0 4 4 8 8 8h218v0zM275 120c4 0 8 -4 8 -8v-77c0 -4 -4 -8 -8 -8h-267c-4 0 -8 4 -8 8v77c0 4 4 8 8 8
|
||||
h267z" />
|
||||
<glyph glyph-name="uniF155" unicode="" horiz-adv-x="380"
|
||||
d="M212 382c93 -1 167 -76 168 -169c0 -4 -2 -6 -6 -6h-1v0h-161c-4 0 -7 2 -7 6v161v0v1c0 4 3 7 7 7zM341 174v0v-2c0 -94 -76 -170 -170 -170s-171 76 -171 170s77 171 171 171h1v0h1c4 0 7 -3 7 -7l-1 -1h1v-147c0 -4 2 -7 6 -7h148c4 0 7 -3 7 -7z" />
|
||||
<glyph glyph-name="uniF156" unicode="" horiz-adv-x="410"
|
||||
d="M384 37h-359c-14 0 -25 11 -25 25v260c0 14 11 25 25 25h359c14 0 26 -11 26 -25v-260c0 -14 -12 -25 -26 -25zM359 87v210h-309v-210h309zM162 111c-5 0 -10 2 -13 5l-25 25l-31 -25c-8 -6 -19 -6 -25 2s-6 19 2 25l44 36c7 6 17 6 24 -1l21 -21l46 72c4 5 9 8 16 8
|
||||
s12 -4 15 -10l27 -58l52 92c5 9 16 12 25 7s12 -15 7 -24l-70 -123c-3 -6 -9 -9 -16 -9s-13 5 -16 11l-28 59l-40 -63c-3 -5 -8 -7 -13 -8h-2z" />
|
||||
<glyph glyph-name="uniF157" unicode="" horiz-adv-x="399"
|
||||
d="M148 320c-3 2 -5 5 -5 9c0 6 4 10 10 10c3 0 6 -1 8 -3l60 -60c3 -2 5 -5 5 -9c0 -6 -5 -10 -11 -10c-2 0 -4 1 -6 2v0h-1v1zM215 111h-25c-14 0 -28 0 -41 1l24 -42c2 -3 4 -7 4 -11c0 -10 -8 -18 -18 -18c-6 0 -11 3 -14 7v0l-38 65l-37 -65h-1c-3 -4 -8 -7 -14 -7
|
||||
c-10 0 -18 8 -18 18c0 4 2 8 4 11l32 56c-8 6 -14 29 -14 56c0 13 2 24 4 34l-57 33v0c-4 2 -6 6 -6 11c0 7 6 13 13 13c2 0 4 0 6 -1v0l56 -33c1 0 2 1 3 1h137v-129zM306 125l31 -55c2 -3 4 -7 4 -11c0 -10 -8 -18 -18 -18c-6 0 -11 3 -14 7h-1l-37 65l-38 -65v0
|
||||
c-3 -4 -8 -7 -14 -7c-10 0 -18 8 -18 18c0 4 2 8 4 11l31 54v116l83 -83c-2 -17 -7 -29 -13 -32zM399 235c0 -4 -2 -8 -4 -10v0l-11 -11v0h-10h-40l-14 -14c1 -5 1 -11 1 -16l-72 72l42 42l26 45l13 -22c3 0 5 -2 7 -3v1l26 -15c7 -3 11 -10 11 -18v-21l20 -20
|
||||
c3 -2 5 -6 5 -10z" />
|
||||
<glyph glyph-name="uniF158" unicode="" horiz-adv-x="321"
|
||||
d="M148 302c58 0 104 -48 104 -106c0 -13 -2 -24 -6 -36c0 -1 -1 -2 -1 -3c0 0 -15 -26 -25 -38c-1 -2 -3 -3 -4 -5c-7 -8 -10 -11 -10 -24c1 -27 1 -37 -1 -45c-4 -26 -23 -39 -55 -40v0v0c-9 0 -17 7 -17 16c0 5 1 10 4 13s7 5 12 5c21 1 22 7 23 11v2c1 5 0 21 0 37
|
||||
c-1 26 10 38 18 48l4 4c6 7 17 24 21 32c2 7 3 15 3 23c0 39 -31 72 -70 72s-71 -33 -71 -72c0 -9 -8 -17 -17 -17s-17 8 -17 17c0 58 47 106 105 106zM172 194c0 13 -11 24 -24 24s-24 -11 -24 -24c0 -8 -7 -15 -15 -15s-14 7 -14 15c0 29 24 52 53 52s52 -23 52 -52
|
||||
c0 -8 -6 -15 -14 -15s-14 7 -14 15zM75 142c6 6 16 6 22 0c3 -3 5 -8 5 -12s-2 -8 -5 -11l-70 -71c-3 -3 -7 -4 -11 -4s-8 1 -11 4s-5 8 -5 12s2 8 5 11zM207 334c38 0 69 -30 69 -68v0v-7v0c0 -3 -3 -6 -6 -6v0h-12v0c-3 0 -6 3 -6 6v0v7v0c0 24 -21 44 -45 44v0v0h-7v0
|
||||
c-3 0 -5 3 -5 6v0v11v0c0 3 2 7 5 7v0h7v0v0zM321 266v0v-7v0c0 -3 -3 -6 -6 -6v0h-11v0c-3 0 -7 3 -7 6v0v7v0c0 49 -41 89 -90 89v0v0h-7v0c-3 0 -5 3 -5 6v0v12v0c0 3 2 6 5 6v0h7v0v0c63 0 114 -50 114 -113z" />
|
||||
<glyph glyph-name="uniF159" unicode="" horiz-adv-x="409"
|
||||
d="M295 379c63 0 114 -51 114 -114c0 -68 -33 -108 -59 -140l-6 -7c-31 -38 -128 -108 -132 -111c-2 -2 -5 -2 -8 -2s-5 0 -7 2c-4 3 -101 73 -132 111l-6 7c-26 32 -59 72 -59 140c0 63 51 114 114 114c36 0 69 -16 90 -44c21 28 55 44 91 44z" />
|
||||
<glyph glyph-name="uniF15A" unicode="" horiz-adv-x="353"
|
||||
d="M348 254c3 -2 5 -6 5 -10v-233c0 -7 -6 -13 -13 -13h-96c-7 0 -12 6 -12 13v143h-111v-143c0 -7 -5 -13 -12 -13h-96c-7 0 -13 6 -13 13v233c0 4 2 8 5 10l161 129c5 4 11 4 16 0z" />
|
||||
<glyph glyph-name="uniF15B" unicode="" horiz-adv-x="300"
|
||||
d="M0 362v0h300l-27 -306l-123 -34l-123 34zM243 289l1 11h-94v0h-94l1 -11l9 -103h84v0h46l-4 -49l-42 -11v0v0l-42 11l-3 30h-20h-17l5 -59l77 -21v0v0l77 21v7l9 98l1 11h-10h-77v0h-50l-3 38h53v0h90h1v8z" />
|
||||
<glyph glyph-name="uniF15C" unicode="" horiz-adv-x="355"
|
||||
d="M337 370c10 0 18 -7 18 -17v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM337 64c10 0 18 -7 18 -17v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM355 149v0v-16v0c0 -10 -8 -17 -18 -17v0h-198
|
||||
c-10 0 -18 7 -18 17v16c0 10 8 17 18 17h198v0v0c10 0 18 -7 18 -17zM355 250v0v-16v0c0 -10 -8 -17 -18 -17v0h-198c-10 0 -18 7 -18 17v16c0 10 8 18 18 18h198v0v0c10 0 18 -8 18 -18zM0 192c0 1 0 1 1 2v1l64 36c1 1 1 1 2 1c2 0 3 -1 3 -3v-74v0c0 -2 -1 -3 -3 -3
|
||||
c-1 0 -1 0 -2 1l-63 36v0c-1 0 -2 2 -2 3z" />
|
||||
<glyph glyph-name="uniF15D" unicode="" horiz-adv-x="355"
|
||||
d="M337 370c10 0 18 -7 18 -17v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM337 64c10 0 18 -7 18 -17v-16c0 -10 -8 -17 -18 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM355 149v0v-16v0c0 -10 -8 -17 -18 -17v0h-199
|
||||
c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h199v0c10 0 18 -7 18 -17zM355 250v0v-16v0c0 -10 -8 -17 -18 -17v0h-199c-10 0 -17 7 -17 17v16c0 10 7 18 17 18h199v0c10 0 18 -8 18 -18zM3 152c-2 0 -3 1 -3 3v74v0c0 2 1 3 3 3c1 0 1 0 2 -1l63 -36v0c1 0 2 -2 2 -3
|
||||
s0 -1 -1 -2v-1l-64 -36c-1 -1 -1 -1 -2 -1z" />
|
||||
<glyph glyph-name="uniF15E" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM212 85v124c0 4 -3 7 -7 7h-26c-4 0 -7 -3 -7 -7v-124c0 -4 3 -6 7 -6h26c4 0 7 2 7 6zM192 244c13 0 23 10 23 23s-10 23 -23 23s-23 -10 -23 -23s10 -23 23 -23z" />
|
||||
<glyph glyph-name="uniF15F" unicode="" horiz-adv-x="108"
|
||||
d="M108 324v-4v0l-58 -261v0c-1 -7 -6 -12 -13 -12h-25v0c-7 1 -12 6 -12 13v3v0v0v0l58 261v0c0 7 6 13 13 13h24c7 0 13 -6 13 -13z" />
|
||||
<glyph glyph-name="uniF160" unicode="" horiz-adv-x="445"
|
||||
d="M445 218v0v0v-32v0c0 -2 0 -5 -2 -7s-5 -2 -7 -2v0h-27h-1v-61v0v-39v0c0 -5 -4 -9 -9 -9h-1h-31v0c-5 0 -10 4 -10 9v0v21v0v79h-25v-26v0v-39v0c0 -5 -5 -9 -10 -9v0h-31v0h-1c-5 0 -9 4 -9 9v0v16v23v26h-45c-10 -56 -58 -99 -117 -99c-66 0 -119 53 -119 119
|
||||
s53 119 119 119c55 0 102 -38 115 -89h163h12h27c2 0 5 -1 7 -3s2 -4 2 -6zM119 128c38 0 68 30 68 68s-30 68 -68 68s-68 -30 -68 -68s30 -68 68 -68z" />
|
||||
<glyph glyph-name="uniF161" unicode="" horiz-adv-x="488"
|
||||
d="M60 101c-14 0 -26 12 -26 26v226c0 14 12 25 26 25h368c14 0 25 -11 25 -25v-226c0 -14 -11 -26 -25 -26h-368zM85 327v-175h318v175h-318zM476 76c6 0 12 -6 12 -12v-28c0 -3 -2 -7 -4 -9l-18 -18c-2 -2 -5 -3 -8 -3h-430c-3 0 -6 2 -8 4l-17 18c-2 2 -3 5 -3 8v28
|
||||
c0 6 6 12 12 12h464zM288 35v12c0 1 -1 2 -2 2h-84c-1 0 -3 -1 -3 -2v-12c0 -1 2 -3 3 -3h84c1 0 2 2 2 3z" />
|
||||
<glyph glyph-name="uniF162" unicode="" horiz-adv-x="381"
|
||||
d="M76 173v119h229v-119h-229zM82 92v56h57v-56h-57zM246 92v56h57v-56h-57zM164 92v56h57v-56h-57zM358 368c13 0 23 -10 23 -23v-307v0c-1 -12 -11 -22 -23 -22h-335v0v0c-12 0 -22 10 -23 22v0v307v0c0 13 10 23 23 23v0h335v0zM330 67v0v250h-279v-250h279z" />
|
||||
<glyph glyph-name="uniF163" unicode="" horiz-adv-x="426"
|
||||
d="M368 351v0l-45 -45c-3 -3 -7 -3 -10 0v0l-11 11v0c-3 3 -3 7 0 10l45 45v0c3 3 8 3 11 0v0v0l10 -10v0c3 -3 3 -8 0 -11v0v0v0zM206 349c-4 0 -8 3 -8 7v0v64c0 4 4 8 8 8v0h14v0c4 0 8 -4 8 -8v-64v0c0 -4 -4 -7 -8 -7v0h-14v0zM426 243v0v-15v0c0 -4 -3 -7 -7 -7v0h-64
|
||||
c-4 0 -7 3 -7 7v0v15v0c0 4 3 8 7 8h64v0c4 0 7 -4 7 -8zM213 324c60 0 109 -49 109 -109c0 -22 -7 -42 -18 -59c-18 -26 -28 -60 -29 -99c-1 -2 -4 -5 -7 -5h-1v0h-108v0h-1c-3 0 -5 2 -6 4c-1 37 -12 71 -28 96v0c-13 18 -20 39 -20 63c0 60 49 109 109 109zM268 -12
|
||||
c4 0 7 -3 7 -7v-17c0 -4 -3 -8 -7 -8h-1v0h-108v0h-1c-4 0 -8 4 -8 8v17c0 4 4 7 8 7h1v0h108v0h1zM268 37c4 0 7 -4 7 -8v-17c0 -4 -3 -8 -7 -8l-1 1v-1h-108v1l-1 -1c-4 0 -8 4 -8 8v17v0c0 4 4 8 8 8h1v0h108v0h1zM71 245c4 0 8 -4 8 -8v0v-14v0c0 -4 -4 -8 -8 -8v0h-64
|
||||
c-4 0 -7 4 -7 8v14c0 4 3 8 7 8h64v0zM60 354c-3 3 -3 7 0 10v0l11 11v0v0c3 3 8 3 11 0l45 -46v0c3 -3 3 -7 0 -10v0l-11 -10v0c-3 -3 -7 -4 -10 -1v0z" />
|
||||
<glyph glyph-name="uniF164" unicode="" horiz-adv-x="333"
|
||||
d="M333 67c0 -7 -6 -13 -13 -13v0v0v0v0h-26v1c-7 0 -11 5 -12 11v0v141v0c0 7 5 13 12 13v0h25h1c7 0 12 -6 12 -13v0v0v-138c0 -1 1 -1 1 -2zM256 46v0v-1v0v0c0 -7 -6 -12 -13 -12h-1h-185c-2 0 -4 0 -5 1v0l-50 50v0c-1 1 -2 3 -2 5v0v144v0c0 7 6 13 13 13v0h70v58v1
|
||||
v17v0v0c0 16 13 29 29 29c11 0 21 -6 26 -15v0l51 -87c1 -1 1 -2 2 -3h51h1c7 0 13 -6 13 -13v0v0v-144v0v-43zM15 89l1 -1l-1 1v0z" />
|
||||
<glyph glyph-name="uniF165" unicode="" horiz-adv-x="353"
|
||||
d="M323 339c39 -39 40 -101 4 -141v0l-52 -52c-9 -9 -20 -16 -31 -21c-4 -10 -10 -20 -18 -28v0l-51 -52c-40 -40 -105 -40 -145 0s-40 105 0 145l52 52v-1c8 8 17 14 27 18c5 11 13 23 22 32l52 51v0c40 36 101 36 140 -3zM140 82l37 38c-17 4 -33 13 -46 26s-23 30 -27 47
|
||||
l-37 -38v0c-20 -20 -20 -53 0 -73s53 -20 73 0v0zM168 183c9 -9 21 -14 33 -15c-1 12 -6 24 -15 33s-21 14 -33 15c1 -12 6 -24 15 -33zM290 232v0c17 20 16 51 -3 70s-50 20 -70 3v0l-3 -3v0v0l-38 -38c17 -4 33 -13 46 -26s23 -30 27 -47l38 38v0v0z" />
|
||||
<glyph glyph-name="uniF166" unicode="" horiz-adv-x="431"
|
||||
d="M414 345c10 0 17 -8 17 -18v-16c0 -10 -7 -17 -17 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 18 17 18h320zM414 217c10 0 17 -7 17 -17v-16c0 -10 -7 -17 -17 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 17 17 17h320zM414 90c10 0 17 -7 17 -17v-16c0 -10 -7 -18 -17 -18
|
||||
h-320c-10 0 -17 8 -17 18v16c0 10 7 17 17 17h320zM0 319c0 17 9 26 26 26s25 -9 25 -26s-8 -25 -25 -25s-26 8 -26 25zM0 197c0 17 9 26 26 26s25 -9 25 -26s-8 -25 -25 -25s-26 8 -26 25zM0 65c0 17 9 25 26 25s25 -8 25 -25s-8 -26 -25 -26s-26 9 -26 26z" />
|
||||
<glyph glyph-name="uniF167" unicode="" horiz-adv-x="423"
|
||||
d="M29 333l-9 -9l-6 7l17 17h10v-55h-12v40zM21 210c-6 0 -10 -2 -14 -6l-7 8c5 6 13 9 21 9c12 0 21 -7 21 -18c0 -9 -8 -18 -22 -28h22v-10h-41v9c22 17 29 22 29 29c0 5 -4 7 -9 7zM30 65c6 -1 13 -5 13 -13c0 -9 -8 -16 -21 -16c-10 0 -18 4 -22 9l6 8c4 -4 10 -7 15 -7
|
||||
c7 0 11 3 11 7s-3 7 -11 7h-7v10h7c6 0 10 2 10 6s-4 6 -10 6c-5 0 -10 -1 -14 -5l-6 7c4 5 11 9 21 9c13 0 20 -6 20 -15c0 -7 -6 -12 -12 -13zM406 346c10 0 17 -7 17 -17v-16c0 -10 -7 -18 -17 -18h-320c-10 0 -17 8 -17 18v16c0 10 7 17 17 17h320zM406 219
|
||||
c10 0 17 -8 17 -18v-16c0 -10 -7 -17 -17 -17h-320c-10 0 -17 7 -17 17v16c0 10 7 18 17 18h320zM406 91c10 0 17 -7 17 -17v-16c0 -10 -7 -18 -17 -18h-320c-10 0 -17 8 -17 18v16c0 10 7 17 17 17h320z" />
|
||||
<glyph glyph-name="uniF168" unicode="" horiz-adv-x="332"
|
||||
d="M321 103c6 0 11 -6 11 -12v-1v-53c0 -6 -5 -11 -11 -11v0h-182v0c-6 0 -11 5 -11 11v0v53v1c0 6 5 12 11 12v0v0h182v0zM65 103c6 0 12 -6 12 -12v0v0v-54v0c0 -6 -6 -11 -12 -11v0h-53v0v0c-6 0 -12 5 -12 11v0v54v0v0c0 6 6 12 12 12v0v0h53v0zM321 231
|
||||
c6 0 11 -6 11 -12v-1v-53c0 -6 -5 -11 -11 -11v0h-182v0c-6 0 -11 5 -11 11v0v53v1c0 6 5 12 11 12v0v0h182v0zM65 231c6 0 12 -6 12 -12v0v0v-54v0c0 -6 -6 -11 -12 -11v0h-53v0v0c-6 0 -12 5 -12 11v0v54v0v0c0 6 6 12 12 12v0v0h53v0zM128 293v0v53v1c0 6 5 11 11 11v0v0
|
||||
h182v0c6 0 11 -5 11 -11v-1v-53c0 -6 -5 -12 -11 -12v0h-182v0c-6 0 -11 6 -11 12v0zM65 358c6 0 12 -5 12 -11v0v0v-54v0c0 -6 -6 -12 -12 -12v0h-53v0v0c-6 0 -12 6 -12 12v0v54v0v0c0 6 6 11 12 11v0v0h53v0z" />
|
||||
<glyph glyph-name="uniF169" unicode="" horiz-adv-x="332"
|
||||
d="M0 293v53v1c0 6 6 11 12 11v0v0h309v0c6 0 11 -5 11 -11v0v-54v0c0 -6 -5 -12 -11 -12v0h-309v0c-6 0 -12 6 -12 12v0zM321 230c6 0 11 -5 11 -11v0v-54v0c0 -6 -5 -11 -11 -11v0h-309v0c-6 0 -12 5 -12 11v0v53v1c0 6 6 11 12 11v0v0h309v0zM321 103c6 0 11 -6 11 -12v0
|
||||
v-54v0c0 -6 -5 -11 -11 -11v0h-309v0c-6 0 -12 5 -12 11v0v53v1c0 6 6 12 12 12v0v0h309v0z" />
|
||||
<glyph glyph-name="uniF16A" unicode="" horiz-adv-x="356"
|
||||
d="M342 222c7 0 14 -7 14 -14v-197c0 -7 -7 -14 -14 -14h-329c-7 0 -13 7 -13 14v197c0 7 6 14 13 14h19h22v43c0 67 54 122 121 122s122 -55 122 -122v0v-43h26h19zM126 265v-43h99v43v1v0v0c0 27 -23 49 -50 49c-28 0 -49 -22 -49 -50z" />
|
||||
<glyph glyph-name="uniF16B" unicode="" horiz-adv-x="346"
|
||||
d="M346 327v-137c0 -2 -1 -5 -3 -6s-5 -2 -7 -1l-130 44c-3 1 -5 3 -5 6s1 6 3 8l30 21l5 4c-18 14 -41 23 -66 23c-40 0 -75 -22 -93 -55v0c-4 -6 -12 -9 -18 -5l-42 24v0c-6 3 -8 11 -5 17v0c31 56 90 93 158 93c50 0 95 -20 128 -53l2 2l31 22c2 2 5 1 8 0s4 -4 4 -7z
|
||||
M326 131c6 -3 9 -11 6 -17v0c-31 -56 -91 -93 -159 -93c-50 0 -94 20 -127 53l-3 -2l-30 -22c-2 -2 -5 -1 -8 0s-5 4 -5 7v137c0 2 1 5 3 6s5 2 7 1l130 -44c3 -1 6 -3 6 -6s-1 -6 -3 -8l-31 -21l-5 -4c18 -14 41 -23 66 -23c40 0 76 22 94 55v0c4 6 12 9 18 5l41 -24v0z
|
||||
" />
|
||||
<glyph glyph-name="uniF16C" unicode="" horiz-adv-x="397"
|
||||
d="M233 395c91 0 164 -74 164 -164s-73 -164 -164 -164c-26 0 -51 6 -73 17l-82 -82v1c-8 -8 -20 -14 -33 -14c-25 0 -45 20 -45 45c0 13 6 25 14 33h-1l80 79c-15 25 -24 54 -24 85c0 90 73 164 164 164zM234 132c57 0 103 45 103 102s-46 102 -103 102s-102 -45 -102 -102
|
||||
s45 -102 102 -102z" />
|
||||
<glyph glyph-name="uniF16D" unicode="" horiz-adv-x="394"
|
||||
d="M381 345c7 0 13 -6 13 -13v-24c0 -2 -1 -2 -2 -3s-4 -2 -5 -3l-188 -110c-1 0 -1 -1 -2 -1s0 1 -1 1l-194 110c-1 1 -2 2 -2 3v27c0 7 6 13 13 13h368zM393 265c1 -1 1 -1 1 -2v-177c0 -1 -1 -3 -2 -3l-1 -1c-1 0 -1 0 -2 1l-107 115c-1 1 0 2 0 3s0 2 1 2l106 62
|
||||
c1 1 3 1 4 0zM253 182l127 -137c1 -1 1 -3 0 -4s-2 -2 -3 -2h-364c-2 0 -4 1 -6 2c-1 1 -2 2 -2 3s0 2 1 3l142 131c1 1 3 2 4 1l38 -22c5 -3 11 -2 16 1l42 25c1 1 4 0 5 -1zM117 194l-112 -103c-1 -1 -1 -1 -2 -1h-1c-1 1 -2 2 -2 3v167c0 1 1 2 2 3s2 1 3 0l111 -64
|
||||
c1 -1 2 -1 2 -2s0 -2 -1 -3z" />
|
||||
<glyph glyph-name="uniF16E" unicode="" horiz-adv-x="466"
|
||||
d="M49 347c0 28 14 42 42 42s43 -14 43 -42s-15 -42 -43 -42s-42 14 -42 42zM172 293c5 -1 9 -2 12 -6s6 -8 6 -13v-120v0c0 -5 -3 -10 -6 -13s-7 -5 -12 -5s-10 2 -13 5s-5 8 -5 13v0v82v1c0 4 -2 6 -6 6s-6 -2 -6 -6v-1v-53v-55v-110c0 -6 -2 -11 -6 -15s-8 -6 -14 -6
|
||||
s-11 2 -15 6s-6 9 -6 15v110v0c0 4 -2 6 -6 6s-6 -2 -6 -6v0v-110c0 -6 -2 -11 -6 -15s-9 -6 -15 -6s-11 2 -15 6s-6 9 -6 15v165v53v1v0c0 4 -1 6 -5 6s-6 -2 -6 -6v0v-1v-82v0c0 -5 -2 -10 -5 -13s-8 -5 -13 -5s-10 2 -13 5s-5 8 -5 13v0v120v0c0 5 2 10 6 14s9 5 14 5v0
|
||||
h152v0zM305 347c0 28 14 42 42 42s43 -14 43 -42s-15 -43 -43 -43s-42 15 -42 43zM466 171v0v-3c0 -3 0 -6 -2 -9s-4 -5 -7 -7s-6 -2 -9 -2c-8 0 -14 3 -17 11v0l-21 78v0c-1 3 -2 4 -5 4c-4 0 -6 -1 -6 -5v-2v0l33 -124c1 -1 1 -3 1 -4h1h-1h1c0 -6 -4 -10 -10 -10h-25v-82
|
||||
c0 -6 -2 -11 -6 -15s-9 -6 -15 -6s-11 2 -15 6s-6 9 -6 15v82h-12v-82c0 -4 -1 -8 -3 -11s-4 -6 -7 -8s-7 -2 -11 -2c-6 0 -11 2 -15 6s-6 9 -6 15v82h-24c-6 0 -10 4 -10 10v0v0v0c0 1 0 3 1 4l33 124v1v1v0v1v0c-1 3 -2 4 -5 4s-5 -1 -6 -4v0v0l-21 -78v0
|
||||
c-3 -8 -9 -11 -17 -11c-5 0 -9 1 -13 5s-5 8 -5 13v3v0l29 106v0v2v0c3 9 9 14 19 14v0h134v0v0c10 0 16 -5 19 -14v0l1 -2v0z" />
|
||||
<glyph glyph-name="uniF16F" unicode="" horiz-adv-x="342"
|
||||
d="M342 354v0v-106v0c0 -4 -4 -8 -8 -8h-35c-4 0 -8 4 -8 8v28l-46 -46c14 -21 23 -46 23 -74c0 -74 -60 -134 -134 -134s-134 60 -134 134s60 134 134 134c28 0 54 -9 76 -24l44 45h-26v0c-4 0 -8 4 -8 8v0v0v35c0 4 4 8 8 8v0h106v0c4 0 8 -4 8 -8v0zM134 73
|
||||
c46 0 83 37 83 83s-37 83 -83 83s-83 -37 -83 -83s37 -83 83 -83z" />
|
||||
<glyph glyph-name="uniF170" unicode="" horiz-adv-x="190"
|
||||
d="M49 346c0 28 14 42 42 42s43 -14 43 -42s-15 -42 -43 -42s-42 14 -42 42zM172 292c5 -1 9 -2 12 -6s6 -9 6 -14v-120v0c0 -5 -3 -9 -6 -12s-7 -5 -12 -5s-10 2 -13 5s-5 7 -5 12v0v83v1c0 4 -2 6 -6 6s-6 -2 -6 -6v-1v-53v-55v-110c0 -6 -2 -11 -6 -15s-8 -6 -14 -6
|
||||
s-11 2 -15 6s-6 9 -6 15v110v0c0 4 -2 6 -6 6s-6 -2 -6 -6v0v-110c0 -6 -2 -11 -6 -15s-9 -6 -15 -6s-11 2 -15 6s-6 9 -6 15v165v53v1v0c0 4 -1 6 -5 6s-6 -2 -6 -6v0v-1v-83v0c0 -5 -2 -9 -5 -12s-8 -5 -13 -5s-10 2 -13 5s-5 7 -5 12v0v120v0c0 4 1 7 3 10s4 6 7 8
|
||||
s6 2 10 2v0h152v0z" />
|
||||
<glyph glyph-name="uniF171" unicode="" horiz-adv-x="430"
|
||||
d="M430 407v-430v0v-1v-2h-1c-1 -6 -6 -11 -13 -11v0h-402v0c-8 0 -14 6 -14 14v0v0v283v0l161 161v0v0v0v0h255v0v0v0v0c8 0 14 -6 14 -14v0zM305 370l-19 -33l93 -92v125h-74zM161 246h-110v-31l86 -85l139 240h-101v-110v0v0c0 -8 -6 -14 -14 -14v0zM51 14h19l53 93
|
||||
l-72 72v-165zM99 14h280v194l-106 106zM276 215c34 0 62 -28 62 -62c0 -14 -4 -27 -12 -37l-39 -67c0 -1 -1 -2 -2 -3v0v0c-2 -2 -5 -4 -8 -4c-4 0 -8 1 -10 4v0v1v1l-40 69c-7 10 -12 22 -12 36c0 34 27 62 61 62zM276 122c17 0 30 13 30 30s-13 31 -30 31s-30 -14 -30 -31
|
||||
s13 -30 30 -30z" />
|
||||
<glyph glyph-name="uniF172" unicode="" horiz-adv-x="289"
|
||||
d="M144 395c80 0 145 -65 145 -145c0 -33 -12 -63 -30 -87l-90 -157c-1 -2 -3 -4 -4 -6l-1 -2v1c-5 -6 -12 -10 -20 -10c-9 0 -16 4 -21 11v0v0c-1 1 -1 2 -2 3l-92 161c-18 24 -29 54 -29 86c0 80 64 145 144 145zM143 177c39 0 71 32 71 71s-32 71 -71 71s-71 -32 -71 -71
|
||||
s32 -71 71 -71z" />
|
||||
<glyph glyph-name="uniF173" unicode="" horiz-adv-x="385"
|
||||
d="M76 302c8 0 14 -6 14 -14v-127v0c-1 -7 -7 -12 -14 -12c-42 0 -76 35 -76 77s34 76 76 76zM385 364v0v0v-24v-236v-23v0v-2c0 -8 -6 -14 -14 -14c-4 0 -7 2 -9 4l-134 77h-98c-7 0 -13 6 -14 13v0v132c0 8 6 14 14 14h110l123 70c2 2 5 3 8 3c8 0 14 -6 14 -14zM224 41v0
|
||||
c3 -6 2 -13 -3 -17v-1l-26 -14v0c-1 -1 -1 -2 -2 -2c-6 -4 -14 -1 -18 5v0l-1 1v0v0l-49 85v1s-1 0 -1 1c-4 7 -2 15 5 19c2 1 4 2 6 2v0h37v0c4 0 7 -3 9 -6v0l43 -73v-1v0v0z" />
|
||||
<glyph glyph-name="uniF174" unicode="" horiz-adv-x="261"
|
||||
d="M261 196c0 -65 -48 -119 -111 -128v-28h68v0c11 0 19 -8 19 -19s-8 -20 -19 -20v0h-175v0c-11 0 -20 9 -20 20s9 19 20 19v0h68v28c-63 9 -111 63 -111 128v0v74c0 11 8 19 19 19s20 -8 20 -19v-73v0c0 -51 40 -92 91 -92s92 41 92 92v73c0 11 8 19 19 19s20 -8 20 -19
|
||||
v-73v0v0v-1v0zM65 197v2v0v119v0c1 36 29 65 65 65s65 -29 66 -65v0v-119v0v-2c0 -36 -30 -65 -66 -65s-65 29 -65 65z" />
|
||||
<glyph glyph-name="uniF175" unicode="" horiz-adv-x="384"
|
||||
d="M281 219c3 0 5 -2 5 -5v-44c0 -3 -2 -5 -5 -5h-178c-3 0 -5 2 -5 5v44c0 3 2 5 5 5h178zM192 333c-78 0 -141 -63 -141 -141s63 -141 141 -141s141 63 141 141s-63 141 -141 141zM192 384v0c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192z
|
||||
" />
|
||||
<glyph glyph-name="uniF176" unicode="" horiz-adv-x="414"
|
||||
d="M404 251c6 0 10 -5 10 -11v-96c0 -6 -4 -11 -10 -11h-394c-6 0 -10 5 -10 11v96c0 6 4 11 10 11h394z" />
|
||||
<glyph glyph-name="uniF177" unicode="" horiz-adv-x="224"
|
||||
d="M211 295c7 0 13 -6 13 -13v-307c0 -7 -6 -13 -13 -13h-199v0c-7 0 -12 6 -12 13v307c0 7 5 13 12 13v0h199zM112 -24c7 0 13 5 13 12s-6 13 -13 13s-12 -6 -12 -13s5 -12 12 -12zM173 13v0v231h-122v-231h122zM212 368v0v-1v0v0l-9 -9v0v0h-1v0c-3 -3 -7 -3 -10 -1v0v1v0
|
||||
v0l-5 5v0c-41 41 -109 40 -150 -1v0v0l-6 -5v0c-3 -2 -6 -2 -9 0v0l-10 9v0c-3 3 -3 7 -1 10v1h1v0v0l5 5v0v0c52 52 138 53 190 1v0v-1v0v0l5 -5v0c2 -3 2 -6 0 -9zM174 339c2 -3 2 -6 0 -9v0l-9 -10v0v0v0v0c-3 -3 -8 -3 -11 -1v0v1v0v0l-5 5v0c-21 20 -54 20 -74 0v-1v0
|
||||
l-6 -5v0c-3 -2 -6 -2 -9 0v0l-10 9v1c-3 3 -3 7 -1 10v0l6 5v0v1c31 31 82 31 114 0v0l5 -6v0z" />
|
||||
<glyph glyph-name="uniF178" unicode="" horiz-adv-x="224"
|
||||
d="M211 358c7 0 13 -5 13 -12v-308c0 -7 -6 -12 -13 -12h-199v0c-7 0 -12 5 -12 12v308c0 7 5 12 12 12v0h199zM112 39c7 0 13 5 13 12s-6 13 -13 13s-12 -6 -12 -13s5 -12 12 -12zM173 77v0v230h-122v-230h122z" />
|
||||
<glyph glyph-name="uniF179" unicode="" horiz-adv-x="471"
|
||||
d="M442 381c16 0 29 -12 29 -28v-252c0 -16 -13 -29 -29 -29h-156v-44h44c5 0 9 -3 9 -8v-9c0 -5 -4 -8 -9 -8h-194c-5 0 -8 3 -8 8v9c0 5 3 8 8 8h48v44h-155c-16 0 -29 13 -29 29v252c0 16 13 28 29 28h413zM51 123h368v208h-368v-208z" />
|
||||
<glyph glyph-name="uniF17A" unicode="" horiz-adv-x="467"
|
||||
d="M465 48c1 -2 2 -4 2 -6c0 -7 -5 -13 -12 -14v0h-256h-103h-87v1c-1 0 -1 -1 -2 -1c-4 0 -7 3 -7 7c0 2 0 4 1 5l8 13v1h1l81 140c2 4 6 7 11 7s9 -3 11 -7v0l27 -48l114 196c4 8 12 14 21 14s16 -5 20 -13v0l171 -295h-1z" />
|
||||
<glyph glyph-name="uniF17B" unicode="" horiz-adv-x="382"
|
||||
d="M366 378c9 0 16 -7 16 -16v-253c0 -31 -31 -56 -69 -56s-69 25 -69 56s31 56 69 56c6 0 12 -1 18 -2v135h-193v-236c0 -31 -31 -56 -69 -56s-69 25 -69 56s31 56 69 56c6 0 12 -1 18 -2v246c0 9 8 16 17 16v0h262v0z" />
|
||||
<glyph glyph-name="uniF17C" unicode="" horiz-adv-x="397"
|
||||
d="M397 52v0c0 -7 -6 -13 -13 -13v-1h-25v0c-7 0 -13 6 -13 13v1v0v120l-170 -99c-2 -2 -5 -2 -7 -2c-5 0 -8 3 -8 8v78l-146 -84c-2 -2 -4 -2 -6 -2c-5 0 -9 3 -9 8v226v0c0 5 4 8 9 8c2 0 4 0 6 -2l146 -84v78v0c0 5 3 8 8 8c2 0 5 0 7 -2l170 -99v119v2c0 7 6 13 13 13
|
||||
l1 -1h24v0c7 0 12 -4 13 -11v0v-2v0v0v-280z" />
|
||||
<glyph glyph-name="uniF17D" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM192 51c34 0 66 13 90 33l-24 24c-3 0 -4 1 -6 3v0l-4 7l-21 21l-16 -28h-1c-2 -2 -4 -4 -7 -4c-5 0 -10 5 -10 10c0 2 1 4 2 6l13 23h-21h-23l13 -23c1 -2 3 -4 3 -6
|
||||
c0 -5 -5 -10 -10 -10c-3 0 -6 2 -8 4v0l-21 36l-21 -36v0c-2 -2 -5 -4 -8 -4c-5 0 -10 5 -10 10c0 2 2 4 3 6l17 31c-4 4 -7 16 -7 31c0 7 1 14 2 19l-32 18v0c-2 1 -3 3 -3 6c0 4 3 7 7 7c1 0 3 0 4 -1v0l31 -18v1v0h25l-65 65c-20 -24 -33 -56 -33 -90
|
||||
c0 -78 63 -141 141 -141zM300 102c20 24 33 56 33 90c0 78 -63 141 -141 141c-34 0 -66 -13 -90 -33l83 -83h26l30 30h-1l17 30l10 -17h1v0l14 -8c4 -2 6 -6 6 -10v-11l11 -11c2 -1 3 -4 3 -6s-1 -4 -2 -5v0l-6 -6v0h-6h-22l-8 -8c0 -3 1 -6 1 -10c0 -16 -4 -29 -9 -32l3 -4
|
||||
z" />
|
||||
<glyph glyph-name="uniF17E" unicode="" horiz-adv-x="384"
|
||||
d="M272 213c3 0 5 -3 5 -6v-31v0c0 -3 -2 -5 -5 -5v0v0h-4v0c-3 0 -6 2 -6 5v0v1v0v0v30v0c0 3 3 6 6 6v0h4v0zM293 213c3 0 6 -3 6 -6v0v-30v-1v0c0 -3 -3 -5 -6 -5v0v0h-3v0c-3 0 -6 2 -6 5v0v31v0c0 3 3 6 6 6v0h3v0zM192 384c106 0 192 -86 192 -192s-86 -192 -192 -192
|
||||
s-192 86 -192 192s86 192 192 192zM192 51c34 0 66 13 90 33l-87 87h-104c-3 0 -6 3 -6 6v0v30v0v0c0 3 3 6 6 6v0h62l-69 69c-20 -24 -33 -56 -33 -90c0 -78 63 -141 141 -141zM300 102c20 24 33 56 33 90c0 78 -63 141 -141 141c-34 0 -66 -13 -90 -33l87 -87h60v0
|
||||
c3 0 6 -3 6 -6v0v-30v0c0 -3 -3 -6 -6 -6h-18z" />
|
||||
<glyph glyph-name="uniF17F" unicode="" horiz-adv-x="360"
|
||||
d="M301 46c5 0 9 -4 9 -9v0v-45v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0v-127v0v0v0v0c0 -5 -4 -9 -9 -9h-33c-5 0 -9 4 -9 9v0v105h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v15v0c0 5 4 9 9 9v0h33z
|
||||
M351 174c5 0 9 -4 9 -9v-36c0 -5 -4 -8 -9 -8h-40v-40c0 -5 -4 -9 -9 -9h-35c-5 0 -9 4 -9 9v40h-40c-5 0 -9 3 -9 8v36c0 5 4 9 9 9h40v40c0 5 4 8 9 8h35c5 0 9 -3 9 -8v-40h40z" />
|
||||
<glyph glyph-name="uniF180" unicode="" horiz-adv-x="361"
|
||||
d="M310 410v-392v0v-13c0 -5 -4 -9 -9 -9h-8h-276h-8c-5 0 -9 4 -9 9v13v271v5v12l133 133h9v0h147v0h12c5 0 9 -4 9 -9v-20v0zM51 47h208v341h-108v-91c0 -5 -4 -8 -9 -8h-91v-242zM354 321c4 0 7 -4 7 -8v-360c0 -4 -3 -8 -7 -8h-272v0v0c-4 0 -7 4 -7 8v17h253
|
||||
c4 0 8 4 8 8v343h18z" />
|
||||
<glyph glyph-name="uniF181" unicode="" horiz-adv-x="310"
|
||||
d="M106 119c-7 0 -12 -4 -12 -11s5 -12 12 -12c4 0 8 3 9 7l12 -6c-3 -6 -9 -14 -21 -14c-15 0 -26 10 -26 25s11 24 26 24c12 0 18 -7 21 -14l-12 -5c-1 4 -5 6 -9 6zM148 118c0 -4 26 0 26 -18c0 -10 -7 -17 -20 -17c-10 0 -17 3 -22 8l7 10c4 -3 9 -6 15 -6c3 0 6 1 6 3
|
||||
c0 5 -27 -1 -27 18c0 8 7 16 20 16c8 0 15 -3 20 -7l-8 -10c-4 3 -10 5 -14 5c-3 0 -3 -1 -3 -2zM204 99l10 32h16l-17 -47h-18l-18 47h16zM310 384v-392v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0zM51 22
|
||||
h208v340h-108v-90c0 -5 -4 -9 -9 -9h-91v-241z" />
|
||||
<glyph glyph-name="uniF182" unicode="" horiz-adv-x="361"
|
||||
d="M301 46c5 0 9 -4 9 -9v0v-45v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0v-127v0v0v0v0c0 -5 -4 -9 -9 -9h-33c-5 0 -9 4 -9 9v0v105h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v15v0c0 5 4 9 9 9v0h33z
|
||||
M330 147l28 -28c3 -3 3 -10 0 -13l-25 -25c-3 -3 -9 -3 -12 0l-29 29l-28 -29c-3 -3 -9 -3 -12 0l-25 25c-3 3 -3 10 0 13l28 28l-28 28c-3 3 -3 10 0 13l25 25c3 3 9 3 12 0l28 -28l28 28c3 3 10 3 13 0l25 -25c3 -3 3 -10 0 -13z" />
|
||||
<glyph glyph-name="uniF183" unicode="" horiz-adv-x="310"
|
||||
d="M310 384v-392v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0zM51 22h208v340h-108v-90c0 -5 -4 -9 -9 -9h-91v-241zM97 131c15 0 26 -8 26 -23s-11 -24 -26 -24h-21v47h21zM97 96c7 0 11 6 11 12
|
||||
s-3 11 -11 11h-7v-23h7zM155 132c15 0 26 -9 26 -24s-11 -25 -26 -25s-26 10 -26 25s11 24 26 24zM155 96c7 0 11 5 11 12s-4 11 -11 11s-12 -4 -12 -11s5 -12 12 -12zM213 119c-7 0 -12 -4 -12 -11s5 -12 12 -12c4 0 8 3 9 7l12 -6c-3 -6 -9 -14 -21 -14
|
||||
c-15 0 -26 10 -26 25s11 24 26 24c12 0 18 -7 21 -14l-12 -5c-1 4 -5 6 -9 6z" />
|
||||
<glyph glyph-name="uniF184" unicode="" horiz-adv-x="428"
|
||||
d="M301 46c5 0 9 -4 9 -9v0v-45v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0v-84v0v0v-1v0c0 -5 -4 -8 -9 -8h-33c-5 0 -9 3 -9 8v0v63h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v15v0c0 5 4 9 9 9v0h33z
|
||||
M425 248c3 -3 3 -9 0 -12l-163 -163v0v0l-82 -22v0c-3 -2 -7 -2 -10 1c-2 2 -3 6 -2 9v0l22 84l1 -1l-1 1l163 163c3 3 10 3 13 0zM195 78l49 13l-36 36z" />
|
||||
<glyph glyph-name="uniF185" unicode="" horiz-adv-x="458"
|
||||
d="M456 112c2 -1 2 -3 2 -5v0c0 -2 0 -4 -2 -5l-94 -68c-2 -1 -5 -2 -7 -1s-3 4 -3 6v32h-86c-4 0 -7 3 -7 7v58c0 4 3 6 7 6h85v32c0 2 2 5 4 6s4 1 6 0zM301 46c5 0 9 -4 9 -9v0v-45v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12
|
||||
c5 0 9 -3 9 -8v-21v0v-207v0v0v-1v0c0 -5 -4 -8 -9 -8h-33c-5 0 -9 3 -9 8v0v186h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v15v0c0 5 4 9 9 9v0h33zM107 119c-7 0 -11 -4 -11 -11s4 -12 11 -12c4 0 8 3 9 7l13 -6c-3 -6 -10 -14 -22 -14c-15 0 -26 10 -26 25s11 24 26 24
|
||||
c12 0 19 -7 22 -14l-13 -5c-1 4 -5 6 -9 6zM156 95c3 0 5 1 5 3c0 5 -26 -1 -26 18c0 8 6 16 19 16c8 0 15 -3 20 -7l-7 -10c-4 3 -10 5 -14 5c-3 0 -4 -1 -4 -2c0 -4 26 0 26 -18c0 -10 -7 -17 -20 -17c-10 0 -17 3 -22 8l8 10c4 -3 9 -6 15 -6zM195 131l10 -32l10 32h16
|
||||
l-17 -47h-18l-17 47h16z" />
|
||||
<glyph glyph-name="uniF186" unicode="" horiz-adv-x="458"
|
||||
d="M456 112c2 -1 2 -3 2 -5v0c0 -2 0 -4 -2 -5l-94 -68c-2 -1 -5 -2 -7 -1s-3 4 -3 6v32h-86c-4 0 -7 3 -7 7v58c0 4 3 6 7 6h85v32c0 2 2 5 4 6s4 1 6 0zM301 46c5 0 9 -4 9 -9v0v-45v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12
|
||||
c5 0 9 -3 9 -8v-21v0v-207v0v0v-1v0c0 -5 -4 -8 -9 -8h-33c-5 0 -9 3 -9 8v0v186h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v15v0c0 5 4 9 9 9v0h33zM77 131h22c15 0 26 -8 26 -23s-11 -24 -26 -24h-22v47zM110 108c0 6 -3 11 -11 11h-7v-23h7c7 0 11 6 11 12zM131 108
|
||||
c0 15 10 24 25 24s26 -9 26 -24s-11 -25 -26 -25s-25 10 -25 25zM168 108c0 7 -5 11 -12 11s-11 -4 -11 -11s4 -12 11 -12s12 5 12 12zM214 119c-7 0 -11 -4 -11 -11s4 -12 11 -12c4 0 8 3 9 7l13 -6c-3 -6 -10 -14 -22 -14c-15 0 -26 10 -26 25s11 24 26 24
|
||||
c12 0 19 -7 22 -14l-13 -5c-1 4 -5 6 -9 6z" />
|
||||
<glyph glyph-name="uniF187" unicode="" horiz-adv-x="458"
|
||||
d="M456 112c2 -1 2 -3 2 -5v0c0 -2 0 -4 -2 -5l-94 -68c-2 -1 -5 -2 -7 -1s-3 4 -3 6v32h-86c-4 0 -7 3 -7 7v58c0 4 3 6 7 6h85v32c0 2 2 5 4 6s4 1 6 0zM301 46c5 0 9 -4 9 -9v0v-45v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12
|
||||
c5 0 9 -3 9 -8v-21v0v-207v0v0v-1v0c0 -5 -4 -8 -9 -8h-33c-5 0 -9 3 -9 8v0v186h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v15v0c0 5 4 9 9 9v0h33zM83 131h26c11 0 17 -7 17 -16s-6 -16 -17 -16h-11v-15h-15v47zM111 115c0 3 -2 4 -4 4h-9v-8h9c2 0 4 2 4 4zM133 131h21
|
||||
c15 0 26 -8 26 -23s-11 -24 -26 -24h-21v47zM166 108c0 6 -4 11 -12 11h-7v-23h7c7 0 12 6 12 12zM225 119h-22v-5h21v-12h-21v-18h-14v47h36v-12z" />
|
||||
<glyph glyph-name="uniF188" unicode="" horiz-adv-x="458"
|
||||
d="M456 112c2 -1 2 -3 2 -5v0c0 -2 0 -4 -2 -5l-94 -68c-2 -1 -5 -2 -7 -1s-3 4 -3 6v32h-86c-4 0 -7 3 -7 7v58c0 4 3 6 7 6h85v32c0 2 2 5 4 6s4 1 6 0zM301 46c5 0 9 -4 9 -9v0v-45v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12
|
||||
c5 0 9 -3 9 -8v-21v0v-207v0v0v-1v0c0 -5 -4 -8 -9 -8h-33c-5 0 -9 3 -9 8v0v186h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v15v0c0 5 4 9 9 9v0h33z" />
|
||||
<glyph glyph-name="uniF189" unicode="" horiz-adv-x="310"
|
||||
d="M9 263c-5 0 -9 4 -9 9v9l133 132h9c5 0 9 -3 9 -8v-133c0 -5 -4 -9 -9 -9h-133zM301 413c5 0 9 -3 9 -8v-426c0 -5 -4 -8 -9 -8h-292c-5 0 -9 3 -9 8v224v0c1 4 5 8 9 8h184v0v0c5 0 9 4 9 9v0v0v187v0c1 4 4 6 8 6h91z" />
|
||||
<glyph glyph-name="uniF18A" unicode="" horiz-adv-x="389"
|
||||
d="M381 329c4 0 8 -4 8 -8v-360c0 -4 -4 -8 -8 -8h-271v0v0c-4 0 -8 4 -8 8v18h253c4 0 8 3 8 7v343h18zM338 12c0 -4 -4 -8 -8 -8h-271v0c-4 0 -8 4 -8 8v18h253c4 0 8 3 8 7v343h18c4 0 8 -4 8 -8v-360zM287 63c0 -4 -4 -8 -8 -8h-271c-4 0 -8 4 -8 8v360c0 4 4 8 8 8h271
|
||||
c4 0 8 -4 8 -8v-360z" />
|
||||
<glyph glyph-name="uniF18B" unicode="" horiz-adv-x="310"
|
||||
d="M110 131c11 0 17 -7 17 -16s-6 -16 -17 -16h-11v-15h-15v47h26zM108 111c2 0 4 2 4 4c0 3 -2 4 -4 4h-9v-8h9zM155 131c15 0 26 -8 26 -23s-11 -24 -26 -24h-21v47h21zM155 96c7 0 12 6 12 12s-4 11 -12 11h-7v-23h7zM190 84v47h36v-12h-22v-5h21v-12h-21v-18h-14z
|
||||
M310 384v-392v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0zM51 22h208v340h-108v-90c0 -5 -4 -9 -9 -9h-91v-241z" />
|
||||
<glyph glyph-name="uniF18C" unicode="" horiz-adv-x="360"
|
||||
d="M310 86v0v0v-94v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0v-176v0v0v0v0c0 -5 -4 -9 -9 -9h-33c-5 0 -9 4 -9 9v0v154h-108v-90c0 -5 -4 -9 -9 -9h-91v-241h208v64v0c0 5 4 9 9 9v0h33c5 0 9 -4 9 -9v0v0
|
||||
zM351 174c5 0 9 -4 9 -9v-36c0 -5 -4 -8 -9 -8h-133c-5 0 -9 3 -9 8v36c0 5 4 9 9 9h133z" />
|
||||
<glyph glyph-name="uniF18D" unicode="" horiz-adv-x="403"
|
||||
d="M403 384l-1 -392v0v-13c0 -5 -3 -8 -8 -8h-8h-277h-8c-5 0 -9 3 -9 8v13v45v0c0 5 4 9 9 9v0h34c5 0 8 -4 8 -9v0v-15h209v340h-109v-90c0 -5 -4 -9 -9 -9h-91v-9v0c0 -5 -3 -8 -8 -8v0h-34c-5 0 -8 3 -8 8h-1v9v5v13l133 132h9v0h147v0h13c5 0 8 -3 8 -8v-21h1zM199 146
|
||||
c0 -45 -37 -82 -82 -82c-13 0 -26 3 -37 9l-41 -41v0c-4 -4 -10 -7 -16 -7c-13 0 -23 9 -23 22c0 7 3 13 7 17v0l40 40c-7 12 -12 27 -12 42c0 45 37 82 82 82s82 -37 82 -82zM70 146c0 -26 21 -48 47 -48s48 22 48 48s-22 47 -48 47s-47 -21 -47 -47z" />
|
||||
<glyph glyph-name="uniF18E" unicode="" horiz-adv-x="310"
|
||||
d="M310 384v-392v0v-13c0 -5 -4 -8 -9 -8h-8h-276h-8c-5 0 -9 3 -9 8v13v271v5v13l133 132h9v0h147v0h12c5 0 9 -3 9 -8v-21v0zM51 22h208v340h-108v-90c0 -5 -4 -9 -9 -9h-91v-241z" />
|
||||
<glyph glyph-name="uniF18F" unicode="" horiz-adv-x="439"
|
||||
d="M389 203c5 -5 5 -13 0 -18l-203 -203v0c-5 -5 -13 -5 -18 0l-164 164c-5 5 -5 14 0 19v0l139 139l-57 58c-5 5 -8 11 -8 18c0 14 12 26 26 26c7 0 13 -3 18 -8l57 -58l27 27c5 5 14 5 19 0v0v0l164 -164v0zM288 156l38 38l-110 110l-149 -148h221zM430 70
|
||||
c6 -8 9 -17 9 -27c0 -26 -21 -48 -47 -48s-48 22 -48 48c0 11 4 20 10 28l30 52c0 1 1 0 1 1v1v0c2 2 4 3 7 3s5 -2 7 -4v0v0v-1z" />
|
||||
<glyph glyph-name="uniF190" unicode="" horiz-adv-x="356"
|
||||
d="M77 -5c-14 0 -32 5 -50 23c-24 24 -27 47 -25 62c2 18 11 34 27 50l150 151c42 42 70 26 83 13c16 -16 26 -42 -14 -82l-138 -139l-27 27l138 139c21 21 16 26 14 28s-8 8 -29 -13l-150 -151c-7 -7 -15 -17 -16 -28c-1 -10 3 -19 14 -30c13 -13 23 -11 26 -11
|
||||
c9 1 20 8 30 18l178 178c15 15 24 29 28 42c5 19 -1 38 -20 57c-20 20 -50 40 -98 -8l-165 -165c-7 -7 -20 -7 -27 0s-7 20 0 27l165 165c51 51 106 54 152 8c36 -36 36 -71 30 -94c-6 -20 -18 -39 -38 -59l-178 -178c-16 -16 -34 -27 -51 -29c-3 0 -6 -1 -9 -1z" />
|
||||
<glyph glyph-name="uniF191" unicode="" horiz-adv-x="228"
|
||||
d="M65 346c6 0 12 -5 12 -11v0v0v-286v0v0c0 -6 -6 -11 -12 -11v0h-54v0v0c-6 0 -11 5 -11 11v0v0v286v0v0c0 6 5 11 11 11v0h53v0h1zM228 49v0v0c0 -6 -5 -11 -11 -11v0h-55v0v0c-6 0 -11 5 -11 11v0v0v286v0v0c0 6 5 11 11 11v0h53v0h2c6 0 11 -5 11 -11v0v0v-286z" />
|
||||
<glyph glyph-name="uniF192" unicode="" horiz-adv-x="363"
|
||||
d="M104 240c0 -29 -23 -52 -52 -52s-52 23 -52 52s23 51 52 51s52 -22 52 -51zM311 281c29 0 52 -23 52 -52s-23 -51 -52 -51s-52 22 -52 51s23 52 52 52zM264 172l3 -4c16 -19 35 -44 35 -84c0 -37 -31 -68 -68 -68c-21 0 -40 10 -53 27c-13 -17 -33 -27 -54 -27
|
||||
c-37 0 -68 31 -68 68c0 40 19 65 35 84l3 4c5 6 13 13 22 21c16 17 37 27 62 27c28 0 52 -13 68 -33c6 -5 11 -11 15 -15zM128 310c0 38 19 58 57 58s57 -20 57 -58s-19 -57 -57 -57s-57 19 -57 57z" />
|
||||
<glyph glyph-name="uniF193" unicode="" horiz-adv-x="315"
|
||||
d="M73 88c-2 -9 -11 -16 -20 -16h-40c-9 0 -15 8 -13 16l58 248c2 8 10 16 19 16h85c18 0 34 -2 48 -4c14 -3 25 -7 35 -13s17 -14 22 -24s8 -22 8 -37c0 -33 -13 -60 -41 -80s-66 -31 -116 -31h-12c-9 0 -17 -7 -19 -15zM106 232c-2 -9 3 -16 12 -16h10c22 0 40 5 52 14
|
||||
s18 22 18 38c0 11 -4 19 -12 24s-19 8 -35 8h-13c-9 0 -18 -7 -20 -15zM307 271c5 -10 8 -21 8 -36c0 -33 -14 -61 -42 -81s-65 -30 -115 -30h-12c-9 0 -17 -8 -19 -16l-14 -60c-2 -9 -11 -16 -20 -16h-40c-9 0 -15 8 -13 16l2 8h28c9 0 17 6 19 15l14 61c2 8 10 15 19 15
|
||||
h12c50 0 88 11 116 31s41 47 41 80c0 15 -3 27 -8 37v1c1 0 1 -1 2 -1c10 -6 17 -14 22 -24z" />
|
||||
<glyph glyph-name="uniF194" unicode="" horiz-adv-x="405"
|
||||
d="M401 298c5 -5 5 -14 0 -19l-253 -254v0v0l-128 -34v0c-5 -2 -12 -2 -16 2s-5 9 -3 14v0l34 130h1v0l253 254c5 5 15 5 20 0zM43 33l77 20l-57 56z" />
|
||||
<glyph glyph-name="uniF195" unicode="" horiz-adv-x="443"
|
||||
d="M442 356h1v-330h-1c-1 -11 -10 -21 -22 -21c-1 0 -3 1 -4 1v-1h-393v0c-12 0 -22 10 -23 21v0v2v0v0v328v0c0 13 10 23 23 23v0h393v-1c1 0 3 1 4 1c13 0 22 -10 22 -23zM392 56v272h-341v-218l28 48c1 3 5 5 8 5s6 -2 7 -5v0l19 -33l77 134c2 5 9 10 15 10s11 -4 14 -9
|
||||
v0l116 -202v0c0 -1 1 -1 1 -2h56zM262 250c0 34 18 52 52 52s52 -18 52 -52s-18 -51 -52 -51s-52 17 -52 51z" />
|
||||
<glyph glyph-name="uniF196" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM192 51c78 0 141 63 141 141s-63 141 -141 141s-141 -63 -141 -141s63 -141 141 -141zM276 197c2 -1 2 -3 2 -5s0 -4 -2 -5v0l-120 -69v0h-3c-3 0 -5 1 -5 4v0v138v0v1c0 3 2 6 5 6
|
||||
c1 0 2 -1 3 -1v0l120 -69v0z" />
|
||||
<glyph glyph-name="uniF197" unicode="" horiz-adv-x="415"
|
||||
d="M389 35h-364c-14 0 -25 12 -25 26v262c0 14 11 26 25 26h364c14 0 26 -12 26 -26v-262c0 -14 -12 -26 -26 -26zM364 86v212h-313v-212h313zM283 191l-61 -36l-61 -35v71v70l61 -35z" />
|
||||
<glyph glyph-name="uniF198" unicode="" horiz-adv-x="276"
|
||||
d="M276 192c0 -4 -2 -8 -5 -10v0l-254 -146v0c-2 -1 -4 -2 -6 -2c-6 0 -10 4 -11 10v0v293v0v1c0 6 5 12 11 12c2 0 5 -1 7 -2l252 -146c4 -2 6 -6 6 -10z" />
|
||||
<glyph glyph-name="uniF199" unicode="" horiz-adv-x="371"
|
||||
d="M362 245c5 0 9 -5 9 -10v-86c0 -3 -1 -5 -3 -7s-3 -3 -6 -3h-124v-123c0 -2 -1 -5 -3 -7s-4 -3 -6 -3h-87c-2 0 -4 1 -6 3s-3 5 -3 7v123h-124c-2 0 -4 1 -6 3s-3 5 -3 7v86c0 5 4 10 9 10h124v123c0 5 4 10 9 10h87c5 0 9 -5 9 -10v-123h124z" />
|
||||
<glyph glyph-name="uniF19A" unicode="" horiz-adv-x="221"
|
||||
d="M221 75c0 -2 -1 -4 -2 -5v0c-12 -12 -31 -20 -61 -20c-36 0 -50 18 -75 18c-14 0 -32 -7 -48 -16v0h-2c-2 0 -4 1 -5 3v0h-1v0l-14 30v0v0v0v2c0 2 1 4 3 5v0v1v0c26 12 45 30 45 51c0 8 -2 15 -5 22h-50v0v0c-3 0 -6 2 -6 5v0v22v0c0 3 3 6 6 6v0v0h28
|
||||
c-10 14 -19 30 -19 50c0 52 51 85 100 85c46 0 79 -16 96 -50v0c1 -1 1 -2 1 -3c0 -2 -1 -4 -3 -5v0l-37 -22v0v0h-2c-2 0 -5 1 -6 3c-7 17 -23 29 -42 29c-24 0 -43 -15 -43 -38c0 -21 11 -34 20 -49h60v0c3 0 5 -2 5 -5v0v-22v0c0 -3 -2 -6 -5 -6v0h-47c0 -2 1 -6 1 -8
|
||||
c0 -19 -12 -37 -27 -46c6 2 14 4 20 4c24 0 34 -14 54 -14c18 0 30 8 35 15v0c1 1 3 2 5 2s4 -2 5 -4v0v0v0l15 -37v0c0 -1 1 -2 1 -3z" />
|
||||
<glyph glyph-name="uniF19B" unicode="" horiz-adv-x="384"
|
||||
d="M328 332c35 -35 56 -82 56 -135c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 51 20 98 53 132c2 3 6 6 10 6c3 0 5 -1 7 -3v0h1v0l21 -19v-1v0v0c2 -2 4 -4 4 -7s-2 -7 -4 -9v0c-25 -26 -41 -60 -41 -99c0 -78 63 -141 141 -141s141 63 141 141c0 38 -15 73 -40 98
|
||||
c-3 2 -5 6 -5 10c0 3 1 5 3 7v0v0v1l21 19v0h1v0c2 2 4 3 7 3s6 -1 8 -3v0zM178 127c-6 0 -11 5 -11 11v0v0v230v0v0c0 6 5 11 11 11v0h28v0v0c6 0 11 -5 11 -11v0v0v-230v0v0c0 -6 -5 -11 -11 -11v0v0h-28v0v0v0v0z" />
|
||||
<glyph glyph-name="uniF19C" unicode="" horiz-adv-x="397"
|
||||
d="M388 313c5 0 9 -3 9 -8v-226v0c0 -5 -4 -8 -9 -8c-2 0 -4 0 -6 2l-146 84v-78v0c0 -5 -3 -8 -8 -8c-2 0 -4 0 -6 2l-171 99v-119v-2c0 -7 -6 -13 -13 -13l-1 1h-23h-1c-7 0 -12 4 -13 11v0v2v0v0v280v0c0 7 6 13 13 13v1h25v0c7 0 13 -6 13 -13v-1v0v-120l170 99
|
||||
c2 2 5 2 7 2c5 0 8 -3 8 -8v-78l146 84c2 2 4 2 6 2z" />
|
||||
<glyph glyph-name="uniF19D" unicode="" horiz-adv-x="325"
|
||||
d="M324 109c3 -5 1 -11 -4 -14v0l-166 -96v0c-5 -3 -12 -1 -15 4v1l-137 238v0h-1c-1 2 -1 4 -1 6v0v65v0c0 4 2 7 5 9l109 63v0v0l1 1v0c3 1 6 1 9 -1v0l57 -32v0c2 -1 3 -2 4 -4h1l137 -239v0zM93 298c9 5 12 18 7 27s-18 12 -27 7s-12 -18 -7 -27s18 -12 27 -7z" />
|
||||
<glyph glyph-name="uniF19E" unicode="" horiz-adv-x="395"
|
||||
d="M393 100c3 -5 2 -12 -3 -15v0l-167 -96v0c-5 -3 -11 -1 -14 4v1l-7 12l153 88v0c5 3 7 10 4 15v0v0l-104 179l-45 79l41 -24v0c2 -1 3 -2 4 -4v0l138 -238v0v-1zM320 104v0l-166 -96v0c-5 -3 -12 -1 -15 4v1l-137 238v0h-1c-1 2 -1 5 -1 7v0v65v0c0 4 2 7 5 9l109 62v0v1
|
||||
h1v0c3 1 6 1 9 -1v1l57 -33v0c2 -1 3 -2 4 -4h1l137 -239v0h1c3 -5 1 -12 -4 -15zM93 307c9 5 12 18 7 27s-18 12 -27 7s-12 -18 -7 -27s18 -12 27 -7z" />
|
||||
<glyph glyph-name="uniF19F" unicode="" horiz-adv-x="414"
|
||||
d="M414 268v0v-188c0 -5 -4 -10 -9 -10h-67v79v0h-26h-210h-25v0v-79h-68v0c-5 0 -9 5 -9 10v188v0c0 5 4 9 9 9v0h68v0v110c0 5 4 10 9 10h242c5 0 10 -5 10 -10v-110v0v0h67c5 0 9 -4 9 -9zM312 235v0v127c0 5 -4 9 -9 9h-192v0c-5 0 -9 -4 -9 -9v-127h210zM103 -3v126
|
||||
h209v-126c0 -5 -5 -10 -10 -10h-190c-5 0 -9 5 -9 10z" />
|
||||
<glyph glyph-name="uniF1A0" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM192 51c34 0 66 13 90 33l-198 198c-20 -24 -33 -56 -33 -90c0 -78 63 -141 141 -141zM300 102c20 24 33 56 33 90c0 78 -63 141 -141 141c-34 0 -66 -13 -90 -33z" />
|
||||
<glyph glyph-name="uniF1A1" unicode="" horiz-adv-x="391"
|
||||
d="M391 363v0v-32v0c0 -5 -4 -9 -9 -9h-373v0c-5 0 -9 4 -9 9v0v32v0c0 5 4 10 9 10v0h373c5 0 9 -5 9 -10v0zM359 296c5 0 9 -4 9 -9v0v-190c0 -11 -9 -21 -21 -21h-139v-27c5 -4 8 -10 8 -17c0 -12 -9 -21 -21 -21s-21 9 -21 21c0 7 4 13 9 17v27h-139
|
||||
c-12 0 -22 10 -22 21v190v0v0c0 5 4 9 9 9h328z" />
|
||||
<glyph glyph-name="uniF1A2" unicode="" horiz-adv-x="293"
|
||||
d="M293 198v0v0v-3h-1c-1 -5 -6 -8 -11 -8v0v-1c-4 1 -8 2 -13 2c-28 0 -50 -22 -50 -50s22 -50 50 -50c5 0 9 1 13 2v-1c6 0 11 -4 12 -10v0v-67v0c0 -11 -10 -20 -21 -20h-65v0c-6 0 -12 6 -12 12c0 2 0 3 1 4v0c1 4 2 9 2 14c0 28 -22 50 -50 50s-50 -22 -50 -50
|
||||
c0 -5 1 -10 2 -14v0v-1v0c0 -1 1 -2 1 -3c0 -6 -5 -12 -11 -12h-68h-2c-11 0 -20 9 -20 20v1v66v0v2c0 6 6 12 12 12c1 0 3 -1 4 -1v0c6 -3 12 -4 19 -4c28 0 50 22 50 50s-22 50 -50 50c-7 0 -14 -1 -20 -4c-1 0 -2 -1 -3 -1c-6 0 -12 6 -12 12v0v68v1c0 11 9 21 20 21v0
|
||||
h75v0c14 1 25 12 25 27c0 6 -1 12 -5 17v0c-4 6 -6 13 -6 21c0 23 20 42 43 42s42 -19 42 -42c0 -8 -2 -15 -6 -21h1c-4 -5 -6 -11 -6 -17c0 -15 11 -26 25 -27v0h1h1h1h62v-1c11 0 20 -9 20 -20v0v-66z" />
|
||||
<glyph glyph-name="uniF1A3" unicode="" horiz-adv-x="435"
|
||||
d="M52 224c20 0 35 -15 35 -37s-19 -41 -41 -41c-24 0 -46 19 -46 53c0 39 21 73 53 96v0c1 0 2 1 3 1s2 -1 3 -2v0l22 -13v0c2 -1 2 -3 2 -5s-1 -4 -3 -5v0v0v0c-16 -9 -34 -30 -39 -48c2 1 7 1 11 1zM157 224c20 0 35 -15 35 -37s-19 -41 -41 -41c-24 0 -46 19 -46 53
|
||||
c0 39 21 73 53 96h1c1 0 1 1 2 1s3 -1 4 -2v0l21 -13v0c2 -1 3 -3 3 -5s-2 -4 -4 -5v0v0v0c-16 -9 -33 -30 -38 -48c2 1 6 1 10 1zM284 238c24 0 46 -19 46 -53c0 -39 -21 -73 -53 -96v0c-1 0 -2 -1 -3 -1s-2 1 -3 2v0l-22 13v0c-2 1 -2 3 -2 5s1 4 3 5v0v0v0
|
||||
c16 9 34 30 39 48c-2 -1 -6 -1 -10 -1c-20 0 -36 15 -36 37s19 41 41 41zM389 238c24 0 46 -19 46 -53c0 -39 -21 -73 -53 -96v0c-1 0 -1 -1 -2 -1s-3 1 -4 2v0l-21 13v0c-2 1 -3 3 -3 5s1 4 3 5v0h1v0c16 9 33 30 38 48c-2 -1 -6 -1 -10 -1c-20 0 -35 15 -35 37
|
||||
s18 41 40 41z" />
|
||||
<glyph glyph-name="uniF1A4" unicode="" horiz-adv-x="380"
|
||||
d="M190 382c105 0 190 -85 190 -190s-85 -190 -190 -190s-190 85 -190 190s85 190 190 190zM190 130c34 0 62 28 62 62s-28 62 -62 62s-63 -28 -63 -62s29 -62 63 -62z" />
|
||||
<glyph glyph-name="uniF1A5" unicode="" horiz-adv-x="355"
|
||||
d="M354 337l1 -137c0 -2 -2 -5 -4 -6s-5 -2 -7 -1l-130 44c-3 1 -5 3 -5 6s1 6 3 8l31 22l5 3c-18 14 -41 23 -66 23c-59 0 -108 -48 -108 -107s49 -107 108 -107c36 0 69 17 89 47c3 4 9 6 13 3l45 -32c2 -1 4 -4 4 -6s0 -4 -1 -6c-34 -50 -91 -80 -151 -80
|
||||
c-100 0 -181 81 -181 181s81 181 181 181c50 0 95 -20 128 -53l2 2l31 22c2 2 5 1 8 0s4 -4 4 -7z" />
|
||||
<glyph glyph-name="uniF1A6" unicode="" horiz-adv-x="471"
|
||||
d="M123 210c2 -3 3 -7 5 -10l-53 -24c-14 -7 -23 -22 -23 -39v-56h-41c-6 0 -11 6 -11 13v54c0 5 3 10 7 12l69 32c-16 10 -28 29 -28 52c0 33 23 59 51 59c8 0 15 -2 21 -5c-2 -4 -3 -9 -4 -13c-3 -10 -4 -19 -4 -28c0 -16 4 -33 11 -47zM287 270c-1 4 -1 8 -2 13
|
||||
c-3 14 -10 27 -18 38h195v0v0c5 0 9 -4 9 -9v0v-33v0c0 -5 -4 -9 -9 -9v0v0h-175zM471 108v0v-33v0c0 -5 -4 -9 -9 -9v0v0h-114v4v11v36h114v0v0c5 0 9 -4 9 -9zM462 219c5 0 9 -4 9 -9v0v-33v0c0 -5 -4 -9 -9 -9v0v0h-126c-3 3 -7 6 -11 8l-53 25c2 4 5 7 7 11c1 2 1 5 2 7
|
||||
h181v0v0zM314 153c5 -3 9 -9 9 -16v-56v-11c0 -9 -6 -16 -14 -16h-218c-8 0 -14 7 -14 16v11v56c0 7 4 14 9 16l61 28l24 11c-11 7 -19 17 -25 29c-5 11 -9 23 -9 36c0 8 1 14 3 21c8 30 32 52 60 52c29 0 53 -22 60 -53c2 -6 3 -13 3 -20c0 -12 -3 -24 -8 -34
|
||||
c-6 -13 -14 -23 -25 -30l25 -12z" />
|
||||
<glyph glyph-name="uniF1A7" unicode="" horiz-adv-x="431"
|
||||
d="M431 336v-33v0c0 -5 -4 -9 -9 -9v0v0h-235v0c-5 0 -9 4 -9 9v0v33v0v0v0v0c0 5 4 9 9 9v0h235v0v0c5 0 9 -4 9 -9v0zM431 259v-32v0c0 -5 -4 -10 -9 -10v0v0h-235v0c-5 0 -9 5 -9 10v0v32v0v0v0v0c0 5 4 9 9 9v0h235v0v0c5 0 9 -4 9 -9v0zM127 336v-109v0v0
|
||||
c0 -5 -4 -10 -9 -10v0v0h-109v0c-5 0 -9 5 -9 10v0v0v109v0c0 5 4 9 9 9h1h108v0c5 0 9 -4 9 -9v0zM431 157v-32v0c0 -5 -4 -9 -9 -9v0v0h-235v0c-5 0 -9 4 -9 9v0v32v0v0v0v0c0 5 4 9 9 9v1h235v-1v0c5 0 9 -4 9 -9v0zM431 81v-33v0c0 -5 -4 -9 -9 -9v0v0h-235v0
|
||||
c-5 0 -9 4 -9 9v1v32v0v0v0v0c0 5 4 9 9 9v0h235v0v0c5 0 9 -4 9 -9v0zM127 157v-109v0v0c0 -5 -4 -9 -9 -9v0h-109v0c-5 0 -9 4 -9 9v0v0v109v0c0 5 4 10 9 10l1 -1h108v1c5 0 9 -5 9 -10v0z" />
|
||||
<glyph glyph-name="uniF1A8" unicode="" horiz-adv-x="406"
|
||||
d="M351 197c-2 -2 -5 -2 -7 -1l-131 42c-3 1 -5 3 -5 6s1 5 3 7l30 23l5 4c-19 14 -42 21 -67 21c-59 -1 -106 -50 -105 -109s51 -106 110 -105h10v0v0c7 0 14 -6 14 -13v0v0l1 -47v0c0 -3 -2 -7 -4 -9v0v0v-1l-2 -1v0c-1 0 -1 -1 -2 -1v0c-3 -1 -5 -2 -5 -2h-11
|
||||
c-100 -2 -183 78 -185 178s78 182 178 184c50 1 96 -18 129 -50l2 1l30 23c2 2 5 2 8 1s4 -4 4 -7l3 -138c0 -2 -1 -4 -3 -6zM291 142h18l2 -99h-21l-1 72l-16 -17l-13 12zM365 145c28 1 41 -25 41 -50s-11 -51 -39 -52s-42 25 -42 50s12 51 40 52zM366 61c14 0 19 15 19 33
|
||||
s-6 32 -20 32s-19 -15 -19 -33s6 -32 20 -32z" />
|
||||
<glyph glyph-name="uniF1A9" unicode="" horiz-adv-x="372"
|
||||
d="M363 313c5 0 9 -3 9 -8v-226v0c0 -5 -4 -8 -9 -8c-2 0 -4 0 -6 2l-145 84v-78v0c0 -5 -4 -8 -9 -8c-2 0 -4 0 -6 2l-192 111v0c-3 1 -5 4 -5 8c0 3 1 5 4 7v1l192 111c2 2 5 2 7 2c5 0 9 -3 9 -8v-78l145 84c2 2 4 2 6 2z" />
|
||||
<glyph glyph-name="uniF1AA" unicode="" horiz-adv-x="339"
|
||||
d="M48 115c25 0 45 -20 45 -45s-20 -44 -45 -44s-45 19 -45 44s20 45 45 45zM34 239c101 0 183 -81 184 -182v0v-18v0c-1 -8 -8 -14 -16 -15v-1h-31v0c-9 0 -17 7 -18 16v0v18v0c-1 65 -54 118 -119 118h-1v0h-17v0c-8 1 -15 7 -16 15v0v32v0c0 9 7 16 16 17v0h17v0h1z
|
||||
M339 57v0v0v-18v0c-1 -8 -7 -14 -15 -15v-1h-32v0c-9 0 -16 7 -17 16v0v18v0c-1 132 -109 239 -241 239h-1v0h-17v0c-8 1 -15 8 -16 16v0v31v0c0 9 7 16 16 17v1h17v0h1c168 0 304 -136 305 -304z" />
|
||||
<glyph glyph-name="uniF1AB" unicode="" horiz-adv-x="482"
|
||||
d="M482 28v-2c0 -7 -6 -12 -13 -12v0v0h-457c-7 0 -12 5 -12 12v1v0v25c0 7 5 12 12 12h39l169 293c4 8 12 13 21 13s17 -5 21 -13v0l169 -293h38v0c7 0 13 -5 13 -12v0v0v-24zM228 319l-29 -51h84l-29 51h-26zM169 217l-29 -51h202l-29 51h-144zM81 64h320l-30 51h-261z
|
||||
" />
|
||||
<glyph glyph-name="uniF1AC" unicode="" horiz-adv-x="379"
|
||||
d="M204 251v110h53v-110h-53zM375 350c2 -2 4 -5 4 -9v-1v-324v0v0c0 -7 -5 -12 -12 -12v0h-39v169v0c0 6 -6 11 -12 11v0v0v0v0h-253v0h-1h-1v0c-5 -1 -10 -5 -10 -11v0v-1v0v0v0v-156v0v-12h-39v0c-7 0 -12 5 -12 12v0v168v49v135v0c0 7 5 12 12 12v0v0h67v0c2 0 3 0 5 -2
|
||||
c1 -1 2 -2 2 -3v0v-130v0c0 -6 6 -12 12 -12v0h175h1c7 0 13 5 13 12v0v130v0c0 1 1 3 2 4s3 1 4 1v0v0v0h46v0c4 0 7 -2 9 -4l27 -26v0z" />
|
||||
<glyph glyph-name="uniF1AD" unicode="" horiz-adv-x="358"
|
||||
d="M298 252c33 0 60 -27 60 -60s-27 -60 -60 -60c-7 0 -14 2 -21 4l-157 -91v-3c0 -33 -27 -61 -60 -61s-60 28 -60 61s27 60 60 60c13 0 26 -5 36 -12l144 84c-2 6 -2 12 -2 18s0 12 2 18l-145 84c-10 -7 -22 -12 -35 -12c-33 0 -60 27 -60 60s27 61 60 61s60 -28 60 -61
|
||||
v-4l156 -90c7 3 14 4 22 4z" />
|
||||
<glyph glyph-name="uniF1AE" unicode="" horiz-adv-x="384"
|
||||
d="M356 130c15 0 28 -12 28 -27s-13 -28 -28 -28c-10 0 -19 6 -24 15h-80l-35 -61c2 -4 3 -7 3 -12c0 -15 -12 -28 -27 -28s-28 13 -28 28c0 5 1 9 3 13l-34 60h-78c-5 -7 -14 -12 -23 -12c-15 0 -27 12 -27 27s12 28 27 28c2 0 5 0 7 -1l35 60l-35 60c-4 -2 -8 -3 -12 -3
|
||||
c-15 0 -28 13 -28 28s13 27 28 27c10 0 19 -5 24 -14h79l37 63c-3 4 -5 9 -5 14c0 15 13 28 28 28s27 -13 27 -28c0 -6 -1 -11 -4 -15l36 -62h78c5 7 13 12 22 12c15 0 28 -13 28 -28s-13 -27 -28 -27c-2 0 -5 0 -7 1l-34 -60l35 -60c4 2 8 2 12 2z" />
|
||||
<glyph glyph-name="uniF1AF" unicode="" horiz-adv-x="344"
|
||||
d="M172 394l172 -99v0v-118c-1 -98 -76 -178 -172 -188c-96 10 -171 90 -172 188v0v118v0l172 100v-1zM172 41c67 10 120 66 121 136v0v6h-121v152l-121 -70v-82h121v-142z" />
|
||||
<glyph glyph-name="uniF1B0" unicode="" horiz-adv-x="441"
|
||||
d="M441 250v0v-216c0 -11 -9 -20 -20 -20v0v0h-401v0c-11 0 -20 9 -20 20v0v216v0c1 10 10 18 20 18h31c32 61 97 102 170 102s137 -41 169 -102h31v0c10 0 19 -8 20 -18zM112 268h217c-26 31 -64 51 -108 51s-83 -20 -109 -51z" />
|
||||
<glyph glyph-name="uniF1B1" unicode="" horiz-adv-x="425"
|
||||
d="M95 33c0 20 10 30 30 30s31 -10 31 -30s-11 -30 -31 -30s-30 10 -30 30zM307 33c0 20 10 30 30 30s30 -10 30 -30s-10 -30 -30 -30s-30 10 -30 30zM333 165v0h-200v-25h270v0c5 0 9 -3 12 -6s5 -7 5 -12v0v-15v0v-1v-2v0c-1 -9 -8 -14 -17 -15v0h-303v0v0
|
||||
c-5 0 -9 2 -12 5s-6 7 -6 12v0v224h-63v0v0h-1c-5 0 -10 2 -13 5s-5 8 -5 13v0v17v0c1 4 3 9 6 12s8 4 12 4v0h1v0h97v0v0c5 0 9 -2 12 -5s5 -8 5 -13v0v-33h54h146h75v0c5 0 9 -2 12 -5s5 -8 5 -13c0 -3 0 -5 -1 -7v0l-75 -130v0c-3 -7 -9 -10 -16 -10z" />
|
||||
<glyph glyph-name="uniF1B2" unicode="" horiz-adv-x="462"
|
||||
d="M74 129l44 45l55 -55l-54 -54c-4 -7 -12 -12 -21 -12v0h-87v0c-5 1 -9 5 -10 10h-1v56h1c1 6 6 11 12 11c1 0 2 -1 3 -1h58zM460 290c2 -1 2 -3 2 -5v0c0 -2 0 -4 -2 -5l-95 -69c-2 -1 -5 -1 -7 0s-4 4 -4 6v30h-53l-38 -37l-54 54l54 54v0c4 3 10 6 15 6v0h76v29
|
||||
c0 2 2 5 4 6s4 0 6 -1zM459 104c2 -1 3 -3 3 -5v0c0 -2 -1 -4 -3 -5l-95 -68c-2 -1 -5 -2 -7 -1s-3 4 -3 6v29h-77v0c-5 0 -10 3 -14 6v0l-189 189h-58c-1 0 -2 -1 -3 -1c-6 0 -12 5 -13 11v0v56v0c1 5 6 9 11 10v0h87v0c9 0 17 -5 21 -12l182 -182h53v30c0 2 1 5 3 6
|
||||
s5 1 7 0z" />
|
||||
<glyph glyph-name="uniF1B3" unicode="" horiz-adv-x="399"
|
||||
d="M390 78c12 -12 13 -31 1 -43c-7 -7 -18 -10 -27 -8c2 -9 -1 -19 -8 -26c-12 -12 -30 -11 -42 1s-12 29 -1 41l-45 45v-31c-19 -15 -42 -24 -68 -24s-50 9 -69 24v31l-45 -45c11 -12 11 -30 -1 -42s-30 -12 -42 0c-7 7 -10 17 -8 26c-9 -2 -19 2 -26 9c-12 12 -12 30 0 42
|
||||
c12 11 30 12 42 1l46 46c-13 19 -20 42 -20 67s7 48 20 67l-46 46c-12 -11 -30 -11 -42 1s-12 31 0 43c7 7 17 10 26 8c-2 9 1 19 8 26c12 12 31 11 43 -1s12 -29 1 -41l46 -46c19 13 42 20 67 20s48 -7 67 -20l46 46c-11 12 -10 30 1 42c12 12 30 12 42 0
|
||||
c7 -7 11 -17 9 -26c9 2 18 -2 25 -9c12 -12 12 -30 0 -42s-29 -12 -41 -1l-46 -46c13 -19 20 -42 20 -67s-7 -48 -20 -67l46 -46c12 11 29 10 41 -1zM166 146c13 0 24 10 24 23s-11 24 -24 24s-23 -11 -23 -24s10 -23 23 -23zM233 146c13 0 24 10 24 23s-11 24 -24 24
|
||||
s-23 -11 -23 -24s10 -23 23 -23z" />
|
||||
<glyph glyph-name="uniF1B4" unicode=""
|
||||
d="M262 227c10 0 17 -3 23 -10s9 -14 9 -23s-3 -18 -8 -24s-13 -9 -23 -9c-6 0 -10 1 -15 3s-10 4 -14 7s-9 6 -13 10s-8 8 -11 12l11 11s8 8 12 11s9 7 14 9s10 3 15 3zM151 204l11 -11c-3 -4 -6 -8 -10 -12s-9 -7 -13 -10s-9 -5 -14 -7s-10 -3 -15 -3c-10 0 -17 3 -23 9
|
||||
s-8 14 -8 23s3 17 8 24s13 10 22 10c5 0 10 -1 15 -3s9 -6 14 -9s9 -7 13 -11zM333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM326 166c3 9 5 19 5 29s-2 19 -5 28s-7 17 -13 23s-14 11 -22 15s-17 6 -28 6
|
||||
c-8 0 -17 -1 -24 -4s-14 -7 -20 -11s-12 -9 -17 -15s-11 -12 -16 -18c-5 6 -11 12 -16 18s-11 11 -17 15s-13 8 -20 11s-15 4 -24 4c-11 0 -21 -2 -29 -6s-15 -9 -21 -15s-10 -14 -13 -23s-5 -19 -5 -29s2 -20 5 -29s8 -17 14 -23s13 -11 21 -15s18 -6 29 -6c9 0 17 1 24 4
|
||||
s13 5 19 9s12 10 17 15l16 16c5 -6 10 -11 16 -16s12 -11 18 -15s13 -6 20 -9s15 -4 23 -4c11 0 19 2 28 6s16 8 22 15s10 15 13 24z" />
|
||||
<glyph glyph-name="uniF1B5" unicode=""
|
||||
d="M232 355h137v-326zM0 355h136l-136 -326v326zM125 94l59 141l87 -206h-57l-26 65h-63z" />
|
||||
<glyph glyph-name="uniF1B6" unicode="" horiz-adv-x="377"
|
||||
d="M199 264h7c1 0 1 1 3 1c-1 10 0 21 -2 31c-2 12 -11 20 -24 22c-20 3 -41 -8 -46 -29c-2 -7 -6 -9 -13 -8c-13 2 -26 3 -39 5c-9 1 -11 4 -9 13c6 27 22 47 47 58c38 17 75 18 113 1c25 -11 38 -31 39 -58c1 -35 2 -69 1 -104c0 -19 4 -36 17 -51c5 -6 5 -10 -1 -15
|
||||
c-11 -9 -22 -20 -33 -29c-6 -5 -12 -5 -17 1c-9 9 -16 18 -25 27c-5 -5 -11 -9 -17 -14c-21 -17 -45 -22 -70 -19c-39 4 -62 30 -63 70c-1 44 22 74 66 87c21 6 44 9 66 11zM198 163c13 20 10 41 10 64c-11 -1 -22 -2 -33 -4c-26 -5 -40 -23 -38 -50c1 -20 15 -32 34 -29
|
||||
c12 2 21 9 27 19zM318 85c6 2 11 0 14 -5s2 -10 -3 -14c-7 -5 -15 -10 -22 -14c-41 -24 -85 -37 -126 -38c-50 0 -88 14 -123 38c-19 13 -35 28 -53 42c-5 4 -6 9 -3 13s7 5 13 2c18 -9 36 -19 54 -28c28 -14 57 -25 89 -28c26 -2 52 0 77 5c27 5 53 14 78 25c2 1 3 1 5 2z
|
||||
M357 124c18 -2 21 -6 19 -24c-2 -19 -9 -35 -22 -49c-2 -2 -3 -4 -5 -4c-3 0 -7 -1 -9 1s-3 6 -2 9c2 8 5 15 7 23c1 4 2 9 3 13s0 6 -4 6h-10v0c-9 -1 -17 -2 -26 -3c-5 -1 -8 0 -10 4c-2 5 0 9 4 12c17 12 35 14 55 12z" />
|
||||
<glyph glyph-name="uniF1B7" unicode="" horiz-adv-x="338"
|
||||
d="M223 355c34 -17 57 -51 57 -89h-222c0 38 23 72 57 89l-18 32c-1 2 0 3 2 4s3 1 4 -1l18 -32c15 6 31 10 48 10s33 -4 48 -10l18 32c1 2 2 2 4 1s3 -2 2 -4zM118 307c5 0 10 4 10 9s-5 9 -10 9s-9 -4 -9 -9s4 -9 9 -9zM220 307c5 0 9 4 9 9s-4 9 -9 9s-10 -4 -10 -9
|
||||
s5 -9 10 -9zM338 238v-103c0 -14 -11 -25 -25 -25s-24 11 -24 25v103c0 14 10 25 24 25s25 -11 25 -25zM279 258v0v-160c0 -10 -5 -18 -13 -23c-4 -2 -8 -3 -13 -3h-18v-55c0 -14 -11 -25 -25 -25c-2 0 -3 1 -5 1c-11 2 -19 12 -19 24v55h-34v-55c0 -12 -8 -22 -19 -24
|
||||
c-2 0 -3 -1 -5 -1c-12 0 -22 9 -24 20c0 2 -1 3 -1 5v55h-18c-10 0 -19 5 -23 14c-2 4 -3 8 -3 12v160h220v0zM25 263c14 0 24 -11 24 -25v-103v-5c-2 -11 -12 -20 -24 -20c-5 0 -10 1 -14 4c-7 4 -11 12 -11 21v103c0 14 11 25 25 25z" />
|
||||
<glyph glyph-name="uniF1B8" unicode="" horiz-adv-x="352"
|
||||
d="M340 259c-69 -38 -58 -137 12 -163c-10 -21 -15 -30 -27 -49c-17 -26 -41 -60 -71 -60c-27 0 -35 18 -71 18s-43 -18 -70 -18c-30 0 -54 30 -71 56c-48 74 -53 160 -23 206c21 33 55 52 86 52c32 0 52 -18 78 -18s41 18 78 18c28 0 58 -16 79 -42zM233 330
|
||||
c-14 -18 -39 -33 -63 -32c-4 24 7 48 21 65c15 18 40 32 62 34c4 -25 -7 -50 -20 -67z" />
|
||||
<glyph glyph-name="uniF1B9" unicode="" horiz-adv-x="365"
|
||||
d="M255 160c6 0 11 -1 15 -5s6 -11 6 -14h-45c2 6 7 19 24 19zM140 136c1 0 14 0 14 -18c0 -15 -9 -18 -16 -18h-41v36h43v0zM331 376c16 0 29 -10 34 -24v-320c-4 -12 -14 -21 -26 -24h-312c-13 3 -23 13 -27 25v318c4 15 18 25 34 25h297zM220 220v-19c0 -1 1 -2 2 -2h64
|
||||
c1 0 3 1 3 2v19c0 1 -2 3 -3 3h-64c-1 0 -2 -2 -2 -3zM193 115c0 1 0 20 -11 32c-3 3 -6 6 -10 7c7 4 15 12 15 29c0 27 -17 43 -46 43h-80c-1 0 -3 -1 -3 -2v-155c0 -1 2 -2 3 -2h81c3 0 15 0 27 6c11 6 24 18 24 42zM312 117c0 1 4 33 -14 53c-10 11 -24 17 -42 17
|
||||
c-32 0 -48 -17 -55 -31c-8 -15 -7 -31 -7 -31c0 -1 -2 -26 15 -44c11 -12 26 -18 46 -18v0h3c9 0 53 2 53 44c0 1 -1 3 -2 3h-28c-1 0 -2 0 -2 -1c-1 -1 0 -1 0 -2c0 0 0 -4 -4 -8s-10 -6 -19 -6v0c-2 0 -9 1 -14 4c-6 4 -9 10 -10 18h77c1 0 3 1 3 2zM148 181
|
||||
c0 -15 -5 -16 -11 -16h-40v30h37h6s8 -1 8 -14z" />
|
||||
<glyph glyph-name="uniF1BA" unicode="" horiz-adv-x="388"
|
||||
d="M95 160c0 46 34 69 100 69s99 -23 99 -69s-33 -70 -99 -70s-100 24 -100 70zM333 252c42 -29 60 -64 54 -105c0 -16 -5 -31 -15 -45s-23 -26 -40 -36c-20 -12 -40 -20 -61 -25c-24 -6 -49 -9 -77 -9c-29 0 -55 3 -79 9c-37 14 -66 30 -86 50s-29 47 -29 82v179h58v-99
|
||||
c38 26 87 40 149 39c49 -3 91 -16 126 -40zM211 64c32 1 60 12 84 34s35 43 33 66c-1 14 -6 27 -13 38s-16 20 -26 27s-21 12 -33 17s-24 7 -34 9s-20 2 -28 2c-44 -2 -78 -13 -101 -33s-33 -42 -31 -66s12 -43 28 -58s34 -25 54 -30s43 -7 67 -6z" />
|
||||
<glyph glyph-name="uniF1BB" unicode=""
|
||||
d="M308 376c33 0 61 -28 61 -61v-246c0 -33 -28 -61 -61 -61h-247c-33 0 -61 28 -61 61v246c0 33 28 61 61 61h247zM296 151v58v3l-2 4l-3 2c-4 3 -25 0 -31 5c-4 4 -5 11 -6 20c-2 17 -3 18 -6 24c-10 21 -37 37 -55 39h-50c-39 0 -72 -33 -72 -72v-83c0 -39 33 -71 72 -71
|
||||
h82c39 0 71 32 71 71zM144 220c-8 0 -14 7 -14 14s6 13 14 13h39c8 0 14 -6 14 -13s-6 -14 -14 -14h-39zM224 166c7 0 14 -7 14 -14s-7 -13 -14 -13h-80c-8 0 -14 6 -14 13s6 14 14 14h80z" />
|
||||
<glyph glyph-name="uniF1BC" unicode="" horiz-adv-x="348"
|
||||
d="M174 192h174v-174h-174v174h-174v174h174v-174z" />
|
||||
<glyph glyph-name="uniF1BD" unicode=""
|
||||
d="M270 254h31v-57v-71h-28l-50 78l2 -78h-32v84v44h1h4h23l3 -5l47 -76zM333 376c20 0 36 -16 36 -36v-131l-63 50v0h-5h-31h-5v-5v-29l-39 31v1l-2 2h-3h-28h-5v-5v-40l-13 11c-1 3 -4 5 -6 8c-5 7 -11 12 -17 16c-12 7 -23 10 -43 10h-43h-3h-2h-5v-2v-10v-124l143 -115
|
||||
h-163c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM137 251v0c1 0 4 -1 5 -2v0v0c1 -1 3 -1 4 -2s3 -1 4 -2s3 -2 4 -3c1 0 0 -1 1 -1l2 -2l2 -2l1 -1l2 -2v0v0c1 -1 2 -3 3 -4c8 -11 12 -24 12 -40c0 -39 -24 -64 -60 -64h-51v123v5h20h5h18h3c11 0 18 -1 25 -3z
|
||||
M144 189c0 23 -11 36 -31 36h-14v-70h14c20 0 31 12 31 34z" />
|
||||
<glyph glyph-name="uniF1BE" unicode=""
|
||||
d="M166 219c9 -19 45 -93 45 -93l129 35v-118c0 -1 -1 -1 -2 -2s-2 -2 -3 -2h-303c-1 0 -2 1 -3 2s-1 1 -1 2v31l169 48l-48 101c82 18 123 11 165 -23c5 -5 3 -8 0 -9l-67 -16l-25 50c-19 3 -46 -2 -56 -6zM335 348c1 0 2 -1 3 -1c1 -1 2 -2 2 -3v-105l-1 1
|
||||
c-87 38 -186 21 -206 15c0 1 -15 33 -15 33h-56l20 -46c-23 -7 -48 -25 -54 -30v132c0 1 1 2 2 3c1 0 1 1 2 1h303zM68 131c-13 -3 -12 6 -12 6c-3 55 33 71 41 73l31 -63s-47 -13 -60 -16zM338 376c17 0 31 -14 31 -31v-306c0 -17 -14 -31 -31 -31h-307
|
||||
c-17 0 -31 14 -31 31v306c0 17 14 31 31 31h307zM350 43v301c0 8 -7 14 -15 14h-303c-8 0 -14 -6 -14 -14v-301c0 -8 6 -14 14 -14h303c8 0 15 6 15 14z" />
|
||||
<glyph glyph-name="uniF1BF" unicode="" horiz-adv-x="436"
|
||||
d="M436 253v-173c0 -4 -1 -6 -6 -6h-106c-4 0 -5 1 -5 5v23c0 4 1 5 5 5h62c4 0 5 1 5 5v16h-5h-62c-4 0 -5 2 -5 6v120c0 4 1 5 5 5h107h4c0 -2 1 -4 1 -6zM387 161c3 0 4 2 4 5v49v11h-25c-1 0 -2 -3 -2 -4v-57c0 -3 1 -4 4 -4h19zM300 259c4 0 5 -1 5 -5v-175v-5h-5h-106
|
||||
c-4 0 -5 1 -5 5v28h5h62c4 0 5 1 5 5v11s-1 6 -6 6c-20 0 -40 -1 -61 -1c-4 0 -5 2 -5 6v120c0 4 1 5 5 5h106zM261 164v59c0 1 -2 3 -3 3h-25c0 -21 1 -41 1 -62c0 -1 1 -3 2 -3h22c1 0 3 2 3 3zM72 305v5h44v-193h-4h-107c-4 0 -5 1 -5 5v132c0 4 1 5 5 5h61c7 0 6 -1 6 6
|
||||
v40zM67 150c4 0 5 1 5 5v66v5h-27v-74c0 -1 2 -2 3 -2h19zM171 259c3 0 4 0 4 -3v-137v-2h-26h-14c-4 0 -4 1 -4 5v94v38c0 4 0 5 4 5h36zM134 276c-1 0 -3 2 -3 3v31h44v-17v-13c0 -3 0 -4 -3 -4h-38z" />
|
||||
<glyph glyph-name="uniF1C0" unicode="" horiz-adv-x="371"
|
||||
d="M186 378c102 0 185 -84 185 -186s-83 -186 -185 -186s-186 84 -186 186s84 186 186 186zM308 292c-3 -5 -29 -39 -88 -63c4 -8 7 -14 10 -22c1 -3 3 -6 4 -9c53 7 105 -4 110 -5c0 37 -14 72 -36 99zM186 350c-13 0 -26 -1 -38 -4c4 -6 34 -45 60 -93c56 21 80 53 83 57
|
||||
c-28 25 -65 40 -105 40zM118 335c-44 -21 -78 -62 -88 -111c7 0 73 0 147 20c-26 47 -55 85 -59 91zM27 192c0 -41 16 -78 41 -106c4 6 47 78 129 104c2 1 4 1 6 2c-4 9 -8 18 -13 27c-79 -24 -156 -22 -163 -22v-5zM186 33c22 0 42 5 61 13c-2 14 -11 62 -33 120h-1
|
||||
c-89 -31 -122 -93 -125 -99c27 -21 61 -34 98 -34zM274 60c36 24 61 63 68 107c-5 2 -49 14 -99 6c21 -57 29 -103 31 -113z" />
|
||||
<glyph glyph-name="uniF1C1" unicode="" horiz-adv-x="384"
|
||||
d="M144 143h240l-67 -115h-240zM376 149l-132 1l-121 208l133 -1zM120 349l66 -115l-120 -208l-66 115z" />
|
||||
<glyph glyph-name="uniF1C2" unicode="" horiz-adv-x="396"
|
||||
d="M117 376l81 -68l-117 -72l-81 64zM0 171l81 65l117 -73l-81 -68zM198 163l118 73l80 -65l-116 -76zM396 300l-80 -64l-118 72l82 68zM198 148l82 -68l35 23v-25l-117 -70l-116 70v25l35 -23z" />
|
||||
<glyph glyph-name="uniF1C3" unicode="" horiz-adv-x="335"
|
||||
d="M33 315c-9 0 -17 -2 -23 -5l-4 -2l1 1l73 72v0l-1 -2c-3 -5 -5 -12 -5 -19v0c0 -9 1 -42 1 -42c0 -2 -2 -3 -4 -3h-38v0zM325 322c5 -27 12 -135 9 -171c-5 -57 -14 -90 -18 -101c-18 -56 -33 -58 -77 -58c-56 0 -73 8 -73 53c0 49 24 50 63 49c6 0 -1 -5 -1 -15
|
||||
s4 -13 -1 -13c-11 0 -27 2 -27 -14c0 -19 10 -19 34 -19c30 0 35 4 35 31c0 45 -13 51 -30 53c-19 2 -38 6 -47 9c-23 8 -22 38 -22 47c0 1 -2 1 -2 0c0 -12 -1 -29 -7 -48c-2 -5 -3 -9 -3 -9c-7 -15 -20 -10 -39 -8s-61 11 -79 19c-8 4 -11 7 -15 16c-11 22 -22 95 -23 105
|
||||
c-2 13 -2 20 -2 20c0 8 1 17 6 24c3 3 5 6 10 8s11 4 19 4h38c8 0 15 6 15 14c0 0 -1 9 -1 18v24c0 8 2 13 5 17c4 6 13 11 20 13c9 3 45 4 68 -5c9 -4 16 -13 18 -24c13 0 36 0 55 -2c24 -3 42 -7 51 -10s18 -11 21 -27zM249 203c10 0 19 -3 27 -6c0 11 -2 28 -20 29
|
||||
c-16 1 -21 -13 -22 -24c5 1 10 1 15 1z" />
|
||||
<glyph glyph-name="uniF1C4" unicode=""
|
||||
d="M348 376c11 0 21 -9 21 -20v-328c0 -11 -10 -20 -21 -20h-94v142h48l7 56h-55v36c0 16 5 27 28 27h29v49c-5 1 -23 3 -43 3c-42 0 -71 -26 -71 -74v-41h-48v-56h48v-142h-177c-11 0 -20 9 -20 20v328c0 11 9 20 20 20h328z" />
|
||||
<glyph glyph-name="uniF1C5" unicode=""
|
||||
d="M333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM110 133c33 0 60 27 60 60s-27 60 -60 60s-60 -27 -60 -60s27 -60 60 -60zM261 133c33 0 60 27 60 60s-27 60 -60 60s-59 -27 -59 -60s26 -60 59 -60z" />
|
||||
<glyph glyph-name="uniF1C6" unicode="" horiz-adv-x="350"
|
||||
d="M350 -18h-65v1h-92v66l73 36l-9 18l-64 -33v25l43 22l-10 18l-33 -18v43h-46v-67l-33 23l-11 -16l44 -31v-73v-13h-147l175 419z" />
|
||||
<glyph glyph-name="uniF1C7" unicode="" horiz-adv-x="415"
|
||||
d="M137 239l67 -67l155 154c3 3 6 4 10 4s6 -1 9 -4l33 -32c5 -5 5 -14 0 -19l-197 -197c-3 -3 -6 -4 -10 -4v0v0h-1c-3 0 -6 2 -8 4l-110 110c-5 5 -5 14 0 19l33 32c3 3 5 4 9 4s7 -1 10 -4zM399 227v-1c19 -19 19 -49 0 -68l-158 -159c-19 -19 -50 -19 -69 0l-158 159
|
||||
c-19 19 -19 49 0 68l158 159c19 19 50 19 69 0l72 -72l-108 -107l-50 50c-7 7 -17 12 -27 12s-20 -5 -27 -12l-32 -32c-7 -7 -11 -17 -11 -27s4 -20 11 -27l109 -109c5 -5 11 -8 18 -10l2 -1h7c10 0 20 4 27 11z" />
|
||||
<glyph glyph-name="uniF1C8" unicode=""
|
||||
d="M333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM215 350c-55 0 -99 -44 -99 -99c0 -36 20 -68 49 -85c14 28 43 47 77 47c20 0 39 -7 54 -19c11 16 18 36 18 57c0 55 -44 99 -99 99zM30 208
|
||||
c0 -41 22 -77 54 -98c9 22 31 36 56 36c6 0 11 0 17 -2c1 4 3 7 4 11c-33 19 -56 55 -56 96c0 28 11 53 28 72c-58 -7 -103 -55 -103 -115zM140 33c29 0 52 23 52 52s-23 52 -52 52s-52 -23 -52 -52s23 -52 52 -52zM242 50c42 0 77 34 77 76s-35 77 -77 77
|
||||
c-38 0 -69 -27 -75 -63c20 -10 34 -31 34 -55c0 -7 -2 -14 -4 -21c13 -9 28 -14 45 -14z" />
|
||||
<glyph glyph-name="uniF1C9" unicode="" horiz-adv-x="399"
|
||||
d="M200 387c110 0 199 -90 199 -200c0 -88 -57 -163 -136 -189c-10 -2 -14 4 -14 9v55c0 19 -6 31 -13 37c44 5 91 22 91 99c0 22 -7 39 -20 53c2 5 9 25 -2 53c0 0 -17 5 -55 -21c-16 4 -33 7 -50 7s-34 -3 -50 -7c-38 26 -55 21 -55 21c-11 -28 -4 -48 -2 -53
|
||||
c-13 -14 -21 -31 -21 -53c0 -77 47 -94 91 -99c-6 -5 -10 -14 -12 -27c-11 -5 -41 -14 -59 17c0 0 -10 19 -30 20c0 0 -20 0 -2 -12c0 0 14 -6 23 -29c0 0 11 -39 67 -27v-34s-3 -11 -13 -9c-79 26 -137 101 -137 189c0 110 90 200 200 200z" />
|
||||
<glyph glyph-name="uniF1CA" unicode=""
|
||||
d="M57 184c-9 7 -16 16 -22 26c-12 22 -17 42 -17 62c0 15 4 30 12 42c10 12 22 18 37 18c11 0 21 -4 30 -10c9 -7 16 -15 21 -26c11 -22 17 -45 17 -67c0 -5 0 -11 -1 -18s-4 -15 -9 -22c-10 -10 -22 -15 -37 -16c-12 0 -22 4 -31 11zM91 100c-13 0 -29 -2 -49 -5
|
||||
c-15 -3 -28 -7 -42 -13v99c15 -15 36 -23 62 -23c6 0 12 0 18 1l-3 -9s-2 -8 -2 -13c0 -8 1 -15 5 -21c3 -6 7 -11 11 -16zM106 84c21 -14 36 -27 46 -37c9 -10 14 -23 14 -37v-1h-140c-14 0 -26 12 -26 26v15c3 4 6 8 9 11c5 4 11 8 16 10s9 4 12 5c12 4 24 5 35 7
|
||||
c12 1 19 1 22 1h12zM343 375c14 0 26 -12 26 -26v-28v-286c0 -14 -12 -26 -26 -26h-145c2 7 3 15 3 23c0 19 -5 34 -13 46c-9 12 -18 22 -30 32l-19 15c-3 3 -6 6 -9 10s-5 8 -5 14s2 11 5 16c3 4 6 9 9 12c6 5 12 9 17 14s9 10 13 16c8 12 13 28 13 48c0 11 -2 21 -4 29
|
||||
c-3 8 -6 15 -10 21s-8 12 -12 16s-9 7 -12 9h34l35 20h-111c-15 0 -31 -2 -48 -5c-17 -4 -33 -12 -49 -25c-2 -2 -3 -4 -5 -6v7v28c0 14 12 26 26 26h65h93h93h66zM363 261v29h-58v58h-28v-58h-59v-29h59v-58h28v58h58z" />
|
||||
<glyph glyph-name="uniF1CB" unicode=""
|
||||
d="M333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM200 178l70 119h-31l-29 -57c-8 -16 -15 -30 -21 -43h-1c-6 14 -12 27 -20 43l-30 57h-30l65 -119v-88h27v88z" />
|
||||
<glyph glyph-name="uniF1CC" unicode="" horiz-adv-x="476"
|
||||
d="M459 222c13 -16 18 -36 16 -57c-2 -24 -12 -47 -30 -62c-17 -14 -41 -23 -71 -23c-22 0 -45 4 -64 15v-10h-310v76h15v66h-15v77h116v-55c19 7 45 7 62 -6v9h29v40h88v-31l8 43h160c-1 -27 -3 -55 -4 -82zM227 272v-32h48v32h-48zM195 105v0v36h-16v54c0 11 -5 39 -37 39
|
||||
c-22 0 -36 -12 -46 -28v78h-76v-37h15v-106h-15v-36h83v36h-7v23c0 34 24 42 24 21v-44h-8v-36h83zM290 105v36h-15v90h-76v-36h15v-54h-15v-36h91zM374 100c53 0 81 33 81 67c2 45 -26 62 -60 62c-13 0 -26 -4 -38 -9l2 16h81l2 48h-122l-17 -92l44 -6c6 7 13 9 18 9
|
||||
c13 0 19 -14 18 -28c-1 -15 -10 -29 -23 -29c-8 0 -18 4 -13 17c4 19 -7 28 -24 28c-26 0 -35 -31 -24 -51c10 -19 40 -32 75 -32z" />
|
||||
<glyph glyph-name="uniF1CD" unicode=""
|
||||
d="M276 216c0 14 -3 28 -9 40h102v-215c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v215h102c-6 -12 -10 -26 -10 -40c0 -51 41 -92 92 -92s92 41 92 92zM333 379c20 0 36 -16 36 -36v-72h-111c-17 22 -44 37 -74 37s-56 -15 -73 -37h-111v72c0 20 16 36 36 36h297z
|
||||
M29 288v0v72c-8 -3 -13 -11 -13 -20v-52h13zM51 288v74h-12v-74h12zM73 288v74h-12v-74h12zM95 340v22h-13v-74h13v22v30zM350 310v30c0 12 -10 22 -22 22h-35c-12 0 -22 -10 -22 -22v-30c0 -12 10 -22 22 -22h35c12 0 22 10 22 22zM184 135c-45 0 -81 36 -81 81
|
||||
s36 81 81 81s81 -36 81 -81s-36 -81 -81 -81zM184 280c-36 0 -64 -28 -64 -64s28 -65 64 -65s65 29 65 65s-29 64 -65 64z" />
|
||||
<glyph glyph-name="uniF1CE" unicode="" horiz-adv-x="357"
|
||||
d="M340 98c29 -24 22 -67 -13 -81c-2 -1 -3 -2 -5 -3h-24c-17 7 -31 18 -35 38c-31 -7 -59 -1 -81 22c12 12 23 22 33 32c9 -3 18 -7 27 -7c12 0 21 8 25 19c4 12 1 22 -8 31c-24 24 -46 47 -70 71c-2 2 -6 4 -8 6c12 13 23 25 36 39c12 -13 22 -25 33 -36
|
||||
c12 -12 22 -25 35 -36c25 -23 38 -49 32 -82c8 -4 17 -8 23 -13zM212 186c14 -12 25 -23 36 -33c-28 -28 -54 -56 -80 -82c-17 -17 -39 -24 -63 -21c-8 1 -11 -1 -14 -8c-5 -15 -17 -22 -31 -28h-22c-21 7 -33 21 -38 42v10c4 21 15 36 37 42c-5 30 1 56 23 77l35 -35
|
||||
c-1 -1 -3 -3 -4 -5c-9 -13 -8 -29 4 -39s27 -11 39 1c24 23 48 47 72 71c3 3 5 6 6 8zM107 228c29 29 56 59 85 87c17 16 40 20 63 15h6c4 15 11 29 27 35c10 3 21 5 31 4c20 -2 36 -21 38 -43c2 -23 -10 -39 -41 -52c6 -30 -1 -56 -23 -78l-34 34c3 5 7 11 9 17
|
||||
c3 12 -3 25 -14 31c-11 7 -24 6 -35 -4c-12 -11 -23 -23 -35 -35c-15 -14 -29 -29 -44 -44zM38 275c-28 10 -41 30 -35 60c4 19 22 33 41 35c25 2 39 -9 53 -40c29 5 53 -2 73 -22l-35 -35c0 0 -1 2 -3 3c-13 10 -29 8 -40 -4c-10 -12 -9 -27 2 -39c23 -24 47 -48 70 -72
|
||||
c3 -3 4 -5 7 -8c-12 -11 -22 -22 -35 -35c-11 12 -23 24 -34 36c-12 12 -23 24 -35 35c-25 23 -37 51 -29 86z" />
|
||||
<glyph glyph-name="uniF1CF" unicode="" horiz-adv-x="417"
|
||||
d="M354 210c41 -10 63 -29 63 -68c0 -48 -40 -66 -99 -66c-83 0 -112 38 -127 84l-15 48c-11 35 -25 62 -67 62c-29 0 -59 -21 -59 -80c0 -46 24 -75 57 -75c37 0 62 28 62 28l15 -42s-26 -25 -80 -25c-67 0 -104 39 -104 112c0 75 37 120 107 120c64 0 96 -23 116 -85
|
||||
l16 -48c11 -35 32 -60 80 -60c32 0 49 7 49 25c0 14 -8 23 -32 29l-33 8c-40 10 -55 31 -55 63c0 52 42 68 85 68c49 0 78 -18 82 -61l-48 -6c-2 21 -14 30 -37 30c-21 0 -34 -10 -34 -26c0 -14 6 -23 27 -28z" />
|
||||
<glyph glyph-name="uniF1D0" unicode=""
|
||||
d="M341 376c15 0 28 -11 28 -26v-316c0 -15 -13 -26 -28 -26h-314c-15 0 -27 11 -27 26v316c0 15 12 26 27 26h314zM109 62v176h-54v-176h54zM82 262c17 0 32 14 32 32c0 17 -15 32 -32 32c-18 0 -32 -15 -32 -32c0 -18 14 -32 32 -32zM314 62v0v97c0 47 -10 83 -65 83
|
||||
c-27 0 -45 -14 -52 -28h-1v24h-52v-176h54v87c0 23 5 45 33 45s28 -26 28 -46v-86h55z" />
|
||||
<glyph glyph-name="uniF1D1" unicode=""
|
||||
d="M346 376c13 -5 23 -18 23 -33v-299c0 -20 -16 -36 -36 -36h-299c-16 0 -29 11 -34 25v321c3 10 10 18 20 22h326zM276 241v22h-68l-22 -84h-1l-22 84h-68v-22h7c3 0 6 -4 6 -6v-89c0 -2 -3 -6 -6 -6h-7v-21h54v21h-13v94v0l32 -115h24l32 115v0v-94h-12v-21h64v21h-7
|
||||
c-3 0 -6 4 -6 6v89c0 2 3 6 6 6h7z" />
|
||||
<glyph glyph-name="uniF1D2" unicode="" horiz-adv-x="454"
|
||||
d="M375 187c-40 0 -73 32 -73 72s33 72 73 72s72 -32 72 -72s-32 -72 -72 -72zM147 238c0 43 22 65 65 65s65 -22 65 -65s-22 -65 -65 -65s-65 22 -65 65zM64 161c-32 0 -58 27 -58 59s26 58 58 58s59 -26 59 -58s-27 -59 -59 -59zM64 148c37 0 65 -32 65 -66v-23
|
||||
c0 -3 -3 -6 -6 -6h-2h-113h-2c-3 0 -6 3 -6 6v23c0 34 27 66 64 66zM212 159c41 0 71 -37 71 -74v-25c0 -4 -2 -7 -6 -7h-2h-126h-2c-4 0 -7 3 -7 7v25c0 37 31 74 72 74zM375 170c46 0 79 -40 79 -82v-27c0 -4 -3 -8 -7 -8h-3h-139h-2c-4 0 -8 4 -8 8v27c0 42 34 82 80 82z
|
||||
" />
|
||||
<glyph glyph-name="uniF1D3" unicode=""
|
||||
d="M185 272c45 0 82 -37 82 -82s-37 -82 -82 -82s-82 37 -82 82s37 82 82 82zM333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM185 66c69 0 124 55 124 124s-55 124 -124 124s-125 -55 -125 -124
|
||||
s56 -124 125 -124z" />
|
||||
<glyph glyph-name="uniF1D4" unicode="" horiz-adv-x="348"
|
||||
d="M348 235c0 -83 -67 -136 -171 -137v-23c0 -28 -16 -54 -41 -65c-6 -3 -17 -5 -28 -5c-10 0 -22 2 -35 8v65c21 -15 41 -7 41 11v181h63v-113c30 0 112 8 112 78c0 62 -60 85 -115 85c-57 0 -114 -27 -114 -85c0 -18 9 -45 18 -53l-41 -43c-24 22 -37 66 -37 96
|
||||
c0 85 72 144 174 144c104 0 174 -58 174 -144z" />
|
||||
<glyph glyph-name="uniF1D5" unicode="" horiz-adv-x="399"
|
||||
d="M282 373v0v-133c-7 6 -147 133 -152 138c23 8 46 13 70 13c29 0 56 -6 82 -18zM97 21v0c-37 23 -67 57 -83 97c2 2 76 69 83 75v-172zM0 192v0c0 75 42 143 109 177c2 -2 72 -65 75 -68c-3 -3 -172 -156 -177 -161c-5 17 -7 35 -7 52zM118 105v0h261
|
||||
c-31 -63 -92 -106 -161 -112h-37c-22 2 -43 8 -63 17v95zM303 362v0c59 -36 96 -101 96 -170c0 -22 -4 -45 -11 -66h-85v236z" />
|
||||
<glyph glyph-name="uniF1D6" unicode="" horiz-adv-x="399"
|
||||
d="M200 392c110 0 199 -90 199 -200s-89 -200 -199 -200c-20 0 -39 3 -57 8c8 12 16 28 20 43c2 9 14 55 14 55c7 -13 27 -25 49 -25c64 0 108 59 108 137c0 59 -51 115 -127 115c-95 0 -142 -68 -142 -125c0 -34 13 -66 41 -77c5 -2 9 0 10 5c1 4 3 13 4 17c1 5 1 7 -3 11
|
||||
c-8 9 -13 22 -13 39c0 50 37 95 98 95c54 0 83 -32 83 -76c0 -58 -25 -106 -63 -106c-21 0 -37 17 -32 38c6 25 18 53 18 71c0 16 -9 30 -27 30c-21 0 -39 -22 -39 -52c0 -19 7 -31 7 -31s-22 -93 -26 -109c-4 -15 -4 -32 -3 -46c-70 31 -120 101 -120 183
|
||||
c0 110 90 200 200 200z" />
|
||||
<glyph glyph-name="uniF1D7" unicode="" horiz-adv-x="435"
|
||||
d="M424 291c27 -2 4 -60 -52 -75c1 -7 1 -15 1 -23v-1c0 -99 -80 -179 -187 -179s-186 79 -186 178v1c0 99 80 179 187 179c19 0 36 -3 53 -7v-105c-3 2 -6 4 -10 5c-46 16 -96 -7 -119 -45l-1 -1c-24 -39 -12 -83 33 -98c46 -16 95 7 119 45l1 1c8 13 12 27 12 40v0v145
|
||||
c3 -1 6 -3 8 -4s4 -3 6 -4c24 -15 85 -53 135 -52z" />
|
||||
<glyph glyph-name="uniF1D8" unicode="" horiz-adv-x="458"
|
||||
d="M458 197c0 -18 -10 -35 -25 -45c1 -5 2 -10 2 -15c0 -76 -92 -138 -206 -138s-206 62 -206 138c0 5 0 11 1 16c-15 10 -24 26 -24 44c0 29 24 53 53 53c13 0 24 -5 34 -13c36 23 83 37 136 38l37 105l89 -22c6 16 22 27 40 27c24 0 43 -19 43 -43s-19 -43 -43 -43
|
||||
s-43 19 -43 43l-75 18l-31 -85c50 -2 97 -16 131 -38h1c10 8 21 13 34 13c29 0 52 -24 52 -53zM299 129c18 0 32 14 32 32s-14 33 -32 33s-33 -15 -33 -33s15 -32 33 -32zM305 73c3 3 3 9 0 12s-9 3 -12 0c0 0 -20 -20 -65 -20c-44 0 -62 19 -62 20c-3 3 -9 4 -12 1
|
||||
s-4 -9 -1 -12c1 -1 22 -25 75 -25s76 23 77 24zM131 161c0 -18 14 -32 32 -32s33 14 33 32s-15 33 -33 33s-32 -15 -32 -33z" />
|
||||
<glyph glyph-name="uniF1D9" unicode="" horiz-adv-x="390"
|
||||
d="M103 162c0 0 -20 3 -44 14l275 3c-25 -12 -48 -16 -48 -16h-74s-6 -1 -8 -4s-2 -9 -2 -9v-9c-11 8 -18 21 -24 21h-75zM25 166c-2 1 -4 2 -5 4c2 -1 3 -2 5 -4zM39 368v-182c-11 6 -17 11 -21 13v180c0 6 4 10 10 10h332c6 0 10 -4 10 -10v-180c-4 -3 -9 -7 -20 -13v182
|
||||
h-311zM388 202c3 -2 1 -6 0 -8s-7 -17 -33 -34s-51 -27 -51 -27s16 -51 1 -89s-48 -48 -64 -48s-39 12 -39 34v77c6 -1 13 -2 21 -2c18 0 31 8 42 19s19 32 10 35s-12 -3 -20 -14c-7 -9 -22 -17 -44 -9c-3 1 -6 3 -9 5v9s0 6 2 9s7 4 8 4h74s23 3 48 15c1 1 3 1 4 2
|
||||
c4 2 9 4 12 6c11 6 16 10 20 13l6 3c6 2 9 2 12 0zM265 124c-11 -11 -24 -19 -42 -19c-8 0 -15 1 -21 2c-8 2 -14 4 -14 4v-83s-24 -33 -40 -33s-48 9 -63 47s1 89 1 89s-25 11 -51 28c-4 2 -7 5 -10 7c-2 2 -3 3 -5 4c-14 12 -19 21 -19 23c-1 2 -3 6 0 8s7 2 13 0
|
||||
c1 -1 2 -1 4 -2c4 -2 10 -7 21 -13c4 -2 7 -5 12 -7c2 -1 6 -2 8 -3c24 -11 44 -14 44 -14h75c6 0 13 -13 24 -21c3 -2 6 -4 9 -5c22 -8 37 0 44 9c8 11 11 17 20 14s1 -24 -10 -35zM251 272c26 0 47 -20 47 -46s-21 -47 -47 -47s-46 21 -46 47s20 46 46 46zM141 272
|
||||
c26 0 47 -20 47 -46s-21 -47 -47 -47s-46 21 -46 47s20 46 46 46z" />
|
||||
<glyph glyph-name="uniF1DA" unicode="" horiz-adv-x="394"
|
||||
d="M383 150c7 -15 11 -32 11 -49c0 -60 -49 -109 -109 -109c-19 0 -36 5 -51 13c-11 -2 -23 -3 -35 -3c-104 0 -188 84 -188 188c0 13 2 26 4 38c-10 16 -15 35 -15 55c0 60 49 109 109 109c21 0 41 -6 58 -17c10 2 21 3 32 3c104 0 188 -84 188 -188c0 -14 -1 -27 -4 -40z
|
||||
M296 100c9 12 13 27 13 42c0 13 -3 24 -8 33s-12 16 -21 22s-19 11 -32 15c-12 4 -27 8 -42 11c-12 3 -21 5 -26 6s-10 4 -15 6s-8 6 -11 9s-4 7 -4 11c0 7 4 13 12 18s19 8 32 8c14 0 26 -2 32 -7c7 -5 12 -12 17 -21c4 -7 7 -12 11 -15s9 -5 16 -5c8 0 14 3 19 8
|
||||
s8 11 8 18s-2 14 -6 21s-10 15 -18 21s-19 11 -31 15s-27 6 -44 6c-21 0 -39 -2 -55 -8s-29 -15 -37 -26s-12 -24 -12 -38c0 -15 4 -28 12 -38s19 -17 32 -23s29 -11 49 -15c14 -3 26 -5 35 -8c8 -3 15 -7 20 -12s7 -10 7 -17c0 -9 -5 -18 -14 -24c-10 -7 -22 -10 -38 -10
|
||||
c-11 0 -20 2 -27 5s-12 7 -16 12s-8 11 -11 19c-3 7 -7 13 -11 17c-5 4 -10 5 -16 5c-8 0 -15 -2 -20 -7s-8 -11 -8 -18c0 -11 4 -22 12 -34c8 -11 18 -20 31 -27c18 -9 41 -14 68 -14c23 0 41 3 58 10s30 17 39 29z" />
|
||||
<glyph glyph-name="uniF1DB" unicode="" horiz-adv-x="390"
|
||||
d="M173 165c98 -37 75 -98 23 -98s-89 32 -89 32l-30 -70c21 -11 43 -19 56 -23l-33 -8c-15 -4 -31 6 -35 21l-64 268c-4 16 6 31 21 35l77 19c-7 -8 -12 -17 -16 -26c0 -1 -1 -1 -1 -2c-1 -2 -1 -4 -2 -6c0 -1 -1 -2 -1 -3c-1 -2 -2 -4 -2 -6v-4c0 -2 -1 -4 -1 -6
|
||||
c0 -1 -1 -2 -1 -3v-7v-3v-10s1 -6 1 -8v-1c0 -2 1 -6 2 -8v0c1 -2 1 -5 2 -7c0 -1 1 0 1 -1c1 -2 2 -5 3 -7v-1c1 -2 3 -4 4 -6c0 -1 1 0 1 -1c1 -2 3 -4 5 -6v-1c1 -2 3 -4 5 -6c0 -1 1 0 1 -1l6 -6v-1c2 -2 4 -2 6 -4c1 0 0 -2 1 -2c2 -2 5 -3 7 -5l1 -1
|
||||
c15 -11 33 -20 52 -27zM390 97c4 -15 -7 -31 -22 -35l-56 -14c9 14 17 33 18 56c1 29 -10 60 -39 85v0c-2 1 -3 3 -5 4l-1 1c-2 1 -3 3 -5 4l-1 1c-2 1 -4 3 -6 4h-1c-2 1 -4 3 -6 4c-1 0 -1 1 -2 1l-6 3h-1c-2 1 -5 3 -8 4h-2l-6 3c-1 0 -1 1 -2 1l-9 3
|
||||
c-100 33 -71 88 -20 85c54 -3 74 -25 74 -25l24 67c-2 1 -5 2 -7 3c-1 0 -1 1 -2 1c-2 1 -3 1 -5 2c-1 0 -1 1 -2 1c-2 1 -5 2 -7 3c-1 0 -1 1 -2 1c-1 1 -3 1 -4 2h-3c-1 1 -3 2 -4 2s-1 1 -2 1c-2 1 -3 0 -5 1c-1 0 -1 1 -2 1s-3 1 -4 1h-2c-2 0 -3 2 -5 2
|
||||
c-7 2 -13 2 -17 3l56 13c16 4 30 -5 34 -21z" />
|
||||
<glyph glyph-name="uniF1DC" unicode="" horiz-adv-x="379"
|
||||
d="M302 224c4 1 8 4 12 4c7 0 14 0 20 -3c10 -5 11 -16 2 -22c-7 -5 -16 -8 -24 -11c-18 -7 -21 -13 -12 -30c15 -29 37 -51 70 -59c3 -1 9 -4 9 -6c0 -5 -3 -11 -6 -13c-11 -5 -23 -9 -35 -12c-7 -2 -10 -4 -12 -11c-3 -15 -6 -17 -20 -14c-23 5 -44 0 -63 -14
|
||||
c-39 -28 -69 -27 -108 1c-19 14 -38 18 -61 13c-15 -3 -17 -1 -21 14c-1 6 -4 10 -11 11c-11 2 -24 6 -34 11c-4 2 -7 8 -8 13c0 2 7 7 11 8c36 10 57 34 72 66c3 8 0 13 -6 17c-6 3 -12 4 -18 7c-4 2 -8 4 -11 6c-7 4 -13 10 -9 19c3 8 14 12 23 9c5 -2 10 -4 15 -5
|
||||
c7 -1 10 1 10 9c-1 18 -1 36 0 54c3 38 26 65 60 78c50 19 109 4 136 -44c9 -17 10 -35 11 -54c-1 -12 -1 -23 -2 -35c-1 -8 4 -9 10 -7z" />
|
||||
<glyph glyph-name="uniF1DD" unicode="" horiz-adv-x="399"
|
||||
d="M200 392c110 0 199 -90 199 -200c0 -71 -37 -133 -92 -168c-8 17 -19 32 -33 45c-29 26 -66 41 -105 41c-25 0 -48 -6 -70 -17c-18 -9 -34 -21 -47 -36c-33 36 -52 83 -52 135c0 110 90 200 200 200zM294 114c4 6 3 15 -3 19c-36 25 -77 38 -121 38c-25 0 -51 -4 -74 -13
|
||||
c-7 -3 -11 -10 -8 -17s11 -11 18 -8c20 8 42 11 64 11c38 0 75 -11 106 -33c2 -2 4 -2 7 -2c4 0 8 1 11 5zM323 176c4 7 3 16 -4 20c-45 28 -96 43 -149 43c-29 0 -58 -4 -86 -13c-8 -3 -13 -11 -10 -19s11 -13 19 -10c25 8 51 12 77 12c47 0 93 -13 133 -38c2 -2 5 -2 8 -2
|
||||
c5 0 9 2 12 7zM338 229c6 0 11 3 14 8c5 8 2 18 -6 23c-53 31 -114 48 -176 48c-34 0 -67 -5 -99 -14c-9 -3 -15 -12 -12 -21s12 -14 21 -11c29 9 60 13 90 13c56 0 112 -16 160 -44c3 -2 5 -2 8 -2zM225 16c6 -6 11 -13 15 -20c-13 -3 -26 -4 -40 -4c-32 0 -63 7 -90 21
|
||||
c6 6 13 12 21 16c12 6 25 9 38 9c21 0 41 -8 56 -22z" />
|
||||
<glyph glyph-name="uniF1DE" unicode="" horiz-adv-x="425"
|
||||
d="M420 109c6 -21 7 -44 0 -65c-15 -44 -45 -72 -92 -78c-30 -4 -56 5 -77 28c-17 19 -26 41 -28 66c0 4 0 8 -1 12c-4 21 -18 30 -39 27c-24 -3 -47 -8 -71 -7c-13 0 -26 4 -38 10c-19 10 -28 27 -31 48s0 42 4 63c2 8 3 16 4 25c1 17 -8 29 -21 39c1 1 3 0 4 0
|
||||
c23 -3 39 -23 38 -46c-1 -22 -2 -43 3 -65c1 -4 2 -8 3 -11c4 -12 15 -14 26 -15c20 -1 40 3 60 6c10 2 18 3 29 5c-9 6 -17 11 -25 16c-40 24 -65 57 -73 104c-1 9 -4 17 -6 26c-5 26 -21 41 -47 45c-13 2 -25 1 -38 -1c-1 0 -3 -1 -4 0c-1 2 1 2 2 3c24 12 49 15 75 8
|
||||
c14 -4 22 -15 28 -27c6 -13 9 -27 13 -41c1 -4 3 -8 4 -12c6 -20 19 -35 38 -44s39 -15 60 -18c2 0 4 -2 4 2c-1 11 -1 22 -2 33c-2 21 -14 35 -32 45c-13 8 -26 17 -38 27c-30 27 -42 60 -35 100v2h3c-1 -24 5 -45 23 -63c10 -10 22 -15 34 -21c32 -14 58 -35 77 -64
|
||||
c9 -14 13 -29 16 -44c0 -1 1 -2 1 -4c7 13 18 23 26 34c14 20 12 37 -4 55c-12 13 -28 21 -44 28c-2 1 -5 2 -7 3c-21 8 -31 25 -29 48c0 3 0 5 2 8c1 -5 2 -9 3 -14c4 -17 13 -27 30 -31c25 -6 50 -16 69 -34c12 -11 20 -23 23 -39c2 -14 0 -26 -6 -38
|
||||
c-4 -9 -10 -18 -14 -27c-5 -10 -4 -20 0 -30c3 -6 7 -9 14 -9c41 -2 75 -28 86 -68z" />
|
||||
<glyph glyph-name="uniF1DF" unicode="" horiz-adv-x="337"
|
||||
d="M247 12v144h34v-179h-281v179h33l-2 -144h216zM53 35v36h169v-36h-169zM53 99l4 37l169 -17l-4 -36zM62 173l10 36l164 -46l-10 -36zM93 260l19 31l145 -87l-19 -32zM293 232l-30 -22l-98 138l29 22zM301 234l-28 167l36 6l28 -167z" />
|
||||
<glyph glyph-name="uniF1E0" unicode="" horiz-adv-x="497"
|
||||
d="M466 238c0 -20 -16 -36 -36 -36s-37 16 -37 36s17 36 37 36s36 -16 36 -36zM429 306c37 0 68 -31 68 -68s-31 -67 -68 -67l-64 -47c-2 -25 -24 -46 -50 -46c-24 0 -44 17 -49 40l-190 76c-8 -4 -17 -7 -26 -7c-28 0 -50 23 -50 51s22 50 50 50c24 0 44 -17 49 -40
|
||||
l190 -76c8 4 17 7 26 7h5l42 60c0 37 30 67 67 67zM429 283c-25 0 -45 -20 -45 -45s20 -45 45 -45s45 20 45 45s-20 45 -45 45zM50 275c-20 0 -37 -17 -37 -37s17 -37 37 -37c3 0 5 -1 8 0l-15 7v0c-14 6 -22 23 -16 38s23 21 38 16v0l18 -7c-6 12 -19 20 -33 20zM315 166
|
||||
c-3 0 -5 0 -8 -1l15 -6c15 -6 23 -24 17 -39s-24 -22 -39 -16c-6 2 -12 5 -18 7c6 -12 19 -19 33 -19c20 0 37 17 37 37s-17 37 -37 37z" />
|
||||
<glyph glyph-name="uniF1E1" unicode="" horiz-adv-x="399"
|
||||
d="M357 314c26 -34 42 -76 42 -122c0 -110 -89 -200 -199 -200c-78 0 -145 44 -178 109h87c41 0 70 22 70 58c0 76 -87 45 -87 72c0 13 10 18 29 18h32h29c17 0 36 -4 36 -22v-60c0 -44 35 -66 70 -66c36 0 69 22 69 66v147v0zM200 392c42 0 80 -13 112 -35v-191
|
||||
c0 -13 -11 -24 -24 -24v0c-13 0 -24 11 -24 24v57c0 46 -24 65 -54 65h-98c-36 0 -65 -23 -65 -59c0 -18 8 -45 45 -52c30 -5 42 -4 42 -20s-17 -15 -40 -15h-88c-4 16 -6 33 -6 50c0 110 90 200 200 200v0z" />
|
||||
<glyph glyph-name="uniF1E2" unicode="" horiz-adv-x="394"
|
||||
d="M193 244c-24 -18 -47 -38 -74 -52c-4 -2 -8 -4 -13 -5c-12 -3 -20 -14 -20 -27c0 -12 9 -24 21 -27s25 2 31 13c7 15 20 25 33 34c5 4 7 3 11 -2c4 9 9 18 13 27c1 -1 1 -1 1 -2c-7 -25 -14 -52 -22 -77c-2 -6 -5 -10 -10 -13c-14 -9 -18 -28 -9 -43c9 -14 27 -19 42 -11
|
||||
s21 26 14 41c-3 5 -3 11 -2 16c4 14 6 28 14 41c3 6 7 11 13 15c7 4 11 3 16 -3c6 -7 9 -15 8 -25c-1 -13 7 -25 19 -29s25 1 32 11c7 11 7 24 -2 34c-10 12 -21 23 -30 35c-16 21 -17 43 -4 66c7 12 15 25 22 38c6 11 15 21 26 27c10 5 19 6 29 0c6 -4 12 -7 19 -11
|
||||
c15 -9 23 -22 23 -39v-168c0 -17 -8 -30 -22 -38c-51 -29 -101 -58 -152 -86c-15 -8 -30 -8 -45 0c-51 29 -102 57 -153 86c-14 8 -22 21 -22 37v170c0 16 7 29 21 37c51 29 103 58 155 87c13 7 28 7 42 0c8 -4 15 -8 23 -12c6 -3 8 -9 9 -16c1 -12 -1 -23 -7 -33
|
||||
c-7 -12 -14 -25 -21 -37c-14 -22 -33 -36 -59 -40c-16 -3 -33 -1 -49 1c-12 1 -23 -5 -27 -16s0 -24 10 -30s23 -4 31 5c5 6 13 5 20 6c5 1 10 2 15 2c2 0 3 0 5 1c8 4 16 9 24 13z" />
|
||||
<glyph glyph-name="uniF1E3" unicode=""
|
||||
d="M333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM270 68v0v44c-14 -9 -28 -14 -42 -14c-8 0 -15 2 -21 6c-5 3 -8 6 -10 11s-2 15 -2 31v71h66v44h-66v70h-40c-2 -14 -4 -27 -9 -36s-11 -16 -19 -23
|
||||
s-17 -12 -28 -16v-39h30v-97c0 -13 1 -22 4 -29s8 -13 15 -19s15 -11 25 -14s20 -5 33 -5c11 0 22 1 32 3s20 6 32 12z" />
|
||||
<glyph glyph-name="uniF1E4" unicode="" horiz-adv-x="394"
|
||||
d="M394 314c-11 -16 -24 -31 -40 -42v-10c0 -107 -81 -230 -230 -230c-46 0 -88 13 -124 36c6 -1 12 -1 19 -1c38 0 73 13 101 35c-35 1 -66 24 -76 56c5 -1 10 -2 15 -2c7 0 15 1 22 3c-37 7 -65 40 -65 79v2c11 -6 23 -11 36 -11c-22 15 -35 40 -35 68c0 15 3 28 10 40
|
||||
c40 -49 100 -81 167 -84c-1 6 -2 12 -2 18c0 45 36 81 81 81c23 0 44 -9 59 -25c18 4 35 10 51 19c-6 -19 -18 -34 -35 -44c16 2 31 6 46 12z" />
|
||||
<glyph glyph-name="uniF1E5" unicode=""
|
||||
d="M333 376c20 0 36 -15 36 -35v-298c0 -20 -16 -35 -36 -35h-297c-20 0 -36 15 -36 35v298c0 20 16 35 36 35h297zM309 259c1 7 2 15 0 22c-1 3 -2 6 -4 8c-9 11 -29 11 -42 9c-11 -2 -48 -17 -60 -55h6c14 0 22 -2 25 -12c1 -4 2 -8 1 -14c-1 -10 -6 -20 -12 -31
|
||||
c-7 -12 -19 -37 -35 -20c-2 2 -4 6 -5 6v0c-10 15 -9 42 -12 59c-2 11 -4 26 -8 37c0 1 0 5 -1 5v0c-4 10 -11 17 -18 19c-9 3 -22 -2 -29 -6c-22 -13 -39 -31 -59 -46v-1c5 -1 4 -2 5 -4c2 -3 4 -5 8 -6c13 -2 25 11 34 -3c1 -2 2 -3 3 -5h-1l1 -1v1v-1c3 -7 4 -15 7 -22
|
||||
c5 -13 8 -26 12 -41c4 -16 8 -37 17 -52c5 -9 11 -16 19 -19c11 -5 28 2 36 7c23 13 40 32 55 52c35 46 54 99 57 114z" />
|
||||
<glyph glyph-name="uniF1E6" unicode="" horiz-adv-x="368"
|
||||
d="M368 203h-205v149l205 29v-178zM149 349v-146h-149v125zM0 183h149v-148l-149 22v126zM163 33v150h205v-180z" />
|
||||
<glyph glyph-name="uniF1E7" unicode="" horiz-adv-x="399"
|
||||
d="M147 277c-131 -136 -103 -210 -103 -210c-27 34 -44 78 -44 125c0 53 21 100 54 136c0 0 34 -15 93 -51zM200 315c-80 58 -130 29 -130 29c35 30 81 48 130 48s94 -18 129 -48c0 0 -49 29 -129 -29v0v0zM199 233c124 -92 145 -179 145 -179c-36 -38 -87 -62 -144 -62
|
||||
s-109 24 -145 62c0 0 33 97 144 179zM399 192c0 -47 -16 -91 -43 -125c0 0 27 74 -104 210c59 36 94 51 94 51c33 -36 53 -83 53 -136z" />
|
||||
<glyph glyph-name="uniF1E8" unicode="" horiz-adv-x="512"
|
||||
d="M460 50l-53 6l6 46l53 -6zM512 328l-50 -202l-39 6l-1 207zM332 292c35 -27 53 -61 53 -103c0 -43 -18 -78 -53 -105c-30 -22 -67 -35 -111 -39h-56c-44 4 -82 17 -111 39c-36 27 -54 62 -54 105c0 42 18 76 54 103c35 27 82 41 139 41c56 0 103 -14 139 -41zM305 224
|
||||
l7 10h-48h-50l2 -10l30 -5c-1 -6 -16 -20 -46 -43c-23 28 -39 51 -50 67l35 4l2 8c-16 1 -36 1 -60 0c-34 1 -52 1 -54 0v-10l33 -5c6 -5 18 -17 37 -40c18 -22 27 -36 28 -39l1 -15v-7c0 -12 -1 -20 -2 -21c-2 -2 -6 -2 -15 -3l-17 -1l-2 -10h52h59l1 11l-36 1l-3 22l1 9
|
||||
l1 14c2 5 13 16 33 32c19 16 30 24 34 25z" />
|
||||
<glyph glyph-name="uniF1E9" unicode="" horiz-adv-x="344"
|
||||
d="M212 133c7 7 17 4 17 4l101 -32s14 -2 14 -12c0 -7 -4 -15 -4 -15l-43 -61s-7 -6 -15 -6s-17 12 -17 12l-54 90s-6 13 1 20zM207 179c-5 8 0 17 0 17l57 89s6 12 16 11c9 -1 13 -8 13 -8l48 -57s4 -9 2 -16s-16 -13 -16 -13l-100 -29s-15 -3 -20 6zM159 214
|
||||
c-11 -3 -19 6 -19 6l-87 118s-12 14 -6 24c4 7 12 10 12 10l84 31c4 1 8 5 20 -3c8 -5 9 -23 9 -23l1 -143s-2 -17 -14 -20zM139 156c0 -15 -8 -15 -12 -18l-105 -23s-15 -6 -20 2c-3 6 -2 18 -2 18l6 73c0 5 5 9 10 12c6 4 20 -1 20 -1l90 -46s13 -6 13 -17zM165 117
|
||||
c8 -4 9 -15 9 -15l-2 -105s1 -14 -8 -17c-6 -2 -15 0 -15 0l-70 23c-5 2 -9 5 -11 12s7 19 7 19l70 78s11 10 20 5z" />
|
||||
<glyph glyph-name="uniF1EA" unicode=""
|
||||
d="M160 88v67h16v-88h-16v9c-6 -7 -13 -11 -19 -11c-5 0 -8 3 -10 7c-1 3 -1 7 -1 13v70h16v-65v-6c0 -2 2 -4 4 -4c3 0 6 3 10 8zM71 169v17h56v-17h-19v-102h-18v102h-19zM181 247c-5 0 -8 4 -8 12v38c0 8 3 12 8 12s7 -4 7 -12v-38c0 -8 -2 -12 -7 -12zM222 156
|
||||
c6 0 11 -3 13 -10c1 -4 2 -9 2 -17v-36c0 -8 -1 -14 -2 -18c-2 -7 -7 -10 -13 -10s-11 3 -16 10v-8h-16v119h16v-39c5 6 10 9 16 9zM221 92v38c0 8 -2 12 -7 12c-3 0 -5 -1 -8 -4v-54c3 -3 5 -4 8 -4c5 0 7 4 7 12zM274 156c8 0 15 -3 19 -9c3 -4 5 -11 5 -20v-19h-33v-16
|
||||
c0 -8 3 -12 9 -12c4 0 6 3 7 7v10h17v-2c0 -5 -1 -8 -1 -10c-1 -4 -2 -7 -4 -10c-4 -6 -11 -10 -19 -10s-14 4 -19 10c-3 4 -6 11 -6 20v31c0 9 2 17 5 21c5 6 12 9 20 9zM281 122v8c0 8 -3 12 -8 12s-8 -4 -8 -12v-8h16zM333 376c20 0 36 -16 36 -36v-296
|
||||
c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM218 323v-71c0 -6 0 -11 1 -14c2 -5 6 -6 11 -6c6 0 12 4 18 11v-10h17v90h-17v-69c-4 -5 -7 -7 -10 -7c-2 0 -4 0 -4 3v7v66h-16zM157 293v-31c0 -10 2 -17 5 -21c4 -6 11 -9 19 -9s14 3 19 9
|
||||
c3 4 5 11 5 21v31c0 10 -2 17 -5 22c-5 6 -11 9 -19 9s-15 -3 -19 -9c-3 -5 -5 -12 -5 -22zM113 353h-19l12 -33c6 -17 9 -29 11 -38v-49h18v49l21 71h-18l-12 -47zM313 61c5 20 4 42 4 63s1 43 -4 63c-3 14 -15 24 -29 26c-33 4 -67 4 -100 4s-66 0 -99 -4
|
||||
c-14 -2 -26 -12 -29 -26c-5 -20 -5 -42 -5 -63s0 -43 5 -63c3 -14 15 -24 29 -26c33 -4 66 -3 99 -3s67 -1 100 3c14 2 26 12 29 26z" />
|
||||
<glyph glyph-name="uniF1EB" unicode="" horiz-adv-x="281"
|
||||
d="M76 133c37 -3 66 -23 96 -41c21 -13 44 -20 69 -20c12 0 22 4 31 12c4 3 6 2 7 -3c9 -37 -21 -75 -59 -76c-19 -1 -35 6 -50 16c-17 11 -35 25 -52 36c-32 21 -67 28 -105 24c-11 -1 -12 -1 -13 11c-2 22 6 40 21 56c42 46 83 91 122 140c3 4 7 9 10 13c1 1 3 2 2 4
|
||||
s-2 1 -4 1c-18 -1 -37 -2 -56 -2c-10 0 -18 2 -27 6c-15 7 -20 17 -14 32c5 12 11 23 19 34c2 3 4 4 7 2c17 -9 36 -11 55 -13c40 -3 80 0 119 8c5 1 6 -1 6 -5c2 -18 -4 -33 -16 -46c-42 -48 -82 -98 -127 -143c-14 -14 -29 -28 -41 -46z" />
|
||||
<glyph glyph-name="uniF1EC" unicode=""
|
||||
d="M333 376c20 0 36 -16 36 -36v-296c0 -20 -16 -36 -36 -36h-297c-20 0 -36 16 -36 36v296c0 20 16 36 36 36h297zM289 155h-165l135 39c9 3 16 7 21 13s9 15 9 23c0 10 -5 19 -13 26s-18 11 -29 11h-155c-5 -1 -9 -6 -9 -11v-27h164l-135 -38c-8 -3 -16 -7 -21 -14
|
||||
s-8 -14 -8 -22c0 -10 4 -20 12 -27s18 -11 29 -11h154c5 1 10 6 11 11v27z" />
|
||||
<glyph glyph-name="uniF1ED" unicode="" horiz-adv-x="394"
|
||||
d="M175 214c12 12 32 12 44 0s12 -32 0 -44s-32 -12 -44 0s-12 32 0 44zM333 43v0v-1h-1v0l-8 -8v0c-4 -4 -11 -3 -15 0v0l-1 1v0v0l-7 7v0v0l-7 7v0v0v0v0c-4 4 -5 11 -1 16v1h1v1v0l7 7h1c64 65 64 171 -1 236v0v0l-8 7v0v0l-1 1v1c-4 4 -3 11 0 15v0l1 1v0v0l14 14v0v0v0
|
||||
v0c4 4 11 5 16 1v0l9 -9v0v0c82 -82 83 -216 1 -298zM274 102v0h-1v0v0l-8 -9v1c-4 -4 -11 -3 -15 0v-1l-2 1v0v0l-14 15v0c-4 4 -5 11 -1 16v0l1 1v0v0l8 8v0c32 32 31 84 -1 116v0v0l-8 8v0v0l-1 1v0c-4 4 -3 11 0 15v0l1 1v0v0l14 14l1 1v0v0v0c4 4 11 4 16 0v0l9 -8v0
|
||||
v-1c49 -49 50 -129 1 -179zM219 214c12 -12 12 -32 0 -44s-32 -12 -44 0s-12 32 0 44s32 12 44 0zM162 125c4 -4 3 -11 0 -15v0l-1 -1v0v0l-14 -14v0v-1v0v0c-4 -4 -12 -4 -17 0v0l-8 8v0l-1 1c-49 49 -49 129 0 179v0v0v0v0l7 8v0v0l1 1v-1c4 4 12 3 16 0v1l15 -16v0
|
||||
c4 -4 5 -11 1 -16v0l-9 -9v0c-32 -32 -31 -84 1 -116v0v0l8 -8v0v0l1 -1v0zM102 65c4 -4 3 -11 0 -15v0l-1 -1v0v0l-14 -14v0v0v0v0c-4 -4 -11 -5 -16 -1v0l-9 9v0v0c-82 82 -83 216 -1 298v0l9 9v0c4 4 11 3 15 0v0l8 -8v0v0l8 -7v0c4 -4 4 -11 0 -16v-1h-1v-1v0l-7 -7v0
|
||||
c-64 -65 -65 -171 0 -236h1v0l7 -7v0v0l1 -1v-1z" />
|
||||
<glyph glyph-name="uniF1EE" unicode="" horiz-adv-x="426"
|
||||
d="M426 244c1 -4 0 -8 -3 -11l-113 -90l50 -142c1 -4 0 -8 -3 -11c-2 -2 -4 -3 -6 -3s-4 1 -6 2l-132 79l-132 -79c-4 -2 -9 -2 -12 1s-4 7 -3 11l50 142l-112 90c-3 3 -4 7 -3 11s5 7 9 7h144l50 139c1 4 5 7 9 7s9 -3 10 -7l49 -139h144c4 0 9 -3 10 -7z" />
|
||||
<glyph glyph-name="uniF1EF" unicode="" horiz-adv-x="308"
|
||||
d="M308 335v0v-286v0c0 -6 -5 -11 -11 -11v0h-285v0h-1c-6 0 -11 5 -11 11v0v0v284v2c0 6 5 11 11 11h1h284v0h1c6 0 11 -5 11 -11z" />
|
||||
<glyph glyph-name="uniF1F0" unicode="" horiz-adv-x="312"
|
||||
d="M297 193c8 0 15 -7 15 -15s-7 -15 -15 -15h-1v0h-281v0c-8 0 -15 7 -15 15s7 15 15 15v0h281v0h1zM263 144c4 0 8 -4 8 -8v-1v-3c0 -48 -34 -90 -112 -90c-53 0 -91 19 -117 46c-2 1 -4 3 -4 6c0 2 1 4 2 5v0l18 27v0v0v0c1 2 4 4 7 4s5 -2 6 -4c20 -21 50 -39 90 -39
|
||||
c42 0 58 20 58 40c0 2 -1 5 -1 7v0v2c0 4 4 8 8 8l1 -1v1h36zM63 214v0c-8 11 -12 25 -12 43c0 48 41 85 105 85c45 0 82 -15 108 -41v0c2 -1 3 -4 3 -6s-1 -4 -2 -5v0l-17 -25h-1v-1v0c-1 -2 -3 -3 -6 -3c-2 0 -4 1 -5 2v0c-23 23 -55 34 -85 34s-48 -15 -48 -36
|
||||
c0 -28 45 -33 88 -46v0c1 0 2 -1 2 -2s-1 -3 -2 -3h-121c-3 0 -6 2 -7 4z" />
|
||||
<glyph glyph-name="uniF1F1" unicode="" horiz-adv-x="315"
|
||||
d="M313 54c1 -1 2 -3 2 -4v-11c0 -1 -1 -3 -2 -4s-2 -1 -3 -1h-67v0h-1c-1 0 -2 1 -2 2v13v0c0 1 1 2 2 3l1 1v0c37 26 41 30 41 36c0 4 -5 6 -10 6c-8 0 -15 -3 -21 -8v0v0v0v0c-2 -1 -5 -2 -7 0v0l-7 10v0c-1 2 -1 4 0 6v0v0l1 1v0c9 9 23 13 34 13c21 0 35 -12 35 -28
|
||||
c0 -11 -6 -21 -26 -34h27v0c1 0 2 0 3 -1zM210 277c5 -5 5 -14 0 -19v0l-67 -66l67 -67v0c5 -5 5 -14 0 -19l-17 -17c-5 -5 -14 -5 -19 0v0v0l-67 66l-67 -66v0c-5 -5 -14 -5 -19 0l-17 17c-5 5 -5 14 0 19v0v0l67 67l-67 66v1c-5 5 -5 13 0 18l17 18c5 5 14 5 19 0l67 -67
|
||||
l67 67v0c5 5 14 5 19 0z" />
|
||||
<glyph glyph-name="uniF1F2" unicode="" horiz-adv-x="315"
|
||||
d="M313 287c1 -1 2 -2 2 -3v-12c0 -1 -1 -2 -2 -3s-2 -2 -3 -2h-67v0h-1c-1 0 -2 1 -2 2v14v0c0 1 1 2 2 3h1v0c37 26 41 30 41 36c0 4 -5 6 -10 6c-8 0 -15 -3 -21 -8v0v0v0v0c-2 -1 -5 -2 -7 0v0l-7 11v0c-1 2 -1 3 0 5v0v1h1v1c9 9 23 12 34 12c21 0 35 -12 35 -28
|
||||
c0 -11 -6 -20 -26 -33h27v0c1 0 2 -1 3 -2zM210 277c5 -5 5 -14 0 -19v0l-67 -67l67 -67v0c5 -5 5 -14 0 -19l-17 -17c-5 -5 -14 -5 -19 0v0v0l-67 67l-67 -67v0c-5 -5 -14 -5 -19 0l-17 17c-5 5 -5 14 0 19v0v0l67 67l-67 67v0c-5 5 -5 14 0 19l17 17c5 5 14 5 19 0l67 -67
|
||||
l67 67v0c5 5 14 5 19 0z" />
|
||||
<glyph glyph-name="uniF1F3" unicode="" horiz-adv-x="436"
|
||||
d="M436 335v-1v0v-286v0c0 -8 -8 -14 -16 -14h-404c-8 0 -16 6 -16 14v0v286v0v1c0 9 7 15 16 15h404c9 0 16 -6 16 -15zM385 84v0v216h-334v-216h334zM410 179c7 0 13 5 13 12s-6 13 -13 13s-12 -6 -12 -13s5 -12 12 -12z" />
|
||||
<glyph glyph-name="uniF1F4" unicode="" horiz-adv-x="317"
|
||||
d="M301 410c9 0 16 -7 16 -16v-404c0 -9 -7 -16 -16 -16v0v0h-286v0c-8 0 -15 8 -15 16v404c0 8 7 16 15 16v0h286v0v0zM158 -13c7 0 13 6 13 13s-6 12 -13 12s-13 -5 -13 -12s6 -13 13 -13zM266 25v0v334h-215v-334h215z" />
|
||||
<glyph glyph-name="uniF1F5" unicode="" horiz-adv-x="486"
|
||||
d="M473 205c7 0 13 -6 13 -13s-6 -13 -13 -13h-38c-6 -96 -83 -173 -179 -179v-38c0 -7 -6 -13 -13 -13s-13 6 -13 13v38c-96 6 -172 83 -178 179h-39c-7 0 -13 6 -13 13s6 13 13 13h39c6 96 82 173 178 179v38c0 7 6 13 13 13s13 -6 13 -13v-38c96 -6 173 -83 179 -179h38z
|
||||
M230 51v26c-54 6 -96 48 -102 102h-25c6 -68 59 -122 127 -128zM230 307v0v26c-68 -6 -121 -60 -127 -128h25c6 54 48 96 102 102zM256 333v-26c54 -6 96 -48 102 -102h26c-6 68 -60 122 -128 128zM256 51c68 6 122 60 128 128h-26c-6 -54 -48 -96 -102 -102v-26z" />
|
||||
<glyph glyph-name="uniF1F6" unicode="" horiz-adv-x="384"
|
||||
d="M192 307c64 0 115 -51 115 -115s-51 -115 -115 -115s-116 51 -116 115s52 115 116 115zM192 127c36 0 64 29 64 65s-28 65 -64 65s-65 -29 -65 -65s29 -65 65 -65zM192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM192 51
|
||||
c78 0 141 63 141 141s-63 141 -141 141s-141 -63 -141 -141s63 -141 141 -141zM153 192c0 26 13 39 39 39s39 -13 39 -39s-13 -39 -39 -39s-39 13 -39 39z" />
|
||||
<glyph glyph-name="uniF1F7" unicode="" horiz-adv-x="333"
|
||||
d="M12 256c-3 3 -6 6 -6 11v56c0 5 3 12 6 16c0 0 1 3 3 5c11 11 54 45 153 45c117 0 154 -48 156 -50c3 -4 6 -11 6 -16v-56c0 -4 -1 -7 -4 -9c-4 -4 -9 -5 -14 -3l-65 20c-7 2 -12 9 -12 16v21c0 1 0 3 -1 4c0 0 -15 13 -66 13s-66 -13 -66 -13c0 -1 -1 -3 -1 -4v-24
|
||||
c0 -5 -3 -10 -6 -13c-2 -2 -4 -3 -6 -4h-1l-65 -17c-4 -1 -8 0 -11 2zM35 148c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13c0 -6 -5 -11 -11 -11h-35c-6 0 -11 5 -11 11v13zM161 135c0 -6 -5 -11 -11 -11h-35c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13z
|
||||
M230 135c0 -6 -5 -11 -11 -11h-35c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13zM299 135c0 -6 -5 -11 -11 -11h-35c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13zM11 189c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13
|
||||
c0 -6 -5 -11 -11 -11h-35zM115 189h-35c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13c0 -6 -5 -11 -11 -11zM184 189h-35c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13c0 -6 -5 -11 -11 -11zM253 224c6 0 11 -5 11 -11v-13
|
||||
c0 -6 -5 -11 -11 -11h-35c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35zM322 224c6 0 11 -5 11 -11v-13c0 -6 -5 -11 -11 -11h-35c-6 0 -11 5 -11 11v13c0 6 5 11 11 11h35zM57 70c0 -6 -5 -10 -11 -10h-35c-6 0 -11 4 -11 10v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13zM80 60
|
||||
c-6 0 -11 4 -11 10v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13c0 -6 -5 -10 -11 -10h-35zM149 60c-6 0 -11 4 -11 10v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13c0 -6 -5 -10 -11 -10h-35zM218 60c-6 0 -11 4 -11 10v13c0 6 5 11 11 11h35c6 0 11 -5 11 -11v-13
|
||||
c0 -6 -5 -10 -11 -10h-35zM322 94c6 0 11 -5 11 -11v-13c0 -6 -5 -10 -11 -10h-35c-6 0 -11 4 -11 10v13c0 6 5 11 11 11h35zM281 30c6 0 11 -5 11 -11v-13c0 -6 -5 -11 -11 -11h-233c-6 0 -10 5 -10 11v13c0 6 4 11 10 11h233z" />
|
||||
<glyph glyph-name="uniF1F8" unicode="" horiz-adv-x="358"
|
||||
d="M358 88c1 -5 -1 -11 -5 -15l-50 -50c-5 -5 -13 -9 -20 -10h-7v0c-19 0 -89 7 -179 97c-106 106 -97 183 -97 186c1 7 5 15 10 20l51 50c3 3 7 5 12 5c6 0 12 -4 15 -10l41 -76c4 -8 2 -19 -5 -26l-18 -19c-1 -1 -2 -4 -2 -5c0 0 1 -25 47 -71s72 -48 72 -48c1 0 3 2 4 3
|
||||
l22 21c4 4 10 7 16 7c4 0 7 -1 10 -3h1l73 -43c5 -3 8 -8 9 -13z" />
|
||||
<glyph glyph-name="uniF1F9" unicode="" horiz-adv-x="379"
|
||||
d="M364 45c8 0 15 -8 15 -16s-7 -15 -15 -15h-1v0h-348v0c-8 0 -15 7 -15 15s7 16 15 16v0h348v0h1zM63 80c-7 0 -13 6 -13 13c0 2 1 4 1 5v0l103 263v0c2 5 7 9 13 9h45c6 0 11 -4 13 -9v0l103 -262v-1v-1v0c0 -1 1 -3 1 -4c0 -7 -7 -13 -14 -13h-1v0h-29v0
|
||||
c-5 0 -9 4 -11 8v0l-18 48h-133l-18 -47c-2 -5 -7 -9 -13 -9h-29zM189 319l-52 -138h104z" />
|
||||
<glyph glyph-name="uniF1FA" unicode="" horiz-adv-x="332"
|
||||
d="M65 358c6 0 12 -5 12 -11v0v0v-54v0c0 -6 -6 -12 -12 -12v0h-53v0v0c-6 0 -12 6 -12 12v0v54v0v0c0 6 6 11 12 11v0v0h53v0zM193 358c6 0 12 -5 12 -11v0v0v-54v0c0 -6 -6 -12 -12 -12v0h-54v0v0c-6 0 -11 6 -11 12v0v54v0v0c0 6 5 11 11 11v0v0h54v0zM332 347v0v0v-54v0
|
||||
c0 -6 -5 -12 -11 -12v0h-54v0v0c-6 0 -12 6 -12 12v0v54v0c0 6 6 11 12 11v0v0h54v0c6 0 11 -5 11 -11zM65 230c6 0 12 -5 12 -11v0v0v-54v0c0 -6 -6 -11 -12 -11v0h-53v0v0c-6 0 -12 5 -12 11v0v54v0v0c0 6 6 11 12 11v0v0h53v0zM193 230c6 0 12 -5 12 -11v0v0v-54v0
|
||||
c0 -6 -6 -11 -12 -11v0h-54v0v0c-6 0 -11 5 -11 11v0v54v0v0c0 6 5 11 11 11v0v0h54v0zM321 230c6 0 11 -5 11 -11v0v0v-54v0c0 -6 -5 -11 -11 -11v0h-54v0v0c-6 0 -12 5 -12 11v0v54v0c0 6 6 11 12 11v0v0h54v0zM65 103c6 0 12 -6 12 -12v0v0v-54v0c0 -6 -6 -11 -12 -11v0
|
||||
h-53v0v0c-6 0 -12 5 -12 11v0v54v0v0c0 6 6 12 12 12v0v0h53v0zM193 103c6 0 12 -6 12 -12v0v0v-54v0c0 -6 -6 -11 -12 -11v0h-54v0v0c-6 0 -11 5 -11 11v0v54v0v0c0 6 5 12 11 12v0v0h54v0zM321 103c6 0 11 -6 11 -12v0v0v-54v0c0 -6 -5 -11 -11 -11v0h-54v0v0
|
||||
c-6 0 -12 5 -12 11v0v54v0c0 6 6 12 12 12v0v0h54v0z" />
|
||||
<glyph glyph-name="uniF1FB" unicode="" horiz-adv-x="512"
|
||||
d="M509 276c4 -4 4 -9 0 -13v0l-324 -324v0c-4 -4 -9 -4 -13 0v1l-63 62c8 12 7 28 -4 39s-27 12 -39 4l-63 63v0v0c-4 4 -4 9 0 13v0l324 324v0c4 4 9 4 13 0l63 -63c-8 -12 -7 -28 4 -39s27 -12 39 -4l63 -63v0zM438 263c4 4 4 9 0 13l-98 98v0c-4 4 -9 4 -13 0v0
|
||||
l-253 -253v0c-4 -4 -4 -9 0 -13v0l98 -98v0v0c4 -4 9 -4 13 0v0v0zM317 184c1 0 2 -1 2 -2s-1 -2 -1 -2l-1 -1l-39 -9l-9 -39c0 -1 -2 -2 -3 -2s-2 1 -2 2l-17 35l-36 -4c-1 0 -3 0 -3 1s-1 2 0 3l27 26l-17 34c0 1 0 2 1 3s2 1 3 1l34 -17l26 27c1 1 2 0 3 0s1 -2 1 -3
|
||||
l-4 -36z" />
|
||||
<glyph glyph-name="uniF1FC" unicode="" horiz-adv-x="332"
|
||||
d="M321 139c7 -3 11 -12 11 -21v-77v-14c0 -12 -9 -22 -19 -22h-123v70v2v0l-20 34v0v1v0c-1 1 -2 2 -4 2s-2 -1 -3 -2v0l-21 -35h1c0 -1 -1 -1 -1 -2v-70h-123c-10 0 -19 10 -19 22v14v77c0 9 5 18 12 21l83 38l32 15c-15 9 -27 22 -35 39c-7 14 -11 31 -11 49
|
||||
c0 10 2 20 4 29c11 40 43 70 81 70c39 0 72 -30 82 -72c2 -9 3 -18 3 -27c0 -17 -4 -32 -10 -46c-8 -17 -19 -32 -34 -41l33 -16zM190 162v2c0 2 -2 4 -4 4h-40c-2 0 -4 -2 -4 -4c0 -1 1 -1 1 -2v0l19 -35v0h1v0c1 -1 1 -2 3 -2s3 1 4 2v0l20 35v0z" />
|
||||
<glyph glyph-name="uniF1FD" unicode="" horiz-adv-x="332"
|
||||
d="M321 139c7 -3 11 -12 11 -21v-77v-14c0 -12 -9 -22 -19 -22h-294c-10 0 -19 10 -19 22v14v77c0 9 5 18 12 21l83 38l32 15c-1 1 -3 2 -4 3h-44c-7 0 -13 5 -13 12v33v0c1 46 18 87 42 112c13 14 29 23 47 26h2s2 1 3 1h6v0v0v0h6c1 0 2 -1 3 -1h3c18 -3 34 -13 47 -27
|
||||
c24 -25 40 -65 41 -111v0v-33c0 -7 -5 -12 -12 -12h-45l-2 -2l33 -16z" />
|
||||
<glyph glyph-name="uniF1FE" unicode="" horiz-adv-x="332"
|
||||
d="M321 139c7 -3 11 -12 11 -21v-77v-14c0 -12 -9 -22 -19 -22h-294c-10 0 -19 10 -19 22v14v77c0 9 5 18 12 21l83 38l32 15c-15 9 -27 22 -35 39c-7 14 -11 31 -11 49c0 10 2 20 4 29c11 40 43 70 81 70c39 0 72 -30 82 -72c2 -9 3 -18 3 -27c0 -17 -4 -32 -10 -46
|
||||
c-8 -17 -19 -32 -34 -41l33 -16z" />
|
||||
<glyph glyph-name="uniF1FF" unicode="" horiz-adv-x="488"
|
||||
d="M382 145c4 -2 7 -5 9 -9c2 -3 3 -7 3 -11v-69v-13c0 -11 -8 -20 -17 -20h-266c-9 0 -17 9 -17 20v13v69v3c1 7 5 14 11 17l74 34l29 14c-1 1 -2 0 -3 1h-40c-6 0 -11 5 -11 11v30v0c1 37 12 69 30 92c14 21 36 34 60 34c22 0 42 -11 56 -29c20 -23 33 -58 34 -97v0v-30
|
||||
c0 -6 -5 -11 -11 -11h-40c-1 0 -1 -1 -2 -1l29 -14zM119 179l-25 -11c-15 -7 -25 -24 -25 -42v-69h-55c-8 0 -14 7 -14 16v66c0 7 4 13 9 15l83 39c-20 12 -33 36 -33 64c0 40 28 71 62 71c10 0 20 -3 28 -8c-17 -30 -29 -68 -30 -110v0v-31zM479 153c5 -2 9 -8 9 -15v-66
|
||||
c0 -9 -6 -16 -14 -16h-55v69c0 18 -11 35 -26 42l-24 11v31h-1c-1 42 -12 80 -29 110c8 5 18 9 28 9c34 0 62 -32 62 -72c0 -28 -14 -52 -34 -64z" />
|
||||
<glyph glyph-name="uniF200" unicode="" horiz-adv-x="489"
|
||||
d="M481 153c5 -3 8 -8 8 -15v-66c0 -9 -5 -16 -13 -16h-58v70c0 18 -9 34 -24 41l-54 25v0c-5 3 -10 7 -14 12c12 19 19 43 19 67c0 16 -2 32 -8 46c9 7 20 11 32 11c34 0 61 -32 61 -72c0 -27 -13 -51 -32 -63zM150 193l-56 -26c-15 -7 -25 -23 -25 -41v-70h-55
|
||||
c-8 0 -14 7 -14 16v66c0 7 4 13 9 15l83 39c-20 12 -33 36 -33 64c0 40 28 72 62 72c11 0 21 -4 30 -10c-6 -14 -9 -30 -9 -47c0 -25 7 -49 20 -68c-4 -4 -8 -7 -12 -10zM383 144c6 -3 10 -10 10 -18v-70v-12c0 -11 -8 -20 -17 -20h-265c-9 0 -17 9 -17 20v12v70
|
||||
c0 8 5 15 11 18l75 35l29 13c-13 8 -25 20 -32 35c-6 13 -10 28 -10 44c0 9 2 18 4 26c10 36 39 63 73 63c35 0 64 -28 73 -65c2 -8 3 -16 3 -24c0 -15 -3 -29 -9 -41c-7 -16 -18 -29 -31 -37l31 -15z" />
|
||||
<glyph glyph-name="uniF201" unicode="" horiz-adv-x="442"
|
||||
d="M140 207v0v-24l-39 -18c-16 -8 -27 -25 -27 -44v-74h-59c-8 0 -15 8 -15 17v71c0 7 3 13 9 16l90 41c-21 13 -36 38 -36 68c0 42 30 77 66 77c12 0 22 -4 32 -10c-1 -4 -3 -7 -4 -11c-10 -22 -16 -48 -17 -76v0v-28v-5zM430 139c7 -3 12 -12 12 -21v-77v-14
|
||||
c0 -12 -9 -22 -19 -22h-295c-10 0 -19 10 -19 22v14v77c0 9 5 18 12 21l83 38l33 15c-1 1 -3 2 -4 3h-45c-7 0 -12 5 -12 12v33v0c1 46 18 87 42 112c13 14 28 23 46 26h3s2 1 3 1h6h6c1 0 2 -1 3 -1h2c18 -3 34 -13 47 -27c24 -25 40 -65 41 -111h1v-33
|
||||
c0 -7 -6 -12 -13 -12h-44c-1 -1 -2 -1 -3 -2l34 -16z" />
|
||||
<glyph glyph-name="uniF202" unicode="" horiz-adv-x="420"
|
||||
d="M419 124c0 -1 1 -2 1 -3v-74v-13c0 -12 -9 -21 -19 -21h-282c-10 0 -18 9 -18 21v13v74c0 2 0 4 1 6c2 6 5 12 10 14l80 37l31 14c-14 8 -26 22 -34 38c-6 12 -9 25 -10 40v6v8c1 7 2 13 4 20c1 4 2 8 3 11c13 33 41 56 74 56v0v0c37 0 68 -29 78 -69c2 -8 4 -17 4 -26
|
||||
c0 -16 -4 -31 -10 -44c-8 -17 -19 -30 -33 -39l32 -16l77 -36c6 -3 10 -10 11 -17zM155 190l-54 -25c-16 -8 -27 -25 -27 -44v-74h-59c-8 0 -15 8 -15 17v71c0 7 3 13 9 16l90 41l-2 1h-36c-5 0 -10 5 -10 10v26v0c2 62 37 111 80 111c9 0 17 -2 25 -6
|
||||
c-8 -17 -13 -37 -13 -58c0 -30 10 -56 26 -78z" />
|
||||
<glyph glyph-name="uniF203" unicode="" horiz-adv-x="420"
|
||||
d="M160 193l-59 -28c-16 -8 -27 -25 -27 -44v-74h-59c-8 0 -15 8 -15 17v71c0 7 3 13 9 16l90 41c-21 13 -36 38 -36 68c0 42 30 77 66 77c12 0 22 -4 32 -10c-6 -15 -9 -33 -9 -51c0 -27 7 -51 21 -72c-4 -4 -8 -8 -13 -11zM408 141c7 -3 12 -11 12 -20v-74v-13
|
||||
c0 -12 -9 -21 -19 -21h-282c-10 0 -18 9 -18 21v13v74c0 9 4 17 11 20l80 37l31 14c-14 8 -26 22 -34 38c-7 14 -10 29 -10 46c0 10 2 19 4 28c10 39 40 67 77 67s68 -29 78 -69c2 -8 4 -17 4 -26c0 -16 -4 -31 -10 -44c-8 -17 -19 -30 -33 -39l32 -16z" />
|
||||
<glyph glyph-name="uniF204" unicode="" horiz-adv-x="321"
|
||||
d="M293 277c7 0 12 -5 12 -12v-256c0 -7 -5 -12 -12 -12h-265c-7 0 -12 5 -12 12v256c0 7 5 12 12 12h265zM309 359c7 0 12 -5 12 -12v-35c0 -7 -5 -13 -12 -13h-297c-7 0 -12 6 -12 13v35c0 7 5 12 12 12h101v16c0 7 5 12 12 12h72c7 0 12 -5 12 -12v-16h100z" />
|
||||
<glyph glyph-name="uniF205" unicode="" horiz-adv-x="431"
|
||||
d="M431 33c1 -1 0 -2 0 -3c0 -4 -2 -7 -6 -7v0h-72v-20c0 -3 -3 -5 -6 -5h-26c-3 0 -6 2 -6 5v20h-72v0c-4 0 -6 3 -6 7c0 1 0 2 1 3v0l8 16h-82v-44c0 -4 -4 -7 -8 -7h-38c-4 0 -7 3 -7 7v44h-101v0c-5 0 -10 4 -10 9c0 2 1 4 2 6l52 90h-21v0c-4 0 -8 4 -8 8c0 2 1 4 2 5
|
||||
l48 83h-12v0c-3 0 -6 2 -6 5c0 1 1 2 1 3v0l71 123c2 3 4 5 8 5s7 -2 9 -5v0l71 -123v0c0 -1 1 -2 1 -3c0 -3 -3 -5 -6 -5v0h-12l49 -84v-1c1 -1 1 -2 1 -3c0 -4 -4 -8 -8 -8v0h-21l43 -75l11 19h-15v0c-3 0 -5 3 -5 6v2v0l35 60h-9v0c-2 0 -4 2 -4 4c0 1 1 1 1 2v0l50 87v0
|
||||
c1 2 3 4 6 4s5 -2 6 -4v0l50 -87v0c0 -1 1 -1 1 -2c0 -2 -2 -4 -4 -4v0h-8l34 -60v0c0 -1 1 -1 1 -2c0 -3 -3 -6 -6 -6v0h-15l38 -65v0z" />
|
||||
<glyph glyph-name="uniF206" unicode="" horiz-adv-x="331"
|
||||
d="M331 325v0v-133v0c0 -5 -5 -10 -10 -10v0h-43c-7 -47 -42 -84 -87 -94v-65h51v0c7 0 13 -6 13 -13s-6 -13 -13 -13v0v0h-153v0c-7 0 -13 6 -13 13s6 13 13 13h51v65c-45 10 -81 47 -88 94h-42v0c-5 0 -10 5 -10 10v0v0v0v0v133v0v1v0v0c0 5 5 9 10 9h41v36v1
|
||||
c0 8 6 14 14 15v0h199v0h1c8 0 15 -7 15 -15v-1v-36h41v0c5 0 10 -5 10 -10zM51 208v102h-25v-102h25zM305 208v102h-25v-102h25z" />
|
||||
<glyph glyph-name="uniF207" unicode="" horiz-adv-x="312"
|
||||
d="M297 61c8 0 15 -7 15 -15s-7 -16 -15 -16l-1 1v-1h-281v1c-8 0 -15 7 -15 15s7 15 15 15v0h281v0h1zM156 79c-81 0 -121 46 -121 115v145c0 8 7 15 15 15h20c8 0 15 -7 15 -15v-1v-143c0 -44 25 -73 71 -73s71 29 71 73v143v1c0 8 7 15 15 15h20c8 0 15 -7 15 -15v-145
|
||||
c0 -69 -40 -115 -121 -115z" />
|
||||
<glyph glyph-name="uniF208" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM192 51c78 0 141 63 141 141s-63 141 -141 141s-141 -63 -141 -141s63 -141 141 -141zM166 281c0 16 8 25 24 25s24 -9 24 -25s-8 -24 -24 -24s-24 8 -24 24zM273 201v0
|
||||
c2 -2 3 -4 3 -7c0 -6 -4 -10 -10 -10c-3 0 -5 1 -7 3v0l-34 34v0h-1v0c-1 0 -1 1 -2 1c-2 0 -3 -1 -3 -3v-1v0v-30v-32v-63c0 -7 -5 -12 -12 -12s-12 5 -12 12v63v0c0 2 -1 4 -3 4s-3 -2 -3 -4v0v-63c0 -7 -5 -12 -12 -12s-12 5 -12 12v63v32v31v0c0 2 -1 3 -3 3
|
||||
c-1 0 -2 0 -3 -1v0l-34 -34v0c-2 -2 -4 -3 -7 -3c-6 0 -10 4 -10 10c0 3 1 5 3 7v0l46 46v1v0v0c2 2 5 3 8 3v0h53h1c3 0 6 -1 8 -3v0v0v-1z" />
|
||||
<glyph glyph-name="uniF209" unicode="" horiz-adv-x="463"
|
||||
d="M59 344v0c-6 6 -6 14 0 20s14 6 20 0v0v0v0h1l49 -49c6 -6 6 -15 0 -21s-15 -6 -21 0zM144 363v0c-2 8 2 16 10 18s16 -2 18 -10v0v0v0v0l19 -68c2 -8 -3 -16 -11 -18s-16 2 -18 10zM58 246c-8 2 -12 10 -10 18s9 12 17 10v0h1v0v0l67 -18c8 -2 13 -10 11 -18
|
||||
s-10 -12 -18 -10l-68 18v0v0v0v0zM405 40v0c6 -6 5 -14 -1 -20s-14 -6 -20 0v0v0v0v0l-50 49c-6 6 -6 15 0 21s15 6 21 0zM319 21v0c2 -8 -2 -16 -10 -18s-16 2 -18 10v0v0v0v0l-18 68c-2 8 2 16 10 18s16 -2 18 -10zM405 138c8 -2 13 -10 11 -18s-10 -12 -18 -10v0v0v0v0
|
||||
l-68 18c-8 2 -13 10 -11 18s10 12 18 10l68 -18v0v0v0v0zM222 183c39 -39 40 -101 4 -141v0l-51 -52c-40 -40 -105 -40 -145 0s-40 105 0 145l52 52v0c40 36 101 35 140 -4zM189 77v0c17 20 16 50 -3 69s-50 20 -70 3v0l-3 -3v0v0l-46 -46v0c-20 -20 -20 -53 0 -73
|
||||
s53 -20 73 0v0l46 46v0v0zM433 394c39 -39 40 -101 4 -141v0l-52 -52c-40 -40 -104 -40 -144 0s-40 105 0 145l51 51h1c40 36 101 36 140 -3zM400 287v0c17 20 16 51 -3 70s-50 20 -70 3v0l-3 -3v0v0l-46 -46h-1c-20 -20 -20 -53 0 -73s53 -20 73 0v0l47 46v0v0z" />
|
||||
<glyph glyph-name="uniF20A" unicode="" horiz-adv-x="356"
|
||||
d="M342 215c7 0 14 -6 14 -13v-192c0 -7 -7 -13 -14 -13h-329c-7 0 -13 6 -13 13v192c0 7 6 13 13 13h19h29v54c0 65 55 118 122 118c66 0 120 -52 121 -116v-2c0 -5 -4 -10 -10 -10v0h-51c-6 0 -10 5 -10 10c0 27 -22 48 -50 48s-50 -21 -50 -48v-54h123h67h19z" />
|
||||
<glyph glyph-name="uniF20B" unicode="" horiz-adv-x="473"
|
||||
d="M387 259c46 6 86 -34 86 -83c0 -18 -6 -35 -16 -50c-3 -4 -7 -7 -12 -7h-138c-1 47 -39 86 -87 86s-86 -39 -87 -86h-102c-5 0 -10 3 -13 8c-12 20 -18 42 -18 66c0 66 49 121 110 121c8 0 15 -1 23 -3c27 39 70 61 115 61c65 0 121 -47 139 -113zM274 88c1 -2 1 -3 0 -5
|
||||
s-2 -3 -4 -3h-24v-64c0 -3 -2 -4 -5 -4h-44c-3 0 -4 1 -4 4v64h-24c-2 0 -4 1 -5 3s0 4 1 5l50 71c1 1 2 2 4 2v0c2 0 3 -1 4 -2z" />
|
||||
<glyph glyph-name="uniF20C" unicode="" horiz-adv-x="420"
|
||||
d="M394 194c14 0 26 -11 26 -25v-144c0 -14 -12 -25 -26 -25h-368c-14 0 -26 11 -26 25v144c0 14 12 25 26 25h93c11 0 22 -7 25 -17c9 -28 36 -46 66 -46s57 18 66 46c3 10 13 17 24 17h94zM137 273c-3 0 -5 1 -6 3s-1 5 1 7l72 98c1 2 4 3 6 3v0c2 0 4 -1 5 -3l73 -98
|
||||
c2 -2 2 -5 1 -7s-3 -3 -6 -3h-35v-88c0 -4 -3 -7 -7 -7h-63c-4 0 -7 3 -7 7v88h-34z" />
|
||||
<glyph glyph-name="uniF20D" unicode="" horiz-adv-x="150"
|
||||
d="M150 266v0v-233v0c0 -8 -7 -15 -15 -15v0h-121v0c-8 0 -14 7 -14 15v0v233v0c0 8 6 14 14 14h1h11v77v0c0 4 3 7 7 8v1h83c5 0 8 -4 8 -9v0v0v-77h11v0c8 0 15 -6 15 -14zM99 280v60h-48v-60h48zM62 294v11h26v-11h-26z" />
|
||||
<glyph glyph-name="uniF20E" unicode="" horiz-adv-x="410"
|
||||
d="M288 134v-54c0 -13 -10 -23 -23 -23h-242c-13 0 -23 10 -23 23v224c0 13 10 23 23 23h242c13 0 23 -10 23 -23v-53v0l122 57v-232z" />
|
||||
<glyph glyph-name="uniF20F" unicode="" horiz-adv-x="243"
|
||||
d="M243 328v-270h-1l1 -1c0 -6 -5 -11 -11 -11c-2 0 -4 1 -6 2l-85 49v0l-59 34h-74v0v0c-4 0 -8 4 -8 8v106c0 4 4 8 8 8v0v0h74l40 23v0l105 60v0c2 1 3 2 5 2c5 0 9 -5 10 -10h1z" />
|
||||
<glyph glyph-name="uniF210" unicode="" horiz-adv-x="436"
|
||||
d="M271 268c-4 5 -4 12 0 17v0l1 1v0v0l16 16v0v0v0v0c5 5 14 5 19 1v0l10 -10v0v0c43 -43 53 -106 31 -159l-41 41c5 29 -4 60 -26 82v1v0l-10 10v0zM366 361c77 -77 90 -194 40 -285l-37 37c31 70 18 155 -39 212v0h-1l-8 9v0v0l-1 1v0c-4 5 -4 12 0 17v0l17 18v0
|
||||
c5 5 13 5 18 1v0l10 -10v0h1zM243 316v0v-77l-60 60l44 25v0c2 1 3 2 5 2c5 0 9 -5 10 -10h1zM82 241l9 5l152 -151v-49h-1l1 -1c0 -6 -5 -10 -11 -10c-2 0 -4 0 -6 1l-85 49v0l-59 34h-74v0v0c-4 0 -8 4 -8 8v106c0 4 4 8 8 8v0v0h74zM401 45v0c5 -5 5 -13 0 -18l-1 -1
|
||||
l-17 -18v0c-5 -5 -13 -5 -18 0v0l-331 331c-5 5 -5 13 0 18v0l18 18v1c5 5 13 5 18 0v0v0z" />
|
||||
<glyph glyph-name="uniF211" unicode="" horiz-adv-x="436"
|
||||
d="M366 361c93 -93 93 -245 0 -338v0l-8 -9v0v0l-1 -1h-1c-5 -4 -12 -4 -17 0v0l-17 17v0c-5 5 -5 14 -1 19v0l1 1v0v0l9 9v-1c73 74 73 193 -1 267v1l-1 -1l-8 9v0v0l-1 1v0c-4 5 -4 13 0 18v0l17 17v0c5 5 13 5 18 1v0l10 -10v0h1zM317 293c56 -56 56 -147 1 -203v0
|
||||
l-10 -10v0c-5 -4 -12 -4 -17 0v0l-18 18v0c-5 5 -5 13 -1 18v0l1 1v0v0l9 9v0c36 37 35 96 -1 132v0v0l-10 10v0c-4 5 -4 12 0 17v0l1 1v0v0l16 16v1v0v0v0c5 5 14 5 19 1v0l10 -10v0v-1zM232 326c5 0 9 -4 10 -9h1v-270h-1l1 -1c0 -6 -5 -11 -11 -11c-2 0 -4 1 -6 2l-85 49
|
||||
v0l-59 34h-74v0v0c-4 0 -8 4 -8 8v105c0 4 4 8 8 8v0v0h74l40 23v0l105 61v0c2 1 3 1 5 1z" />
|
||||
<glyph glyph-name="uniF212" unicode="" horiz-adv-x="384"
|
||||
d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM53 167c8 -44 37 -81 75 -101c-24 28 -40 63 -45 101h-30zM83 217c5 38 21 73 45 101c-38 -20 -67 -57 -75 -101h30zM167 100v67h-33c5 -25 17 -48 33 -67zM167 217v67
|
||||
c-16 -19 -28 -42 -33 -67h33zM331 217c-8 44 -37 81 -75 101c24 -28 40 -63 45 -101h30zM217 100c16 19 28 42 33 67h-33v-67zM217 217h33c-5 25 -17 48 -33 67v-67zM256 66c38 20 67 57 75 101h-30c-5 -38 -21 -73 -45 -101z" />
|
||||
<glyph glyph-name="uniF213" unicode="" horiz-adv-x="285"
|
||||
d="M152 62l29 -29c-19 -15 -44 -25 -70 -25c-61 0 -111 50 -111 111c0 26 10 51 25 70l27 -28c-8 -12 -13 -25 -13 -40c0 -39 33 -72 72 -72c15 0 29 5 41 13zM202 340c0 24 13 36 37 36s37 -12 37 -36s-13 -37 -37 -37s-37 13 -37 37zM262 215c13 0 23 -10 23 -23v-117
|
||||
c0 -13 -10 -23 -23 -23s-23 10 -23 23v94h-29c8 -15 12 -32 12 -50c0 -26 -8 -49 -23 -68l-29 29c8 12 12 26 12 41c0 39 -32 71 -71 71c-15 0 -29 -5 -41 -13l-27 27c10 8 22 15 35 19l67 66l-28 17l-33 -33h-1v-1v0c-4 -4 -10 -6 -16 -6c-13 0 -23 10 -23 23
|
||||
c0 6 3 12 7 16v0l45 45l1 1v1v-1c4 4 10 6 16 6c3 0 6 -1 9 -2v1l103 -60v0c7 -4 11 -11 11 -19c0 -5 -1 -10 -4 -14v0l-1 -1c-1 -1 -3 -2 -4 -3l-46 -46h81z" />
|
||||
<glyph glyph-name="uniF214" unicode="" horiz-adv-x="415"
|
||||
d="M405 226c6 -1 10 -5 10 -11v-46c0 -6 -4 -10 -10 -11l-53 -5c-3 -13 -8 -25 -15 -36l34 -41c4 -4 3 -11 -1 -15l-32 -32c-2 -2 -5 -3 -8 -3c-2 0 -5 1 -7 3l-41 33c-11 -7 -23 -12 -36 -15l-5 -52c-1 -6 -5 -10 -11 -10h-45c-6 0 -10 4 -11 10l-5 52c-13 3 -26 8 -37 15
|
||||
l-40 -33c-2 -2 -5 -3 -7 -3c-3 0 -6 1 -8 3l-32 32c-4 4 -5 11 -1 15l34 41c-7 11 -12 23 -15 36l-53 5c-6 1 -10 5 -10 11v46c0 6 4 10 10 11l53 5c3 13 8 25 15 36l-34 41c-4 4 -3 11 1 15l32 32c2 2 5 3 8 3c2 0 5 -1 7 -3l40 -33c11 7 24 12 37 15l5 52c1 6 5 10 11 10
|
||||
h45c6 0 10 -4 11 -10l5 -52c13 -3 25 -8 36 -15l41 33c2 2 5 3 7 3c3 0 6 -1 8 -3l32 -32c4 -4 5 -11 1 -15l-34 -41c7 -11 12 -23 15 -36zM207 131c34 0 62 27 62 61s-28 61 -62 61s-61 -27 -61 -61s27 -61 61 -61z" />
|
||||
<glyph glyph-name="uniF215" unicode="" horiz-adv-x="401"
|
||||
d="M386 328c1 1 4 1 5 0v0v0l1 -1v0c6 -14 9 -29 9 -45c0 -61 -49 -111 -110 -111c-12 0 -23 3 -34 6l-115 -116c-1 -39 -32 -70 -71 -70s-71 32 -71 71s31 70 70 71l115 116c-3 11 -5 21 -5 33c0 61 50 111 111 111c16 0 30 -4 44 -10h1v0v0l1 -1c1 -1 1 -3 0 -4l-20 -20
|
||||
l-19 -19l-24 -25c-1 -13 3 -26 13 -36s23 -14 36 -13l24 24l20 19zM100 62c0 16 -13 30 -29 30s-29 -14 -29 -30s13 -29 29 -29s29 13 29 29z" />
|
||||
<glyph glyph-name="uniF216" unicode="" horiz-adv-x="384"
|
||||
d="M284 142c2 -2 2 -5 0 -7l-35 -35c-1 -1 -2 -2 -3 -2s-3 1 -4 2l-50 50l-50 -50c-1 -1 -3 -2 -4 -2s-2 1 -3 2l-35 35c-1 1 -2 2 -2 3s1 3 2 4l50 50l-50 50c-1 1 -2 3 -2 4s1 2 2 3l35 35c2 2 5 2 7 0l50 -50l50 50c2 2 5 2 7 0l35 -35c2 -2 2 -5 0 -7l-50 -50zM192 333
|
||||
c-78 0 -141 -63 -141 -141s63 -141 141 -141s141 63 141 141s-63 141 -141 141zM192 384v0c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192z" />
|
||||
<glyph glyph-name="uniF217" unicode="" horiz-adv-x="361"
|
||||
d="M358 96c4 -4 4 -10 0 -14l-67 -68c-2 -2 -4 -3 -7 -3s-5 1 -7 3l-96 96l-96 -96c-2 -2 -5 -3 -8 -3s-5 1 -7 3l-67 68c-2 2 -3 4 -3 7s1 5 3 7l96 96l-96 96c-2 2 -3 4 -3 7s1 5 3 7l67 68c4 4 11 4 15 0l96 -96l96 96c4 4 10 4 14 0l67 -68c4 -4 4 -10 0 -14l-96 -96z
|
||||
" />
|
||||
<glyph glyph-name="uniF218" unicode="" horiz-adv-x="270"
|
||||
d="M269 331h1l-85 -130h74v0v0c3 0 6 -2 6 -5v0v-21c0 -3 -3 -6 -6 -6v0v0h-95v-33h95v0v0c3 0 6 -3 6 -6v-20c0 -3 -3 -6 -6 -6v0v0h-95v-48v0c0 -3 -2 -6 -5 -6v0h-47v0v0c-3 0 -6 3 -6 6v1v47h-94v0v0c-3 0 -6 3 -6 6v20c0 3 3 6 6 6v0v0h94v33h-94v0v0c-3 0 -6 2 -6 5v0
|
||||
v1v0v0v20v0c0 3 3 6 6 6v0v0h72l-84 130v0v1c0 1 0 2 1 2h3h2h57c2 0 3 -2 4 -3v0l68 -110l68 110v0c1 1 2 3 4 3h57h2h3v-1c1 0 1 0 1 -1z" />
|
||||
<glyph glyph-name="uniF219" unicode="" horiz-adv-x="397"
|
||||
d="M233 395c91 0 164 -74 164 -164s-73 -164 -164 -164c-26 0 -51 6 -73 17l-82 -82v1c-8 -8 -20 -14 -33 -14c-25 0 -45 20 -45 45c0 13 6 25 14 33h-1l80 79c-15 25 -24 54 -24 85c0 90 73 164 164 164zM234 132c57 0 103 45 103 102s-46 102 -103 102s-102 -45 -102 -102
|
||||
s45 -102 102 -102zM295 258c4 0 7 -4 7 -8v-32c0 -4 -4 -8 -8 -8v0v0h-36v-36v0c0 -4 -4 -8 -8 -8v0h-32v0v0c-4 0 -8 4 -8 8v0v0v36h-35h-1c-4 0 -8 4 -8 8v32c0 4 4 8 8 8h36v35v1c0 4 4 8 8 8h1h31v0c4 0 8 -4 8 -8v-36h37v0z" />
|
||||
<glyph glyph-name="uniF21A" unicode="" horiz-adv-x="397"
|
||||
d="M233 395c91 0 164 -74 164 -164s-73 -164 -164 -164c-26 0 -51 6 -73 17l-82 -82v1c-8 -8 -20 -14 -33 -14c-25 0 -45 20 -45 45c0 13 6 25 14 33h-1l80 79c-15 25 -24 54 -24 85c0 90 73 164 164 164zM234 132c57 0 103 45 103 102s-46 102 -103 102s-102 -45 -102 -102
|
||||
s45 -102 102 -102zM294 258c4 0 9 -4 9 -8v0v-32c0 -4 -5 -8 -9 -8h-120c-4 0 -8 4 -8 8v32v0c0 4 4 8 8 8h120z" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
After Width: | Height: | Size: 147 KiB |
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,619 @@
|
|||
/* style.css */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
article, textarea, main.container {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
article > header, article > footer {
|
||||
margin-top: 0.1rem;
|
||||
margin-bottom: 0.1rem;
|
||||
padding-top: 0.2rem;
|
||||
padding-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
input:not([type="checkbox"], [type="radio"]), select {
|
||||
padding: 4px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: #ffebee;
|
||||
color: #c62828;
|
||||
border: 1px solid #ffcdd2;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: #e8f5e8;
|
||||
color: #2e7d32;
|
||||
border: 1px solid #c8e6c9;
|
||||
}
|
||||
|
||||
.compact-button {
|
||||
padding: 3px 8px !important;
|
||||
font-size: 0.85rem;
|
||||
text-decoration: none;
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid var(--secondary);
|
||||
border-radius: 4px;
|
||||
background: var(--secondary);
|
||||
color: var(--secondary-inverse);
|
||||
cursor: pointer;
|
||||
height: 28px !important;
|
||||
box-sizing: border-box;
|
||||
line-height: 1 !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.compact-button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.compact-table {
|
||||
width: 100%;
|
||||
font-size: 0.9rem;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.compact-table th,
|
||||
.compact-table td {
|
||||
padding: 6px 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.compact-table th {
|
||||
background: #f5f5f5;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.button-group button,
|
||||
.button-group a[role="button"] {
|
||||
flex: 1;
|
||||
padding: 0.5rem;
|
||||
height: 38px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.button-group .delete-btn {
|
||||
background: #ff4444 !important;
|
||||
border-color: #ff4444 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.green-btn {
|
||||
background: #449944 !important;
|
||||
border-color: #449944 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.green-btn:hover {
|
||||
background: #44bb44 !important;
|
||||
border-color: #44bb44 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.profile-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.profile-button {
|
||||
flex: 1;
|
||||
padding: 0.75rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
border: 1px solid;
|
||||
border-radius: 4px;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
height: 62px;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.profile-button.primary {
|
||||
background: var(--primary);
|
||||
border-color: var(--primary);
|
||||
color: var(--primary-inverse);
|
||||
}
|
||||
|
||||
.profile-button.secondary {
|
||||
background: var(--secondary);
|
||||
border-color: var(--secondary);
|
||||
color: var(--secondary-inverse);
|
||||
}
|
||||
|
||||
.adaptive-button {
|
||||
padding: 8px 12px !important;
|
||||
font-size: 0.85rem;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid var(--secondary);
|
||||
border-radius: 4px;
|
||||
background: var(--secondary);
|
||||
color: var(--secondary-inverse);
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
min-height: 44px;
|
||||
flex: 1;
|
||||
min-width: 120px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.adaptive-button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.primary.adaptive-button {
|
||||
background: var(--primary);
|
||||
border-color: var(--primary);
|
||||
color: var(--primary-inverse);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.adaptive-button {
|
||||
flex: 1 1 calc(50% - 10px);
|
||||
min-width: calc(50% - 10px);
|
||||
font-size: 0.8rem;
|
||||
padding: 10px 8px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.adaptive-button {
|
||||
flex: 1 1 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Стили для Markdown редактора */
|
||||
#content {
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
min-height: 400px;
|
||||
color: #111;
|
||||
background-color: #fff;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
#content:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
|
||||
outline: none;
|
||||
color: #111;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* Стили для полноэкранного режима */
|
||||
|
||||
|
||||
.editor-controls {
|
||||
position: sticky !important;
|
||||
top: 10px !important;
|
||||
right: 10px !important;
|
||||
z-index: 100 !important;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.editor-controls button {
|
||||
width: 40px !important;
|
||||
height: 40px !important;
|
||||
border-radius: 50% !important;
|
||||
border: 1px solid #ddd !important;
|
||||
background: white !important;
|
||||
cursor: pointer !important;
|
||||
font-size: 16px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.2) !important;
|
||||
transition: all 0.3s ease !important;
|
||||
color: #333333 !important;
|
||||
}
|
||||
|
||||
.editor-controls button:hover {
|
||||
transform: scale(1.1) !important;
|
||||
background-color: #f8f9fa !important;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.3) !important;
|
||||
}
|
||||
|
||||
/* Стили для полноэкранных кнопок */
|
||||
#fullscreen-controls {
|
||||
position: fixed !important;
|
||||
top: 15px !important;
|
||||
right: 15px !important;
|
||||
z-index: 9999 !important;
|
||||
display: flex !important;
|
||||
gap: 5px !important;
|
||||
}
|
||||
|
||||
#fullscreen-controls button {
|
||||
width: 45px !important;
|
||||
height: 45px !important;
|
||||
border-radius: 50% !important;
|
||||
border: 1px solid #ddd !important;
|
||||
background: white !important;
|
||||
cursor: pointer !important;
|
||||
font-size: 18px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.3) !important;
|
||||
transition: all 0.3s ease !important;
|
||||
color: #333333 !important;
|
||||
}
|
||||
|
||||
#fullscreen-controls button:hover {
|
||||
transform: scale(1.1) !important;
|
||||
background-color: #f8f9fa !important;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.4) !important;
|
||||
}
|
||||
|
||||
/* Стили для полноэкранного режима - упрощенные для мобильных */
|
||||
#content.mobile-fullscreen {
|
||||
position: fixed !important;
|
||||
top: 50px !important;
|
||||
left: 0 !important;
|
||||
width: 100vw !important;
|
||||
height: calc(100vh - 100px) !important; /* Оставляем место для клавиатуры */
|
||||
z-index: 9998 !important;
|
||||
background-color: white !important;
|
||||
border: 2px solid #007bff !important;
|
||||
border-radius: 0 !important;
|
||||
font-size: 18px !important;
|
||||
padding: 15px !important;
|
||||
margin: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
resize: none !important;
|
||||
box-shadow: none !important;
|
||||
overflow-y: auto !important;
|
||||
-webkit-overflow-scrolling: touch !important;
|
||||
}
|
||||
|
||||
/* Стили для ПК в полноэкранном режиме */
|
||||
#content.desktop-fullscreen {
|
||||
position: fixed !important;
|
||||
top: 5vh !important;
|
||||
left: 5vw !important;
|
||||
width: 90vw !important;
|
||||
height: 90vh !important;
|
||||
z-index: 9998 !important;
|
||||
background-color: white !important;
|
||||
border: 2px solid #007bff !important;
|
||||
border-radius: 8px !important;
|
||||
font-size: 16px !important;
|
||||
padding: 20px !important;
|
||||
margin: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
resize: none !important;
|
||||
box-shadow: 0 0 20px rgba(0,0,0,0.3) !important;
|
||||
}
|
||||
|
||||
/* Улучшенные стили для кнопок в полноэкранном режиме */
|
||||
#fullscreen-controls {
|
||||
position: fixed !important;
|
||||
z-index: 9999 !important;
|
||||
display: flex !important;
|
||||
gap: 5px !important;
|
||||
}
|
||||
|
||||
/* Для мобильных устройств */
|
||||
@media (max-width: 768px) {
|
||||
#fullscreen-controls {
|
||||
top: 10px !important;
|
||||
right: 10px !important;
|
||||
}
|
||||
|
||||
#fullscreen-controls button {
|
||||
width: 60px !important;
|
||||
height: 60px !important;
|
||||
font-size: 24px !important;
|
||||
border: 2px solid #ddd !important;
|
||||
}
|
||||
|
||||
.editor-controls button {
|
||||
width: 50px !important;
|
||||
height: 50px !important;
|
||||
font-size: 20px !important;
|
||||
}
|
||||
|
||||
/* Улучшенный полноэкранный режим для мобильных с учетом клавиатуры */
|
||||
#content.mobile-fullscreen {
|
||||
padding: 15px !important;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
/* Дополнительные стили для очень маленьких экранов */
|
||||
@media (max-width: 480px) {
|
||||
#fullscreen-controls button {
|
||||
width: 55px !important;
|
||||
height: 55px !important;
|
||||
font-size: 22px !important;
|
||||
}
|
||||
|
||||
#content.mobile-fullscreen {
|
||||
padding: 10px !important;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Для десктопов */
|
||||
@media (min-width: 769px) {
|
||||
#fullscreen-controls {
|
||||
top: 15px !important;
|
||||
right: 15px !important;
|
||||
}
|
||||
|
||||
#fullscreen-controls button {
|
||||
width: 50px !important;
|
||||
height: 50px !important;
|
||||
font-size: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Кастомный скроллбар */
|
||||
#content::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
#content::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#content::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#content::-webkit-scrollbar-thumb:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
|
||||
/* Для Firefox */
|
||||
#content {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #c1c1c1 #f1f1f1;
|
||||
}
|
||||
|
||||
|
||||
.book-content {
|
||||
line-height: 1.7;
|
||||
font-family: Georgia, serif;
|
||||
}
|
||||
|
||||
.book-content h1 {
|
||||
font-size: 2em;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 2px solid #eee;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.book-content h2 {
|
||||
font-size: 1.6em;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.book-content h3 {
|
||||
font-size: 1.3em;
|
||||
margin-top: 1.2rem;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
|
||||
.book-content p {
|
||||
margin-bottom: 1rem;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.book-content blockquote {
|
||||
border-left: 4px solid #007bff;
|
||||
padding-left: 1.5rem;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
color: #555;
|
||||
font-style: italic;
|
||||
background: #f8f9fa;
|
||||
padding: 1rem;
|
||||
border-radius: 0 5px 5px 0;
|
||||
}
|
||||
|
||||
.book-content code {
|
||||
background: #f5f5f5;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.book-content pre {
|
||||
background: #2d2d2d;
|
||||
color: #f8f8f2;
|
||||
padding: 1rem;
|
||||
border-radius: 5px;
|
||||
overflow-x: auto;
|
||||
border-left: 4px solid #007bff;
|
||||
}
|
||||
|
||||
.book-content pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.book-content ul, .book-content ol {
|
||||
margin-bottom: 1rem;
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.book-content li {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.book-content table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.book-content th, .book-content td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 10px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.book-content th {
|
||||
background: #f5f5f5;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.book-content tr:nth-child(even) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
/* Стили для диалогов */
|
||||
.dialogue {
|
||||
margin-left: 2rem;
|
||||
font-style: italic;
|
||||
color: #2c5aa0;
|
||||
}
|
||||
|
||||
/* Адаптивность для мобильных */
|
||||
@media (max-width: 768px) {
|
||||
.book-content {
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.book-content h1 {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
.book-content h2 {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.book-content h3 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.book-content pre {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Стили для кнопок действий */
|
||||
.action-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 0.9rem;
|
||||
text-decoration: none;
|
||||
border: 1px solid;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
height: 44px;
|
||||
min-width: 140px;
|
||||
white-space: nowrap;
|
||||
transition: all 0.3s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.action-button.primary {
|
||||
background: #007bff;
|
||||
border-color: #007bff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.action-button.primary:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.action-button.delete {
|
||||
margin-top: 1rem;
|
||||
background: #ff4444;
|
||||
border-color: #ff4444;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-button.delete:hover {
|
||||
background: #dd3333;
|
||||
border-color: #dd3333;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Адаптивность для мобильных */
|
||||
@media (max-width: 768px) {
|
||||
.action-button {
|
||||
padding: 0.6rem 1rem;
|
||||
font-size: 0.85rem;
|
||||
min-width: 120px;
|
||||
height: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.action-button {
|
||||
padding: 0.5rem 0.8rem;
|
||||
font-size: 0.8rem;
|
||||
min-width: 110px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
/* На очень маленьких экранах делаем кнопки блочными */
|
||||
.action-buttons-container {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action-buttons-container .action-button {
|
||||
width: 100%;
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// assets/js/autosave.js
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const contentTextarea = document.getElementById('content');
|
||||
const titleInput = document.getElementById('title');
|
||||
const statusSelect = document.getElementById('status');
|
||||
|
||||
// Проверяем, что это редактирование существующей главы
|
||||
// Если в URL есть параметр 'id', значит это редактирование
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const isEditMode = urlParams.has('id');
|
||||
|
||||
if (!contentTextarea || !isEditMode) {
|
||||
console.log('Автосохранение отключено: создание новой главы');
|
||||
return;
|
||||
}
|
||||
|
||||
let saveTimeout;
|
||||
let isSaving = false;
|
||||
let lastSavedContent = contentTextarea.value;
|
||||
|
||||
function showSaveMessage(message) {
|
||||
let messageEl = document.getElementById('autosave-message');
|
||||
if (!messageEl) {
|
||||
messageEl = document.createElement('div');
|
||||
messageEl.id = 'autosave-message';
|
||||
messageEl.style.cssText = 'position: fixed; top: 10px; right: 10px; padding: 8px 12px; background: #333; color: white; border-radius: 3px; z-index: 1000; font-size: 0.8rem;';
|
||||
document.body.appendChild(messageEl);
|
||||
}
|
||||
|
||||
messageEl.textContent = message;
|
||||
messageEl.style.display = 'block';
|
||||
|
||||
setTimeout(() => {
|
||||
messageEl.style.display = 'none';
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function autoSave() {
|
||||
if (isSaving) return;
|
||||
|
||||
const currentContent = contentTextarea.value;
|
||||
const currentTitle = titleInput ? titleInput.value : '';
|
||||
const currentStatus = statusSelect ? statusSelect.value : 'draft';
|
||||
|
||||
if (currentContent === lastSavedContent) return;
|
||||
|
||||
isSaving = true;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('content', currentContent);
|
||||
formData.append('title', currentTitle);
|
||||
formData.append('status', currentStatus);
|
||||
formData.append('autosave', 'true');
|
||||
formData.append('csrf_token', document.querySelector('input[name="csrf_token"]').value);
|
||||
|
||||
fetch(window.location.href, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
lastSavedContent = currentContent;
|
||||
showSaveMessage('Сохранено: ' + new Date().toLocaleTimeString());
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка автосохранения:', error);
|
||||
})
|
||||
.finally(() => {
|
||||
isSaving = false;
|
||||
});
|
||||
}
|
||||
|
||||
contentTextarea.addEventListener('input', function() {
|
||||
clearTimeout(saveTimeout);
|
||||
saveTimeout = setTimeout(autoSave, 2000);
|
||||
});
|
||||
|
||||
if (titleInput) {
|
||||
titleInput.addEventListener('input', function() {
|
||||
clearTimeout(saveTimeout);
|
||||
saveTimeout = setTimeout(autoSave, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
if (statusSelect) {
|
||||
statusSelect.addEventListener('change', autoSave);
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', function(e) {
|
||||
if (contentTextarea.value !== lastSavedContent) {
|
||||
e.preventDefault();
|
||||
e.returnValue = 'У вас есть несохраненные изменения. Вы уверены, что хотите уйти?';
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Автосохранение включено для редактирования главы');
|
||||
});
|
||||
|
|
@ -0,0 +1,563 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const contentTextarea = document.getElementById('content');
|
||||
const previewForm = document.getElementById('preview-form');
|
||||
|
||||
if (!contentTextarea) return;
|
||||
|
||||
let isFullscreen = false;
|
||||
let originalStyles = {};
|
||||
let isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||
|
||||
initEditor();
|
||||
|
||||
function initEditor() {
|
||||
autoResize();
|
||||
contentTextarea.addEventListener('input', autoResize);
|
||||
contentTextarea.addEventListener('input', processDialogues);
|
||||
contentTextarea.addEventListener('keydown', handleTab);
|
||||
contentTextarea.addEventListener('input', updatePreviewContent);
|
||||
|
||||
updatePreviewContent();
|
||||
addControlButtons();
|
||||
|
||||
// На мобильных устройствах добавляем обработчик изменения ориентации
|
||||
if (isMobile) {
|
||||
window.addEventListener('orientationchange', function() {
|
||||
if (isFullscreen) {
|
||||
setTimeout(adjustForMobileKeyboard, 300);
|
||||
}
|
||||
});
|
||||
|
||||
// Обработчик для виртуальной клавиатуры
|
||||
window.addEventListener('resize', function() {
|
||||
if (isFullscreen && isMobile) {
|
||||
adjustForMobileKeyboard();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function autoResize() {
|
||||
if (isFullscreen) return;
|
||||
|
||||
contentTextarea.style.height = 'auto';
|
||||
contentTextarea.style.height = contentTextarea.scrollHeight + 'px';
|
||||
}
|
||||
|
||||
function processDialogues() {
|
||||
const lines = contentTextarea.value.split('\n');
|
||||
let changed = false;
|
||||
|
||||
const processedLines = lines.map(line => {
|
||||
if (line.trim().startsWith('- ') && line.trim().length > 2) {
|
||||
const trimmed = line.trim();
|
||||
const restOfLine = trimmed.substring(2);
|
||||
if (/^[a-zA-Zа-яА-Я]/.test(restOfLine)) {
|
||||
changed = true;
|
||||
return line.replace(trimmed, `— ${restOfLine}`);
|
||||
}
|
||||
}
|
||||
return line;
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
const cursorPos = contentTextarea.selectionStart;
|
||||
contentTextarea.value = processedLines.join('\n');
|
||||
contentTextarea.setSelectionRange(cursorPos, cursorPos);
|
||||
if (!isFullscreen) autoResize();
|
||||
}
|
||||
}
|
||||
|
||||
function handleTab(e) {
|
||||
if (e.key === 'Tab') {
|
||||
e.preventDefault();
|
||||
const start = contentTextarea.selectionStart;
|
||||
const end = contentTextarea.selectionEnd;
|
||||
|
||||
contentTextarea.value = contentTextarea.value.substring(0, start) + ' ' + contentTextarea.value.substring(end);
|
||||
contentTextarea.selectionStart = contentTextarea.selectionEnd = start + 4;
|
||||
if (!isFullscreen) autoResize();
|
||||
}
|
||||
}
|
||||
|
||||
function updatePreviewContent() {
|
||||
if (previewForm) {
|
||||
document.getElementById('preview-content').value = contentTextarea.value;
|
||||
}
|
||||
}
|
||||
|
||||
function adjustForMobileKeyboard() {
|
||||
if (!isMobile || !isFullscreen) return;
|
||||
|
||||
// На мобильных устройствах уменьшаем высоту textarea, чтобы клавиатура не перекрывала контент
|
||||
const viewportHeight = window.innerHeight;
|
||||
const keyboardHeight = viewportHeight * 0.4; // Предполагаемая высота клавиатуры (40% экрана)
|
||||
const availableHeight = viewportHeight - keyboardHeight - 80; // 80px для кнопок и отступов
|
||||
|
||||
contentTextarea.style.height = availableHeight + 'px';
|
||||
contentTextarea.style.paddingBottom = '20px';
|
||||
|
||||
// Прокручиваем к курсору
|
||||
setTimeout(() => {
|
||||
const cursorPos = contentTextarea.selectionStart;
|
||||
if (cursorPos > 0) {
|
||||
scrollToCursor();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function scrollToCursor() {
|
||||
const textarea = contentTextarea;
|
||||
const cursorPos = textarea.selectionStart;
|
||||
|
||||
// Создаем временный элемент для измерения позиции курсора
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.style.cssText = `
|
||||
position: absolute;
|
||||
top: -1000px;
|
||||
left: -1000px;
|
||||
width: ${textarea.clientWidth}px;
|
||||
padding: ${textarea.style.padding};
|
||||
font: ${getComputedStyle(textarea).font};
|
||||
line-height: ${textarea.style.lineHeight};
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
visibility: hidden;
|
||||
`;
|
||||
|
||||
const textBeforeCursor = textarea.value.substring(0, cursorPos);
|
||||
tempDiv.textContent = textBeforeCursor;
|
||||
|
||||
document.body.appendChild(tempDiv);
|
||||
const textHeight = tempDiv.offsetHeight;
|
||||
document.body.removeChild(tempDiv);
|
||||
|
||||
// Прокручиваем так, чтобы курсор был виден
|
||||
const lineHeight = parseInt(getComputedStyle(textarea).lineHeight) || 24;
|
||||
const visibleHeight = textarea.clientHeight;
|
||||
const cursorLine = Math.floor(textHeight / lineHeight);
|
||||
const visibleLines = Math.floor(visibleHeight / lineHeight);
|
||||
|
||||
const targetScroll = Math.max(0, (cursorLine - Math.floor(visibleLines / 3)) * lineHeight);
|
||||
|
||||
textarea.scrollTop = targetScroll;
|
||||
}
|
||||
|
||||
function addControlButtons() {
|
||||
const container = contentTextarea.parentElement;
|
||||
|
||||
const controlsContainer = document.createElement('div');
|
||||
controlsContainer.className = 'editor-controls';
|
||||
|
||||
const fullscreenBtn = createButton('⛶', 'Полноэкранный режим', toggleFullscreen);
|
||||
const helpBtn = createButton('❓', 'Справка по Markdown', showHelp);
|
||||
|
||||
controlsContainer.appendChild(fullscreenBtn);
|
||||
controlsContainer.appendChild(helpBtn);
|
||||
|
||||
container.insertBefore(controlsContainer, contentTextarea);
|
||||
|
||||
function toggleFullscreen() {
|
||||
if (!isFullscreen) {
|
||||
enterFullscreen();
|
||||
} else {
|
||||
exitFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
function enterFullscreen() {
|
||||
originalStyles = {
|
||||
position: contentTextarea.style.position,
|
||||
top: contentTextarea.style.top,
|
||||
left: contentTextarea.style.left,
|
||||
width: contentTextarea.style.width,
|
||||
height: contentTextarea.style.height,
|
||||
zIndex: contentTextarea.style.zIndex,
|
||||
backgroundColor: contentTextarea.style.backgroundColor,
|
||||
border: contentTextarea.style.border,
|
||||
borderRadius: contentTextarea.style.borderRadius,
|
||||
fontSize: contentTextarea.style.fontSize,
|
||||
padding: contentTextarea.style.padding,
|
||||
margin: contentTextarea.style.margin
|
||||
};
|
||||
|
||||
if (isMobile) {
|
||||
// Для мобильных - адаптивный режим с учетом клавиатуры
|
||||
const viewportHeight = window.innerHeight;
|
||||
const availableHeight = viewportHeight - 100; // Оставляем место для кнопок
|
||||
|
||||
Object.assign(contentTextarea.style, {
|
||||
position: 'fixed',
|
||||
top: '50px',
|
||||
left: '0',
|
||||
width: '100vw',
|
||||
height: availableHeight + 'px',
|
||||
zIndex: '9998',
|
||||
backgroundColor: 'white',
|
||||
border: '2px solid #007bff',
|
||||
borderRadius: '0',
|
||||
fontSize: '18px',
|
||||
padding: '15px',
|
||||
margin: '0',
|
||||
boxSizing: 'border-box',
|
||||
resize: 'none'
|
||||
});
|
||||
|
||||
// На мобильных устройствах фокусируем textarea сразу
|
||||
setTimeout(() => {
|
||||
contentTextarea.focus();
|
||||
}, 300);
|
||||
} else {
|
||||
// Для ПК - классический полноэкранный режим
|
||||
Object.assign(contentTextarea.style, {
|
||||
position: 'fixed',
|
||||
top: '5vh',
|
||||
left: '5vw',
|
||||
width: '90vw',
|
||||
height: '90vh',
|
||||
zIndex: '9998',
|
||||
backgroundColor: 'white',
|
||||
border: '2px solid #007bff',
|
||||
borderRadius: '8px',
|
||||
fontSize: '16px',
|
||||
padding: '20px',
|
||||
margin: '0',
|
||||
boxSizing: 'border-box',
|
||||
resize: 'none'
|
||||
});
|
||||
}
|
||||
|
||||
controlsContainer.style.display = 'none';
|
||||
createFullscreenControls();
|
||||
|
||||
isFullscreen = true;
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
function exitFullscreen() {
|
||||
Object.assign(contentTextarea.style, originalStyles);
|
||||
|
||||
controlsContainer.style.display = 'flex';
|
||||
removeFullscreenControls();
|
||||
|
||||
isFullscreen = false;
|
||||
document.body.style.overflow = '';
|
||||
|
||||
autoResize();
|
||||
}
|
||||
|
||||
function createFullscreenControls() {
|
||||
const fullscreenControls = document.createElement('div');
|
||||
fullscreenControls.id = 'fullscreen-controls';
|
||||
|
||||
const exitBtn = createButton('❌', 'Выйти из полноэкранного режима', exitFullscreen);
|
||||
const helpBtnFullscreen = createButton('❓', 'Справка по Markdown', showHelp);
|
||||
|
||||
// Для мобильных увеличиваем кнопки и добавляем отступы
|
||||
const buttonSize = isMobile ? '60px' : '50px';
|
||||
const fontSize = isMobile ? '24px' : '20px';
|
||||
const topPosition = isMobile ? '10px' : '15px';
|
||||
|
||||
[exitBtn, helpBtnFullscreen].forEach(btn => {
|
||||
btn.style.cssText = `
|
||||
width: ${buttonSize};
|
||||
height: ${buttonSize};
|
||||
border-radius: 50%;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
font-size: ${fontSize};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
|
||||
transition: all 0.3s ease;
|
||||
color: #333333;
|
||||
touch-action: manipulation;
|
||||
`;
|
||||
});
|
||||
|
||||
fullscreenControls.appendChild(helpBtnFullscreen);
|
||||
fullscreenControls.appendChild(exitBtn);
|
||||
|
||||
fullscreenControls.style.cssText = `
|
||||
position: fixed;
|
||||
top: ${topPosition};
|
||||
right: 10px;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
`;
|
||||
|
||||
document.body.appendChild(fullscreenControls);
|
||||
|
||||
// Предотвращаем всплытие событий от кнопок к textarea
|
||||
fullscreenControls.addEventListener('touchstart', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
fullscreenControls.addEventListener('touchend', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
function removeFullscreenControls() {
|
||||
const fullscreenControls = document.getElementById('fullscreen-controls');
|
||||
if (fullscreenControls) {
|
||||
fullscreenControls.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Выход по ESC
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape' && isFullscreen) {
|
||||
exitFullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
// На мобильных устройствах добавляем обработчик для выхода по тапу вне textarea
|
||||
if (isMobile) {
|
||||
document.addEventListener('touchstart', function(e) {
|
||||
if (isFullscreen && !contentTextarea.contains(e.target) &&
|
||||
!document.getElementById('fullscreen-controls')?.contains(e.target)) {
|
||||
exitFullscreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Обработчик фокуса для мобильных устройств
|
||||
if (isMobile) {
|
||||
contentTextarea.addEventListener('focus', function() {
|
||||
if (isFullscreen) {
|
||||
setTimeout(adjustForMobileKeyboard, 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function createButton(icon, title, onClick) {
|
||||
const button = document.createElement('button');
|
||||
button.innerHTML = icon;
|
||||
button.title = title;
|
||||
button.type = 'button';
|
||||
|
||||
const buttonSize = isMobile ? '50px' : '40px';
|
||||
const fontSize = isMobile ? '20px' : '16px';
|
||||
|
||||
button.style.cssText = `
|
||||
width: ${buttonSize};
|
||||
height: ${buttonSize};
|
||||
border-radius: 50%;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
font-size: ${fontSize};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
||||
transition: all 0.3s ease;
|
||||
color: #333333;
|
||||
touch-action: manipulation;
|
||||
`;
|
||||
|
||||
button.addEventListener('mouseenter', function() {
|
||||
this.style.transform = 'scale(1.1)';
|
||||
this.style.backgroundColor = '#f8f9fa';
|
||||
this.style.boxShadow = '0 4px 8px rgba(0,0,0,0.3)';
|
||||
});
|
||||
|
||||
button.addEventListener('mouseleave', function() {
|
||||
this.style.transform = 'scale(1)';
|
||||
this.style.backgroundColor = 'white';
|
||||
this.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
|
||||
});
|
||||
|
||||
button.addEventListener('click', onClick);
|
||||
|
||||
// Для мобильных устройств
|
||||
button.addEventListener('touchstart', function(e) {
|
||||
e.stopPropagation();
|
||||
this.style.transform = 'scale(1.1)';
|
||||
this.style.backgroundColor = '#f8f9fa';
|
||||
this.style.boxShadow = '0 4px 8px rgba(0,0,0,0.3)';
|
||||
});
|
||||
|
||||
button.addEventListener('touchend', function(e) {
|
||||
e.stopPropagation();
|
||||
this.style.transform = 'scale(1)';
|
||||
this.style.backgroundColor = 'white';
|
||||
this.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
|
||||
onClick();
|
||||
});
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
function showHelp() {
|
||||
const helpContent = `
|
||||
<div style="font-family: system-ui, sans-serif; line-height: 1.6; color: #333;">
|
||||
<h1 style="color: #007bff; margin-top: 0; border-bottom: 2px solid #007bff; padding-bottom: 10px;">Справка по Markdown</h1>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="color: #555;">Основное форматирование</h2>
|
||||
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; border-left: 4px solid #007bff;">
|
||||
<p><strong>Жирный текст:</strong> **текст** или __текст__</p>
|
||||
<p><em>Наклонный текст:</em> *текст* или _текст_</p>
|
||||
<p><u>Подчеркнутый текст:</u> <u>текст</u></p>
|
||||
<p><del>Зачеркнутый текст:</del> ~~текст~~</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="color: #555;">Заголовки</h2>
|
||||
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; border-left: 4px solid #28a745;">
|
||||
<h1 style="margin: 10px 0; font-size: 1.5em;">Заголовок 1 (# Заголовок)</h1>
|
||||
<h2 style="margin: 10px 0; font-size: 1.3em;">Заголовок 2 (## Заголовок)</h2>
|
||||
<h3 style="margin: 10px 0; font-size: 1.1em;">Заголовок 3 (### Заголовок)</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="color: #555;">Цитаты</h2>
|
||||
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; border-left: 4px solid #ffc107;">
|
||||
<blockquote style="margin: 0; padding-left: 15px; border-left: 3px solid #ddd; color: #666;">
|
||||
> Это цитата
|
||||
</blockquote>
|
||||
<blockquote style="margin: 10px 0 0 20px; padding-left: 15px; border-left: 3px solid #ddd; color: #666;">
|
||||
> > Вложенная цитата
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="color: #555;">Диалоги</h2>
|
||||
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; border-left: 4px solid #dc3545;">
|
||||
<p><strong>Автоматическое преобразование:</strong></p>
|
||||
<p><code>- Привет!</code> → <em>— Привет!</em></p>
|
||||
<p style="font-size: 0.9em; color: #666; margin-top: 5px;">
|
||||
Дефис в начале строки автоматически заменяется на тире с пробелом
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="color: #555;">Списки</h2>
|
||||
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; border-left: 4px solid #6f42c1;">
|
||||
<p><strong>Маркированный список:</strong></p>
|
||||
<ul style="margin: 10px 0; padding-left: 20px;">
|
||||
<li>- Элемент списка</li>
|
||||
<li>- Другой элемент</li>
|
||||
</ul>
|
||||
<p><strong>Нумерованный список:</strong></p>
|
||||
<ol style="margin: 10px 0; padding-left: 20px;">
|
||||
<li>1. Первый элемент</li>
|
||||
<li>2. Второй элемент</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="color: #555;">Код</h2>
|
||||
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; border-left: 4px solid #fd7e14;">
|
||||
<p><strong>Код в строке:</strong></p>
|
||||
<p><code>\`код в строке\`</code></p>
|
||||
<p><strong>Блок кода:</strong></p>
|
||||
<pre style="background: #e9ecef; padding: 10px; border-radius: 3px; overflow-x: auto; margin: 10px 0;">
|
||||
\`\`\`
|
||||
блок кода
|
||||
многострочный
|
||||
\`\`\`</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #e7f3ff; padding: 15px; border-radius: 5px; border-left: 4px solid #007bff; margin-top: 20px;">
|
||||
<p style="margin: 0; font-size: 0.9em;"><strong>💡 Подсказка:</strong> Используйте кнопку "👁️ Предпросмотр" чтобы увидеть как будет выглядеть готовый текст!</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const modal = document.createElement('div');
|
||||
modal.style.cssText = `
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
border: 2px solid #007bff;
|
||||
border-radius: 10px;
|
||||
padding: 25px;
|
||||
z-index: 10000;
|
||||
width: 90%;
|
||||
max-width: 700px;
|
||||
max-height: 85vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
`;
|
||||
|
||||
const closeBtn = document.createElement('button');
|
||||
closeBtn.innerHTML = '✕';
|
||||
closeBtn.title = 'Закрыть справку';
|
||||
closeBtn.style.cssText = `
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
background: #ff4444;
|
||||
color: white;
|
||||
border: none;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: background 0.3s ease;
|
||||
`;
|
||||
|
||||
closeBtn.addEventListener('mouseenter', function() {
|
||||
this.style.background = '#cc0000';
|
||||
});
|
||||
|
||||
closeBtn.addEventListener('mouseleave', function() {
|
||||
this.style.background = '#ff4444';
|
||||
});
|
||||
|
||||
closeBtn.addEventListener('click', function() {
|
||||
modal.remove();
|
||||
overlay.remove();
|
||||
});
|
||||
|
||||
modal.innerHTML = helpContent;
|
||||
modal.appendChild(closeBtn);
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 9999;
|
||||
`;
|
||||
|
||||
overlay.addEventListener('click', function() {
|
||||
modal.remove();
|
||||
overlay.remove();
|
||||
});
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
document.body.appendChild(modal);
|
||||
|
||||
const closeHandler = function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
modal.remove();
|
||||
overlay.remove();
|
||||
document.removeEventListener('keydown', closeHandler);
|
||||
}
|
||||
};
|
||||
document.addEventListener('keydown', closeHandler);
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$_SESSION['error'] = "Неверный метод запроса";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$_SESSION['error'] = "Ошибка безопасности";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$book_id = $_POST['book_id'] ?? null;
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
if (!$book_id) {
|
||||
$_SESSION['error'] = "Не указана книга для удаления";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$bookModel = new Book($pdo);
|
||||
|
||||
// Проверяем права доступа
|
||||
if (!$bookModel->userOwnsBook($book_id, $user_id)) {
|
||||
$_SESSION['error'] = "У вас нет доступа к этой книге";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
// Получаем информацию о книге перед удалением (для сообщения)
|
||||
$book = $bookModel->findById($book_id);
|
||||
|
||||
// Удаляем книгу
|
||||
if ($bookModel->delete($book_id, $user_id)) {
|
||||
$_SESSION['success'] = "Книга «" . e($book['title']) . "» успешно удалена";
|
||||
} else {
|
||||
$_SESSION['error'] = "Ошибка при удалении книги";
|
||||
}
|
||||
|
||||
redirect('books.php');
|
||||
?>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$_SESSION['error'] = "Неверный метод запроса";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$_SESSION['error'] = "Ошибка безопасности";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$bookModel = new Book($pdo);
|
||||
|
||||
// Получаем все книги пользователя
|
||||
$books = $bookModel->findByUser($user_id);
|
||||
|
||||
if (empty($books)) {
|
||||
$_SESSION['error'] = "У вас нет книг для удаления";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$deleted_count = 0;
|
||||
$error_count = 0;
|
||||
|
||||
// Удаляем каждую книгу
|
||||
foreach ($books as $book) {
|
||||
if ($bookModel->delete($book['id'], $user_id)) {
|
||||
$deleted_count++;
|
||||
} else {
|
||||
$error_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($error_count === 0) {
|
||||
$_SESSION['success'] = "Все книги успешно удалены ($deleted_count книг)";
|
||||
} else {
|
||||
$_SESSION['error'] = "Удалено $deleted_count книг, не удалось удалить $error_count книг";
|
||||
}
|
||||
|
||||
redirect('books.php');
|
||||
?>
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$bookModel = new Book($pdo);
|
||||
|
||||
// Проверяем, редактируем ли существующую книгу
|
||||
$book_id = $_GET['id'] ?? null;
|
||||
$book = null;
|
||||
$is_edit = false;
|
||||
|
||||
if ($book_id) {
|
||||
$book = $bookModel->findById($book_id);
|
||||
if (!$book || $book['user_id'] != $user_id) {
|
||||
$_SESSION['error'] = "Книга не найдена или у вас нет доступа";
|
||||
redirect('books.php');
|
||||
}
|
||||
$is_edit = true;
|
||||
}
|
||||
|
||||
// Обработка формы
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$_SESSION['error'] = "Ошибка безопасности";
|
||||
redirect($is_edit ? "book_edit.php?id=$book_id" : 'book_edit.php');
|
||||
}
|
||||
|
||||
$title = trim($_POST['title'] ?? '');
|
||||
$description = trim($_POST['description'] ?? '');
|
||||
$genre = trim($_POST['genre'] ?? '');
|
||||
|
||||
if (empty($title)) {
|
||||
$_SESSION['error'] = "Название книги обязательно";
|
||||
} else {
|
||||
$data = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'genre' => $genre,
|
||||
'user_id' => $user_id
|
||||
];
|
||||
|
||||
if ($is_edit) {
|
||||
$success = $bookModel->update($book_id, $data);
|
||||
$message = $success ? "Книга успешно обновлена" : "Ошибка при обновлении книги";
|
||||
} else {
|
||||
$success = $bookModel->create($data);
|
||||
$message = $success ? "Книга успешно создана" : "Ошибка при создании книги";
|
||||
|
||||
if ($success) {
|
||||
$new_book_id = $pdo->lastInsertId();
|
||||
redirect("book_edit.php?id=$new_book_id");
|
||||
}
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
$_SESSION['success'] = $message;
|
||||
redirect('books.php');
|
||||
} else {
|
||||
$_SESSION['error'] = $message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$page_title = $is_edit ? "Редактирование книги" : "Создание новой книги";
|
||||
include 'views/header.php';
|
||||
?>
|
||||
|
||||
<h1><?= $is_edit ? "Редактирование книги" : "Создание новой книги" ?></h1>
|
||||
|
||||
<?php if (isset($_SESSION['error'])): ?>
|
||||
<div class="alert alert-error">
|
||||
<?= e($_SESSION['error']) ?>
|
||||
<?php unset($_SESSION['error']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
|
||||
<div style="max-width: 100%; margin-bottom: 0.5rem;">
|
||||
<label for="title" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Название книги *
|
||||
</label>
|
||||
<input type="text" id="title" name="title"
|
||||
value="<?= e($book['title'] ?? $_POST['title'] ?? '') ?>"
|
||||
placeholder="Введите название книги"
|
||||
style="width: 100%; margin-bottom: 1.5rem;"
|
||||
required>
|
||||
|
||||
<label for="genre" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Жанр
|
||||
</label>
|
||||
<input type="text" id="genre" name="genre"
|
||||
value="<?= e($book['genre'] ?? $_POST['genre'] ?? '') ?>"
|
||||
placeholder="Например: Фантастика, Роман, Детектив..."
|
||||
style="width: 100%; margin-bottom: 1.5rem;">
|
||||
|
||||
<label for="description" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Описание книги
|
||||
</label>
|
||||
<textarea id="description" name="description"
|
||||
placeholder="Краткое описание сюжета или аннотация..."
|
||||
rows="6"
|
||||
style="width: 100%;"><?= e($book['description'] ?? $_POST['description'] ?? '') ?></textarea>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 5px; flex-wrap: wrap; align-items: center;">
|
||||
<button type="submit" class="contrast compact-button" >
|
||||
<?= $is_edit ? '💾 Сохранить изменения' : '📖 Создать книгу' ?>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php if ($is_edit): ?>
|
||||
<form method="post" action="book_delete.php" style="display: inline;" onsubmit="return confirm('Вы уверены, что хотите удалить книгу «<?= e($book['title']) ?>»? Все главы также будут удалены.');">
|
||||
<input type="hidden" name="book_id" value="<?= $book['id'] ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<button type="submit" class="compact-button secondary" style="background: #ff4444; border-color: #ff4444; color: white;" title="Удалить книгу">
|
||||
🗑️
|
||||
</button>
|
||||
</form>
|
||||
<?php endif ?>
|
||||
<?php if ($is_edit): ?>
|
||||
<div style="margin-top: 2rem; padding: 1rem; background: #f8f9fa; border-radius: 5px;">
|
||||
<h3>Публичная ссылка для чтения</h3>
|
||||
<p style="margin-bottom: 0.5rem;">Отправьте эту ссылку читателям для просмотра опубликованных глав:</p>
|
||||
|
||||
<div style="display: flex; gap: 5px; align-items: center; flex-wrap: wrap;">
|
||||
<input type="text"
|
||||
id="share-link"
|
||||
value="<?= e(SITE_URL . '/view_book.php?share_token=' . $book['share_token']) ?>"
|
||||
readonly
|
||||
style="flex: 1; padding: 8px; border: 1px solid #ddd; border-radius: 4px; background: white;">
|
||||
|
||||
<button type="button" onclick="copyShareLink()" class="compact-button secondary">
|
||||
📋 Копировать
|
||||
</button>
|
||||
|
||||
<form method="post" action="book_regenerate_token.php" style="display: inline;">
|
||||
<input type="hidden" name="book_id" value="<?= $book_id ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<button type="submit" class="compact-button secondary" onclick="return confirm('Создать новую ссылку? Старая ссылка перестанет работать.')">
|
||||
🔄 Обновить
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<p style="margin-top: 0.5rem; font-size: 0.9em; color: #666;">
|
||||
<strong>Примечание:</strong> В публичном просмотре отображаются только главы со статусом "Опубликована"
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyShareLink() {
|
||||
const shareLink = document.getElementById('share-link');
|
||||
shareLink.select();
|
||||
shareLink.setSelectionRange(0, 99999);
|
||||
document.execCommand('copy');
|
||||
|
||||
// Показать уведомление
|
||||
const button = event.target;
|
||||
const originalText = button.innerHTML;
|
||||
button.innerHTML = '✅ Скопировано';
|
||||
setTimeout(() => {
|
||||
button.innerHTML = originalText;
|
||||
}, 2000);
|
||||
}
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($is_edit): ?>
|
||||
<div style="margin-top: 2rem; padding: 1rem; background: #f8f9fa; border-radius: 5px;">
|
||||
<h3>Экспорт книги</h3>
|
||||
<p style="margin-bottom: 0.5rem;">Экспортируйте книгу в различные форматы:</p>
|
||||
|
||||
<div style="display: flex; gap: 5px; flex-wrap: wrap;">
|
||||
<a href="export_book.php?book_id=<?= $book_id ?>&format=pdf" class="adaptive-button secondary" target="_blank">
|
||||
📄 PDF
|
||||
</a>
|
||||
<a href="export_book.php?book_id=<?= $book_id ?>&format=docx" class="adaptive-button secondary" target="_blank">
|
||||
📝 DOCX
|
||||
</a>
|
||||
<a href="export_book.php?book_id=<?= $book_id ?>&format=odt" class="adaptive-button secondary" target="_blank">
|
||||
📄 ODT
|
||||
</a>
|
||||
<a href="export_book.php?book_id=<?= $book_id ?>&format=html" class="adaptive-button secondary" target="_blank">
|
||||
🌐 HTML
|
||||
</a>
|
||||
<a href="export_book.php?book_id=<?= $book_id ?>&format=txt" class="adaptive-button secondary" target="_blank">
|
||||
📄 TXT
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p style="margin-top: 0.5rem; font-size: 0.9em; color: #666;">
|
||||
<strong>Примечание:</strong> Экспортируются все главы книги (включая черновики)
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($is_edit): ?>
|
||||
<div style="margin-top: 3rem;">
|
||||
<h2>Главы этой книги</h2>
|
||||
<a href="chapters.php?book_id=<?= $book_id ?>" class="compact-button secondary">
|
||||
📑 Все главы
|
||||
</a>
|
||||
|
||||
<a href="chapter_edit.php?book_id=<?= $book_id ?>" role="button" class="compact-button secondary">
|
||||
✏️ Добавить главу
|
||||
</a>
|
||||
<?php
|
||||
// Получаем главы книги
|
||||
$stmt = $pdo->prepare("SELECT * FROM chapters WHERE book_id = ? ORDER BY sort_order, created_at");
|
||||
$stmt->execute([$book_id]);
|
||||
$chapters = $stmt->fetchAll();
|
||||
|
||||
if ($chapters): ?>
|
||||
<div style="overflow-x: auto;">
|
||||
<table style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: left; padding: 12px 8px;">Название</th>
|
||||
<th style="text-align: left; padding: 12px 8px;">Статус</th>
|
||||
<th style="text-align: left; padding: 12px 8px;">Слов</th>
|
||||
<th style="text-align: left; padding: 12px 8px;">Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($chapters as $chapter): ?>
|
||||
<tr style="border-bottom: 1px solid #eee;">
|
||||
<td style="padding: 12px 8px;"><?= e($chapter['title']) ?></td>
|
||||
<td style="padding: 12px 8px;">
|
||||
<span style="color: <?= $chapter['status'] == 'published' ? 'green' : 'orange' ?>">
|
||||
<?= $chapter['status'] == 'published' ? 'Опубликована' : 'Черновик' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td style="padding: 12px 8px;"><?= $chapter['word_count'] ?></td>
|
||||
<td style="padding: 12px 8px;">
|
||||
<a href="chapter_edit.php?id=<?= $chapter['id'] ?>" role="button" class="compact-button secondary" style="text-decoration: none;">
|
||||
Редактировать
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div style="text-align: center; padding: 2rem; background: #f9f9f9; border-radius: 5px;">
|
||||
<p style="margin-bottom: 1rem;">В этой книге пока нет глав.</p>
|
||||
<a href="chapter_edit.php?book_id=<?= $book_id ?>" role="button" class="compact-button secondary" >
|
||||
✏️ Добавить первую главу
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$_SESSION['error'] = "Неверный метод запроса";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$_SESSION['error'] = "Ошибка безопасности";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$book_id = $_POST['book_id'] ?? null;
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
if (!$book_id) {
|
||||
$_SESSION['error'] = "Не указана книга";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$bookModel = new Book($pdo);
|
||||
|
||||
// Проверяем права доступа
|
||||
if (!$bookModel->userOwnsBook($book_id, $user_id)) {
|
||||
$_SESSION['error'] = "У вас нет доступа к этой книге";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
// Генерируем новый токен
|
||||
$new_token = $bookModel->generateNewShareToken($book_id);
|
||||
|
||||
if ($new_token) {
|
||||
$_SESSION['success'] = "Публичная ссылка обновлена";
|
||||
} else {
|
||||
$_SESSION['error'] = "Ошибка при обновлении ссылки";
|
||||
}
|
||||
|
||||
redirect("book_edit.php?id=$book_id");
|
||||
?>
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$bookModel = new Book($pdo);
|
||||
$books = $bookModel->findByUser($user_id);
|
||||
|
||||
$page_title = "Мои книги";
|
||||
include 'views/header.php';
|
||||
?>
|
||||
|
||||
<h1>Мои книги</h1>
|
||||
|
||||
<?php if (isset($_SESSION['success'])): ?>
|
||||
<div class="alert alert-success">
|
||||
<?= e($_SESSION['success']) ?>
|
||||
<?php unset($_SESSION['success']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION['error'])): ?>
|
||||
<div class="alert alert-error">
|
||||
<?= e($_SESSION['error']) ?>
|
||||
<?php unset($_SESSION['error']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
|
||||
<h2 style="margin: 0;">Всего книг: <?= count($books) ?></h2>
|
||||
<div style="display: flex; gap: 10px; align-items: center;">
|
||||
<a href="book_edit.php" class="action-button primary">➕ Новая книга</a>
|
||||
<?php if (!empty($books)): ?>
|
||||
<button type="button" onclick="showDeleteConfirmation()" class="action-button delete">
|
||||
🗑️ Удалить все книги
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (empty($books)): ?>
|
||||
<article style="text-align: center; padding: 2rem;">
|
||||
<h3>У вас пока нет книг</h3>
|
||||
<p>Создайте свою первую книгу и начните писать!</p>
|
||||
<a href="book_edit.php" role="button">📖 Создать первую книгу</a>
|
||||
</article>
|
||||
<?php else: ?>
|
||||
<div class="grid">
|
||||
<?php foreach ($books as $book): ?>
|
||||
<article>
|
||||
<header>
|
||||
<h3><?= e($book['title']) ?></h3>
|
||||
<?php if ($book['genre']): ?>
|
||||
<small style="color: #666;"><?= e($book['genre']) ?></small>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<?php if ($book['description']): ?>
|
||||
<p><?= e(mb_strimwidth($book['description'], 0, 150, '...')) ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<footer style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<div>
|
||||
<small>
|
||||
Глав: <?= $book['chapter_count'] ?> |
|
||||
Слов: <?= $book['total_words'] ?>
|
||||
</small>
|
||||
</div>
|
||||
<div style="display: flex; gap: 3px;">
|
||||
<a href="export_book.php?book_id=<?= $book['id'] ?>&format=pdf" class="compact-button secondary" title="Экспорт в PDF" target="_blank">
|
||||
📄
|
||||
</a>
|
||||
<a href="view_book.php?share_token=<?= $book['share_token'] ?>" class="compact-button secondary" title="Просмотреть книгу" target="_blank">
|
||||
👁️
|
||||
</a>
|
||||
<a href="book_edit.php?id=<?= $book['id'] ?>" class="compact-button secondary" title="Редактировать книгу">
|
||||
✏️
|
||||
</a>
|
||||
<a href="chapters.php?book_id=<?= $book['id'] ?>" class="compact-button secondary" title="Просмотр глав">
|
||||
📑
|
||||
</a>
|
||||
<form method="post" action="book_delete.php" style="display: inline;" onsubmit="return confirm('Вы уверены, что хотите удалить книгу «<?= e($book['title']) ?>»? Все главы также будут удалены.');">
|
||||
<input type="hidden" name="book_id" value="<?= $book['id'] ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<button type="submit" class="compact-button secondary" style="background: #ff4444; border-color: #ff4444; color: white;" title="Удалить книгу">
|
||||
🗑️
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<!-- Модальное окно для удаления всех книг -->
|
||||
<dialog id="deleteAllDialog" style="border-radius: 8px; padding: 20px; max-width: 500px; background-color: #fff;">
|
||||
<h3 style="margin-top: 0;">Удалить все книги?</h3>
|
||||
<p>Это действие удалит все ваши книги и все связанные с ними главы. Это действие нельзя отменить.</p>
|
||||
|
||||
<form method="post" action="book_delete_all.php" style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<button type="button" onclick="closeDeleteDialog()" class="secondary" style="flex: 1;">
|
||||
❌ Отмена
|
||||
</button>
|
||||
<button type="submit" class="contrast" style="flex: 1; background: #ff4444; border-color: #ff4444; color: white;">
|
||||
🗑️ Удалить все
|
||||
</button>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<script>
|
||||
function showDeleteConfirmation() {
|
||||
const dialog = document.getElementById('deleteAllDialog');
|
||||
dialog.showModal();
|
||||
}
|
||||
|
||||
function closeDeleteDialog() {
|
||||
const dialog = document.getElementById('deleteAllDialog');
|
||||
dialog.close();
|
||||
}
|
||||
|
||||
// Закрытие диалога по клику вне его области
|
||||
document.getElementById('deleteAllDialog').addEventListener('click', function(event) {
|
||||
if (event.target === this) {
|
||||
closeDeleteDialog();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$_SESSION['error'] = "Неверный метод запроса";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$_SESSION['error'] = "Ошибка безопасности";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$chapter_id = $_POST['chapter_id'] ?? null;
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
if (!$chapter_id) {
|
||||
$_SESSION['error'] = "Не указана глава для удаления";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$chapterModel = new Chapter($pdo);
|
||||
|
||||
// Проверяем права доступа
|
||||
if (!$chapterModel->userOwnsChapter($chapter_id, $user_id)) {
|
||||
$_SESSION['error'] = "У вас нет доступа к этой главе";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
// Получаем информацию о главе перед удалением (для редиректа)
|
||||
$chapter = $chapterModel->findById($chapter_id);
|
||||
$book_id = $chapter['book_id'];
|
||||
|
||||
// Удаляем главу
|
||||
if ($chapterModel->delete($chapter_id)) {
|
||||
$_SESSION['success'] = "Глава успешно удалена";
|
||||
} else {
|
||||
$_SESSION['error'] = "Ошибка при удалении главы";
|
||||
}
|
||||
|
||||
// Редирект обратно к списку глав книги
|
||||
redirect("chapters.php?book_id=$book_id");
|
||||
?>
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$chapterModel = new Chapter($pdo);
|
||||
$bookModel = new Book($pdo);
|
||||
|
||||
// Получаем book_id из GET или из существующей главы
|
||||
$chapter_id = $_GET['id'] ?? null;
|
||||
$book_id = $_GET['book_id'] ?? null;
|
||||
$chapter = null;
|
||||
$is_edit = false;
|
||||
|
||||
// Если редактируем существующую главу
|
||||
if ($chapter_id) {
|
||||
$chapter = $chapterModel->findById($chapter_id);
|
||||
if (!$chapter || $chapter['user_id'] != $user_id) {
|
||||
$_SESSION['error'] = "Глава не найдена или у вас нет доступа";
|
||||
redirect('books.php');
|
||||
}
|
||||
$book_id = $chapter['book_id'];
|
||||
$is_edit = true;
|
||||
}
|
||||
|
||||
// Проверяем, что book_id указан и пользователь имеет доступ к книге
|
||||
if (!$book_id) {
|
||||
$_SESSION['error'] = "Не указана книга";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
if (!$bookModel->userOwnsBook($book_id, $user_id)) {
|
||||
$_SESSION['error'] = "У вас нет доступа к этой книге";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
// Получаем информацию о книге
|
||||
$book = $bookModel->findById($book_id);
|
||||
|
||||
// Обработка формы
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$_SESSION['error'] = "Ошибка безопасности";
|
||||
redirect($is_edit ? "chapter_edit.php?id=$chapter_id" : "chapter_edit.php?book_id=$book_id");
|
||||
}
|
||||
|
||||
// Обработка автосохранения
|
||||
if (isset($_POST['autosave']) && $_POST['autosave'] === 'true') {
|
||||
// Автосохранение работает только для существующих глав
|
||||
if (!$is_edit) {
|
||||
// Если это не редактирование, игнорируем автосохранение
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => false, 'message' => 'Автосохранение недоступно для новых глав']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$title = trim($_POST['title'] ?? '');
|
||||
$content = trim($_POST['content'] ?? '');
|
||||
$status = $_POST['status'] ?? 'draft';
|
||||
|
||||
if (empty($title)) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => false, 'message' => 'Название главы обязательно']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
'status' => $status,
|
||||
'book_id' => $book_id
|
||||
];
|
||||
|
||||
$success = $chapterModel->update($chapter_id, $data);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => $success]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Обычная обработка формы (не автосохранение)
|
||||
$title = trim($_POST['title'] ?? '');
|
||||
$content = trim($_POST['content'] ?? '');
|
||||
$status = $_POST['status'] ?? 'draft';
|
||||
|
||||
if (empty($title)) {
|
||||
$_SESSION['error'] = "Название главы обязательно";
|
||||
} else {
|
||||
$data = [
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
'status' => $status,
|
||||
'book_id' => $book_id
|
||||
];
|
||||
|
||||
if ($is_edit) {
|
||||
$success = $chapterModel->update($chapter_id, $data);
|
||||
$message = $success ? "Глава успешно обновлена" : "Ошибка при обновлении главы";
|
||||
} else {
|
||||
$success = $chapterModel->create($data);
|
||||
$message = $success ? "Глава успешно создана" : "Ошибка при создании главы";
|
||||
|
||||
if ($success) {
|
||||
$new_chapter_id = $pdo->lastInsertId();
|
||||
redirect("chapter_edit.php?id=$new_chapter_id");
|
||||
}
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
$_SESSION['success'] = $message;
|
||||
redirect("book_edit.php?id=$book_id");
|
||||
} else {
|
||||
$_SESSION['error'] = $message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$page_title = $is_edit ? "Редактирование главы" : "Создание новой главы";
|
||||
include 'views/header.php';
|
||||
?>
|
||||
<?php if ($is_edit): ?>
|
||||
<div style="margin-top: 1rem;">
|
||||
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
|
||||
<?php
|
||||
// Получаем все главы книги для навигации
|
||||
$chapters = $chapterModel->findByBook($book_id);
|
||||
$current_index = null;
|
||||
|
||||
// Находим индекс текущей главы
|
||||
foreach ($chapters as $index => $chap) {
|
||||
if ($chap['id'] == $chapter_id) {
|
||||
$current_index = $index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($current_index !== null && $current_index > 0):
|
||||
$prev_chapter = $chapters[$current_index - 1];
|
||||
?>
|
||||
<a href="chapter_edit.php?id=<?= $prev_chapter['id'] ?>" role="button" class="secondary" style="padding: 2px 4px;">
|
||||
⬅️ Предыдущая: <?= e(mb_strimwidth($prev_chapter['title'], 0, 30, '...')) ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($current_index !== null && $current_index < count($chapters) - 1):
|
||||
$next_chapter = $chapters[$current_index + 1];
|
||||
?>
|
||||
<a href="chapter_edit.php?id=<?= $next_chapter['id'] ?>" role="button" class="secondary" style="padding: 2px 4px;">
|
||||
Следующая: <?= e(mb_strimwidth($next_chapter['title'], 0, 30, '...')) ?> ➡️
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h1><?= $is_edit ? "Редактирование главы" : "Создание новой главы" ?></h1>
|
||||
<p><strong>Книга:</strong> <?= e($book['title']) ?></p>
|
||||
|
||||
<?php if (isset($_SESSION['error'])): ?>
|
||||
<div class="alert alert-error">
|
||||
<?= e($_SESSION['error']) ?>
|
||||
<?php unset($_SESSION['error']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" id="main-form">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
|
||||
<div style="max-width: 100%; margin-bottom: 1rem;">
|
||||
<label for="title" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Название главы *
|
||||
</label>
|
||||
<input type="text" id="title" name="title"
|
||||
value="<?= e($chapter['title'] ?? $_POST['title'] ?? '') ?>"
|
||||
placeholder="Введите название главы"
|
||||
style="width: 100%; margin-bottom: 1.5rem;"
|
||||
required>
|
||||
|
||||
<label for="status" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Статус
|
||||
</label>
|
||||
<select id="status" name="status" style="width: 100%; margin-bottom: 1.5rem;">
|
||||
<option value="draft" <?= ($chapter['status'] ?? 'draft') == 'draft' ? 'selected' : '' ?>>Черновик</option>
|
||||
<option value="published" <?= ($chapter['status'] ?? '') == 'published' ? 'selected' : '' ?>>Опубликована</option>
|
||||
</select>
|
||||
|
||||
<label for="content" style="display: block; margin-bottom: 0; font-weight: bold;">
|
||||
Содержание главы
|
||||
</label>
|
||||
<textarea name="content" id="content"
|
||||
placeholder="Начните писать вашу главу здесь..."
|
||||
rows="15"
|
||||
style="width: 100%; font-family: monospace;"><?= e($chapter['content'] ?? $_POST['content'] ?? '') ?></textarea>
|
||||
<?php if ($is_edit && isset($chapter['word_count'])): ?>
|
||||
<div style="background: #f5f5f5; padding: 10px; border-radius: 5px; margin-bottom: 1rem;">
|
||||
<strong>Статистика:</strong> <?= $chapter['word_count'] ?> слов
|
||||
| Обновлено: <?= date('d.m.Y H:i', strtotime($chapter['updated_at'])) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Основные кнопки формы - Сохранить, Отмена и Предпросмотр -->
|
||||
<div class="button-group">
|
||||
<button type="submit" form="main-form" class="contrast">
|
||||
<?= $is_edit ? '💾 Сохранить изменения' : '📝 Создать главу' ?>
|
||||
</button>
|
||||
|
||||
<a href="book_edit.php?id=<?= $book_id ?>" role="button" class="secondary">
|
||||
❌ Отмена
|
||||
</a>
|
||||
|
||||
<button type="button" class="green-btn" id="preview-button">
|
||||
👁️ Предпросмотр
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Скрытая форма для предпросмотра -->
|
||||
<form method="post" action="preview.php" target="_blank" id="preview-form" style="display: none;">
|
||||
<input type="hidden" name="content" id="preview-content">
|
||||
<input type="hidden" name="title" id="preview-title" value="<?= e($chapter['title'] ?? 'Новая глава') ?>">
|
||||
</form>
|
||||
|
||||
<!-- Дополнительные кнопки (вне основной формы) -->
|
||||
<?php if ($is_edit): ?>
|
||||
<div class="button-group">
|
||||
<a href="chapter_edit.php?book_id=<?= $book_id ?>" role="button">
|
||||
➕ Новая глава
|
||||
</a>
|
||||
|
||||
<form method="post" action="chapter_delete.php" style="flex: 1;" onsubmit="return confirm('Вы уверены, что хотите удалить эту главу? Это действие нельзя отменить.');">
|
||||
<input type="hidden" name="chapter_id" value="<?= $chapter_id ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<button type="submit" class="secondary delete-btn">
|
||||
🗑️ Удалить
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($is_edit): ?>
|
||||
<div style="margin-top: 3rem;">
|
||||
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
|
||||
<?php
|
||||
// Получаем все главы книги для навигации
|
||||
$chapters = $chapterModel->findByBook($book_id);
|
||||
$current_index = null;
|
||||
|
||||
// Находим индекс текущей главы
|
||||
foreach ($chapters as $index => $chap) {
|
||||
if ($chap['id'] == $chapter_id) {
|
||||
$current_index = $index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($current_index !== null && $current_index > 0):
|
||||
$prev_chapter = $chapters[$current_index - 1];
|
||||
?>
|
||||
<a href="chapter_edit.php?id=<?= $prev_chapter['id'] ?>" role="button" class="secondary" style="padding: 2px 4px;">
|
||||
⬅️ Предыдущая: <?= e(mb_strimwidth($prev_chapter['title'], 0, 30, '...')) ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($current_index !== null && $current_index < count($chapters) - 1):
|
||||
$next_chapter = $chapters[$current_index + 1];
|
||||
?>
|
||||
<a href="chapter_edit.php?id=<?= $next_chapter['id'] ?>" role="button" class="secondary" style="padding: 2px 4px;">
|
||||
Следующая: <?= e(mb_strimwidth($next_chapter['title'], 0, 30, '...')) ?> ➡️
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<script>
|
||||
// Обработчик для кнопки предпросмотра
|
||||
document.getElementById('preview-button').addEventListener('click', function() {
|
||||
// Обновляем содержимое для предпросмотра
|
||||
document.getElementById('preview-content').value = document.getElementById('content').value;
|
||||
document.getElementById('preview-title').value = document.getElementById('title').value || 'Новая глава';
|
||||
|
||||
// Отправляем форму предпросмотра
|
||||
document.getElementById('preview-form').submit();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="assets/js/markdown-editor.js"></script>
|
||||
<?php if ($is_edit): ?>
|
||||
<script src="assets/js/autosave.js"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$book_id = $_GET['book_id'] ?? null;
|
||||
|
||||
if (!$book_id) {
|
||||
$_SESSION['error'] = "Не указана книга";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
$bookModel = new Book($pdo);
|
||||
$chapterModel = new Chapter($pdo);
|
||||
|
||||
// Проверяем права доступа к книге
|
||||
if (!$bookModel->userOwnsBook($book_id, $user_id)) {
|
||||
$_SESSION['error'] = "У вас нет доступа к этой книге";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
// Получаем информацию о книге и главах
|
||||
$book = $bookModel->findById($book_id);
|
||||
$chapters = $chapterModel->findByBook($book_id);
|
||||
|
||||
$page_title = "Главы книги: " . e($book['title']);
|
||||
include 'views/header.php';
|
||||
?>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<h1 style="margin: 0 0 0.5rem 0; font-size: 1.5rem;">Главы книги: <?= e($book['title']) ?></h1>
|
||||
<div style="display: flex; gap: 5px; flex-wrap: wrap;">
|
||||
<a href="chapter_edit.php?book_id=<?= $book_id ?>" class="adaptive-button">➕ Новая глава</a>
|
||||
<a href="book_edit.php?id=<?= $book_id ?>" class="adaptive-button secondary">✏️ Редактировать книгу</a>
|
||||
<a href="view_book.php?share_token=<?= $book['share_token'] ?>" class="adaptive-button secondary" target="_blank">👁️ Просмотреть книгу</a>
|
||||
<a href="books.php" class="adaptive-button secondary">📚 Все книги</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (isset($_SESSION['success'])): ?>
|
||||
<div class="alert alert-success">
|
||||
<?= e($_SESSION['success']) ?>
|
||||
<?php unset($_SESSION['success']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION['error'])): ?>
|
||||
<div class="alert alert-error">
|
||||
<?= e($_SESSION['error']) ?>
|
||||
<?php unset($_SESSION['error']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($chapters)): ?>
|
||||
<div style="text-align: center; padding: 2rem; background: #f9f9f9; border-radius: 5px; margin-top: 1rem;">
|
||||
<h3>В этой книге пока нет глав</h3>
|
||||
<p>Создайте первую главу для вашей книги</p>
|
||||
<a href="chapter_edit.php?book_id=<?= $book_id ?>" class="adaptive-button">📝 Создать первую главу</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div style="overflow-x: auto; margin-top: 1rem;">
|
||||
<table class="compact-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">№</th>
|
||||
<th style="width: 40%;">Название главы</th>
|
||||
<th style="width: 15%;">Статус</th>
|
||||
<th style="width: 10%;">Слов</th>
|
||||
<th style="width: 20%;">Обновлено</th>
|
||||
<th style="width: 10%;">Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($chapters as $index => $chapter): ?>
|
||||
<tr>
|
||||
<td><?= $index + 1 ?></td>
|
||||
<td>
|
||||
<strong><?= e($chapter['title']) ?></strong>
|
||||
<?php if ($chapter['description']): ?>
|
||||
<br><small style="color: #666;"><?= e(mb_strimwidth($chapter['description'], 0, 100, '...')) ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span style="color: <?= $chapter['status'] == 'published' ? 'green' : 'orange' ?>">
|
||||
<?= $chapter['status'] == 'published' ? '✅ Опубликована' : '📝 Черновик' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?= $chapter['word_count'] ?></td>
|
||||
<td>
|
||||
<small><?= date('d.m.Y H:i', strtotime($chapter['updated_at'])) ?></small>
|
||||
</td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 3px; flex-wrap: wrap;">
|
||||
<a href="chapter_edit.php?id=<?= $chapter['id'] ?>" class="compact-button secondary" title="Редактировать">
|
||||
✏️
|
||||
</a>
|
||||
<form method="post" action="chapter_delete.php" style="display: inline;" onsubmit="return confirm('Вы уверены, что хотите удалить эту главу? Это действие нельзя отменить.');">
|
||||
<input type="hidden" name="chapter_id" value="<?= $chapter['id'] ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
<button type="submit" class="compact-button secondary" style="background: #ff4444; border-color: #ff4444; color: white;" title="Удалить">
|
||||
🗑️
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 1rem; padding: 0.5rem; background: #f5f5f5; border-radius: 3px;">
|
||||
<strong>Статистика:</strong>
|
||||
Всего глав: <?= count($chapters) ?> |
|
||||
Всего слов: <?= array_sum(array_column($chapters, 'word_count')) ?> |
|
||||
Опубликовано: <?= count(array_filter($chapters, function($ch) { return $ch['status'] == 'published'; })) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"require": {
|
||||
"phpoffice/phpword": "^1.0",
|
||||
"tecnickcom/tcpdf": "^6.6"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,535 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2a08fae47e0b8e59039cdc770c12dc3c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "dompdf/dompdf",
|
||||
"version": "v2.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/dompdf.git",
|
||||
"reference": "c20247574601700e1f7c8dab39310fca1964dc52"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/c20247574601700e1f7c8dab39310fca1964dc52",
|
||||
"reference": "c20247574601700e1f7c8dab39310fca1964dc52",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-mbstring": "*",
|
||||
"masterminds/html5": "^2.0",
|
||||
"phenx/php-font-lib": ">=0.5.4 <1.0.0",
|
||||
"phenx/php-svg-lib": ">=0.5.2 <1.0.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"mockery/mockery": "^1.3",
|
||||
"phpunit/phpunit": "^7.5 || ^8 || ^9",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "Needed to process images",
|
||||
"ext-gmagick": "Improves image processing performance",
|
||||
"ext-imagick": "Improves image processing performance",
|
||||
"ext-zlib": "Needed for pdf stream compression"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dompdf\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"lib/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The Dompdf Community",
|
||||
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||
"homepage": "https://github.com/dompdf/dompdf",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||
"source": "https://github.com/dompdf/dompdf/tree/v2.0.8"
|
||||
},
|
||||
"time": "2024-04-29T13:06:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Masterminds/html5-php.git",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Masterminds\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matt Butcher",
|
||||
"email": "technosophos@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Matt Farina",
|
||||
"email": "matt@mattfarina.com"
|
||||
},
|
||||
{
|
||||
"name": "Asmir Mustafic",
|
||||
"email": "goetas@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "An HTML5 parser and serializer.",
|
||||
"homepage": "http://masterminds.github.io/html5-php",
|
||||
"keywords": [
|
||||
"HTML5",
|
||||
"dom",
|
||||
"html",
|
||||
"parser",
|
||||
"querypath",
|
||||
"serializer",
|
||||
"xml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
|
||||
},
|
||||
"time": "2025-07-25T09:04:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phenx/php-font-lib",
|
||||
"version": "0.5.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||
"reference": "a1681e9793040740a405ac5b189275059e2a9863"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a1681e9793040740a405ac5b189275059e2a9863",
|
||||
"reference": "a1681e9793040740a405ac5b189275059e2a9863",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FontLib\\": "src/FontLib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Ménager",
|
||||
"email": "fabien.menager@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||
"homepage": "https://github.com/PhenX/php-font-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-font-lib/tree/0.5.6"
|
||||
},
|
||||
"time": "2024-01-29T14:45:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phenx/php-svg-lib",
|
||||
"version": "0.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||
"reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/46b25da81613a9cf43c83b2a8c2c1bdab27df691",
|
||||
"reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabberworm/php-css-parser": "^8.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Svg\\": "src/Svg"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Ménager",
|
||||
"email": "fabien.menager@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse and export to PDF SVG files.",
|
||||
"homepage": "https://github.com/PhenX/php-svg-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-svg-lib/tree/0.5.4"
|
||||
},
|
||||
"time": "2024-04-08T12:52:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/math",
|
||||
"version": "0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/Math.git",
|
||||
"reference": "fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/Math/zipball/fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a",
|
||||
"reference": "fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-xml": "*",
|
||||
"php": "^7.1|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.88 || ^1.0.0",
|
||||
"phpunit/phpunit": "^7.0 || ^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\Math\\": "src/Math/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Progi1984",
|
||||
"homepage": "https://lefevre.dev"
|
||||
}
|
||||
],
|
||||
"description": "Math - Manipulate Math Formula",
|
||||
"homepage": "https://phpoffice.github.io/Math/",
|
||||
"keywords": [
|
||||
"MathML",
|
||||
"officemathml",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/Math/issues",
|
||||
"source": "https://github.com/PHPOffice/Math/tree/0.3.0"
|
||||
},
|
||||
"time": "2025-05-29T08:31:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpword",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PHPWord.git",
|
||||
"reference": "6d75328229bc93790b37e93741adf70646cea958"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/6d75328229bc93790b37e93741adf70646cea958",
|
||||
"reference": "6d75328229bc93790b37e93741adf70646cea958",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-json": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-zip": "*",
|
||||
"php": "^7.1|^8.0",
|
||||
"phpoffice/math": "^0.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"dompdf/dompdf": "^2.0 || ^3.0",
|
||||
"ext-libxml": "*",
|
||||
"friendsofphp/php-cs-fixer": "^3.3",
|
||||
"mpdf/mpdf": "^7.0 || ^8.0",
|
||||
"phpmd/phpmd": "^2.13",
|
||||
"phpstan/phpstan": "^0.12.88 || ^1.0.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
|
||||
"phpunit/phpunit": ">=7.0",
|
||||
"symfony/process": "^4.4 || ^5.0",
|
||||
"tecnickcom/tcpdf": "^6.5"
|
||||
},
|
||||
"suggest": {
|
||||
"dompdf/dompdf": "Allows writing PDF",
|
||||
"ext-xmlwriter": "Allows writing OOXML and ODF",
|
||||
"ext-xsl": "Allows applying XSL style sheet to headers, to main document part, and to footers of an OOXML template"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\PhpWord\\": "src/PhpWord"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker"
|
||||
},
|
||||
{
|
||||
"name": "Gabriel Bull",
|
||||
"email": "me@gabrielbull.com",
|
||||
"homepage": "http://gabrielbull.com/"
|
||||
},
|
||||
{
|
||||
"name": "Franck Lefevre",
|
||||
"homepage": "https://rootslabs.net/blog/"
|
||||
},
|
||||
{
|
||||
"name": "Ivan Lanin",
|
||||
"homepage": "http://ivan.lanin.org"
|
||||
},
|
||||
{
|
||||
"name": "Roman Syroeshko",
|
||||
"homepage": "http://ru.linkedin.com/pub/roman-syroeshko/34/a53/994/"
|
||||
},
|
||||
{
|
||||
"name": "Antoine de Troostembergh"
|
||||
}
|
||||
],
|
||||
"description": "PHPWord - A pure PHP library for reading and writing word processing documents (OOXML, ODF, RTF, HTML, PDF)",
|
||||
"homepage": "https://phpoffice.github.io/PHPWord/",
|
||||
"keywords": [
|
||||
"ISO IEC 29500",
|
||||
"OOXML",
|
||||
"Office Open XML",
|
||||
"OpenDocument",
|
||||
"OpenXML",
|
||||
"PhpOffice",
|
||||
"PhpWord",
|
||||
"Rich Text Format",
|
||||
"WordprocessingML",
|
||||
"doc",
|
||||
"docx",
|
||||
"html",
|
||||
"odf",
|
||||
"odt",
|
||||
"office",
|
||||
"pdf",
|
||||
"php",
|
||||
"reader",
|
||||
"rtf",
|
||||
"template",
|
||||
"template processor",
|
||||
"word",
|
||||
"writer"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PHPWord/issues",
|
||||
"source": "https://github.com/PHPOffice/PHPWord/tree/1.4.0"
|
||||
},
|
||||
"time": "2025-06-05T10:32:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabberworm/php-css-parser",
|
||||
"version": "v8.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41",
|
||||
"rawr/cross-data-providers": "^2.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "9.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabberworm\\CSS\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Raphael Schweikert"
|
||||
},
|
||||
{
|
||||
"name": "Oliver Klee",
|
||||
"email": "github@oliverklee.de"
|
||||
},
|
||||
{
|
||||
"name": "Jake Hotson",
|
||||
"email": "jake.github@qzdesign.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Parser for CSS Files written in PHP",
|
||||
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||
"keywords": [
|
||||
"css",
|
||||
"parser",
|
||||
"stylesheet"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0"
|
||||
},
|
||||
"time": "2025-07-11T13:20:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tecnickcom/tcpdf",
|
||||
"version": "6.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
||||
"reference": "ca5b6de294512145db96bcbc94e61696599c391d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ca5b6de294512145db96bcbc94e61696599c391d",
|
||||
"reference": "ca5b6de294512145db96bcbc94e61696599c391d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"php": ">=7.1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"config",
|
||||
"include",
|
||||
"tcpdf.php",
|
||||
"tcpdf_barcodes_1d.php",
|
||||
"tcpdf_barcodes_2d.php",
|
||||
"include/tcpdf_colors.php",
|
||||
"include/tcpdf_filters.php",
|
||||
"include/tcpdf_font_data.php",
|
||||
"include/tcpdf_fonts.php",
|
||||
"include/tcpdf_images.php",
|
||||
"include/tcpdf_static.php",
|
||||
"include/barcodes/datamatrix.php",
|
||||
"include/barcodes/pdf417.php",
|
||||
"include/barcodes/qrcode.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicola Asuni",
|
||||
"email": "info@tecnick.com",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
|
||||
"homepage": "http://www.tcpdf.org/",
|
||||
"keywords": [
|
||||
"PDFD32000-2008",
|
||||
"TCPDF",
|
||||
"barcodes",
|
||||
"datamatrix",
|
||||
"pdf",
|
||||
"pdf417",
|
||||
"qrcode"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tecnickcom/TCPDF/issues",
|
||||
"source": "https://github.com/tecnickcom/TCPDF/tree/6.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-27T18:02:28+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
// config/config.php
|
||||
// Подключаем функции
|
||||
require_once __DIR__ . '/../includes/functions.php';
|
||||
session_start();
|
||||
|
||||
// Настройки базы данных
|
||||
define('DB_HOST', 'localhost');
|
||||
define('DB_USER', 'writer_mirv');
|
||||
define('DB_PASS', 'writer_moloko22');
|
||||
define('DB_NAME', 'writer_app');
|
||||
define('SITE_URL', 'https://writer.mirv.top');
|
||||
//define('BASE_URL', 'http://' . $_SERVER['HTTP_HOST'] . '/'); // Измените на ваш домен
|
||||
// Настройки приложения
|
||||
define('APP_NAME', 'Web Writer');
|
||||
define('UPLOAD_PATH', __DIR__ . '/../uploads/');
|
||||
|
||||
// Подключение к базе данных
|
||||
try {
|
||||
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4", DB_USER, DB_PASS);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch(PDOException $e) {
|
||||
error_log("DB Error: " . $e->getMessage());
|
||||
die("Ошибка подключения к базе данных");
|
||||
}
|
||||
|
||||
|
||||
// Автозагрузка моделей
|
||||
spl_autoload_register(function ($class_name) {
|
||||
$model_file = __DIR__ . '/../models/' . $class_name . '.php';
|
||||
if (file_exists($model_file)) {
|
||||
require_once $model_file;
|
||||
}
|
||||
});
|
||||
?>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$bookModel = new Book($pdo);
|
||||
$books = $bookModel->findByUser($user_id);
|
||||
|
||||
$page_title = "Панель управления";
|
||||
include 'views/header.php';
|
||||
?>
|
||||
|
||||
<h1>Добро пожаловать, <?= e($_SESSION['display_name']) ?>!</h1>
|
||||
|
||||
<div class="grid">
|
||||
<article>
|
||||
<h2>📚 Мои книги</h2>
|
||||
<p>Управляйте вашими книгами и главами</p>
|
||||
<a href="books.php" role="button">
|
||||
Мои книги (<?= count($books) ?>)
|
||||
</a>
|
||||
|
||||
<a href="book_edit.php" role="button">➕ Новая книга</a>
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<h2>📊 Статистика</h2>
|
||||
<?php
|
||||
$total_chapters = 0;
|
||||
$total_words = 0;
|
||||
foreach ($books as $book) {
|
||||
$total_chapters += $book['chapter_count'];
|
||||
$total_words += $book['total_words'];
|
||||
}
|
||||
?>
|
||||
<p><strong>Книг:</strong> <?= count($books) ?></p>
|
||||
<p><strong>Глав:</strong> <?= $total_chapters ?></p>
|
||||
<p><strong>Всего слов:</strong> <?= $total_words ?></p>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($books)): ?>
|
||||
<div style="margin-top: 2rem;">
|
||||
|
||||
<div class="grid">
|
||||
<article>
|
||||
<h2>Недавние книги</h2>
|
||||
<?php foreach (array_slice($books, 0, 3) as $book): ?>
|
||||
<article>
|
||||
<h4><?= e($book['title']) ?></h4>
|
||||
<p>Глав: <?= $book['chapter_count'] ?> | Слов: <?= $book['total_words'] ?></p>
|
||||
<a href="book_edit.php?id=<?= $book['id'] ?>" role="button" class="secondary">
|
||||
Редактировать
|
||||
</a>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,553 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_once 'vendor/autoload.php';
|
||||
require_once 'includes/parsedown/ParsedownExtra.php';
|
||||
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\IOFactory;
|
||||
use TCPDF;
|
||||
|
||||
// Проверяем авторизацию или share_token
|
||||
$user_id = $_SESSION['user_id'] ?? null;
|
||||
$share_token = $_GET['share_token'] ?? null;
|
||||
$book_id = $_GET['book_id'] ?? null;
|
||||
$format = $_GET['format'] ?? 'pdf';
|
||||
|
||||
if (!$user_id && !$share_token) {
|
||||
$_SESSION['error'] = "Доступ запрещен";
|
||||
redirect('login.php');
|
||||
}
|
||||
|
||||
$bookModel = new Book($pdo);
|
||||
$chapterModel = new Chapter($pdo);
|
||||
$Parsedown = new ParsedownExtra();
|
||||
|
||||
// Получаем книгу
|
||||
if ($share_token) {
|
||||
$book = $bookModel->findByShareToken($share_token);
|
||||
// Для публичного доступа - только опубликованные главы
|
||||
$chapters = $bookModel->getPublishedChapters($book['id']);
|
||||
$is_public = true;
|
||||
} elseif ($book_id && $user_id) {
|
||||
$book = $bookModel->findById($book_id);
|
||||
if (!$book || $book['user_id'] != $user_id) {
|
||||
$_SESSION['error'] = "Доступ запрещен";
|
||||
redirect('books.php');
|
||||
}
|
||||
// Для автора - все главы
|
||||
$chapters = $chapterModel->findByBook($book_id);
|
||||
$is_public = false;
|
||||
} else {
|
||||
$_SESSION['error'] = "Книга не найдена";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
if (!$book) {
|
||||
$_SESSION['error'] = "Книга не найдена";
|
||||
redirect('books.php');
|
||||
}
|
||||
|
||||
// Функция для очистки имени файла
|
||||
// function cleanFilename($filename) {
|
||||
// return preg_replace('/[^a-zA-Z0-9_\-]/', '_', $filename);
|
||||
// }
|
||||
|
||||
// Функция для преобразования Markdown в чистый текст с форматированием абзацев
|
||||
function markdownToPlainText($markdown) {
|
||||
// Обрабатываем диалоги (заменяем - на —)
|
||||
$markdown = preg_replace('/^- (.+)$/m', "— $1", $markdown);
|
||||
|
||||
// Убираем Markdown разметку
|
||||
$text = $markdown;
|
||||
|
||||
// Убираем заголовки
|
||||
$text = preg_replace('/^#+\s+/m', '', $text);
|
||||
|
||||
// Убираем жирный и курсив
|
||||
$text = preg_replace('/\*\*(.*?)\*\*/', '$1', $text);
|
||||
$text = preg_replace('/\*(.*?)\*/', '$1', $text);
|
||||
$text = preg_replace('/__(.*?)__/', '$1', $text);
|
||||
$text = preg_replace('/_(.*?)_/', '$1', $text);
|
||||
|
||||
// Убираем зачеркивание
|
||||
$text = preg_replace('/~~(.*?)~~/', '$1', $text);
|
||||
|
||||
// Убираем код
|
||||
$text = preg_replace('/`(.*?)`/', '$1', $text);
|
||||
$text = preg_replace('/```.*?\n(.*?)```/s', '$1', $text);
|
||||
|
||||
// Убираем ссылки
|
||||
$text = preg_replace('/\[(.*?)\]\(.*?\)/', '$1', $text);
|
||||
|
||||
// Обрабатываем списки
|
||||
$text = preg_replace('/^[\*\-+]\s+/m', '', $text);
|
||||
$text = preg_replace('/^\d+\.\s+/m', '', $text);
|
||||
|
||||
// Обрабатываем цитаты
|
||||
$text = preg_replace('/^>\s+/m', '', $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
// Функция для форматирования текста с сохранением абзацев и диалогов
|
||||
function formatPlainText($text) {
|
||||
$lines = explode("\n", $text);
|
||||
$formatted = [];
|
||||
$in_paragraph = false;
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
|
||||
if (empty($line)) {
|
||||
if ($in_paragraph) {
|
||||
$formatted[] = ''; // Пустая строка для разделения абзацев
|
||||
$in_paragraph = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Диалоги начинаются с —
|
||||
if (str_starts_with($line, '—')) {
|
||||
if ($in_paragraph) {
|
||||
$formatted[] = ''; // Разделяем абзацы перед диалогом
|
||||
}
|
||||
$formatted[] = $line;
|
||||
$formatted[] = ''; // Пустая строка после диалога
|
||||
$in_paragraph = false;
|
||||
} else {
|
||||
// Обычный текст
|
||||
$formatted[] = $line;
|
||||
$in_paragraph = true;
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", array_filter($formatted, function($line) {
|
||||
return $line !== '' || !empty($line);
|
||||
}));
|
||||
}
|
||||
|
||||
// Обработка экспорта
|
||||
switch ($format) {
|
||||
case 'pdf':
|
||||
exportPDF($book, $chapters, $is_public);
|
||||
break;
|
||||
case 'docx':
|
||||
exportDOCX($book, $chapters, $is_public);
|
||||
break;
|
||||
case 'odt':
|
||||
exportODT($book, $chapters, $is_public);
|
||||
break;
|
||||
case 'html':
|
||||
exportHTML($book, $chapters, $is_public);
|
||||
break;
|
||||
case 'txt':
|
||||
exportTXT($book, $chapters, $is_public);
|
||||
break;
|
||||
default:
|
||||
$_SESSION['error'] = "Неверный формат экспорта";
|
||||
redirect($share_token ? "view_book.php?share_token=$share_token" : "book_edit.php?id=$book_id");
|
||||
}
|
||||
|
||||
function exportPDF($book, $chapters, $is_public) {
|
||||
global $Parsedown;
|
||||
|
||||
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
|
||||
|
||||
// Устанавливаем метаданные документа
|
||||
$pdf->SetCreator(APP_NAME);
|
||||
$pdf->SetAuthor($is_public ? 'Автор' : ($_SESSION['display_name'] ?? 'Автор'));
|
||||
$pdf->SetTitle($book['title']);
|
||||
$pdf->SetSubject($book['genre'] ?? '');
|
||||
|
||||
// Устанавливаем margins
|
||||
$pdf->SetMargins(15, 20, 15);
|
||||
$pdf->SetHeaderMargin(10);
|
||||
$pdf->SetFooterMargin(10);
|
||||
|
||||
// Устанавливаем авто разрыв страниц
|
||||
$pdf->SetAutoPageBreak(TRUE, 15);
|
||||
|
||||
// Добавляем страницу
|
||||
$pdf->AddPage();
|
||||
|
||||
// Устанавливаем шрифт с поддержкой кириллицы
|
||||
$pdf->SetFont('dejavusans', '', 12);
|
||||
|
||||
// Заголовок книги
|
||||
$pdf->SetFont('dejavusans', 'B', 16);
|
||||
$pdf->Cell(0, 10, $book['title'], 0, 1, 'C');
|
||||
$pdf->Ln(5);
|
||||
|
||||
// Жанр
|
||||
if (!empty($book['genre'])) {
|
||||
$pdf->SetFont('dejavusans', 'I', 12);
|
||||
$pdf->Cell(0, 10, 'Жанр: ' . $book['genre'], 0, 1, 'C');
|
||||
$pdf->Ln(5);
|
||||
}
|
||||
|
||||
// Описание
|
||||
if (!empty($book['description'])) {
|
||||
$pdf->SetFont('dejavusans', '', 12);
|
||||
$pdf->MultiCell(0, 8, $book['description'], 0, 'J');
|
||||
$pdf->Ln(10);
|
||||
}
|
||||
|
||||
// Разделитель
|
||||
$pdf->Line(15, $pdf->GetY(), 195, $pdf->GetY());
|
||||
$pdf->Ln(10);
|
||||
|
||||
// Главы
|
||||
foreach ($chapters as $index => $chapter) {
|
||||
$pdf->SetFont('dejavusans', '', 12);
|
||||
|
||||
// Название главы
|
||||
$pdf->SetFont('dejavusans', 'B', 14);
|
||||
$pdf->Cell(0, 8, $chapter['title'], 0, 1);
|
||||
$pdf->Ln(2);
|
||||
|
||||
// Контент главы (форматированный HTML)
|
||||
$pdf->SetFont('dejavusans', '', 11);
|
||||
$htmlContent = $Parsedown->text($chapter['content']);
|
||||
$pdf->writeHTML($htmlContent, true, false, true, false, '');
|
||||
|
||||
$pdf->Ln(8);
|
||||
|
||||
// Разделитель между главами (кроме последней)
|
||||
if ($index < count($chapters) - 1) {
|
||||
$pdf->Line(15, $pdf->GetY(), 195, $pdf->GetY());
|
||||
$pdf->Ln(8);
|
||||
}
|
||||
}
|
||||
|
||||
// Футер с информацией
|
||||
$pdf->SetY(-25);
|
||||
$pdf->SetFont('dejavusans', 'I', 8);
|
||||
$pdf->Cell(0, 6, 'Экспортировано из ' . APP_NAME . ' - ' . date('d.m.Y H:i'), 0, 1, 'C');
|
||||
$pdf->Cell(0, 6, 'Всего глав: ' . count($chapters) . ' | Всего слов: ' . array_sum(array_column($chapters, 'word_count')), 0, 1, 'C');
|
||||
|
||||
// Отправляем файл
|
||||
$filename = cleanFilename($book['title']) . '.pdf';
|
||||
$pdf->Output($filename, 'D');
|
||||
exit;
|
||||
}
|
||||
|
||||
function exportDOCX($book, $chapters, $is_public) {
|
||||
global $Parsedown;
|
||||
|
||||
$phpWord = new PhpWord();
|
||||
|
||||
// Стили документа
|
||||
$phpWord->setDefaultFontName('Times New Roman');
|
||||
$phpWord->setDefaultFontSize(12);
|
||||
|
||||
// Секция документа
|
||||
$section = $phpWord->addSection();
|
||||
|
||||
// Заголовок книги
|
||||
$section->addText($book['title'], ['bold' => true, 'size' => 16], ['alignment' => 'center']);
|
||||
$section->addTextBreak(2);
|
||||
|
||||
// Жанр
|
||||
if (!empty($book['genre'])) {
|
||||
$section->addText('Жанр: ' . $book['genre'], ['italic' => true], ['alignment' => 'center']);
|
||||
$section->addTextBreak(1);
|
||||
}
|
||||
|
||||
// Описание
|
||||
if (!empty($book['description'])) {
|
||||
$section->addText($book['description']);
|
||||
$section->addTextBreak(2);
|
||||
}
|
||||
|
||||
// Разделитель
|
||||
$section->addText('СОДЕРЖАНИЕ', ['bold' => true, 'size' => 14], ['alignment' => 'center']);
|
||||
$section->addTextBreak(2);
|
||||
|
||||
// Главы
|
||||
foreach ($chapters as $index => $chapter) {
|
||||
// Заголовок главы
|
||||
$section->addText($chapter['title'], ['bold' => true, 'size' => 14]);
|
||||
|
||||
// Контент главы (форматированный HTML)
|
||||
$htmlContent = $Parsedown->text($chapter['content']);
|
||||
|
||||
// Упрощенное добавление HTML контента
|
||||
$plainContent = strip_tags($htmlContent);
|
||||
$paragraphs = explode("\n\n", $plainContent);
|
||||
|
||||
foreach ($paragraphs as $paragraph) {
|
||||
if (trim($paragraph)) {
|
||||
$section->addText($paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
// Разрыв страницы между главами (кроме последней)
|
||||
if ($index < count($chapters) - 1) {
|
||||
$section->addPageBreak();
|
||||
}
|
||||
}
|
||||
|
||||
// Футер
|
||||
$section->addTextBreak(2);
|
||||
$section->addText('Экспортировано из ' . APP_NAME . ' - ' . date('d.m.Y H:i'), ['italic' => true, 'size' => 9]);
|
||||
$section->addText('Всего глав: ' . count($chapters) . ' | Всего слов: ' . array_sum(array_column($chapters, 'word_count')), ['italic' => true, 'size' => 9]);
|
||||
|
||||
// Сохраняем и отправляем
|
||||
$filename = cleanFilename($book['title']) . '.docx';
|
||||
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
|
||||
$objWriter = IOFactory::createWriter($phpWord, 'Word2007');
|
||||
$objWriter->save('php://output');
|
||||
exit;
|
||||
}
|
||||
|
||||
function exportODT($book, $chapters, $is_public) {
|
||||
global $Parsedown;
|
||||
|
||||
$phpWord = new PhpWord();
|
||||
|
||||
// Стили документа
|
||||
$phpWord->setDefaultFontName('Liberation Serif');
|
||||
$phpWord->setDefaultFontSize(12);
|
||||
|
||||
// Секция документа
|
||||
$section = $phpWord->addSection();
|
||||
|
||||
// Заголовок книги
|
||||
$section->addText($book['title'], ['bold' => true, 'size' => 16], ['alignment' => 'center']);
|
||||
$section->addTextBreak(2);
|
||||
|
||||
// Жанр
|
||||
if (!empty($book['genre'])) {
|
||||
$section->addText('Жанр: ' . $book['genre'], ['italic' => true], ['alignment' => 'center']);
|
||||
$section->addTextBreak(1);
|
||||
}
|
||||
|
||||
// Описание
|
||||
if (!empty($book['description'])) {
|
||||
$section->addText($book['description']);
|
||||
$section->addTextBreak(2);
|
||||
}
|
||||
|
||||
// Главы
|
||||
foreach ($chapters as $index => $chapter) {
|
||||
// Заголовок главы
|
||||
$section->addText($chapter['title'], ['bold' => true, 'size' => 14]);
|
||||
|
||||
// Контент главы (форматированный HTML)
|
||||
$htmlContent = $Parsedown->text($chapter['content']);
|
||||
$plainContent = strip_tags($htmlContent);
|
||||
$paragraphs = explode("\n\n", $plainContent);
|
||||
|
||||
foreach ($paragraphs as $paragraph) {
|
||||
if (trim($paragraph)) {
|
||||
$section->addText($paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
$section->addTextBreak(2);
|
||||
}
|
||||
|
||||
// Футер
|
||||
$section->addTextBreak(2);
|
||||
$section->addText('Экспортировано из ' . APP_NAME . ' - ' . date('d.m.Y H:i'), ['italic' => true, 'size' => 9]);
|
||||
$section->addText('Всего глав: ' . count($chapters) . ' | Всего слов: ' . array_sum(array_column($chapters, 'word_count')), ['italic' => true, 'size' => 9]);
|
||||
|
||||
// Сохраняем и отправляем
|
||||
$filename = cleanFilename($book['title']) . '.odt';
|
||||
header('Content-Type: application/vnd.oasis.opendocument.text');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
|
||||
$objWriter = IOFactory::createWriter($phpWord, 'ODText');
|
||||
$objWriter->save('php://output');
|
||||
exit;
|
||||
}
|
||||
|
||||
function exportHTML($book, $chapters, $is_public) {
|
||||
global $Parsedown;
|
||||
|
||||
$html = '<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>' . htmlspecialchars($book['title']) . '</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Times New Roman", serif;
|
||||
line-height: 1.6;
|
||||
margin: 40px;
|
||||
max-width: 800px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
color: #333;
|
||||
}
|
||||
.book-title {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.book-genre {
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.book-description {
|
||||
background: #f8f9fa;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
margin: 20px 0;
|
||||
border-left: 4px solid #007bff;
|
||||
}
|
||||
.chapter-title {
|
||||
border-bottom: 2px solid #007bff;
|
||||
padding-bottom: 10px;
|
||||
margin-top: 30px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.chapter-content {
|
||||
margin: 20px 0;
|
||||
text-align: justify;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
.chapter-content h1, .chapter-content h2, .chapter-content h3 {
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.chapter-content p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.chapter-content blockquote {
|
||||
border-left: 4px solid #007bff;
|
||||
padding-left: 15px;
|
||||
margin-left: 0;
|
||||
color: #555;
|
||||
font-style: italic;
|
||||
}
|
||||
.chapter-content code {
|
||||
background: #f5f5f5;
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.chapter-content pre {
|
||||
background: #f5f5f5;
|
||||
padding: 1rem;
|
||||
border-radius: 5px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.chapter-content ul, .chapter-content ol {
|
||||
margin-bottom: 1rem;
|
||||
padding-left: 2rem;
|
||||
}
|
||||
.chapter-content table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.chapter-content th, .chapter-content td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
.chapter-content th {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.dialogue {
|
||||
margin-left: 2rem;
|
||||
font-style: italic;
|
||||
color: #2c5aa0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="book-title">' . htmlspecialchars($book['title']) . '</div>';
|
||||
|
||||
if (!empty($book['genre'])) {
|
||||
$html .= '<div class="book-genre">Жанр: ' . htmlspecialchars($book['genre']) . '</div>';
|
||||
}
|
||||
|
||||
if (!empty($book['description'])) {
|
||||
$html .= '<div class="book-description">' . nl2br(htmlspecialchars($book['description'])) . '</div>';
|
||||
}
|
||||
|
||||
$html .= '<hr style="margin: 30px 0;">';
|
||||
|
||||
foreach ($chapters as $index => $chapter) {
|
||||
$html .= '<div class="chapter">';
|
||||
$html .= '<div class="chapter-title">' . htmlspecialchars($chapter['title']) . '</div>';
|
||||
|
||||
$htmlContent = $Parsedown->text($chapter['content']);
|
||||
$html .= '<div class="chapter-content">' . $htmlContent . '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
if ($index < count($chapters) - 1) {
|
||||
$html .= '<hr style="margin: 30px 0;">';
|
||||
}
|
||||
}
|
||||
|
||||
$html .= '<div class="footer">
|
||||
Экспортировано из ' . APP_NAME . ' - ' . date('d.m.Y H:i') . '<br>
|
||||
Всего глав: ' . count($chapters) . ' | Всего слов: ' . array_sum(array_column($chapters, 'word_count')) . '
|
||||
</div>
|
||||
</body>
|
||||
</html>';
|
||||
|
||||
$filename = cleanFilename($book['title']) . '.html';
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
echo $html;
|
||||
exit;
|
||||
}
|
||||
|
||||
function exportTXT($book, $chapters, $is_public) {
|
||||
$content = "=" . str_repeat("=", 60) . "=\n";
|
||||
$content .= str_pad($book['title'], 60, " ", STR_PAD_BOTH) . "\n";
|
||||
$content .= "=" . str_repeat("=", 60) . "=\n\n";
|
||||
|
||||
if (!empty($book['genre'])) {
|
||||
$content .= "Жанр: " . $book['genre'] . "\n\n";
|
||||
}
|
||||
|
||||
if (!empty($book['description'])) {
|
||||
$content .= "ОПИСАНИЕ:\n";
|
||||
$content .= wordwrap($book['description'], 80) . "\n\n";
|
||||
}
|
||||
|
||||
$content .= str_repeat("-", 80) . "\n\n";
|
||||
|
||||
foreach ($chapters as $index => $chapter) {
|
||||
$content .= $chapter['title'] . "\n";
|
||||
$content .= str_repeat("-", 40) . "\n\n";
|
||||
|
||||
// Форматируем текст для TXT
|
||||
$plainText = markdownToPlainText($chapter['content']);
|
||||
$formattedText = formatPlainText($plainText);
|
||||
$content .= wordwrap($formattedText, 80) . "\n\n";
|
||||
|
||||
if ($index < count($chapters) - 1) {
|
||||
$content .= str_repeat("-", 80) . "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
$content .= "\n" . str_repeat("=", 80) . "\n";
|
||||
$content .= "Экспортировано из " . APP_NAME . " - " . date('d.m.Y H:i') . "\n";
|
||||
$content .= "Всего глав: " . count($chapters) . " | Всего слов: " . array_sum(array_column($chapters, 'word_count')) . "\n";
|
||||
$content .= str_repeat("=", 80) . "\n";
|
||||
|
||||
$filename = cleanFilename($book['title']) . '.txt';
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
echo $content;
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
// includes/functions.php
|
||||
|
||||
function is_logged_in() {
|
||||
return isset($_SESSION['user_id']);
|
||||
}
|
||||
|
||||
function require_login() {
|
||||
if (!is_logged_in()) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function generate_csrf_token() {
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
return $_SESSION['csrf_token'];
|
||||
}
|
||||
|
||||
function verify_csrf_token($token) {
|
||||
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
|
||||
}
|
||||
|
||||
|
||||
function e($string) {
|
||||
return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
function redirect($url) {
|
||||
header("Location: " . $url);
|
||||
exit;
|
||||
}
|
||||
|
||||
function transliterate($text) {
|
||||
$cyr = [
|
||||
'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п',
|
||||
'р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я',
|
||||
'А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П',
|
||||
'Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я',
|
||||
' ',',','!','?',':',';','"','\'','(',')','[',']','{','}'
|
||||
];
|
||||
|
||||
$lat = [
|
||||
'a','b','v','g','d','e','yo','zh','z','i','y','k','l','m','n','o','p',
|
||||
'r','s','t','u','f','h','ts','ch','sh','sht','a','i','y','e','yu','ya',
|
||||
'A','B','V','G','D','E','Yo','Zh','Z','I','Y','K','L','M','N','O','P',
|
||||
'R','S','T','U','F','H','Ts','Ch','Sh','Sht','A','I','Y','E','Yu','Ya',
|
||||
'_','_','_','_','_','_','_','_','_','_','_','_','_','_'
|
||||
];
|
||||
|
||||
return str_replace($cyr, $lat, $text);
|
||||
}
|
||||
|
||||
// Функция для очистки имени файла с транслитерацией
|
||||
function cleanFilename($filename) {
|
||||
// Сначала транслитерируем
|
||||
$filename = transliterate($filename);
|
||||
|
||||
// Затем убираем оставшиеся недопустимые символы
|
||||
$filename = preg_replace('/[^a-zA-Z0-9_\-\.]/', '_', $filename);
|
||||
|
||||
// Убираем множественные подчеркивания
|
||||
$filename = preg_replace('/_{2,}/', '_', $filename);
|
||||
|
||||
// Убираем подчеркивания с начала и конца
|
||||
$filename = trim($filename, '_');
|
||||
|
||||
// Если после очистки имя файла пустое, используем стандартное
|
||||
if (empty($filename)) {
|
||||
$filename = 'book';
|
||||
}
|
||||
|
||||
// Ограничиваем длину имени файла
|
||||
if (strlen($filename) > 100) {
|
||||
$filename = substr($filename, 0, 100);
|
||||
}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
require_once 'Parsedown.php';
|
||||
|
||||
class ParsedownExtra extends Parsedown {
|
||||
protected function blockQuote($Line) {
|
||||
// Îáðàáîòêà äèàëîãîâ
|
||||
if (preg_match('/^—\s+/', $Line['text'])) {
|
||||
return array(
|
||||
'element' => array(
|
||||
'name' => 'div',
|
||||
'attributes' => array('class' => 'dialogue'),
|
||||
'text' => ltrim($Line['text'], '— ')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return parent::blockQuote($Line);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
|
||||
if (is_logged_in()) {
|
||||
redirect('dashboard.php');
|
||||
} else {
|
||||
redirect('login.php');
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
|
||||
// Если пользователь уже авторизован, перенаправляем на dashboard
|
||||
if (is_logged_in()) {
|
||||
redirect('dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$error = "Ошибка безопасности";
|
||||
} else {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
$error = 'Пожалуйста, введите имя пользователя и пароль';
|
||||
} else {
|
||||
$userModel = new User($pdo);
|
||||
$user = $userModel->findByUsername($username);
|
||||
|
||||
if ($user && $userModel->verifyPassword($password, $user['password_hash'])) {
|
||||
if (!$user['is_active']) {
|
||||
$error = 'Ваш аккаунт деактивирован или ожидает активации администратором.';
|
||||
} else {
|
||||
// Успешный вход
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['display_name'] = $user['display_name'] ?: $user['username'];
|
||||
|
||||
// Обновляем время последнего входа
|
||||
$userModel->updateLastLogin($user['id']);
|
||||
|
||||
$_SESSION['success'] = 'Добро пожаловать, ' . e($user['display_name'] ?: $user['username']) . '!';
|
||||
redirect('dashboard.php');
|
||||
}
|
||||
} else {
|
||||
$error = 'Неверное имя пользователя или пароль';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$page_title = 'Вход в систему';
|
||||
include 'views/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1>Вход в систему</h1>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-error">
|
||||
<?= e($error) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION['success'])): ?>
|
||||
<div class="alert alert-success">
|
||||
<?= e($_SESSION['success']) ?>
|
||||
<?php unset($_SESSION['success']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" style="max-width: 400px; margin: 0 auto;">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label for="username" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Имя пользователя
|
||||
</label>
|
||||
<input type="text" id="username" name="username"
|
||||
value="<?= e($_POST['username'] ?? '') ?>"
|
||||
placeholder="Введите имя пользователя"
|
||||
style="width: 100%;"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<label for="password" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Пароль
|
||||
</label>
|
||||
<input type="password" id="password" name="password"
|
||||
placeholder="Введите пароль"
|
||||
style="width: 100%;"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="contrast" style="width: 100%;">
|
||||
🔑 Войти
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div style="text-align: center; margin-top: 1rem;">
|
||||
<p>Нет аккаунта? <a href="register.php">Зарегистрируйтесь здесь</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
|
||||
// Очищаем все данные сессии
|
||||
$_SESSION = [];
|
||||
|
||||
// Если нужно полностью уничтожить сессию
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
$params["secure"], $params["httponly"]
|
||||
);
|
||||
}
|
||||
|
||||
// Уничтожаем сессию
|
||||
session_destroy();
|
||||
|
||||
// Редирект на страницу входа
|
||||
redirect('login.php');
|
||||
?>
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
// models/Book.php
|
||||
|
||||
class Book {
|
||||
private $pdo;
|
||||
|
||||
public function __construct($pdo) {
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
public function findById($id) {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM books WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function findByShareToken($share_token) {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM books WHERE share_token = ?");
|
||||
$stmt->execute([$share_token]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function findByUser($user_id) {
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT b.*,
|
||||
COUNT(c.id) as chapter_count,
|
||||
COALESCE(SUM(c.word_count), 0) as total_words
|
||||
FROM books b
|
||||
LEFT JOIN chapters c ON b.id = c.book_id
|
||||
WHERE b.user_id = ?
|
||||
GROUP BY b.id
|
||||
ORDER BY b.created_at DESC
|
||||
");
|
||||
$stmt->execute([$user_id]);
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function create($data) {
|
||||
$share_token = bin2hex(random_bytes(16));
|
||||
|
||||
$stmt = $this->pdo->prepare("
|
||||
INSERT INTO books (title, description, genre, user_id, series_id, sort_order_in_series, share_token)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
return $stmt->execute([
|
||||
$data['title'],
|
||||
$data['description'] ?? null,
|
||||
$data['genre'] ?? null,
|
||||
$data['user_id'],
|
||||
$data['series_id'] ?? null,
|
||||
$data['sort_order_in_series'] ?? null,
|
||||
$share_token
|
||||
]);
|
||||
}
|
||||
|
||||
public function update($id, $data) {
|
||||
$stmt = $this->pdo->prepare("
|
||||
UPDATE books
|
||||
SET title = ?, description = ?, genre = ?, series_id = ?, sort_order_in_series = ?
|
||||
WHERE id = ? AND user_id = ?
|
||||
");
|
||||
return $stmt->execute([
|
||||
$data['title'],
|
||||
$data['description'] ?? null,
|
||||
$data['genre'] ?? null,
|
||||
$data['series_id'] ?? null,
|
||||
$data['sort_order_in_series'] ?? null,
|
||||
$id,
|
||||
$data['user_id']
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete($id, $user_id) {
|
||||
try {
|
||||
$this->pdo->beginTransaction();
|
||||
|
||||
// Удаляем главы книги (сработает CASCADE, но лучше явно)
|
||||
$stmt = $this->pdo->prepare("DELETE FROM chapters WHERE book_id = ?");
|
||||
$stmt->execute([$id]);
|
||||
|
||||
// Удаляем саму книгу
|
||||
$stmt = $this->pdo->prepare("DELETE FROM books WHERE id = ? AND user_id = ?");
|
||||
$result = $stmt->execute([$id, $user_id]);
|
||||
|
||||
$this->pdo->commit();
|
||||
return $result;
|
||||
} catch (Exception $e) {
|
||||
$this->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function userOwnsBook($book_id, $user_id) {
|
||||
$stmt = $this->pdo->prepare("SELECT id FROM books WHERE id = ? AND user_id = ?");
|
||||
$stmt->execute([$book_id, $user_id]);
|
||||
return $stmt->fetch() !== false;
|
||||
}
|
||||
|
||||
public function generateNewShareToken($book_id) {
|
||||
$new_token = bin2hex(random_bytes(16));
|
||||
$stmt = $this->pdo->prepare("UPDATE books SET share_token = ? WHERE id = ?");
|
||||
$success = $stmt->execute([$new_token, $book_id]);
|
||||
return $success ? $new_token : false;
|
||||
}
|
||||
|
||||
public function getPublishedChapters($book_id) {
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT * FROM chapters
|
||||
WHERE book_id = ? AND status = 'published'
|
||||
ORDER BY sort_order, created_at
|
||||
");
|
||||
$stmt->execute([$book_id]);
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
// models/Chapter.php
|
||||
|
||||
class Chapter {
|
||||
private $pdo;
|
||||
|
||||
public function __construct($pdo) {
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
public function findById($id) {
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT c.*, b.user_id, b.title as book_title
|
||||
FROM chapters c
|
||||
JOIN books b ON c.book_id = b.id
|
||||
WHERE c.id = ?
|
||||
");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function findByBook($book_id) {
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT * FROM chapters
|
||||
WHERE book_id = ?
|
||||
ORDER BY sort_order, created_at
|
||||
");
|
||||
$stmt->execute([$book_id]);
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function create($data) {
|
||||
// Сначала получаем максимальный sort_order для этой книги
|
||||
$stmt = $this->pdo->prepare("SELECT MAX(sort_order) as max_order FROM chapters WHERE book_id = ?");
|
||||
$stmt->execute([$data['book_id']]);
|
||||
$result = $stmt->fetch();
|
||||
$next_order = ($result['max_order'] ?? 0) + 1;
|
||||
|
||||
// Подсчитываем количество слов
|
||||
$word_count = $this->countWords($data['content']);
|
||||
|
||||
$stmt = $this->pdo->prepare("
|
||||
INSERT INTO chapters (book_id, title, content, sort_order, word_count, status)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
return $stmt->execute([
|
||||
$data['book_id'],
|
||||
$data['title'],
|
||||
$data['content'],
|
||||
$next_order,
|
||||
$word_count,
|
||||
$data['status'] ?? 'draft'
|
||||
]);
|
||||
}
|
||||
|
||||
public function update($id, $data) {
|
||||
$word_count = $this->countWords($data['content']);
|
||||
|
||||
$stmt = $this->pdo->prepare("
|
||||
UPDATE chapters
|
||||
SET title = ?, content = ?, word_count = ?, status = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
");
|
||||
return $stmt->execute([
|
||||
$data['title'],
|
||||
$data['content'],
|
||||
$word_count,
|
||||
$data['status'] ?? 'draft',
|
||||
$id
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete($id) {
|
||||
$stmt = $this->pdo->prepare("DELETE FROM chapters WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
public function updateSortOrder($chapter_id, $new_order) {
|
||||
$stmt = $this->pdo->prepare("UPDATE chapters SET sort_order = ? WHERE id = ?");
|
||||
return $stmt->execute([$new_order, $chapter_id]);
|
||||
}
|
||||
|
||||
private function countWords($text) {
|
||||
// Простой подсчет слов (можно улучшить)
|
||||
$text = strip_tags($text);
|
||||
$text = preg_replace('/[^\p{L}\p{N}\s]/u', ' ', $text);
|
||||
$words = preg_split('/\s+/', $text);
|
||||
$words = array_filter($words);
|
||||
return count($words);
|
||||
}
|
||||
|
||||
public function userOwnsChapter($chapter_id, $user_id) {
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT c.id
|
||||
FROM chapters c
|
||||
JOIN books b ON c.book_id = b.id
|
||||
WHERE c.id = ? AND b.user_id = ?
|
||||
");
|
||||
$stmt->execute([$chapter_id, $user_id]);
|
||||
return $stmt->fetch() !== false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
// models/User.php
|
||||
|
||||
class User {
|
||||
private $pdo;
|
||||
|
||||
public function __construct($pdo) {
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
public function findById($id) {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function findByUsername($username) {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE username = ?");
|
||||
$stmt->execute([$username]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function findByEmail($email) {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE email = ?");
|
||||
$stmt->execute([$email]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function findAll() {
|
||||
$stmt = $this->pdo->prepare("SELECT id, username, display_name, email, created_at, last_login, is_active FROM users ORDER BY created_at DESC");
|
||||
$stmt->execute();
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function create($data) {
|
||||
$password_hash = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
|
||||
// Определяем статус активности: по умолчанию неактивен, если не указано иное
|
||||
$is_active = $data['is_active'] ?? 0;
|
||||
|
||||
$stmt = $this->pdo->prepare("
|
||||
INSERT INTO users (username, display_name, email, password_hash, is_active)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
");
|
||||
|
||||
return $stmt->execute([
|
||||
$data['username'],
|
||||
$data['display_name'] ?? $data['username'],
|
||||
$data['email'] ?? null,
|
||||
$password_hash,
|
||||
$is_active
|
||||
]);
|
||||
}
|
||||
|
||||
public function update($id, $data) {
|
||||
$sql = "UPDATE users SET display_name = ?, email = ?";
|
||||
$params = [$data['display_name'], $data['email']];
|
||||
|
||||
if (!empty($data['password'])) {
|
||||
$sql .= ", password_hash = ?";
|
||||
$params[] = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
}
|
||||
|
||||
$sql .= " WHERE id = ?";
|
||||
$params[] = $id;
|
||||
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
return $stmt->execute($params);
|
||||
}
|
||||
|
||||
public function updateStatus($id, $is_active) {
|
||||
$stmt = $this->pdo->prepare("UPDATE users SET is_active = ? WHERE id = ?");
|
||||
return $stmt->execute([$is_active, $id]);
|
||||
}
|
||||
|
||||
public function delete($id) {
|
||||
$stmt = $this->pdo->prepare("DELETE FROM users WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
public function updateLastLogin($id) {
|
||||
$stmt = $this->pdo->prepare("UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
public function verifyPassword($password, $hash) {
|
||||
return password_verify($password, $hash);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
require_once 'includes/parsedown/ParsedownExtra.php';
|
||||
$Parsedown = new ParsedownExtra();;
|
||||
|
||||
$content = $_POST['content'] ?? '';
|
||||
$title = $_POST['title'] ?? 'Предпросмотр';
|
||||
|
||||
$Parsedown = new Parsedown();
|
||||
$html_content = $Parsedown->text($content);
|
||||
|
||||
$page_title = "Предпросмотр: " . e($title);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= e($page_title) ?></title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1.5.10/css/pico.min.css">
|
||||
<style>
|
||||
body {
|
||||
padding: 20px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
line-height: 1.6;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
}
|
||||
.content {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 { border-bottom: 2px solid #007bff; padding-bottom: 0.3em; }
|
||||
h2 { border-bottom: 1px solid #eaecef; padding-bottom: 0.3em; }
|
||||
p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
code {
|
||||
background: #f5f5f5;
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
}
|
||||
pre {
|
||||
background: #f5f5f5;
|
||||
padding: 1rem;
|
||||
border-radius: 5px;
|
||||
overflow-x: auto;
|
||||
border-left: 4px solid #007bff;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
blockquote {
|
||||
border-left: 4px solid #ddd;
|
||||
padding-left: 1rem;
|
||||
margin-left: 0;
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
strong { font-weight: bold; }
|
||||
em { font-style: italic; }
|
||||
u { text-decoration: underline; }
|
||||
del { text-decoration: line-through; }
|
||||
.dialogue {
|
||||
margin-left: 2rem;
|
||||
font-style: italic;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
th, td {
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1><?= e($title) ?></h1>
|
||||
<hr>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<?= $html_content ?>
|
||||
</main>
|
||||
|
||||
<footer style="margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #ddd;">
|
||||
<small>Сгенерировано <?= date('d.m.Y H:i') ?> | Markdown Preview</small>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
require_login();
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$userModel = new User($pdo);
|
||||
$user = $userModel->findById($user_id);
|
||||
|
||||
$message = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$message = "Ошибка безопасности";
|
||||
} else {
|
||||
$display_name = trim($_POST['display_name'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE users SET display_name = ?, email = ? WHERE id = ?");
|
||||
if ($stmt->execute([$display_name, $email, $user_id])) {
|
||||
$_SESSION['display_name'] = $display_name ?: $user['username'];
|
||||
$message = "Профиль обновлен";
|
||||
// Обновляем данные пользователя
|
||||
$user = $userModel->findById($user_id);
|
||||
} else {
|
||||
$message = "Ошибка при обновлении профиля";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$page_title = "Мой профиль";
|
||||
include 'views/header.php';
|
||||
?>
|
||||
|
||||
<h1>Мой профиль</h1>
|
||||
|
||||
<?php if ($message): ?>
|
||||
<div class="alert <?= strpos($message, 'Ошибка') !== false ? 'alert-error' : 'alert-success' ?>">
|
||||
<?= e($message) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<article>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label for="username" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Имя пользователя (нельзя изменить)
|
||||
</label>
|
||||
<input type="text" id="username" value="<?= e($user['username']) ?>" disabled style="width: 100%;">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label for="display_name" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Отображаемое имя
|
||||
</label>
|
||||
<input type="text" id="display_name" name="display_name"
|
||||
value="<?= e($user['display_name'] ?? $user['username']) ?>" style="width: 100%;">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<label for="email" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Email
|
||||
</label>
|
||||
<input type="email" id="email" name="email" value="<?= e($user['email'] ?? '') ?>" style="width: 100%;">
|
||||
</div>
|
||||
|
||||
<div class="profile-buttons">
|
||||
<button type="submit" class="profile-button primary">
|
||||
💾 Сохранить изменения
|
||||
</button>
|
||||
<a href="dashboard.php" class="profile-button secondary">
|
||||
↩️ Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<h3>Информация об аккаунте</h3>
|
||||
<p><strong>Дата регистрации:</strong> <?= date('d.m.Y H:i', strtotime($user['created_at'])) ?></p>
|
||||
<?php if ($user['last_login']): ?>
|
||||
<p><strong>Последний вход:</strong> <?= date('d.m.Y H:i', strtotime($user['last_login'])) ?></p>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
require_once 'config/config.php';
|
||||
|
||||
// Если пользователь уже авторизован И он не администратор (ID != 1), перенаправляем на dashboard
|
||||
if (is_logged_in() && $_SESSION['user_id'] != 1) {
|
||||
redirect('dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
$success = '';
|
||||
|
||||
// Проверяем, является ли текущий пользователь администратором
|
||||
$is_admin = is_logged_in() && $_SESSION['user_id'] == 1;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$error = "Ошибка безопасности";
|
||||
} else {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$display_name = trim($_POST['display_name'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
$confirm_password = $_POST['confirm_password'] ?? '';
|
||||
|
||||
// Валидация
|
||||
if (empty($username) || empty($password)) {
|
||||
$error = 'Имя пользователя и пароль обязательны для заполнения';
|
||||
} elseif ($password !== $confirm_password) {
|
||||
$error = 'Пароли не совпадают';
|
||||
} elseif (strlen($password) < 6) {
|
||||
$error = 'Пароль должен содержать не менее 6 символов';
|
||||
} elseif (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
|
||||
$error = 'Имя пользователя может содержать только латинские буквы, цифры и символ подчеркивания';
|
||||
} else {
|
||||
$userModel = new User($pdo);
|
||||
|
||||
// Проверяем, не занят ли username
|
||||
if ($userModel->findByUsername($username)) {
|
||||
$error = 'Это имя пользователя уже занято';
|
||||
} elseif (!empty($email) && $userModel->findByEmail($email)) {
|
||||
$error = 'Этот email уже используется';
|
||||
} else {
|
||||
// Подготавливаем данные для создания пользователя
|
||||
$user_data = [
|
||||
'username' => $username,
|
||||
'display_name' => $display_name ?: $username,
|
||||
'email' => $email,
|
||||
'password' => $password
|
||||
];
|
||||
|
||||
// Если пользователя создает администратор - сразу активный
|
||||
// Если пользователь регистрируется сам - неактивный (требует активации)
|
||||
if ($is_admin) {
|
||||
$user_data['is_active'] = 1;
|
||||
} else {
|
||||
$user_data['is_active'] = 0;
|
||||
}
|
||||
|
||||
// Создаем пользователя
|
||||
$success = $userModel->create($user_data);
|
||||
|
||||
if ($success) {
|
||||
if ($is_admin) {
|
||||
$_SESSION['success'] = 'Пользователь успешно создан и активирован';
|
||||
redirect('admin/users.php');
|
||||
} else {
|
||||
$_SESSION['success'] = 'Регистрация прошла успешно. Ваш аккаунт ожидает активации администратором.';
|
||||
redirect('login.php');
|
||||
}
|
||||
} else {
|
||||
$error = 'Произошла ошибка при регистрации. Попробуйте еще раз.';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$page_title = $is_admin ? 'Добавление пользователя' : 'Регистрация';
|
||||
include 'views/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1><?= $is_admin ? 'Добавление пользователя' : 'Регистрация' ?></h1>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-error">
|
||||
<?= e($error) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success">
|
||||
<?= e($success) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" style="max-width: 500px; margin: 0 auto;">
|
||||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label for="username" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Имя пользователя *
|
||||
</label>
|
||||
<input type="text" id="username" name="username"
|
||||
value="<?= e($_POST['username'] ?? '') ?>"
|
||||
placeholder="Введите имя пользователя"
|
||||
style="width: 100%;"
|
||||
required
|
||||
pattern="[a-zA-Z0-9_]+"
|
||||
title="Только латинские буквы, цифры и символ подчеркивания">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label for="display_name" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Отображаемое имя
|
||||
</label>
|
||||
<input type="text" id="display_name" name="display_name"
|
||||
value="<?= e($_POST['display_name'] ?? '') ?>"
|
||||
placeholder="Введите отображаемое имя"
|
||||
style="width: 100%;">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label for="email" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Email
|
||||
</label>
|
||||
<input type="email" id="email" name="email"
|
||||
value="<?= e($_POST['email'] ?? '') ?>"
|
||||
placeholder="Введите email"
|
||||
style="width: 100%;">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label for="password" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Пароль *
|
||||
</label>
|
||||
<input type="password" id="password" name="password"
|
||||
placeholder="Введите пароль (минимум 6 символов)"
|
||||
style="width: 100%;"
|
||||
required
|
||||
minlength="6">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<label for="confirm_password" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
|
||||
Подтверждение пароля *
|
||||
</label>
|
||||
<input type="password" id="confirm_password" name="confirm_password"
|
||||
placeholder="Повторите пароль"
|
||||
style="width: 100%;"
|
||||
required
|
||||
minlength="6">
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<button type="submit" class="contrast" style="flex: 1;">
|
||||
<?= $is_admin ? '👥 Добавить пользователя' : '📝 Зарегистрироваться' ?>
|
||||
</button>
|
||||
|
||||
<?php if ($is_admin): ?>
|
||||
<a href="admin/users.php" class="secondary" style="display: flex; align-items: center; justify-content: center; padding: 0.75rem; text-decoration: none;">
|
||||
❌ Отмена
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if (!$is_admin): ?>
|
||||
<div style="text-align: center; margin-top: 1rem;">
|
||||
<p>Уже есть аккаунт? <a href="login.php">Войдите здесь</a></p>
|
||||
<?php if (!$is_admin): ?>
|
||||
<p style="color: #666; font-size: 0.9em; margin-top: 0.5rem;">
|
||||
<strong>Примечание:</strong> После регистрации ваш аккаунт должен быть активирован администратором.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php include 'views/footer.php'; ?>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException($err);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitfc3c92cecb1ffdb92cb5808b88609e81::getLoader();
|
||||
|
|
@ -0,0 +1,579 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var string|null */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array<string, list<string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* List of PSR-0 prefixes
|
||||
*
|
||||
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||
*
|
||||
* @var array<string, array<string, list<string>>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var string|null */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var array<string, self>
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param string|null $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string> Array of classname => path
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $classMap Class to filename map
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||
*
|
||||
* @return array<string, self>
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,396 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
|
||||
* @internal
|
||||
*/
|
||||
private static $selfDir = null;
|
||||
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $installedIsLocalDir;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
|
||||
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
|
||||
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
|
||||
// so we have to assume it does not, and that may result in duplicate data being returned when listing
|
||||
// all installed packages for example
|
||||
self::$installedIsLocalDir = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private static function getSelfDir()
|
||||
{
|
||||
if (self::$selfDir === null) {
|
||||
self::$selfDir = strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
|
||||
return self::$selfDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
$copiedLocalDir = false;
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
$selfDir = self::getSelfDir();
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
$vendorDir = strtr($vendorDir, '\\', '/');
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
self::$installedByVendor[$vendorDir] = $required;
|
||||
$installed[] = $required;
|
||||
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
|
||||
self::$installed = $required;
|
||||
self::$installedIsLocalDir = true;
|
||||
}
|
||||
}
|
||||
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
|
||||
$copiedLocalDir = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array() && !$copiedLocalDir) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'Datamatrix' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php',
|
||||
'Dompdf\\Cpdf' => $vendorDir . '/dompdf/dompdf/lib/Cpdf.php',
|
||||
'PDF417' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/pdf417.php',
|
||||
'QRcode' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/qrcode.php',
|
||||
'TCPDF' => $vendorDir . '/tecnickcom/tcpdf/tcpdf.php',
|
||||
'TCPDF2DBarcode' => $vendorDir . '/tecnickcom/tcpdf/tcpdf_barcodes_2d.php',
|
||||
'TCPDFBarcode' => $vendorDir . '/tecnickcom/tcpdf/tcpdf_barcodes_1d.php',
|
||||
'TCPDF_COLORS' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_colors.php',
|
||||
'TCPDF_FILTERS' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_filters.php',
|
||||
'TCPDF_FONTS' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_fonts.php',
|
||||
'TCPDF_FONT_DATA' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_font_data.php',
|
||||
'TCPDF_IMAGES' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_images.php',
|
||||
'TCPDF_STATIC' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_static.php',
|
||||
);
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Svg\\' => array($vendorDir . '/phenx/php-svg-lib/src/Svg'),
|
||||
'Sabberworm\\CSS\\' => array($vendorDir . '/sabberworm/php-css-parser/src'),
|
||||
'PhpOffice\\PhpWord\\' => array($vendorDir . '/phpoffice/phpword/src/PhpWord'),
|
||||
'PhpOffice\\Math\\' => array($vendorDir . '/phpoffice/math/src/Math'),
|
||||
'Masterminds\\' => array($vendorDir . '/masterminds/html5/src'),
|
||||
'FontLib\\' => array($vendorDir . '/phenx/php-font-lib/src/FontLib'),
|
||||
'Dompdf\\' => array($vendorDir . '/dompdf/dompdf/src'),
|
||||
);
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitfc3c92cecb1ffdb92cb5808b88609e81
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitfc3c92cecb1ffdb92cb5808b88609e81', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitfc3c92cecb1ffdb92cb5808b88609e81', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitfc3c92cecb1ffdb92cb5808b88609e81::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInitfc3c92cecb1ffdb92cb5808b88609e81
|
||||
{
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'S' =>
|
||||
array (
|
||||
'Svg\\' => 4,
|
||||
'Sabberworm\\CSS\\' => 15,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'PhpOffice\\PhpWord\\' => 18,
|
||||
'PhpOffice\\Math\\' => 15,
|
||||
),
|
||||
'M' =>
|
||||
array (
|
||||
'Masterminds\\' => 12,
|
||||
),
|
||||
'F' =>
|
||||
array (
|
||||
'FontLib\\' => 8,
|
||||
),
|
||||
'D' =>
|
||||
array (
|
||||
'Dompdf\\' => 7,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Svg\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phenx/php-svg-lib/src/Svg',
|
||||
),
|
||||
'Sabberworm\\CSS\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/src',
|
||||
),
|
||||
'PhpOffice\\PhpWord\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpoffice/phpword/src/PhpWord',
|
||||
),
|
||||
'PhpOffice\\Math\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpoffice/math/src/Math',
|
||||
),
|
||||
'Masterminds\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/masterminds/html5/src',
|
||||
),
|
||||
'FontLib\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phenx/php-font-lib/src/FontLib',
|
||||
),
|
||||
'Dompdf\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/dompdf/dompdf/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'Datamatrix' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php',
|
||||
'Dompdf\\Cpdf' => __DIR__ . '/..' . '/dompdf/dompdf/lib/Cpdf.php',
|
||||
'PDF417' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/pdf417.php',
|
||||
'QRcode' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/qrcode.php',
|
||||
'TCPDF' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf.php',
|
||||
'TCPDF2DBarcode' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf_barcodes_2d.php',
|
||||
'TCPDFBarcode' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf_barcodes_1d.php',
|
||||
'TCPDF_COLORS' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_colors.php',
|
||||
'TCPDF_FILTERS' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_filters.php',
|
||||
'TCPDF_FONTS' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_fonts.php',
|
||||
'TCPDF_FONT_DATA' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_font_data.php',
|
||||
'TCPDF_IMAGES' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_images.php',
|
||||
'TCPDF_STATIC' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_static.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitfc3c92cecb1ffdb92cb5808b88609e81::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitfc3c92cecb1ffdb92cb5808b88609e81::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInitfc3c92cecb1ffdb92cb5808b88609e81::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,546 @@
|
|||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "dompdf/dompdf",
|
||||
"version": "v2.0.8",
|
||||
"version_normalized": "2.0.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/dompdf.git",
|
||||
"reference": "c20247574601700e1f7c8dab39310fca1964dc52"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/c20247574601700e1f7c8dab39310fca1964dc52",
|
||||
"reference": "c20247574601700e1f7c8dab39310fca1964dc52",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-mbstring": "*",
|
||||
"masterminds/html5": "^2.0",
|
||||
"phenx/php-font-lib": ">=0.5.4 <1.0.0",
|
||||
"phenx/php-svg-lib": ">=0.5.2 <1.0.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"mockery/mockery": "^1.3",
|
||||
"phpunit/phpunit": "^7.5 || ^8 || ^9",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "Needed to process images",
|
||||
"ext-gmagick": "Improves image processing performance",
|
||||
"ext-imagick": "Improves image processing performance",
|
||||
"ext-zlib": "Needed for pdf stream compression"
|
||||
},
|
||||
"time": "2024-04-29T13:06:17+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dompdf\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"lib/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The Dompdf Community",
|
||||
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||
"homepage": "https://github.com/dompdf/dompdf",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||
"source": "https://github.com/dompdf/dompdf/tree/v2.0.8"
|
||||
},
|
||||
"install-path": "../dompdf/dompdf"
|
||||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.10.0",
|
||||
"version_normalized": "2.10.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Masterminds/html5-php.git",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||
},
|
||||
"time": "2025-07-25T09:04:22+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Masterminds\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matt Butcher",
|
||||
"email": "technosophos@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Matt Farina",
|
||||
"email": "matt@mattfarina.com"
|
||||
},
|
||||
{
|
||||
"name": "Asmir Mustafic",
|
||||
"email": "goetas@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "An HTML5 parser and serializer.",
|
||||
"homepage": "http://masterminds.github.io/html5-php",
|
||||
"keywords": [
|
||||
"HTML5",
|
||||
"dom",
|
||||
"html",
|
||||
"parser",
|
||||
"querypath",
|
||||
"serializer",
|
||||
"xml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
|
||||
},
|
||||
"install-path": "../masterminds/html5"
|
||||
},
|
||||
{
|
||||
"name": "phenx/php-font-lib",
|
||||
"version": "0.5.6",
|
||||
"version_normalized": "0.5.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||
"reference": "a1681e9793040740a405ac5b189275059e2a9863"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a1681e9793040740a405ac5b189275059e2a9863",
|
||||
"reference": "a1681e9793040740a405ac5b189275059e2a9863",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
|
||||
},
|
||||
"time": "2024-01-29T14:45:26+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FontLib\\": "src/FontLib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Ménager",
|
||||
"email": "fabien.menager@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||
"homepage": "https://github.com/PhenX/php-font-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-font-lib/tree/0.5.6"
|
||||
},
|
||||
"install-path": "../phenx/php-font-lib"
|
||||
},
|
||||
{
|
||||
"name": "phenx/php-svg-lib",
|
||||
"version": "0.5.4",
|
||||
"version_normalized": "0.5.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||
"reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/46b25da81613a9cf43c83b2a8c2c1bdab27df691",
|
||||
"reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabberworm/php-css-parser": "^8.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
|
||||
},
|
||||
"time": "2024-04-08T12:52:34+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Svg\\": "src/Svg"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Ménager",
|
||||
"email": "fabien.menager@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse and export to PDF SVG files.",
|
||||
"homepage": "https://github.com/PhenX/php-svg-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-svg-lib/tree/0.5.4"
|
||||
},
|
||||
"install-path": "../phenx/php-svg-lib"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/math",
|
||||
"version": "0.3.0",
|
||||
"version_normalized": "0.3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/Math.git",
|
||||
"reference": "fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/Math/zipball/fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a",
|
||||
"reference": "fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-xml": "*",
|
||||
"php": "^7.1|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.88 || ^1.0.0",
|
||||
"phpunit/phpunit": "^7.0 || ^9.0"
|
||||
},
|
||||
"time": "2025-05-29T08:31:49+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\Math\\": "src/Math/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Progi1984",
|
||||
"homepage": "https://lefevre.dev"
|
||||
}
|
||||
],
|
||||
"description": "Math - Manipulate Math Formula",
|
||||
"homepage": "https://phpoffice.github.io/Math/",
|
||||
"keywords": [
|
||||
"MathML",
|
||||
"officemathml",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/Math/issues",
|
||||
"source": "https://github.com/PHPOffice/Math/tree/0.3.0"
|
||||
},
|
||||
"install-path": "../phpoffice/math"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpword",
|
||||
"version": "1.4.0",
|
||||
"version_normalized": "1.4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PHPWord.git",
|
||||
"reference": "6d75328229bc93790b37e93741adf70646cea958"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/6d75328229bc93790b37e93741adf70646cea958",
|
||||
"reference": "6d75328229bc93790b37e93741adf70646cea958",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-json": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-zip": "*",
|
||||
"php": "^7.1|^8.0",
|
||||
"phpoffice/math": "^0.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"dompdf/dompdf": "^2.0 || ^3.0",
|
||||
"ext-libxml": "*",
|
||||
"friendsofphp/php-cs-fixer": "^3.3",
|
||||
"mpdf/mpdf": "^7.0 || ^8.0",
|
||||
"phpmd/phpmd": "^2.13",
|
||||
"phpstan/phpstan": "^0.12.88 || ^1.0.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
|
||||
"phpunit/phpunit": ">=7.0",
|
||||
"symfony/process": "^4.4 || ^5.0",
|
||||
"tecnickcom/tcpdf": "^6.5"
|
||||
},
|
||||
"suggest": {
|
||||
"dompdf/dompdf": "Allows writing PDF",
|
||||
"ext-xmlwriter": "Allows writing OOXML and ODF",
|
||||
"ext-xsl": "Allows applying XSL style sheet to headers, to main document part, and to footers of an OOXML template"
|
||||
},
|
||||
"time": "2025-06-05T10:32:36+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\PhpWord\\": "src/PhpWord"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker"
|
||||
},
|
||||
{
|
||||
"name": "Gabriel Bull",
|
||||
"email": "me@gabrielbull.com",
|
||||
"homepage": "http://gabrielbull.com/"
|
||||
},
|
||||
{
|
||||
"name": "Franck Lefevre",
|
||||
"homepage": "https://rootslabs.net/blog/"
|
||||
},
|
||||
{
|
||||
"name": "Ivan Lanin",
|
||||
"homepage": "http://ivan.lanin.org"
|
||||
},
|
||||
{
|
||||
"name": "Roman Syroeshko",
|
||||
"homepage": "http://ru.linkedin.com/pub/roman-syroeshko/34/a53/994/"
|
||||
},
|
||||
{
|
||||
"name": "Antoine de Troostembergh"
|
||||
}
|
||||
],
|
||||
"description": "PHPWord - A pure PHP library for reading and writing word processing documents (OOXML, ODF, RTF, HTML, PDF)",
|
||||
"homepage": "https://phpoffice.github.io/PHPWord/",
|
||||
"keywords": [
|
||||
"ISO IEC 29500",
|
||||
"OOXML",
|
||||
"Office Open XML",
|
||||
"OpenDocument",
|
||||
"OpenXML",
|
||||
"PhpOffice",
|
||||
"PhpWord",
|
||||
"Rich Text Format",
|
||||
"WordprocessingML",
|
||||
"doc",
|
||||
"docx",
|
||||
"html",
|
||||
"odf",
|
||||
"odt",
|
||||
"office",
|
||||
"pdf",
|
||||
"php",
|
||||
"reader",
|
||||
"rtf",
|
||||
"template",
|
||||
"template processor",
|
||||
"word",
|
||||
"writer"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PHPWord/issues",
|
||||
"source": "https://github.com/PHPOffice/PHPWord/tree/1.4.0"
|
||||
},
|
||||
"install-path": "../phpoffice/phpword"
|
||||
},
|
||||
{
|
||||
"name": "sabberworm/php-css-parser",
|
||||
"version": "v8.9.0",
|
||||
"version_normalized": "8.9.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41",
|
||||
"rawr/cross-data-providers": "^2.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||
},
|
||||
"time": "2025-07-11T13:20:48+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "9.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabberworm\\CSS\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Raphael Schweikert"
|
||||
},
|
||||
{
|
||||
"name": "Oliver Klee",
|
||||
"email": "github@oliverklee.de"
|
||||
},
|
||||
{
|
||||
"name": "Jake Hotson",
|
||||
"email": "jake.github@qzdesign.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Parser for CSS Files written in PHP",
|
||||
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||
"keywords": [
|
||||
"css",
|
||||
"parser",
|
||||
"stylesheet"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0"
|
||||
},
|
||||
"install-path": "../sabberworm/php-css-parser"
|
||||
},
|
||||
{
|
||||
"name": "tecnickcom/tcpdf",
|
||||
"version": "6.10.0",
|
||||
"version_normalized": "6.10.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
||||
"reference": "ca5b6de294512145db96bcbc94e61696599c391d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ca5b6de294512145db96bcbc94e61696599c391d",
|
||||
"reference": "ca5b6de294512145db96bcbc94e61696599c391d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"php": ">=7.1.0"
|
||||
},
|
||||
"time": "2025-05-27T18:02:28+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"config",
|
||||
"include",
|
||||
"tcpdf.php",
|
||||
"tcpdf_barcodes_1d.php",
|
||||
"tcpdf_barcodes_2d.php",
|
||||
"include/tcpdf_colors.php",
|
||||
"include/tcpdf_filters.php",
|
||||
"include/tcpdf_font_data.php",
|
||||
"include/tcpdf_fonts.php",
|
||||
"include/tcpdf_images.php",
|
||||
"include/tcpdf_static.php",
|
||||
"include/barcodes/datamatrix.php",
|
||||
"include/barcodes/pdf417.php",
|
||||
"include/barcodes/qrcode.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicola Asuni",
|
||||
"email": "info@tecnick.com",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
|
||||
"homepage": "http://www.tcpdf.org/",
|
||||
"keywords": [
|
||||
"PDFD32000-2008",
|
||||
"TCPDF",
|
||||
"barcodes",
|
||||
"datamatrix",
|
||||
"pdf",
|
||||
"pdf417",
|
||||
"qrcode"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tecnickcom/TCPDF/issues",
|
||||
"source": "https://github.com/tecnickcom/TCPDF/tree/6.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"install-path": "../tecnickcom/tcpdf"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => '__root__',
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => null,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'__root__' => array(
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => null,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'dompdf/dompdf' => array(
|
||||
'pretty_version' => 'v2.0.8',
|
||||
'version' => '2.0.8.0',
|
||||
'reference' => 'c20247574601700e1f7c8dab39310fca1964dc52',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../dompdf/dompdf',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'masterminds/html5' => array(
|
||||
'pretty_version' => '2.10.0',
|
||||
'version' => '2.10.0.0',
|
||||
'reference' => 'fcf91eb64359852f00d921887b219479b4f21251',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../masterminds/html5',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phenx/php-font-lib' => array(
|
||||
'pretty_version' => '0.5.6',
|
||||
'version' => '0.5.6.0',
|
||||
'reference' => 'a1681e9793040740a405ac5b189275059e2a9863',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phenx/php-font-lib',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phenx/php-svg-lib' => array(
|
||||
'pretty_version' => '0.5.4',
|
||||
'version' => '0.5.4.0',
|
||||
'reference' => '46b25da81613a9cf43c83b2a8c2c1bdab27df691',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phenx/php-svg-lib',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpoffice/math' => array(
|
||||
'pretty_version' => '0.3.0',
|
||||
'version' => '0.3.0.0',
|
||||
'reference' => 'fc31c8f57a7a81f962cbf389fd89f4d9d06fc99a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpoffice/math',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpoffice/phpword' => array(
|
||||
'pretty_version' => '1.4.0',
|
||||
'version' => '1.4.0.0',
|
||||
'reference' => '6d75328229bc93790b37e93741adf70646cea958',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpoffice/phpword',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sabberworm/php-css-parser' => array(
|
||||
'pretty_version' => 'v8.9.0',
|
||||
'version' => '8.9.0.0',
|
||||
'reference' => 'd8e916507b88e389e26d4ab03c904a082aa66bb9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabberworm/php-css-parser',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'tecnickcom/tcpdf' => array(
|
||||
'pretty_version' => '6.10.0',
|
||||
'version' => '6.10.0.0',
|
||||
'reference' => 'ca5b6de294512145db96bcbc94e61696599c391d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../tecnickcom/tcpdf',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 70100)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
throw new \RuntimeException(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues)
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Matt Butcher [technosophos] <technosophos@gmail.com> (lead)
|
||||
Matt Farina [mattfarina] <matt@mattfarina.com> (lead)
|
||||
Asmir Mustafic [goetas] <goetas@lignano.it> (contributor)
|
||||
Edward Z. Yang [ezyang] <ezyang@mit.edu> (contributor)
|
||||
Geoffrey Sneddon [gsnedders] <geoffers@gmail.com> (contributor)
|
||||
Kukhar Vasily [ngreduce] <ngreduce@gmail.com> (contributor)
|
||||
Rune Christensen [MrElectronic] <mrelectronic@example.com> (contributor)
|
||||
Mišo Belica [miso-belica] <miso-belica@example.com> (contributor)
|
||||
Asmir Mustafic [goetas] <goetas@example.com> (contributor)
|
||||
KITAITI Makoto [KitaitiMakoto] <KitaitiMakoto@example.com> (contributor)
|
||||
Jacob Floyd [cognifloyd] <cognifloyd@gmail.com> (contributor)
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
## HTML5-PHP License
|
||||
|
||||
Copyright (c) 2013 The Authors of HTML5-PHP
|
||||
|
||||
Matt Butcher - mattbutcher@google.com
|
||||
Matt Farina - matt@mattfarina.com
|
||||
Asmir Mustafic - goetas@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
## HTML5Lib License
|
||||
|
||||
Portions of this are based on html5lib's PHP version, which was a
|
||||
sub-project of html5lib. The following is the list of contributors from
|
||||
html5lib:
|
||||
|
||||
html5lib:
|
||||
|
||||
Copyright (c) 2006-2009 The Authors
|
||||
|
||||
Contributors:
|
||||
James Graham - jg307@cam.ac.uk
|
||||
Anne van Kesteren - annevankesteren@gmail.com
|
||||
Lachlan Hunt - lachlan.hunt@lachy.id.au
|
||||
Matt McDonald - kanashii@kanashii.ca
|
||||
Sam Ruby - rubys@intertwingly.net
|
||||
Ian Hickson (Google) - ian@hixie.ch
|
||||
Thomas Broyer - t.broyer@ltgt.net
|
||||
Jacques Distler - distler@golem.ph.utexas.edu
|
||||
Henri Sivonen - hsivonen@iki.fi
|
||||
Adam Barth - abarth@webkit.org
|
||||
Eric Seidel - eric@webkit.org
|
||||
The Mozilla Foundation (contributions from Henri Sivonen since 2008)
|
||||
David Flanagan (Mozilla) - dflanagan@mozilla.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
> # UKRAINE NEEDS YOUR HELP NOW!
|
||||
>
|
||||
> On 24 February 2022, Russian [President Vladimir Putin ordered an invasion of Ukraine by Russian Armed Forces](https://www.bbc.com/news/world-europe-60504334).
|
||||
>
|
||||
> Your support is urgently needed.
|
||||
>
|
||||
> - Donate to the volunteers. Here is the volunteer fund helping the Ukrainian army to provide all the necessary equipment:
|
||||
> https://bank.gov.ua/en/news/all/natsionalniy-bank-vidkriv-spetsrahunok-dlya-zboru-koshtiv-na-potrebi-armiyi or https://savelife.in.ua/en/donate/
|
||||
> - Triple-check social media sources. Russian disinformation is attempting to coverup and distort the reality in Ukraine.
|
||||
> - Help Ukrainian refugees who are fleeing Russian attacks and shellings: https://www.globalcitizen.org/en/content/ways-to-help-ukraine-conflict/
|
||||
> - Put pressure on your political representatives to provide help to Ukraine.
|
||||
> - Believe in the Ukrainian people, they will not surrender, they don't have another Ukraine.
|
||||
>
|
||||
> THANK YOU!
|
||||
----
|
||||
|
||||
# HTML5-PHP
|
||||
|
||||
HTML5 is a standards-compliant HTML5 parser and writer written entirely in PHP.
|
||||
It is stable and used in many production websites, and has
|
||||
well over [five million downloads](https://packagist.org/packages/masterminds/html5).
|
||||
|
||||
HTML5 provides the following features.
|
||||
|
||||
- An HTML5 serializer
|
||||
- Support for PHP namespaces
|
||||
- Composer support
|
||||
- Event-based (SAX-like) parser
|
||||
- A DOM tree builder
|
||||
- Interoperability with [QueryPath](https://github.com/technosophos/querypath)
|
||||
- Runs on **PHP** 5.3.0 or newer
|
||||
|
||||
[](https://github.com/Masterminds/html5-php/actions/workflows/ci.yaml)
|
||||
[](https://packagist.org/packages/masterminds/html5)
|
||||
[](https://scrutinizer-ci.com/g/Masterminds/html5-php/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/Masterminds/html5-php/?branch=master)
|
||||
[](https://masterminds.github.io/stability/sustained.html)
|
||||
|
||||
## Installation
|
||||
|
||||
Install HTML5-PHP using [composer](http://getcomposer.org/).
|
||||
|
||||
By adding the `masterminds/html5` dependency to your `composer.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"require" : {
|
||||
"masterminds/html5": "^2.0"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
By invoking require command via composer executable:
|
||||
|
||||
```bash
|
||||
composer require masterminds/html5
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
HTML5-PHP has a high-level API and a low-level API.
|
||||
|
||||
Here is how you use the high-level `HTML5` library API:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Assuming you installed from Composer:
|
||||
require "vendor/autoload.php";
|
||||
|
||||
use Masterminds\HTML5;
|
||||
|
||||
// An example HTML document:
|
||||
$html = <<< 'HERE'
|
||||
<html>
|
||||
<head>
|
||||
<title>TEST</title>
|
||||
</head>
|
||||
<body id='foo'>
|
||||
<h1>Hello World</h1>
|
||||
<p>This is a test of the HTML5 parser.</p>
|
||||
</body>
|
||||
</html>
|
||||
HERE;
|
||||
|
||||
// Parse the document. $dom is a DOMDocument.
|
||||
$html5 = new HTML5();
|
||||
$dom = $html5->loadHTML($html);
|
||||
|
||||
// Render it as HTML5:
|
||||
print $html5->saveHTML($dom);
|
||||
|
||||
// Or save it to a file:
|
||||
$html5->save($dom, 'out.html');
|
||||
```
|
||||
|
||||
The `$dom` created by the parser is a full `DOMDocument` object. And the
|
||||
`save()` and `saveHTML()` methods will take any DOMDocument.
|
||||
|
||||
### Options
|
||||
|
||||
It is possible to pass in an array of configuration options when loading
|
||||
an HTML5 document.
|
||||
|
||||
```php
|
||||
// An associative array of options
|
||||
$options = array(
|
||||
'option_name' => 'option_value',
|
||||
);
|
||||
|
||||
// Provide the options to the constructor
|
||||
$html5 = new HTML5($options);
|
||||
|
||||
$dom = $html5->loadHTML($html);
|
||||
```
|
||||
|
||||
The following options are supported:
|
||||
|
||||
* `encode_entities` (boolean): Indicates that the serializer should aggressively
|
||||
encode characters as entities. Without this, it only encodes the bare
|
||||
minimum.
|
||||
* `disable_html_ns` (boolean): Prevents the parser from automatically
|
||||
assigning the HTML5 namespace to the DOM document. This is for
|
||||
non-namespace aware DOM tools.
|
||||
* `target_document` (\DOMDocument): A DOM document that will be used as the
|
||||
destination for the parsed nodes.
|
||||
* `implicit_namespaces` (array): An assoc array of namespaces that should be
|
||||
used by the parser. Name is tag prefix, value is NS URI.
|
||||
|
||||
## The Low-Level API
|
||||
|
||||
This library provides the following low-level APIs that you can use to
|
||||
create more customized HTML5 tools:
|
||||
|
||||
- A SAX-like event-based parser that you can hook into for special kinds
|
||||
of parsing.
|
||||
- A flexible error-reporting mechanism that can be tuned to document
|
||||
syntax checking.
|
||||
- A DOM implementation that uses PHP's built-in DOM library.
|
||||
|
||||
The unit tests exercise each piece of the API, and every public function
|
||||
is well-documented.
|
||||
|
||||
### Parser Design
|
||||
|
||||
The parser is designed as follows:
|
||||
|
||||
- The `Scanner` handles scanning on behalf of the parser.
|
||||
- The `Tokenizer` requests data off of the scanner, parses it, clasifies
|
||||
it, and sends it to an `EventHandler`. It is a *recursive descent parser.*
|
||||
- The `EventHandler` receives notifications and data for each specific
|
||||
semantic event that occurs during tokenization.
|
||||
- The `DOMBuilder` is an `EventHandler` that listens for tokenizing
|
||||
events and builds a document tree (`DOMDocument`) based on the events.
|
||||
|
||||
### Serializer Design
|
||||
|
||||
The serializer takes a data structure (the `DOMDocument`) and transforms
|
||||
it into a character representation -- an HTML5 document.
|
||||
|
||||
The serializer is broken into three parts:
|
||||
|
||||
- The `OutputRules` contain the rules to turn DOM elements into strings. The
|
||||
rules are an implementation of the interface `RulesInterface` allowing for
|
||||
different rule sets to be used.
|
||||
- The `Traverser`, which is a special-purpose tree walker. It visits
|
||||
each node node in the tree and uses the `OutputRules` to transform the node
|
||||
into a string.
|
||||
- `HTML5` manages the `Traverser` and stores the resultant data
|
||||
in the correct place.
|
||||
|
||||
The serializer (`save()`, `saveHTML()`) follows the
|
||||
[section 8.9 of the HTML 5.0 spec](http://www.w3.org/TR/2012/CR-html5-20121217/syntax.html#serializing-html-fragments).
|
||||
So tags are serialized according to these rules:
|
||||
|
||||
- A tag with children: <foo>CHILDREN</foo>
|
||||
- A tag that cannot have content: <foo> (no closing tag)
|
||||
- A tag that could have content, but doesn't: <foo></foo>
|
||||
|
||||
## Known Issues (Or, Things We Designed Against the Spec)
|
||||
|
||||
Please check the issue queue for a full list, but the following are
|
||||
issues known issues that are not presently on the roadmap:
|
||||
|
||||
- Namespaces: HTML5 only [supports a selected list of namespaces](http://www.w3.org/TR/html5/infrastructure.html#namespaces)
|
||||
and they do not operate in the same way as XML namespaces. A `:` has no special
|
||||
meaning.
|
||||
By default the parser does not support XML style namespaces via `:`;
|
||||
to enable the XML namespaces see the [XML Namespaces section](#xml-namespaces)
|
||||
- Scripts: This parser does not contain a JavaScript or a CSS
|
||||
interpreter. While one may be supplied, not all features will be
|
||||
supported.
|
||||
- Reentrance: The current parser is not re-entrant. (Thus you can't pause
|
||||
the parser to modify the HTML string mid-parse.)
|
||||
- Validation: The current tree builder is **not** a validating parser.
|
||||
While it will correct some HTML, it does not check that the HTML
|
||||
conforms to the standard. (Should you wish, you can build a validating
|
||||
parser by extending DOMTree or building your own EventHandler
|
||||
implementation.)
|
||||
* There is limited support for insertion modes.
|
||||
* Some autocorrection is done automatically.
|
||||
* Per the spec, many legacy tags are admitted and correctly handled,
|
||||
even though they are technically not part of HTML5.
|
||||
- Attribute names and values: Due to the implementation details of the
|
||||
PHP implementation of DOM, attribute names that do not follow the
|
||||
XML 1.0 standard are not inserted into the DOM. (Effectively, they
|
||||
are ignored.) If you've got a clever fix for this, jump in!
|
||||
- Processor Instructions: The HTML5 spec does not allow processor
|
||||
instructions. We do. Since this is a server-side library, we think
|
||||
this is useful. And that means, dear reader, that in some cases you
|
||||
can parse the HTML from a mixed PHP/HTML document. This, however,
|
||||
is an incidental feature, not a core feature.
|
||||
- HTML manifests: Unsupported.
|
||||
- PLAINTEXT: Unsupported.
|
||||
- Adoption Agency Algorithm: Not yet implemented. (8.2.5.4.7)
|
||||
|
||||
## XML Namespaces
|
||||
|
||||
To use XML style namespaces you have to configure well the main `HTML5` instance.
|
||||
|
||||
```php
|
||||
use Masterminds\HTML5;
|
||||
$html = new HTML5(array(
|
||||
"xmlNamespaces" => true
|
||||
));
|
||||
|
||||
$dom = $html->loadHTML('<t:tag xmlns:t="http://www.example.com"/>');
|
||||
|
||||
$dom->documentElement->namespaceURI; // http://www.example.com
|
||||
|
||||
```
|
||||
|
||||
You can also add some default prefixes that will not require the namespace declaration,
|
||||
but its elements will be namespaced.
|
||||
|
||||
```php
|
||||
use Masterminds\HTML5;
|
||||
$html = new HTML5(array(
|
||||
"implicitNamespaces"=>array(
|
||||
"t"=>"http://www.example.com"
|
||||
)
|
||||
));
|
||||
|
||||
$dom = $html->loadHTML('<t:tag/>');
|
||||
|
||||
$dom->documentElement->namespaceURI; // http://www.example.com
|
||||
|
||||
```
|
||||
|
||||
## Thanks to...
|
||||
|
||||
The dedicated (and patient) contributors of patches small and large,
|
||||
who have already made this library better.See the CREDITS file for
|
||||
a list of contributors.
|
||||
|
||||
We owe a huge debt of gratitude to the original authors of html5lib.
|
||||
|
||||
While not much of the original parser remains, we learned a lot from
|
||||
reading the html5lib library. And some pieces remain here. In
|
||||
particular, much of the UTF-8 and Unicode handling is derived from the
|
||||
html5lib project.
|
||||
|
||||
## License
|
||||
|
||||
This software is released under the MIT license. The original html5lib
|
||||
library was also released under the MIT license.
|
||||
|
||||
See LICENSE.txt
|
||||
|
||||
Certain files contain copyright assertions by specific individuals
|
||||
involved with html5lib. Those have been retained where appropriate.
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
# Release Notes
|
||||
|
||||
2.7.6 (2021-08-18)
|
||||
|
||||
- #218: Address comment handling issues
|
||||
|
||||
2.7.5 (2021-07-01)
|
||||
|
||||
- #204: Travis: Enable tests on PHP 8.0
|
||||
- #207: Fix PHP 8.1 deprecations
|
||||
|
||||
2.7.4 (2020-10-01)
|
||||
|
||||
- #191: Fix travisci build
|
||||
- #195: Add .gitattributes file with export-ignore rules
|
||||
- #194: Fix query parameter parsed as character entity
|
||||
|
||||
2.7.3 (2020-07-05)
|
||||
|
||||
- #190: mitigate cyclic reference between output rules and the traverser objects
|
||||
|
||||
2.7.2 (2020-07-01)
|
||||
|
||||
- #187: Fixed memory leak in HTML5::saveHTML()
|
||||
- #186: Add special case for end tag </br>
|
||||
|
||||
2.7.1 (2020-06-14)
|
||||
|
||||
- #171: add PHP 7.4 job
|
||||
- #178: Prevent infinite loop on un-terminated entity declaration at EOF
|
||||
|
||||
2.7.0 (2019-07-25)
|
||||
|
||||
- #164: Drop HHVM support
|
||||
- #168: Set default encoding in the DOMDocument object
|
||||
|
||||
2.6.0 (2019-03-10)
|
||||
|
||||
- #163: Allow to pass a charset to the Scanner
|
||||
|
||||
2.5.0 (2018-12-27)
|
||||
|
||||
- #162, #161, #155, #154, #153, #151: big performance improvements
|
||||
- #156: fixed typos
|
||||
- #160: adopt and enforce code style
|
||||
- #159: remove deprecated php unit base test case
|
||||
- #150: backport changes from old master branch
|
||||
|
||||
2.4.0 (2018-11-17)
|
||||
|
||||
- #148: Improve performance by moving sequence matching
|
||||
- #147: Improve the Tokenizer performance
|
||||
- #146: Improve performance by relying on a native string instead of InputStream
|
||||
- #144: Add DOM extension in composer.json
|
||||
- #145: Add more extensions on composer.json, improve phpdocs and remove dead code
|
||||
- #143: Remove experimental comment
|
||||
|
||||
2.3.1 (2018-10-18)
|
||||
|
||||
- #121: Audio is not a block tag (fixed by #141)
|
||||
- #136: Handle illegal self-closing according to spec (fixed by #137)
|
||||
- #141: Minor fixes in the README
|
||||
|
||||
2.3.0 (2017-09-04)
|
||||
|
||||
- #129: image within inline svg breaks system (fixed by #133)
|
||||
- #131: ² does not work (fixed by #132)
|
||||
- #134: Improve tokenizer performance by 20% (alternative version of #130 thanks to @MichaelHeerklotz)
|
||||
- #135: Raw & in attributes
|
||||
|
||||
2.2.2 (2016-09-22)
|
||||
|
||||
- #116: In XML mode, tags are case sensitive
|
||||
- #115: Fix PHP Notice in OutputRules
|
||||
- #112: fix parsing of options of an optgroup
|
||||
- #111: Adding test for the address tag
|
||||
|
||||
2.2.1 (2016-05-10)
|
||||
|
||||
- #109: Fixed issue where address tag could be written without closing tag (thanks sylus)
|
||||
|
||||
2.2.0 (2016-04-11)
|
||||
|
||||
- #105: Enable composer cache (for CI/CD)
|
||||
- #100: Use mb_substitute_character inset of ini_set for environments where ini_set is disable (e.g., shared hosting)
|
||||
- #98: Allow link, meta, style tags in noscript tags
|
||||
- #96: Fixed xml:href on svgs that use the "use" breaking
|
||||
- #94: Counting UTF8 characters performance improvement
|
||||
- #93: Use newer version of coveralls package
|
||||
- #90: Remove duplicate test
|
||||
- #87: Allow multiple root nodes
|
||||
|
||||
2.1.2 (2015-06-07)
|
||||
- #82: Support for PHP7
|
||||
- #84: Improved boolean attribute handling
|
||||
|
||||
2.1.1 (2015-03-23)
|
||||
- #78: Fixes bug where unmatched entity like string drops everything after &.
|
||||
|
||||
2.1.0 (2015-02-01)
|
||||
- #74: Added `disable_html_ns` and `target_doc` dom parsing options
|
||||
- Unified option names
|
||||
- #73: Fixed alphabet, ß now can be detected
|
||||
- #75 and #76: Allow whitespace in RCDATA tags
|
||||
- #77: Fixed parsing blunder for json embeds
|
||||
- #72: Add options to HTML methods
|
||||
|
||||
2.0.2 (2014-12-17)
|
||||
- #50: empty document handling
|
||||
- #63: tags with strange capitalization
|
||||
- #65: dashes and underscores as allowed characters in tag names
|
||||
- #68: Fixed issue with non-inline elements inside inline containers
|
||||
|
||||
2.0.1 (2014-09-23)
|
||||
- #59: Fixed issue parsing some fragments.
|
||||
- #56: Incorrectly saw 0 as empty string
|
||||
- Sami as new documentation generator
|
||||
|
||||
2.0.0 (2014-07-28)
|
||||
- #53: Improved boolean attributes handling
|
||||
- #52: Facebook HHVM compatibility
|
||||
- #48: Adopted PSR-2 as coding standard
|
||||
- #47: Moved everything to Masterminds namespace
|
||||
- #45: Added custom namespaces
|
||||
- #44: Added support to XML-style namespaces
|
||||
- #37: Refactored HTML5 class removing static methods
|
||||
|
||||
1.0.5 (2014-06-10)
|
||||
- #38: Set the dev-master branch as the 1.0.x branch for composer (goetas)
|
||||
- #34: Tests use PSR-4 for autoloading. (goetas)
|
||||
- #40, #41: Fix entity handling in RCDATA sections. (KitaitiMakoto)
|
||||
- #32: Fixed issue where wharacter references were being incorrectly encoded in style tags.
|
||||
|
||||
1.0.4 (2014-04-29)
|
||||
- #30/#31 Don't throw an exception for invalid tag names.
|
||||
|
||||
1.0.3 (2014-02-28)
|
||||
- #23 and #29: Ignore attributes with illegal chars in name for the PHP DOM.
|
||||
|
||||
1.0.2 (2014-02-12)
|
||||
- #23: Handle missing tag close in attribute list.
|
||||
- #25: Fixed text escaping in the serializer (HTML% 8.3).
|
||||
- #27: Fixed tests on Windows: changed "\n" -> PHP_EOL.
|
||||
- #28: Fixed infinite loop for char "&" in unquoted attribute in parser.
|
||||
- #26: Updated tag name case handling to deal with uppercase usage.
|
||||
- #24: Newlines and tabs are allowed inside quoted attributes (HTML5 8.2.4).
|
||||
- Fixed Travis CI testing.
|
||||
|
||||
1.0.1 (2013-11-07)
|
||||
- CDATA encoding is improved. (Non-standard; Issue #19)
|
||||
- Some parser rules were not returning the new current element. (Issue #20)
|
||||
- Added, to the README, details on code test coverage and to packagist version.
|
||||
- Fixed processor instructions.
|
||||
- Improved test coverage and documentation coverage.
|
||||
|
||||
1.0.0 (2013-10-02)
|
||||
- Initial release.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
From 1.x to 2.x
|
||||
=================
|
||||
|
||||
- All classes uses `Masterminds` namespace.
|
||||
- All public static methods has been removed from `HTML5` class and the general API to access the HTML5 functionalities has changed.
|
||||
|
||||
Before:
|
||||
|
||||
$dom = \HTML5::loadHTML('<html>....');
|
||||
\HTML5::saveHTML($dom);
|
||||
|
||||
After:
|
||||
|
||||
use Masterminds\HTML5;
|
||||
|
||||
$html5 = new HTML5();
|
||||
|
||||
$dom = $html5->loadHTML('<html>....');
|
||||
echo $html5->saveHTML($dom);
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* Fetch the entities.json file and convert to PHP datastructure.
|
||||
*/
|
||||
|
||||
// The URL to the official entities JSON file.
|
||||
$ENTITIES_URL = 'http://www.w3.org/TR/2012/CR-html5-20121217/entities.json';
|
||||
|
||||
$payload = file_get_contents($ENTITIES_URL);
|
||||
$json = json_decode($payload);
|
||||
|
||||
$table = array();
|
||||
foreach ($json as $name => $obj) {
|
||||
$sname = substr($name, 1, -1);
|
||||
$table[$sname] = $obj->characters;
|
||||
}
|
||||
|
||||
echo '<?php
|
||||
namespace Masterminds\\HTML5;
|
||||
/** Entity lookup tables. This class is automatically generated. */
|
||||
class Entities {
|
||||
public static $byName = ';
|
||||
var_export($table);
|
||||
echo ';
|
||||
}' . PHP_EOL;
|
||||
//print serialize($table);
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "masterminds/html5",
|
||||
"description": "An HTML5 parser and serializer.",
|
||||
"type": "library",
|
||||
"homepage": "http://masterminds.github.io/html5-php",
|
||||
"license": "MIT",
|
||||
"keywords": ["xml", "html", "html5", "dom", "parser", "serializer", "querypath"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matt Butcher",
|
||||
"email": "technosophos@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Matt Farina",
|
||||
"email": "matt@mattfarina.com"
|
||||
},
|
||||
{
|
||||
"name": "Asmir Mustafic",
|
||||
"email": "goetas@gmail.com"
|
||||
}
|
||||
],
|
||||
"require" : {
|
||||
"ext-dom": "*",
|
||||
"php" : ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit" : "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {"Masterminds\\": "src"}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {"Masterminds\\HTML5\\Tests\\": "test/HTML5"}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds;
|
||||
|
||||
use Masterminds\HTML5\Parser\DOMTreeBuilder;
|
||||
use Masterminds\HTML5\Parser\Scanner;
|
||||
use Masterminds\HTML5\Parser\Tokenizer;
|
||||
use Masterminds\HTML5\Serializer\OutputRules;
|
||||
use Masterminds\HTML5\Serializer\Traverser;
|
||||
|
||||
/**
|
||||
* This class offers convenience methods for parsing and serializing HTML5.
|
||||
* It is roughly designed to mirror the \DOMDocument native class.
|
||||
*/
|
||||
class HTML5
|
||||
{
|
||||
/**
|
||||
* Global options for the parser and serializer.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $defaultOptions = array(
|
||||
// Whether the serializer should aggressively encode all characters as entities.
|
||||
'encode_entities' => false,
|
||||
|
||||
// Prevents the parser from automatically assigning the HTML5 namespace to the DOM document.
|
||||
'disable_html_ns' => false,
|
||||
);
|
||||
|
||||
protected $errors = array();
|
||||
|
||||
public function __construct(array $defaultOptions = array())
|
||||
{
|
||||
$this->defaultOptions = array_merge($this->defaultOptions, $defaultOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current default options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->defaultOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and parse an HTML file.
|
||||
*
|
||||
* This will apply the HTML5 parser, which is tolerant of many
|
||||
* varieties of HTML, including XHTML 1, HTML 4, and well-formed HTML
|
||||
* 3. Note that in these cases, not all of the old data will be
|
||||
* preserved. For example, XHTML's XML declaration will be removed.
|
||||
*
|
||||
* The rules governing parsing are set out in the HTML 5 spec.
|
||||
*
|
||||
* @param string|resource $file The path to the file to parse. If this is a resource, it is
|
||||
* assumed to be an open stream whose pointer is set to the first
|
||||
* byte of input.
|
||||
* @param array $options Configuration options when parsing the HTML.
|
||||
*
|
||||
* @return \DOMDocument A DOM document. These object type is defined by the libxml
|
||||
* library, and should have been included with your version of PHP.
|
||||
*/
|
||||
public function load($file, array $options = array())
|
||||
{
|
||||
// Handle the case where file is a resource.
|
||||
if (is_resource($file)) {
|
||||
return $this->parse(stream_get_contents($file), $options);
|
||||
}
|
||||
|
||||
return $this->parse(file_get_contents($file), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a HTML Document from a string.
|
||||
*
|
||||
* Take a string of HTML 5 (or earlier) and parse it into a
|
||||
* DOMDocument.
|
||||
*
|
||||
* @param string $string A html5 document as a string.
|
||||
* @param array $options Configuration options when parsing the HTML.
|
||||
*
|
||||
* @return \DOMDocument A DOM document. DOM is part of libxml, which is included with
|
||||
* almost all distribtions of PHP.
|
||||
*/
|
||||
public function loadHTML($string, array $options = array())
|
||||
{
|
||||
return $this->parse($string, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to load an HTML file.
|
||||
*
|
||||
* This is here to provide backwards compatibility with the
|
||||
* PHP DOM implementation. It simply calls load().
|
||||
*
|
||||
* @param string $file The path to the file to parse. If this is a resource, it is
|
||||
* assumed to be an open stream whose pointer is set to the first
|
||||
* byte of input.
|
||||
* @param array $options Configuration options when parsing the HTML.
|
||||
*
|
||||
* @return \DOMDocument A DOM document. These object type is defined by the libxml
|
||||
* library, and should have been included with your version of PHP.
|
||||
*/
|
||||
public function loadHTMLFile($file, array $options = array())
|
||||
{
|
||||
return $this->load($file, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a HTML fragment from a string.
|
||||
*
|
||||
* @param string $string the HTML5 fragment as a string
|
||||
* @param array $options Configuration options when parsing the HTML
|
||||
*
|
||||
* @return \DOMDocumentFragment A DOM fragment. The DOM is part of libxml, which is included with
|
||||
* almost all distributions of PHP.
|
||||
*/
|
||||
public function loadHTMLFragment($string, array $options = array())
|
||||
{
|
||||
return $this->parseFragment($string, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all errors encountered into parsing phase.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true it some errors were encountered into parsing phase.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasErrors()
|
||||
{
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an input string.
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
public function parse($input, array $options = array())
|
||||
{
|
||||
$this->errors = array();
|
||||
$options = array_merge($this->defaultOptions, $options);
|
||||
$events = new DOMTreeBuilder(false, $options);
|
||||
$scanner = new Scanner($input, !empty($options['encoding']) ? $options['encoding'] : 'UTF-8');
|
||||
$parser = new Tokenizer($scanner, $events, !empty($options['xmlNamespaces']) ? Tokenizer::CONFORMANT_XML : Tokenizer::CONFORMANT_HTML);
|
||||
|
||||
$parser->parse();
|
||||
$this->errors = $events->getErrors();
|
||||
|
||||
return $events->document();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an input stream where the stream is a fragment.
|
||||
*
|
||||
* Lower-level loading function. This requires an input stream instead
|
||||
* of a string, file, or resource.
|
||||
*
|
||||
* @param string $input The input data to parse in the form of a string.
|
||||
* @param array $options An array of options.
|
||||
*
|
||||
* @return \DOMDocumentFragment
|
||||
*/
|
||||
public function parseFragment($input, array $options = array())
|
||||
{
|
||||
$options = array_merge($this->defaultOptions, $options);
|
||||
$events = new DOMTreeBuilder(true, $options);
|
||||
$scanner = new Scanner($input, !empty($options['encoding']) ? $options['encoding'] : 'UTF-8');
|
||||
$parser = new Tokenizer($scanner, $events, !empty($options['xmlNamespaces']) ? Tokenizer::CONFORMANT_XML : Tokenizer::CONFORMANT_HTML);
|
||||
|
||||
$parser->parse();
|
||||
$this->errors = $events->getErrors();
|
||||
|
||||
return $events->fragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a DOM into a given file as HTML5.
|
||||
*
|
||||
* @param mixed $dom The DOM to be serialized.
|
||||
* @param string|resource $file The filename to be written or resource to write to.
|
||||
* @param array $options Configuration options when serializing the DOM. These include:
|
||||
* - encode_entities: Text written to the output is escaped by default and not all
|
||||
* entities are encoded. If this is set to true all entities will be encoded.
|
||||
* Defaults to false.
|
||||
*/
|
||||
public function save($dom, $file, $options = array())
|
||||
{
|
||||
$close = true;
|
||||
if (is_resource($file)) {
|
||||
$stream = $file;
|
||||
$close = false;
|
||||
} else {
|
||||
$stream = fopen($file, 'wb');
|
||||
}
|
||||
$options = array_merge($this->defaultOptions, $options);
|
||||
$rules = new OutputRules($stream, $options);
|
||||
$trav = new Traverser($dom, $stream, $rules, $options);
|
||||
|
||||
$trav->walk();
|
||||
/*
|
||||
* release the traverser to avoid cyclic references and allow PHP to free memory without waiting for gc_collect_cycles
|
||||
*/
|
||||
$rules->unsetTraverser();
|
||||
if ($close) {
|
||||
fclose($stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a DOM into an HTML5 string.
|
||||
*
|
||||
* @param mixed $dom The DOM to be serialized.
|
||||
* @param array $options Configuration options when serializing the DOM. These include:
|
||||
* - encode_entities: Text written to the output is escaped by default and not all
|
||||
* entities are encoded. If this is set to true all entities will be encoded.
|
||||
* Defaults to false.
|
||||
*
|
||||
* @return string A HTML5 documented generated from the DOM.
|
||||
*/
|
||||
public function saveHTML($dom, $options = array())
|
||||
{
|
||||
$stream = fopen('php://temp', 'wb');
|
||||
$this->save($dom, $stream, array_merge($this->defaultOptions, $options));
|
||||
|
||||
$html = stream_get_contents($stream, -1, 0);
|
||||
|
||||
fclose($stream);
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,637 @@
|
|||
<?php
|
||||
/**
|
||||
* Provide general element functions.
|
||||
*/
|
||||
|
||||
namespace Masterminds\HTML5;
|
||||
|
||||
/**
|
||||
* This class provides general information about HTML5 elements,
|
||||
* including syntactic and semantic issues.
|
||||
* Parsers and serializers can
|
||||
* use this class as a reference point for information about the rules
|
||||
* of various HTML5 elements.
|
||||
*
|
||||
* @todo consider using a bitmask table lookup. There is enough overlap in
|
||||
* naming that this could significantly shrink the size and maybe make it
|
||||
* faster. See the Go teams implementation at https://code.google.com/p/go/source/browse/html/atom.
|
||||
*/
|
||||
class Elements
|
||||
{
|
||||
/**
|
||||
* Indicates an element is described in the specification.
|
||||
*/
|
||||
const KNOWN_ELEMENT = 1;
|
||||
|
||||
// From section 8.1.2: "script", "style"
|
||||
// From 8.2.5.4.7 ("in body" insertion mode): "noembed"
|
||||
// From 8.4 "style", "xmp", "iframe", "noembed", "noframes"
|
||||
/**
|
||||
* Indicates the contained text should be processed as raw text.
|
||||
*/
|
||||
const TEXT_RAW = 2;
|
||||
|
||||
// From section 8.1.2: "textarea", "title"
|
||||
/**
|
||||
* Indicates the contained text should be processed as RCDATA.
|
||||
*/
|
||||
const TEXT_RCDATA = 4;
|
||||
|
||||
/**
|
||||
* Indicates the tag cannot have content.
|
||||
*/
|
||||
const VOID_TAG = 8;
|
||||
|
||||
// "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl",
|
||||
// "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "menu",
|
||||
// "nav", "ol", "p", "section", "summary", "ul"
|
||||
// "h1", "h2", "h3", "h4", "h5", "h6"
|
||||
// "pre", "listing"
|
||||
// "form"
|
||||
// "plaintext"
|
||||
/**
|
||||
* Indicates that if a previous event is for a P tag, that element
|
||||
* should be considered closed.
|
||||
*/
|
||||
const AUTOCLOSE_P = 16;
|
||||
|
||||
/**
|
||||
* Indicates that the text inside is plaintext (pre).
|
||||
*/
|
||||
const TEXT_PLAINTEXT = 32;
|
||||
|
||||
// See https://developer.mozilla.org/en-US/docs/HTML/Block-level_elements
|
||||
/**
|
||||
* Indicates that the tag is a block.
|
||||
*/
|
||||
const BLOCK_TAG = 64;
|
||||
|
||||
/**
|
||||
* Indicates that the tag allows only inline elements as child nodes.
|
||||
*/
|
||||
const BLOCK_ONLY_INLINE = 128;
|
||||
|
||||
/**
|
||||
* Elements with optional end tags that cause auto-closing of previous and parent tags,
|
||||
* as example most of the table related tags, see https://www.w3.org/TR/html401/struct/tables.html
|
||||
* Structure is as follows:
|
||||
* TAG-NAME => [PARENT-TAG-NAME-TO-CLOSE1, PARENT-TAG-NAME-TO-CLOSE2, ...].
|
||||
*
|
||||
* Order is important, after auto-closing one parent with might have to close also their parent.
|
||||
*
|
||||
* @var array<string, string[]>
|
||||
*/
|
||||
public static $optionalEndElementsParentsToClose = array(
|
||||
'tr' => array('td', 'tr'),
|
||||
'td' => array('td', 'th'),
|
||||
'th' => array('td', 'th'),
|
||||
'tfoot' => array('td', 'th', 'tr', 'tbody', 'thead'),
|
||||
'tbody' => array('td', 'th', 'tr', 'thead'),
|
||||
);
|
||||
|
||||
/**
|
||||
* The HTML5 elements as defined in http://dev.w3.org/html5/markup/elements.html.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $html5 = array(
|
||||
'a' => 1,
|
||||
'abbr' => 1,
|
||||
'address' => 65, // NORMAL | BLOCK_TAG
|
||||
'area' => 9, // NORMAL | VOID_TAG
|
||||
'article' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'aside' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'audio' => 1, // NORMAL
|
||||
'b' => 1,
|
||||
'base' => 9, // NORMAL | VOID_TAG
|
||||
'bdi' => 1,
|
||||
'bdo' => 1,
|
||||
'blockquote' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'body' => 1,
|
||||
'br' => 9, // NORMAL | VOID_TAG
|
||||
'button' => 1,
|
||||
'canvas' => 65, // NORMAL | BLOCK_TAG
|
||||
'caption' => 1,
|
||||
'cite' => 1,
|
||||
'code' => 1,
|
||||
'col' => 9, // NORMAL | VOID_TAG
|
||||
'colgroup' => 1,
|
||||
'command' => 9, // NORMAL | VOID_TAG
|
||||
// "data" => 1, // This is highly experimental and only part of the whatwg spec (not w3c). See https://developer.mozilla.org/en-US/docs/HTML/Element/data
|
||||
'datalist' => 1,
|
||||
'dd' => 65, // NORMAL | BLOCK_TAG
|
||||
'del' => 1,
|
||||
'details' => 17, // NORMAL | AUTOCLOSE_P,
|
||||
'dfn' => 1,
|
||||
'dialog' => 17, // NORMAL | AUTOCLOSE_P,
|
||||
'div' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'dl' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'dt' => 1,
|
||||
'em' => 1,
|
||||
'embed' => 9, // NORMAL | VOID_TAG
|
||||
'fieldset' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'figcaption' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'figure' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'footer' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'form' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'h1' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'h2' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'h3' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'h4' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'h5' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'h6' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'head' => 1,
|
||||
'header' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'hgroup' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'hr' => 73, // NORMAL | VOID_TAG
|
||||
'html' => 1,
|
||||
'i' => 1,
|
||||
'iframe' => 3, // NORMAL | TEXT_RAW
|
||||
'img' => 9, // NORMAL | VOID_TAG
|
||||
'input' => 9, // NORMAL | VOID_TAG
|
||||
'kbd' => 1,
|
||||
'ins' => 1,
|
||||
'keygen' => 9, // NORMAL | VOID_TAG
|
||||
'label' => 1,
|
||||
'legend' => 1,
|
||||
'li' => 1,
|
||||
'link' => 9, // NORMAL | VOID_TAG
|
||||
'map' => 1,
|
||||
'mark' => 1,
|
||||
'menu' => 17, // NORMAL | AUTOCLOSE_P,
|
||||
'meta' => 9, // NORMAL | VOID_TAG
|
||||
'meter' => 1,
|
||||
'nav' => 17, // NORMAL | AUTOCLOSE_P,
|
||||
'noscript' => 65, // NORMAL | BLOCK_TAG
|
||||
'object' => 1,
|
||||
'ol' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'optgroup' => 1,
|
||||
'option' => 1,
|
||||
'output' => 65, // NORMAL | BLOCK_TAG
|
||||
'p' => 209, // NORMAL | AUTOCLOSE_P | BLOCK_TAG | BLOCK_ONLY_INLINE
|
||||
'param' => 9, // NORMAL | VOID_TAG
|
||||
'pre' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'progress' => 1,
|
||||
'q' => 1,
|
||||
'rp' => 1,
|
||||
'rt' => 1,
|
||||
'ruby' => 1,
|
||||
's' => 1,
|
||||
'samp' => 1,
|
||||
'script' => 3, // NORMAL | TEXT_RAW
|
||||
'section' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'select' => 1,
|
||||
'small' => 1,
|
||||
'source' => 9, // NORMAL | VOID_TAG
|
||||
'span' => 1,
|
||||
'strong' => 1,
|
||||
'style' => 3, // NORMAL | TEXT_RAW
|
||||
'sub' => 1,
|
||||
'summary' => 17, // NORMAL | AUTOCLOSE_P,
|
||||
'sup' => 1,
|
||||
'table' => 65, // NORMAL | BLOCK_TAG
|
||||
'tbody' => 1,
|
||||
'td' => 1,
|
||||
'textarea' => 5, // NORMAL | TEXT_RCDATA
|
||||
'tfoot' => 65, // NORMAL | BLOCK_TAG
|
||||
'th' => 1,
|
||||
'thead' => 1,
|
||||
'time' => 1,
|
||||
'title' => 5, // NORMAL | TEXT_RCDATA
|
||||
'tr' => 1,
|
||||
'track' => 9, // NORMAL | VOID_TAG
|
||||
'u' => 1,
|
||||
'ul' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
||||
'var' => 1,
|
||||
'video' => 1,
|
||||
'wbr' => 9, // NORMAL | VOID_TAG
|
||||
|
||||
// Legacy?
|
||||
'basefont' => 8, // VOID_TAG
|
||||
'bgsound' => 8, // VOID_TAG
|
||||
'noframes' => 2, // RAW_TEXT
|
||||
'frame' => 9, // NORMAL | VOID_TAG
|
||||
'frameset' => 1,
|
||||
'center' => 16,
|
||||
'dir' => 16,
|
||||
'listing' => 16, // AUTOCLOSE_P
|
||||
'plaintext' => 48, // AUTOCLOSE_P | TEXT_PLAINTEXT
|
||||
'applet' => 0,
|
||||
'marquee' => 0,
|
||||
'isindex' => 8, // VOID_TAG
|
||||
'xmp' => 20, // AUTOCLOSE_P | VOID_TAG | RAW_TEXT
|
||||
'noembed' => 2, // RAW_TEXT
|
||||
);
|
||||
|
||||
/**
|
||||
* The MathML elements.
|
||||
* See http://www.w3.org/wiki/MathML/Elements.
|
||||
*
|
||||
* In our case we are only concerned with presentation MathML and not content
|
||||
* MathML. There is a nice list of this subset at https://developer.mozilla.org/en-US/docs/MathML/Element.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $mathml = array(
|
||||
'maction' => 1,
|
||||
'maligngroup' => 1,
|
||||
'malignmark' => 1,
|
||||
'math' => 1,
|
||||
'menclose' => 1,
|
||||
'merror' => 1,
|
||||
'mfenced' => 1,
|
||||
'mfrac' => 1,
|
||||
'mglyph' => 1,
|
||||
'mi' => 1,
|
||||
'mlabeledtr' => 1,
|
||||
'mlongdiv' => 1,
|
||||
'mmultiscripts' => 1,
|
||||
'mn' => 1,
|
||||
'mo' => 1,
|
||||
'mover' => 1,
|
||||
'mpadded' => 1,
|
||||
'mphantom' => 1,
|
||||
'mroot' => 1,
|
||||
'mrow' => 1,
|
||||
'ms' => 1,
|
||||
'mscarries' => 1,
|
||||
'mscarry' => 1,
|
||||
'msgroup' => 1,
|
||||
'msline' => 1,
|
||||
'mspace' => 1,
|
||||
'msqrt' => 1,
|
||||
'msrow' => 1,
|
||||
'mstack' => 1,
|
||||
'mstyle' => 1,
|
||||
'msub' => 1,
|
||||
'msup' => 1,
|
||||
'msubsup' => 1,
|
||||
'mtable' => 1,
|
||||
'mtd' => 1,
|
||||
'mtext' => 1,
|
||||
'mtr' => 1,
|
||||
'munder' => 1,
|
||||
'munderover' => 1,
|
||||
);
|
||||
|
||||
/**
|
||||
* The svg elements.
|
||||
*
|
||||
* The Mozilla documentation has a good list at https://developer.mozilla.org/en-US/docs/SVG/Element.
|
||||
* The w3c list appears to be lacking in some areas like filter effect elements.
|
||||
* That list can be found at http://www.w3.org/wiki/SVG/Elements.
|
||||
*
|
||||
* Note, FireFox appears to do a better job rendering filter effects than chrome.
|
||||
* While they are in the spec I'm not sure how widely implemented they are.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $svg = array(
|
||||
'a' => 1,
|
||||
'altGlyph' => 1,
|
||||
'altGlyphDef' => 1,
|
||||
'altGlyphItem' => 1,
|
||||
'animate' => 1,
|
||||
'animateColor' => 1,
|
||||
'animateMotion' => 1,
|
||||
'animateTransform' => 1,
|
||||
'circle' => 1,
|
||||
'clipPath' => 1,
|
||||
'color-profile' => 1,
|
||||
'cursor' => 1,
|
||||
'defs' => 1,
|
||||
'desc' => 1,
|
||||
'ellipse' => 1,
|
||||
'feBlend' => 1,
|
||||
'feColorMatrix' => 1,
|
||||
'feComponentTransfer' => 1,
|
||||
'feComposite' => 1,
|
||||
'feConvolveMatrix' => 1,
|
||||
'feDiffuseLighting' => 1,
|
||||
'feDisplacementMap' => 1,
|
||||
'feDistantLight' => 1,
|
||||
'feFlood' => 1,
|
||||
'feFuncA' => 1,
|
||||
'feFuncB' => 1,
|
||||
'feFuncG' => 1,
|
||||
'feFuncR' => 1,
|
||||
'feGaussianBlur' => 1,
|
||||
'feImage' => 1,
|
||||
'feMerge' => 1,
|
||||
'feMergeNode' => 1,
|
||||
'feMorphology' => 1,
|
||||
'feOffset' => 1,
|
||||
'fePointLight' => 1,
|
||||
'feSpecularLighting' => 1,
|
||||
'feSpotLight' => 1,
|
||||
'feTile' => 1,
|
||||
'feTurbulence' => 1,
|
||||
'filter' => 1,
|
||||
'font' => 1,
|
||||
'font-face' => 1,
|
||||
'font-face-format' => 1,
|
||||
'font-face-name' => 1,
|
||||
'font-face-src' => 1,
|
||||
'font-face-uri' => 1,
|
||||
'foreignObject' => 1,
|
||||
'g' => 1,
|
||||
'glyph' => 1,
|
||||
'glyphRef' => 1,
|
||||
'hkern' => 1,
|
||||
'image' => 1,
|
||||
'line' => 1,
|
||||
'linearGradient' => 1,
|
||||
'marker' => 1,
|
||||
'mask' => 1,
|
||||
'metadata' => 1,
|
||||
'missing-glyph' => 1,
|
||||
'mpath' => 1,
|
||||
'path' => 1,
|
||||
'pattern' => 1,
|
||||
'polygon' => 1,
|
||||
'polyline' => 1,
|
||||
'radialGradient' => 1,
|
||||
'rect' => 1,
|
||||
'script' => 3, // NORMAL | RAW_TEXT
|
||||
'set' => 1,
|
||||
'stop' => 1,
|
||||
'style' => 3, // NORMAL | RAW_TEXT
|
||||
'svg' => 1,
|
||||
'switch' => 1,
|
||||
'symbol' => 1,
|
||||
'text' => 1,
|
||||
'textPath' => 1,
|
||||
'title' => 1,
|
||||
'tref' => 1,
|
||||
'tspan' => 1,
|
||||
'use' => 1,
|
||||
'view' => 1,
|
||||
'vkern' => 1,
|
||||
);
|
||||
|
||||
/**
|
||||
* Some attributes in SVG are case sensitive.
|
||||
*
|
||||
* This map contains key/value pairs with the key as the lowercase attribute
|
||||
* name and the value with the correct casing.
|
||||
*/
|
||||
public static $svgCaseSensitiveAttributeMap = array(
|
||||
'attributename' => 'attributeName',
|
||||
'attributetype' => 'attributeType',
|
||||
'basefrequency' => 'baseFrequency',
|
||||
'baseprofile' => 'baseProfile',
|
||||
'calcmode' => 'calcMode',
|
||||
'clippathunits' => 'clipPathUnits',
|
||||
'contentscripttype' => 'contentScriptType',
|
||||
'contentstyletype' => 'contentStyleType',
|
||||
'diffuseconstant' => 'diffuseConstant',
|
||||
'edgemode' => 'edgeMode',
|
||||
'externalresourcesrequired' => 'externalResourcesRequired',
|
||||
'filterres' => 'filterRes',
|
||||
'filterunits' => 'filterUnits',
|
||||
'glyphref' => 'glyphRef',
|
||||
'gradienttransform' => 'gradientTransform',
|
||||
'gradientunits' => 'gradientUnits',
|
||||
'kernelmatrix' => 'kernelMatrix',
|
||||
'kernelunitlength' => 'kernelUnitLength',
|
||||
'keypoints' => 'keyPoints',
|
||||
'keysplines' => 'keySplines',
|
||||
'keytimes' => 'keyTimes',
|
||||
'lengthadjust' => 'lengthAdjust',
|
||||
'limitingconeangle' => 'limitingConeAngle',
|
||||
'markerheight' => 'markerHeight',
|
||||
'markerunits' => 'markerUnits',
|
||||
'markerwidth' => 'markerWidth',
|
||||
'maskcontentunits' => 'maskContentUnits',
|
||||
'maskunits' => 'maskUnits',
|
||||
'numoctaves' => 'numOctaves',
|
||||
'pathlength' => 'pathLength',
|
||||
'patterncontentunits' => 'patternContentUnits',
|
||||
'patterntransform' => 'patternTransform',
|
||||
'patternunits' => 'patternUnits',
|
||||
'pointsatx' => 'pointsAtX',
|
||||
'pointsaty' => 'pointsAtY',
|
||||
'pointsatz' => 'pointsAtZ',
|
||||
'preservealpha' => 'preserveAlpha',
|
||||
'preserveaspectratio' => 'preserveAspectRatio',
|
||||
'primitiveunits' => 'primitiveUnits',
|
||||
'refx' => 'refX',
|
||||
'refy' => 'refY',
|
||||
'repeatcount' => 'repeatCount',
|
||||
'repeatdur' => 'repeatDur',
|
||||
'requiredextensions' => 'requiredExtensions',
|
||||
'requiredfeatures' => 'requiredFeatures',
|
||||
'specularconstant' => 'specularConstant',
|
||||
'specularexponent' => 'specularExponent',
|
||||
'spreadmethod' => 'spreadMethod',
|
||||
'startoffset' => 'startOffset',
|
||||
'stddeviation' => 'stdDeviation',
|
||||
'stitchtiles' => 'stitchTiles',
|
||||
'surfacescale' => 'surfaceScale',
|
||||
'systemlanguage' => 'systemLanguage',
|
||||
'tablevalues' => 'tableValues',
|
||||
'targetx' => 'targetX',
|
||||
'targety' => 'targetY',
|
||||
'textlength' => 'textLength',
|
||||
'viewbox' => 'viewBox',
|
||||
'viewtarget' => 'viewTarget',
|
||||
'xchannelselector' => 'xChannelSelector',
|
||||
'ychannelselector' => 'yChannelSelector',
|
||||
'zoomandpan' => 'zoomAndPan',
|
||||
);
|
||||
|
||||
/**
|
||||
* Some SVG elements are case sensitive.
|
||||
* This map contains these.
|
||||
*
|
||||
* The map contains key/value store of the name is lowercase as the keys and
|
||||
* the correct casing as the value.
|
||||
*/
|
||||
public static $svgCaseSensitiveElementMap = array(
|
||||
'altglyph' => 'altGlyph',
|
||||
'altglyphdef' => 'altGlyphDef',
|
||||
'altglyphitem' => 'altGlyphItem',
|
||||
'animatecolor' => 'animateColor',
|
||||
'animatemotion' => 'animateMotion',
|
||||
'animatetransform' => 'animateTransform',
|
||||
'clippath' => 'clipPath',
|
||||
'feblend' => 'feBlend',
|
||||
'fecolormatrix' => 'feColorMatrix',
|
||||
'fecomponenttransfer' => 'feComponentTransfer',
|
||||
'fecomposite' => 'feComposite',
|
||||
'feconvolvematrix' => 'feConvolveMatrix',
|
||||
'fediffuselighting' => 'feDiffuseLighting',
|
||||
'fedisplacementmap' => 'feDisplacementMap',
|
||||
'fedistantlight' => 'feDistantLight',
|
||||
'feflood' => 'feFlood',
|
||||
'fefunca' => 'feFuncA',
|
||||
'fefuncb' => 'feFuncB',
|
||||
'fefuncg' => 'feFuncG',
|
||||
'fefuncr' => 'feFuncR',
|
||||
'fegaussianblur' => 'feGaussianBlur',
|
||||
'feimage' => 'feImage',
|
||||
'femerge' => 'feMerge',
|
||||
'femergenode' => 'feMergeNode',
|
||||
'femorphology' => 'feMorphology',
|
||||
'feoffset' => 'feOffset',
|
||||
'fepointlight' => 'fePointLight',
|
||||
'fespecularlighting' => 'feSpecularLighting',
|
||||
'fespotlight' => 'feSpotLight',
|
||||
'fetile' => 'feTile',
|
||||
'feturbulence' => 'feTurbulence',
|
||||
'foreignobject' => 'foreignObject',
|
||||
'glyphref' => 'glyphRef',
|
||||
'lineargradient' => 'linearGradient',
|
||||
'radialgradient' => 'radialGradient',
|
||||
'textpath' => 'textPath',
|
||||
);
|
||||
|
||||
/**
|
||||
* Check whether the given element meets the given criterion.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Elements::isA('script', Elements::TEXT_RAW); // Returns true.
|
||||
*
|
||||
* Elements::isA('script', Elements::TEXT_RCDATA); // Returns false.
|
||||
*
|
||||
* @param string $name The element name.
|
||||
* @param int $mask One of the constants on this class.
|
||||
*
|
||||
* @return bool true if the element matches the mask, false otherwise.
|
||||
*/
|
||||
public static function isA($name, $mask)
|
||||
{
|
||||
return (static::element($name) & $mask) === $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if an element is a valid html5 element.
|
||||
*
|
||||
* @param string $name The name of the element.
|
||||
*
|
||||
* @return bool true if a html5 element and false otherwise.
|
||||
*/
|
||||
public static function isHtml5Element($name)
|
||||
{
|
||||
// html5 element names are case insensitive. Forcing lowercase for the check.
|
||||
// Do we need this check or will all data passed here already be lowercase?
|
||||
return isset(static::$html5[strtolower($name)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if an element name is a valid MathML presentation element.
|
||||
*
|
||||
* @param string $name The name of the element.
|
||||
*
|
||||
* @return bool true if a MathML name and false otherwise.
|
||||
*/
|
||||
public static function isMathMLElement($name)
|
||||
{
|
||||
// MathML is case-sensitive unlike html5 elements.
|
||||
return isset(static::$mathml[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if an element is a valid SVG element.
|
||||
*
|
||||
* @param string $name The name of the element.
|
||||
*
|
||||
* @return bool true if a SVG element and false otherise.
|
||||
*/
|
||||
public static function isSvgElement($name)
|
||||
{
|
||||
// SVG is case-sensitive unlike html5 elements.
|
||||
return isset(static::$svg[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is an element name valid in an html5 document.
|
||||
* This includes html5 elements along with other allowed embedded content
|
||||
* such as svg and mathml.
|
||||
*
|
||||
* @param string $name The name of the element.
|
||||
*
|
||||
* @return bool true if valid and false otherwise.
|
||||
*/
|
||||
public static function isElement($name)
|
||||
{
|
||||
return static::isHtml5Element($name) || static::isMathMLElement($name) || static::isSvgElement($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element mask for the given element name.
|
||||
*
|
||||
* @param string $name The name of the element.
|
||||
*
|
||||
* @return int the element mask.
|
||||
*/
|
||||
public static function element($name)
|
||||
{
|
||||
if (isset(static::$html5[$name])) {
|
||||
return static::$html5[$name];
|
||||
}
|
||||
if (isset(static::$svg[$name])) {
|
||||
return static::$svg[$name];
|
||||
}
|
||||
if (isset(static::$mathml[$name])) {
|
||||
return static::$mathml[$name];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a SVG element name to its proper case and form.
|
||||
*
|
||||
* @param string $name The name of the element.
|
||||
*
|
||||
* @return string the normalized form of the element name.
|
||||
*/
|
||||
public static function normalizeSvgElement($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
if (isset(static::$svgCaseSensitiveElementMap[$name])) {
|
||||
$name = static::$svgCaseSensitiveElementMap[$name];
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a SVG attribute name to its proper case and form.
|
||||
*
|
||||
* @param string $name The name of the attribute.
|
||||
*
|
||||
* @return string The normalized form of the attribute name.
|
||||
*/
|
||||
public static function normalizeSvgAttribute($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
if (isset(static::$svgCaseSensitiveAttributeMap[$name])) {
|
||||
$name = static::$svgCaseSensitiveAttributeMap[$name];
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a MathML attribute name to its proper case and form.
|
||||
* Note, all MathML element names are lowercase.
|
||||
*
|
||||
* @param string $name The name of the attribute.
|
||||
*
|
||||
* @return string The normalized form of the attribute name.
|
||||
*/
|
||||
public static function normalizeMathMlAttribute($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
// Only one attribute has a mixed case form for MathML.
|
||||
if ('definitionurl' === $name) {
|
||||
$name = 'definitionURL';
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5;
|
||||
|
||||
/**
|
||||
* The base exception for the HTML5 project.
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* A handler for processor instructions.
|
||||
*/
|
||||
|
||||
namespace Masterminds\HTML5;
|
||||
|
||||
/**
|
||||
* Provide an processor to handle embedded instructions.
|
||||
*
|
||||
* XML defines a mechanism for inserting instructions (like PHP) into a
|
||||
* document. These are called "Processor Instructions." The HTML5 parser
|
||||
* provides an opportunity to handle these processor instructions during
|
||||
* the tree-building phase (before the DOM is constructed), which makes
|
||||
* it possible to alter the document as it is being created.
|
||||
*
|
||||
* One could, for example, use this mechanism to execute well-formed PHP
|
||||
* code embedded inside of an HTML5 document.
|
||||
*/
|
||||
interface InstructionProcessor
|
||||
{
|
||||
/**
|
||||
* Process an individual processing instruction.
|
||||
*
|
||||
* The process() function is responsible for doing the following:
|
||||
* - Determining whether $name is an instruction type it can handle.
|
||||
* - Determining what to do with the data passed in.
|
||||
* - Making any subsequent modifications to the DOM by modifying the
|
||||
* DOMElement or its attached DOM tree.
|
||||
*
|
||||
* @param \DOMElement $element The parent element for the current processing instruction.
|
||||
* @param string $name The instruction's name. E.g. `<?php` has the name `php`.
|
||||
* @param string $data All of the data between the opening and closing PI marks.
|
||||
*
|
||||
* @return \DOMElement The element that should be considered "Current". This may just be
|
||||
* the element passed in, but if the processor added more elements,
|
||||
* it may choose to reset the current element to one of the elements
|
||||
* it created. (When in doubt, return the element passed in.)
|
||||
*/
|
||||
public function process(\DOMElement $element, $name, $data);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
use Masterminds\HTML5\Entities;
|
||||
|
||||
/**
|
||||
* Manage entity references.
|
||||
*
|
||||
* This is a simple resolver for HTML5 character reference entitites. See Entities for the list of supported entities.
|
||||
*/
|
||||
class CharacterReference
|
||||
{
|
||||
protected static $numeric_mask = array(
|
||||
0x0,
|
||||
0x2FFFF,
|
||||
0,
|
||||
0xFFFF,
|
||||
);
|
||||
|
||||
/**
|
||||
* Given a name (e.g. 'amp'), lookup the UTF-8 character ('&').
|
||||
*
|
||||
* @param string $name The name to look up.
|
||||
*
|
||||
* @return string The character sequence. In UTF-8 this may be more than one byte.
|
||||
*/
|
||||
public static function lookupName($name)
|
||||
{
|
||||
// Do we really want to return NULL here? or FFFD
|
||||
return isset(Entities::$byName[$name]) ? Entities::$byName[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a decimal number, return the UTF-8 character.
|
||||
*
|
||||
* @param $int
|
||||
*
|
||||
* @return false|string|string[]|null
|
||||
*/
|
||||
public static function lookupDecimal($int)
|
||||
{
|
||||
$entity = '&#' . $int . ';';
|
||||
|
||||
// UNTESTED: This may fail on some planes. Couldn't find full documentation
|
||||
// on the value of the mask array.
|
||||
return mb_decode_numericentity($entity, static::$numeric_mask, 'utf-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a hexadecimal number, return the UTF-8 character.
|
||||
*
|
||||
* @param $hexdec
|
||||
*
|
||||
* @return false|string|string[]|null
|
||||
*/
|
||||
public static function lookupHex($hexdec)
|
||||
{
|
||||
return static::lookupDecimal(hexdec($hexdec));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,713 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
use Masterminds\HTML5\Elements;
|
||||
use Masterminds\HTML5\InstructionProcessor;
|
||||
|
||||
/**
|
||||
* Create an HTML5 DOM tree from events.
|
||||
*
|
||||
* This attempts to create a DOM from events emitted by a parser. This
|
||||
* attempts (but does not guarantee) to up-convert older HTML documents
|
||||
* to HTML5. It does this by applying HTML5's rules, but it will not
|
||||
* change the architecture of the document itself.
|
||||
*
|
||||
* Many of the error correction and quirks features suggested in the specification
|
||||
* are implemented herein; however, not all of them are. Since we do not
|
||||
* assume a graphical user agent, no presentation-specific logic is conducted
|
||||
* during tree building.
|
||||
*
|
||||
* FIXME: The present tree builder does not exactly follow the state machine rules
|
||||
* for insert modes as outlined in the HTML5 spec. The processor needs to be
|
||||
* re-written to accomodate this. See, for example, the Go language HTML5
|
||||
* parser.
|
||||
*/
|
||||
class DOMTreeBuilder implements EventHandler
|
||||
{
|
||||
/**
|
||||
* Defined in http://www.w3.org/TR/html51/infrastructure.html#html-namespace-0.
|
||||
*/
|
||||
const NAMESPACE_HTML = 'http://www.w3.org/1999/xhtml';
|
||||
|
||||
const NAMESPACE_MATHML = 'http://www.w3.org/1998/Math/MathML';
|
||||
|
||||
const NAMESPACE_SVG = 'http://www.w3.org/2000/svg';
|
||||
|
||||
const NAMESPACE_XLINK = 'http://www.w3.org/1999/xlink';
|
||||
|
||||
const NAMESPACE_XML = 'http://www.w3.org/XML/1998/namespace';
|
||||
|
||||
const NAMESPACE_XMLNS = 'http://www.w3.org/2000/xmlns/';
|
||||
|
||||
const OPT_DISABLE_HTML_NS = 'disable_html_ns';
|
||||
|
||||
const OPT_TARGET_DOC = 'target_document';
|
||||
|
||||
const OPT_IMPLICIT_NS = 'implicit_namespaces';
|
||||
|
||||
/**
|
||||
* Holds the HTML5 element names that causes a namespace switch.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $nsRoots = array(
|
||||
'html' => self::NAMESPACE_HTML,
|
||||
'svg' => self::NAMESPACE_SVG,
|
||||
'math' => self::NAMESPACE_MATHML,
|
||||
);
|
||||
|
||||
/**
|
||||
* Holds the always available namespaces (which does not require the XMLNS declaration).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $implicitNamespaces = array(
|
||||
'xml' => self::NAMESPACE_XML,
|
||||
'xmlns' => self::NAMESPACE_XMLNS,
|
||||
'xlink' => self::NAMESPACE_XLINK,
|
||||
);
|
||||
|
||||
/**
|
||||
* Holds a stack of currently active namespaces.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $nsStack = array();
|
||||
|
||||
/**
|
||||
* Holds the number of namespaces declared by a node.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pushes = array();
|
||||
|
||||
/**
|
||||
* Defined in 8.2.5.
|
||||
*/
|
||||
const IM_INITIAL = 0;
|
||||
|
||||
const IM_BEFORE_HTML = 1;
|
||||
|
||||
const IM_BEFORE_HEAD = 2;
|
||||
|
||||
const IM_IN_HEAD = 3;
|
||||
|
||||
const IM_IN_HEAD_NOSCRIPT = 4;
|
||||
|
||||
const IM_AFTER_HEAD = 5;
|
||||
|
||||
const IM_IN_BODY = 6;
|
||||
|
||||
const IM_TEXT = 7;
|
||||
|
||||
const IM_IN_TABLE = 8;
|
||||
|
||||
const IM_IN_TABLE_TEXT = 9;
|
||||
|
||||
const IM_IN_CAPTION = 10;
|
||||
|
||||
const IM_IN_COLUMN_GROUP = 11;
|
||||
|
||||
const IM_IN_TABLE_BODY = 12;
|
||||
|
||||
const IM_IN_ROW = 13;
|
||||
|
||||
const IM_IN_CELL = 14;
|
||||
|
||||
const IM_IN_SELECT = 15;
|
||||
|
||||
const IM_IN_SELECT_IN_TABLE = 16;
|
||||
|
||||
const IM_AFTER_BODY = 17;
|
||||
|
||||
const IM_IN_FRAMESET = 18;
|
||||
|
||||
const IM_AFTER_FRAMESET = 19;
|
||||
|
||||
const IM_AFTER_AFTER_BODY = 20;
|
||||
|
||||
const IM_AFTER_AFTER_FRAMESET = 21;
|
||||
|
||||
const IM_IN_SVG = 22;
|
||||
|
||||
const IM_IN_MATHML = 23;
|
||||
|
||||
protected $options = array();
|
||||
|
||||
protected $stack = array();
|
||||
|
||||
protected $current; // Pointer in the tag hierarchy.
|
||||
protected $rules;
|
||||
protected $doc;
|
||||
|
||||
protected $frag;
|
||||
|
||||
protected $processor;
|
||||
|
||||
protected $insertMode = 0;
|
||||
|
||||
/**
|
||||
* Track if we are in an element that allows only inline child nodes.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $onlyInline;
|
||||
|
||||
/**
|
||||
* Quirks mode is enabled by default.
|
||||
* Any document that is missing the DT will be considered to be in quirks mode.
|
||||
*/
|
||||
protected $quirks = true;
|
||||
|
||||
protected $errors = array();
|
||||
|
||||
public function __construct($isFragment = false, array $options = array())
|
||||
{
|
||||
$this->options = $options;
|
||||
|
||||
if (isset($options[self::OPT_TARGET_DOC])) {
|
||||
$this->doc = $options[self::OPT_TARGET_DOC];
|
||||
} else {
|
||||
$impl = new \DOMImplementation();
|
||||
// XXX:
|
||||
// Create the doctype. For now, we are always creating HTML5
|
||||
// documents, and attempting to up-convert any older DTDs to HTML5.
|
||||
$dt = $impl->createDocumentType('html');
|
||||
// $this->doc = \DOMImplementation::createDocument(NULL, 'html', $dt);
|
||||
$this->doc = $impl->createDocument(null, '', $dt);
|
||||
$this->doc->encoding = !empty($options['encoding']) ? $options['encoding'] : 'UTF-8';
|
||||
}
|
||||
|
||||
$this->errors = array();
|
||||
|
||||
$this->current = $this->doc; // ->documentElement;
|
||||
|
||||
// Create a rules engine for tags.
|
||||
$this->rules = new TreeBuildingRules();
|
||||
|
||||
$implicitNS = array();
|
||||
if (isset($this->options[self::OPT_IMPLICIT_NS])) {
|
||||
$implicitNS = $this->options[self::OPT_IMPLICIT_NS];
|
||||
} elseif (isset($this->options['implicitNamespaces'])) {
|
||||
$implicitNS = $this->options['implicitNamespaces'];
|
||||
}
|
||||
|
||||
// Fill $nsStack with the defalut HTML5 namespaces, plus the "implicitNamespaces" array taken form $options
|
||||
array_unshift($this->nsStack, $implicitNS + array('' => self::NAMESPACE_HTML) + $this->implicitNamespaces);
|
||||
|
||||
if ($isFragment) {
|
||||
$this->insertMode = static::IM_IN_BODY;
|
||||
$this->frag = $this->doc->createDocumentFragment();
|
||||
$this->current = $this->frag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the document.
|
||||
*/
|
||||
public function document()
|
||||
{
|
||||
return $this->doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DOM fragment for the body.
|
||||
*
|
||||
* This returns a DOMNodeList because a fragment may have zero or more
|
||||
* DOMNodes at its root.
|
||||
*
|
||||
* @see http://www.w3.org/TR/2012/CR-html5-20121217/syntax.html#concept-frag-parse-context
|
||||
*
|
||||
* @return \DOMDocumentFragment
|
||||
*/
|
||||
public function fragment()
|
||||
{
|
||||
return $this->frag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an instruction processor.
|
||||
*
|
||||
* This is used for handling Processor Instructions as they are
|
||||
* inserted. If omitted, PI's are inserted directly into the DOM tree.
|
||||
*/
|
||||
public function setInstructionProcessor(InstructionProcessor $proc)
|
||||
{
|
||||
$this->processor = $proc;
|
||||
}
|
||||
|
||||
public function doctype($name, $idType = 0, $id = null, $quirks = false)
|
||||
{
|
||||
// This is used solely for setting quirks mode. Currently we don't
|
||||
// try to preserve the inbound DT. We convert it to HTML5.
|
||||
$this->quirks = $quirks;
|
||||
|
||||
if ($this->insertMode > static::IM_INITIAL) {
|
||||
$this->parseError('Illegal placement of DOCTYPE tag. Ignoring: ' . $name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->insertMode = static::IM_BEFORE_HTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the start tag.
|
||||
*
|
||||
* @todo - XMLNS namespace handling (we need to parse, even if it's not valid)
|
||||
* - XLink, MathML and SVG namespace handling
|
||||
* - Omission rules: 8.1.2.4 Optional tags
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
* @param bool $selfClosing
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function startTag($name, $attributes = array(), $selfClosing = false)
|
||||
{
|
||||
$lname = $this->normalizeTagName($name);
|
||||
|
||||
// Make sure we have an html element.
|
||||
if (!$this->doc->documentElement && 'html' !== $name && !$this->frag) {
|
||||
$this->startTag('html');
|
||||
}
|
||||
|
||||
// Set quirks mode if we're at IM_INITIAL with no doctype.
|
||||
if ($this->insertMode === static::IM_INITIAL) {
|
||||
$this->quirks = true;
|
||||
$this->parseError('No DOCTYPE specified.');
|
||||
}
|
||||
|
||||
// SPECIAL TAG HANDLING:
|
||||
// Spec says do this, and "don't ask."
|
||||
// find the spec where this is defined... looks problematic
|
||||
if ('image' === $name && !($this->insertMode === static::IM_IN_SVG || $this->insertMode === static::IM_IN_MATHML)) {
|
||||
$name = 'img';
|
||||
}
|
||||
|
||||
// Autoclose p tags where appropriate.
|
||||
if ($this->insertMode >= static::IM_IN_BODY && Elements::isA($name, Elements::AUTOCLOSE_P)) {
|
||||
$this->autoclose('p');
|
||||
}
|
||||
|
||||
// Set insert mode:
|
||||
switch ($name) {
|
||||
case 'html':
|
||||
$this->insertMode = static::IM_BEFORE_HEAD;
|
||||
break;
|
||||
case 'head':
|
||||
if ($this->insertMode > static::IM_BEFORE_HEAD) {
|
||||
$this->parseError('Unexpected head tag outside of head context.');
|
||||
} else {
|
||||
$this->insertMode = static::IM_IN_HEAD;
|
||||
}
|
||||
break;
|
||||
case 'body':
|
||||
$this->insertMode = static::IM_IN_BODY;
|
||||
break;
|
||||
case 'svg':
|
||||
$this->insertMode = static::IM_IN_SVG;
|
||||
break;
|
||||
case 'math':
|
||||
$this->insertMode = static::IM_IN_MATHML;
|
||||
break;
|
||||
case 'noscript':
|
||||
if ($this->insertMode === static::IM_IN_HEAD) {
|
||||
$this->insertMode = static::IM_IN_HEAD_NOSCRIPT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Special case handling for SVG.
|
||||
if ($this->insertMode === static::IM_IN_SVG) {
|
||||
$lname = Elements::normalizeSvgElement($lname);
|
||||
}
|
||||
|
||||
$pushes = 0;
|
||||
// when we found a tag thats appears inside $nsRoots, we have to switch the defalut namespace
|
||||
if (isset($this->nsRoots[$lname]) && $this->nsStack[0][''] !== $this->nsRoots[$lname]) {
|
||||
array_unshift($this->nsStack, array(
|
||||
'' => $this->nsRoots[$lname],
|
||||
) + $this->nsStack[0]);
|
||||
++$pushes;
|
||||
}
|
||||
$needsWorkaround = false;
|
||||
if (isset($this->options['xmlNamespaces']) && $this->options['xmlNamespaces']) {
|
||||
// when xmlNamespaces is true a and we found a 'xmlns' or 'xmlns:*' attribute, we should add a new item to the $nsStack
|
||||
foreach ($attributes as $aName => $aVal) {
|
||||
if ('xmlns' === $aName) {
|
||||
$needsWorkaround = $aVal;
|
||||
array_unshift($this->nsStack, array(
|
||||
'' => $aVal,
|
||||
) + $this->nsStack[0]);
|
||||
++$pushes;
|
||||
} elseif ('xmlns' === (($pos = strpos($aName, ':')) ? substr($aName, 0, $pos) : '')) {
|
||||
array_unshift($this->nsStack, array(
|
||||
substr($aName, $pos + 1) => $aVal,
|
||||
) + $this->nsStack[0]);
|
||||
++$pushes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->onlyInline && Elements::isA($lname, Elements::BLOCK_TAG)) {
|
||||
$this->autoclose($this->onlyInline);
|
||||
$this->onlyInline = null;
|
||||
}
|
||||
|
||||
// some elements as table related tags might have optional end tags that force us to auto close multiple tags
|
||||
// https://www.w3.org/TR/html401/struct/tables.html
|
||||
if ($this->current instanceof \DOMElement && isset(Elements::$optionalEndElementsParentsToClose[$lname])) {
|
||||
foreach (Elements::$optionalEndElementsParentsToClose[$lname] as $parentElName) {
|
||||
if ($this->current instanceof \DOMElement && $this->current->tagName === $parentElName) {
|
||||
$this->autoclose($parentElName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$prefix = ($pos = strpos($lname, ':')) ? substr($lname, 0, $pos) : '';
|
||||
|
||||
if (false !== $needsWorkaround) {
|
||||
$xml = "<$lname xmlns=\"$needsWorkaround\" " . (strlen($prefix) && isset($this->nsStack[0][$prefix]) ? ("xmlns:$prefix=\"" . $this->nsStack[0][$prefix] . '"') : '') . '/>';
|
||||
|
||||
$frag = new \DOMDocument('1.0', 'UTF-8');
|
||||
$frag->loadXML($xml);
|
||||
|
||||
$ele = $this->doc->importNode($frag->documentElement, true);
|
||||
} else {
|
||||
if (!isset($this->nsStack[0][$prefix]) || ('' === $prefix && isset($this->options[self::OPT_DISABLE_HTML_NS]) && $this->options[self::OPT_DISABLE_HTML_NS])) {
|
||||
$ele = $this->doc->createElement($lname);
|
||||
} else {
|
||||
$ele = $this->doc->createElementNS($this->nsStack[0][$prefix], $lname);
|
||||
}
|
||||
}
|
||||
} catch (\DOMException $e) {
|
||||
$this->parseError("Illegal tag name: <$lname>. Replaced with <invalid>.");
|
||||
$ele = $this->doc->createElement('invalid');
|
||||
}
|
||||
|
||||
if (Elements::isA($lname, Elements::BLOCK_ONLY_INLINE)) {
|
||||
$this->onlyInline = $lname;
|
||||
}
|
||||
|
||||
// When we add some namespacess, we have to track them. Later, when "endElement" is invoked, we have to remove them.
|
||||
// When we are on a void tag, we do not need to care about namesapce nesting.
|
||||
if ($pushes > 0 && !Elements::isA($name, Elements::VOID_TAG)) {
|
||||
// PHP tends to free the memory used by DOM,
|
||||
// to avoid spl_object_hash collisions whe have to avoid garbage collection of $ele storing it into $pushes
|
||||
// see https://bugs.php.net/bug.php?id=67459
|
||||
$this->pushes[spl_object_hash($ele)] = array($pushes, $ele);
|
||||
}
|
||||
|
||||
foreach ($attributes as $aName => $aVal) {
|
||||
// xmlns attributes can't be set
|
||||
if ('xmlns' === $aName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->insertMode === static::IM_IN_SVG) {
|
||||
$aName = Elements::normalizeSvgAttribute($aName);
|
||||
} elseif ($this->insertMode === static::IM_IN_MATHML) {
|
||||
$aName = Elements::normalizeMathMlAttribute($aName);
|
||||
}
|
||||
|
||||
$aVal = (string) $aVal;
|
||||
|
||||
try {
|
||||
$prefix = ($pos = strpos($aName, ':')) ? substr($aName, 0, $pos) : false;
|
||||
|
||||
if ('xmlns' === $prefix) {
|
||||
$ele->setAttributeNS(self::NAMESPACE_XMLNS, $aName, $aVal);
|
||||
} elseif (false !== $prefix && isset($this->nsStack[0][$prefix])) {
|
||||
$ele->setAttributeNS($this->nsStack[0][$prefix], $aName, $aVal);
|
||||
} else {
|
||||
$ele->setAttribute($aName, $aVal);
|
||||
}
|
||||
} catch (\DOMException $e) {
|
||||
$this->parseError("Illegal attribute name for tag $name. Ignoring: $aName");
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is necessary on a non-DTD schema, like HTML5.
|
||||
if ('id' === $aName) {
|
||||
$ele->setIdAttribute('id', true);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->frag !== $this->current && $this->rules->hasRules($name)) {
|
||||
// Some elements have special processing rules. Handle those separately.
|
||||
$this->current = $this->rules->evaluate($ele, $this->current);
|
||||
} else {
|
||||
// Otherwise, it's a standard element.
|
||||
$this->current->appendChild($ele);
|
||||
|
||||
if (!Elements::isA($name, Elements::VOID_TAG)) {
|
||||
$this->current = $ele;
|
||||
}
|
||||
|
||||
// Self-closing tags should only be respected on foreign elements
|
||||
// (and are implied on void elements)
|
||||
// See: https://www.w3.org/TR/html5/syntax.html#start-tags
|
||||
if (Elements::isHtml5Element($name)) {
|
||||
$selfClosing = false;
|
||||
}
|
||||
}
|
||||
|
||||
// This is sort of a last-ditch attempt to correct for cases where no head/body
|
||||
// elements are provided.
|
||||
if ($this->insertMode <= static::IM_BEFORE_HEAD && 'head' !== $name && 'html' !== $name) {
|
||||
$this->insertMode = static::IM_IN_BODY;
|
||||
}
|
||||
|
||||
// When we are on a void tag, we do not need to care about namesapce nesting,
|
||||
// but we have to remove the namespaces pushed to $nsStack.
|
||||
if ($pushes > 0 && Elements::isA($name, Elements::VOID_TAG)) {
|
||||
// remove the namespaced definded by current node
|
||||
for ($i = 0; $i < $pushes; ++$i) {
|
||||
array_shift($this->nsStack);
|
||||
}
|
||||
}
|
||||
|
||||
if ($selfClosing) {
|
||||
$this->endTag($name);
|
||||
}
|
||||
|
||||
// Return the element mask, which the tokenizer can then use to set
|
||||
// various processing rules.
|
||||
return Elements::element($name);
|
||||
}
|
||||
|
||||
public function endTag($name)
|
||||
{
|
||||
$lname = $this->normalizeTagName($name);
|
||||
|
||||
// Special case within 12.2.6.4.7: An end tag whose tag name is "br" should be treated as an opening tag
|
||||
if ('br' === $name) {
|
||||
$this->parseError('Closing tag encountered for void element br.');
|
||||
|
||||
$this->startTag('br');
|
||||
}
|
||||
// Ignore closing tags for other unary elements.
|
||||
elseif (Elements::isA($name, Elements::VOID_TAG)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->insertMode <= static::IM_BEFORE_HTML) {
|
||||
// 8.2.5.4.2
|
||||
if (in_array($name, array(
|
||||
'html',
|
||||
'br',
|
||||
'head',
|
||||
'title',
|
||||
))) {
|
||||
$this->startTag('html');
|
||||
$this->endTag($name);
|
||||
$this->insertMode = static::IM_BEFORE_HEAD;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore the tag.
|
||||
$this->parseError('Illegal closing tag at global scope.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Special case handling for SVG.
|
||||
if ($this->insertMode === static::IM_IN_SVG) {
|
||||
$lname = Elements::normalizeSvgElement($lname);
|
||||
}
|
||||
|
||||
$cid = spl_object_hash($this->current);
|
||||
|
||||
// XXX: HTML has no parent. What do we do, though,
|
||||
// if this element appears in the wrong place?
|
||||
if ('html' === $lname) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove the namespaced definded by current node
|
||||
if (isset($this->pushes[$cid])) {
|
||||
for ($i = 0; $i < $this->pushes[$cid][0]; ++$i) {
|
||||
array_shift($this->nsStack);
|
||||
}
|
||||
unset($this->pushes[$cid]);
|
||||
}
|
||||
|
||||
if (!$this->autoclose($lname)) {
|
||||
$this->parseError('Could not find closing tag for ' . $lname);
|
||||
}
|
||||
|
||||
switch ($lname) {
|
||||
case 'head':
|
||||
$this->insertMode = static::IM_AFTER_HEAD;
|
||||
break;
|
||||
case 'body':
|
||||
$this->insertMode = static::IM_AFTER_BODY;
|
||||
break;
|
||||
case 'svg':
|
||||
case 'mathml':
|
||||
$this->insertMode = static::IM_IN_BODY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function comment($cdata)
|
||||
{
|
||||
// TODO: Need to handle case where comment appears outside of the HTML tag.
|
||||
$node = $this->doc->createComment($cdata);
|
||||
$this->current->appendChild($node);
|
||||
}
|
||||
|
||||
public function text($data)
|
||||
{
|
||||
// XXX: Hmmm.... should we really be this strict?
|
||||
if ($this->insertMode < static::IM_IN_HEAD) {
|
||||
// Per '8.2.5.4.3 The "before head" insertion mode' the characters
|
||||
// " \t\n\r\f" should be ignored but no mention of a parse error. This is
|
||||
// practical as most documents contain these characters. Other text is not
|
||||
// expected here so recording a parse error is necessary.
|
||||
$dataTmp = trim($data, " \t\n\r\f");
|
||||
if (!empty($dataTmp)) {
|
||||
// fprintf(STDOUT, "Unexpected insert mode: %d", $this->insertMode);
|
||||
$this->parseError('Unexpected text. Ignoring: ' . $dataTmp);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// fprintf(STDOUT, "Appending text %s.", $data);
|
||||
$node = $this->doc->createTextNode($data);
|
||||
$this->current->appendChild($node);
|
||||
}
|
||||
|
||||
public function eof()
|
||||
{
|
||||
// If the $current isn't the $root, do we need to do anything?
|
||||
}
|
||||
|
||||
public function parseError($msg, $line = 0, $col = 0)
|
||||
{
|
||||
$this->errors[] = sprintf('Line %d, Col %d: %s', $line, $col, $msg);
|
||||
}
|
||||
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function cdata($data)
|
||||
{
|
||||
$node = $this->doc->createCDATASection($data);
|
||||
$this->current->appendChild($node);
|
||||
}
|
||||
|
||||
public function processingInstruction($name, $data = null)
|
||||
{
|
||||
// XXX: Ignore initial XML declaration, per the spec.
|
||||
if ($this->insertMode === static::IM_INITIAL && 'xml' === strtolower($name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Important: The processor may modify the current DOM tree however it sees fit.
|
||||
if ($this->processor instanceof InstructionProcessor) {
|
||||
$res = $this->processor->process($this->current, $name, $data);
|
||||
if (!empty($res)) {
|
||||
$this->current = $res;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, this is just a dumb PI element.
|
||||
$node = $this->doc->createProcessingInstruction($name, $data);
|
||||
|
||||
$this->current->appendChild($node);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// UTILITIES
|
||||
// ==========================================================================
|
||||
|
||||
/**
|
||||
* Apply normalization rules to a tag name.
|
||||
* See sections 2.9 and 8.1.2.
|
||||
*
|
||||
* @param string $tagName
|
||||
*
|
||||
* @return string The normalized tag name.
|
||||
*/
|
||||
protected function normalizeTagName($tagName)
|
||||
{
|
||||
/*
|
||||
* Section 2.9 suggests that we should not do this. if (strpos($name, ':') !== false) { // We know from the grammar that there must be at least one other // char besides :, since : is not a legal tag start. $parts = explode(':', $name); return array_pop($parts); }
|
||||
*/
|
||||
return $tagName;
|
||||
}
|
||||
|
||||
protected function quirksTreeResolver($name)
|
||||
{
|
||||
throw new \Exception('Not implemented.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically climb the tree and close the closest node with the matching $tag.
|
||||
*
|
||||
* @param string $tagName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function autoclose($tagName)
|
||||
{
|
||||
$working = $this->current;
|
||||
do {
|
||||
if (XML_ELEMENT_NODE !== $working->nodeType) {
|
||||
return false;
|
||||
}
|
||||
if ($working->tagName === $tagName) {
|
||||
$this->current = $working->parentNode;
|
||||
|
||||
return true;
|
||||
}
|
||||
} while ($working = $working->parentNode);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given tagname is an ancestor of the present candidate.
|
||||
*
|
||||
* If $this->current or anything above $this->current matches the given tag
|
||||
* name, this returns true.
|
||||
*
|
||||
* @param string $tagName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAncestor($tagName)
|
||||
{
|
||||
$candidate = $this->current;
|
||||
while (XML_ELEMENT_NODE === $candidate->nodeType) {
|
||||
if ($candidate->tagName === $tagName) {
|
||||
return true;
|
||||
}
|
||||
$candidate = $candidate->parentNode;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the immediate parent element is of the given tagname.
|
||||
*
|
||||
* @param string $tagName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isParent($tagName)
|
||||
{
|
||||
return $this->current->tagName === $tagName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
/**
|
||||
* Standard events for HTML5.
|
||||
*
|
||||
* This is roughly analogous to a SAX2 or expat-style interface.
|
||||
* However, it is tuned specifically for HTML5, according to section 8
|
||||
* of the HTML5 specification.
|
||||
*
|
||||
* An event handler receives parser events. For a concrete
|
||||
* implementation, see DOMTreeBuilder.
|
||||
*
|
||||
* Quirks support in the parser is limited to close-in syntax (malformed
|
||||
* tags or attributes). Higher order syntax and semantic issues with a
|
||||
* document (e.g. mismatched tags, illegal nesting, etc.) are the
|
||||
* responsibility of the event handler implementation.
|
||||
*
|
||||
* See HTML5 spec section 8.2.4
|
||||
*/
|
||||
interface EventHandler
|
||||
{
|
||||
const DOCTYPE_NONE = 0;
|
||||
|
||||
const DOCTYPE_PUBLIC = 1;
|
||||
|
||||
const DOCTYPE_SYSTEM = 2;
|
||||
|
||||
/**
|
||||
* A doctype declaration.
|
||||
*
|
||||
* @param string $name The name of the root element.
|
||||
* @param int $idType One of DOCTYPE_NONE, DOCTYPE_PUBLIC, or DOCTYPE_SYSTEM
|
||||
* @param string $id The identifier. For DOCTYPE_PUBLIC, this is the public ID. If DOCTYPE_SYSTEM,
|
||||
* then this is a system ID.
|
||||
* @param bool $quirks Indicates whether the builder should enter quirks mode.
|
||||
*/
|
||||
public function doctype($name, $idType = 0, $id = null, $quirks = false);
|
||||
|
||||
/**
|
||||
* A start tag.
|
||||
*
|
||||
* IMPORTANT: The parser watches the return value of this event. If this returns
|
||||
* an integer, the parser will switch TEXTMODE patters according to the int.
|
||||
*
|
||||
* This is how the Tree Builder can tell the Tokenizer when a certain tag should
|
||||
* cause the parser to go into RAW text mode.
|
||||
*
|
||||
* The HTML5 standard requires that the builder is the one that initiates this
|
||||
* step, and this is the only way short of a circular reference that we can
|
||||
* do that.
|
||||
*
|
||||
* Example: if a startTag even for a `script` name is fired, and the startTag()
|
||||
* implementation returns Tokenizer::TEXTMODE_RAW, then the tokenizer will
|
||||
* switch into RAW text mode and consume data until it reaches a closing
|
||||
* `script` tag.
|
||||
*
|
||||
* The textmode is automatically reset to Tokenizer::TEXTMODE_NORMAL when the
|
||||
* closing tag is encounter. **This behavior may change.**
|
||||
*
|
||||
* @param string $name The tag name.
|
||||
* @param array $attributes An array with all of the tag's attributes.
|
||||
* @param bool $selfClosing An indicator of whether or not this tag is self-closing (<foo/>).
|
||||
*
|
||||
* @return int one of the Tokenizer::TEXTMODE_* constants
|
||||
*/
|
||||
public function startTag($name, $attributes = array(), $selfClosing = false);
|
||||
|
||||
/**
|
||||
* An end-tag.
|
||||
*/
|
||||
public function endTag($name);
|
||||
|
||||
/**
|
||||
* A comment section (unparsed character data).
|
||||
*/
|
||||
public function comment($cdata);
|
||||
|
||||
/**
|
||||
* A unit of parsed character data.
|
||||
*
|
||||
* Entities in this text are *already decoded*.
|
||||
*/
|
||||
public function text($cdata);
|
||||
|
||||
/**
|
||||
* Indicates that the document has been entirely processed.
|
||||
*/
|
||||
public function eof();
|
||||
|
||||
/**
|
||||
* Emitted when the parser encounters an error condition.
|
||||
*/
|
||||
public function parseError($msg, $line, $col);
|
||||
|
||||
/**
|
||||
* A CDATA section.
|
||||
*
|
||||
* @param string $data
|
||||
* The unparsed character data
|
||||
*/
|
||||
public function cdata($data);
|
||||
|
||||
/**
|
||||
* This is a holdover from the XML spec.
|
||||
*
|
||||
* While user agents don't get PIs, server-side does.
|
||||
*
|
||||
* @param string $name The name of the processor (e.g. 'php').
|
||||
* @param string $data The unparsed data.
|
||||
*/
|
||||
public function processingInstruction($name, $data = null);
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
/**
|
||||
* The FileInputStream loads a file to be parsed.
|
||||
*
|
||||
* So right now we read files into strings and then process the
|
||||
* string. We chose to do this largely for the sake of expediency of
|
||||
* development, and also because we could optimize toward processing
|
||||
* arbitrarily large chunks of the input. But in the future, we'd
|
||||
* really like to rewrite this class to efficiently handle lower level
|
||||
* stream reads (and thus efficiently handle large documents).
|
||||
*
|
||||
* @deprecated since 2.4, to remove in 3.0. Use a string in the scanner instead.
|
||||
*/
|
||||
class FileInputStream extends StringInputStream implements InputStream
|
||||
{
|
||||
/**
|
||||
* Load a file input stream.
|
||||
*
|
||||
* @param string $data The file or url path to load.
|
||||
* @param string $encoding The encoding to use for the data.
|
||||
* @param string $debug A fprintf format to use to echo the data on stdout.
|
||||
*/
|
||||
public function __construct($data, $encoding = 'UTF-8', $debug = '')
|
||||
{
|
||||
// Get the contents of the file.
|
||||
$content = file_get_contents($data);
|
||||
|
||||
parent::__construct($content, $encoding, $debug);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
/**
|
||||
* Interface for stream readers.
|
||||
*
|
||||
* The parser only reads from streams. Various input sources can write
|
||||
* an adapater to this InputStream.
|
||||
*
|
||||
* Currently provided InputStream implementations include
|
||||
* FileInputStream and StringInputStream.
|
||||
*
|
||||
* @deprecated since 2.4, to remove in 3.0. Use a string in the scanner instead.
|
||||
*/
|
||||
interface InputStream extends \Iterator
|
||||
{
|
||||
/**
|
||||
* Returns the current line that is being consumed.
|
||||
*
|
||||
* TODO: Move this to the scanner.
|
||||
*/
|
||||
public function currentLine();
|
||||
|
||||
/**
|
||||
* Returns the current column of the current line that the tokenizer is at.
|
||||
*
|
||||
* Newlines are column 0. The first char after a newline is column 1.
|
||||
*
|
||||
* @TODO Move this to the scanner.
|
||||
*
|
||||
* @return int The column number.
|
||||
*/
|
||||
public function columnOffset();
|
||||
|
||||
/**
|
||||
* Get all characters until EOF.
|
||||
*
|
||||
* This consumes characters until the EOF.
|
||||
*/
|
||||
public function remainingChars();
|
||||
|
||||
/**
|
||||
* Read to a particular match (or until $max bytes are consumed).
|
||||
*
|
||||
* This operates on byte sequences, not characters.
|
||||
*
|
||||
* Matches as far as possible until we reach a certain set of bytes
|
||||
* and returns the matched substring.
|
||||
*
|
||||
* @see strcspn
|
||||
*
|
||||
* @param string $bytes Bytes to match.
|
||||
* @param int $max Maximum number of bytes to scan.
|
||||
*
|
||||
* @return mixed Index or false if no match is found. You should use strong
|
||||
* equality when checking the result, since index could be 0.
|
||||
*/
|
||||
public function charsUntil($bytes, $max = null);
|
||||
|
||||
/**
|
||||
* Returns the string so long as $bytes matches.
|
||||
*
|
||||
* Matches as far as possible with a certain set of bytes
|
||||
* and returns the matched substring.
|
||||
*
|
||||
* @see strspn
|
||||
*
|
||||
* @param string $bytes A mask of bytes to match. If ANY byte in this mask matches the
|
||||
* current char, the pointer advances and the char is part of the
|
||||
* substring.
|
||||
* @param int $max The max number of chars to read.
|
||||
*/
|
||||
public function charsWhile($bytes, $max = null);
|
||||
|
||||
/**
|
||||
* Unconsume one character.
|
||||
*
|
||||
* @param int $howMany The number of characters to move the pointer back.
|
||||
*/
|
||||
public function unconsume($howMany = 1);
|
||||
|
||||
/**
|
||||
* Retrieve the next character without advancing the pointer.
|
||||
*/
|
||||
public function peek();
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
/**
|
||||
* Emit when the parser has an error.
|
||||
*/
|
||||
class ParseError extends \Exception
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# The Parser Model
|
||||
|
||||
The parser model here follows the model in section
|
||||
[8.2.1](http://www.w3.org/TR/2012/CR-html5-20121217/syntax.html#parsing)
|
||||
of the HTML5 specification, though we do not assume a networking layer.
|
||||
|
||||
[ InputStream ] // Generic support for reading input.
|
||||
||
|
||||
[ Scanner ] // Breaks down the stream into characters.
|
||||
||
|
||||
[ Tokenizer ] // Groups characters into syntactic
|
||||
||
|
||||
[ Tree Builder ] // Organizes units into a tree of objects
|
||||
||
|
||||
[ DOM Document ] // The final state of the parsed document.
|
||||
|
||||
|
||||
## InputStream
|
||||
|
||||
This is an interface with at least two concrete implementations:
|
||||
|
||||
- StringInputStream: Reads an HTML5 string.
|
||||
- FileInputStream: Reads an HTML5 file.
|
||||
|
||||
## Scanner
|
||||
|
||||
This is a mechanical piece of the parser.
|
||||
|
||||
## Tokenizer
|
||||
|
||||
This follows section 8.4 of the HTML5 spec. It is (roughly) a recursive
|
||||
descent parser. (Though there are plenty of optimizations that are less
|
||||
than purely functional.
|
||||
|
||||
## EventHandler and DOMTree
|
||||
|
||||
EventHandler is the interface for tree builders. Since not all
|
||||
implementations will necessarily build trees, we've chosen a more
|
||||
generic name.
|
||||
|
||||
The event handler emits tokens during tokenization.
|
||||
|
||||
The DOMTree is an event handler that builds a DOM tree. The output of
|
||||
the DOMTree builder is a DOMDocument.
|
||||
|
||||
## DOMDocument
|
||||
|
||||
PHP has a DOMDocument class built-in (technically, it's part of libxml.)
|
||||
We use that, thus rendering the output of this process compatible with
|
||||
SimpleXML, QueryPath, and many other XML/HTML processing tools.
|
||||
|
||||
For cases where the HTML5 is a fragment of a HTML5 document a
|
||||
DOMDocumentFragment is returned instead. This is another built-in class.
|
||||
|
|
@ -0,0 +1,416 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
use Masterminds\HTML5\Exception;
|
||||
|
||||
/**
|
||||
* The scanner scans over a given data input to react appropriately to characters.
|
||||
*/
|
||||
class Scanner
|
||||
{
|
||||
const CHARS_HEX = 'abcdefABCDEF01234567890';
|
||||
const CHARS_ALNUM = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
|
||||
const CHARS_ALPHA = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
/**
|
||||
* The string data we're parsing.
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* The current integer byte position we are in $data.
|
||||
*/
|
||||
private $char;
|
||||
|
||||
/**
|
||||
* Length of $data; when $char === $data, we are at the end-of-file.
|
||||
*/
|
||||
private $EOF;
|
||||
|
||||
/**
|
||||
* Parse errors.
|
||||
*/
|
||||
public $errors = array();
|
||||
|
||||
/**
|
||||
* Create a new Scanner.
|
||||
*
|
||||
* @param string $data Data to parse.
|
||||
* @param string $encoding The encoding to use for the data.
|
||||
*
|
||||
* @throws Exception If the given data cannot be encoded to UTF-8.
|
||||
*/
|
||||
public function __construct($data, $encoding = 'UTF-8')
|
||||
{
|
||||
if ($data instanceof InputStream) {
|
||||
@trigger_error('InputStream objects are deprecated since version 2.4 and will be removed in 3.0. Use strings instead.', E_USER_DEPRECATED);
|
||||
$data = (string) $data;
|
||||
}
|
||||
|
||||
$data = UTF8Utils::convertToUTF8($data, $encoding);
|
||||
|
||||
// There is good reason to question whether it makes sense to
|
||||
// do this here, since most of these checks are done during
|
||||
// parsing, and since this check doesn't actually *do* anything.
|
||||
$this->errors = UTF8Utils::checkForIllegalCodepoints($data);
|
||||
|
||||
$data = $this->replaceLinefeeds($data);
|
||||
|
||||
$this->data = $data;
|
||||
$this->char = 0;
|
||||
$this->EOF = strlen($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if upcomming chars match the given sequence.
|
||||
*
|
||||
* This will read the stream for the $sequence. If it's
|
||||
* found, this will return true. If not, return false.
|
||||
* Since this unconsumes any chars it reads, the caller
|
||||
* will still need to read the next sequence, even if
|
||||
* this returns true.
|
||||
*
|
||||
* Example: $this->scanner->sequenceMatches('</script>') will
|
||||
* see if the input stream is at the start of a
|
||||
* '</script>' string.
|
||||
*
|
||||
* @param string $sequence
|
||||
* @param bool $caseSensitive
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sequenceMatches($sequence, $caseSensitive = true)
|
||||
{
|
||||
$portion = substr($this->data, $this->char, strlen($sequence));
|
||||
|
||||
return $caseSensitive ? $portion === $sequence : 0 === strcasecmp($portion, $sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position.
|
||||
*
|
||||
* @return int The current intiger byte position.
|
||||
*/
|
||||
public function position()
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a peek at the next character in the data.
|
||||
*
|
||||
* @return string The next character.
|
||||
*/
|
||||
public function peek()
|
||||
{
|
||||
if (($this->char + 1) < $this->EOF) {
|
||||
return $this->data[$this->char + 1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next character.
|
||||
* Note: This advances the pointer.
|
||||
*
|
||||
* @return string The next character.
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
++$this->char;
|
||||
|
||||
if ($this->char < $this->EOF) {
|
||||
return $this->data[$this->char];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current character.
|
||||
* Note, this does not advance the pointer.
|
||||
*
|
||||
* @return string The current character.
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->char < $this->EOF) {
|
||||
return $this->data[$this->char];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Silently consume N chars.
|
||||
*
|
||||
* @param int $count
|
||||
*/
|
||||
public function consume($count = 1)
|
||||
{
|
||||
$this->char += $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unconsume some of the data.
|
||||
* This moves the data pointer backwards.
|
||||
*
|
||||
* @param int $howMany The number of characters to move the pointer back.
|
||||
*/
|
||||
public function unconsume($howMany = 1)
|
||||
{
|
||||
if (($this->char - $howMany) >= 0) {
|
||||
$this->char -= $howMany;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next group of that contains hex characters.
|
||||
* Note, along with getting the characters the pointer in the data will be
|
||||
* moved as well.
|
||||
*
|
||||
* @return string The next group that is hex characters.
|
||||
*/
|
||||
public function getHex()
|
||||
{
|
||||
return $this->doCharsWhile(static::CHARS_HEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next group of characters that are ASCII Alpha characters.
|
||||
* Note, along with getting the characters the pointer in the data will be
|
||||
* moved as well.
|
||||
*
|
||||
* @return string The next group of ASCII alpha characters.
|
||||
*/
|
||||
public function getAsciiAlpha()
|
||||
{
|
||||
return $this->doCharsWhile(static::CHARS_ALPHA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next group of characters that are ASCII Alpha characters and numbers.
|
||||
* Note, along with getting the characters the pointer in the data will be
|
||||
* moved as well.
|
||||
*
|
||||
* @return string The next group of ASCII alpha characters and numbers.
|
||||
*/
|
||||
public function getAsciiAlphaNum()
|
||||
{
|
||||
return $this->doCharsWhile(static::CHARS_ALNUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next group of numbers.
|
||||
* Note, along with getting the characters the pointer in the data will be
|
||||
* moved as well.
|
||||
*
|
||||
* @return string The next group of numbers.
|
||||
*/
|
||||
public function getNumeric()
|
||||
{
|
||||
return $this->doCharsWhile('0123456789');
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume whitespace.
|
||||
* Whitespace in HTML5 is: formfeed, tab, newline, space.
|
||||
*
|
||||
* @return int The length of the matched whitespaces.
|
||||
*/
|
||||
public function whitespace()
|
||||
{
|
||||
if ($this->char >= $this->EOF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$len = strspn($this->data, "\n\t\f ", $this->char);
|
||||
|
||||
$this->char += $len;
|
||||
|
||||
return $len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current line that is being consumed.
|
||||
*
|
||||
* @return int The current line number.
|
||||
*/
|
||||
public function currentLine()
|
||||
{
|
||||
if (empty($this->EOF) || 0 === $this->char) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Add one to $this->char because we want the number for the next
|
||||
// byte to be processed.
|
||||
return substr_count($this->data, "\n", 0, min($this->char, $this->EOF)) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read chars until something in the mask is encountered.
|
||||
*
|
||||
* @param string $mask
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function charsUntil($mask)
|
||||
{
|
||||
return $this->doCharsUntil($mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read chars as long as the mask matches.
|
||||
*
|
||||
* @param string $mask
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function charsWhile($mask)
|
||||
{
|
||||
return $this->doCharsWhile($mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current column of the current line that the tokenizer is at.
|
||||
*
|
||||
* Newlines are column 0. The first char after a newline is column 1.
|
||||
*
|
||||
* @return int The column number.
|
||||
*/
|
||||
public function columnOffset()
|
||||
{
|
||||
// Short circuit for the first char.
|
||||
if (0 === $this->char) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// strrpos is weird, and the offset needs to be negative for what we
|
||||
// want (i.e., the last \n before $this->char). This needs to not have
|
||||
// one (to make it point to the next character, the one we want the
|
||||
// position of) added to it because strrpos's behaviour includes the
|
||||
// final offset byte.
|
||||
$backwardFrom = $this->char - 1 - strlen($this->data);
|
||||
$lastLine = strrpos($this->data, "\n", $backwardFrom);
|
||||
|
||||
// However, for here we want the length up until the next byte to be
|
||||
// processed, so add one to the current byte ($this->char).
|
||||
if (false !== $lastLine) {
|
||||
$findLengthOf = substr($this->data, $lastLine + 1, $this->char - 1 - $lastLine);
|
||||
} else {
|
||||
// After a newline.
|
||||
$findLengthOf = substr($this->data, 0, $this->char);
|
||||
}
|
||||
|
||||
return UTF8Utils::countChars($findLengthOf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all characters until EOF.
|
||||
*
|
||||
* This consumes characters until the EOF.
|
||||
*
|
||||
* @return int The number of characters remaining.
|
||||
*/
|
||||
public function remainingChars()
|
||||
{
|
||||
if ($this->char < $this->EOF) {
|
||||
$data = substr($this->data, $this->char);
|
||||
$this->char = $this->EOF;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return ''; // false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace linefeed characters according to the spec.
|
||||
*
|
||||
* @param $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function replaceLinefeeds($data)
|
||||
{
|
||||
/*
|
||||
* U+000D CARRIAGE RETURN (CR) characters and U+000A LINE FEED (LF) characters are treated specially.
|
||||
* Any CR characters that are followed by LF characters must be removed, and any CR characters not
|
||||
* followed by LF characters must be converted to LF characters. Thus, newlines in HTML DOMs are
|
||||
* represented by LF characters, and there are never any CR characters in the input to the tokenization
|
||||
* stage.
|
||||
*/
|
||||
$crlfTable = array(
|
||||
"\0" => "\xEF\xBF\xBD",
|
||||
"\r\n" => "\n",
|
||||
"\r" => "\n",
|
||||
);
|
||||
|
||||
return strtr($data, $crlfTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read to a particular match (or until $max bytes are consumed).
|
||||
*
|
||||
* This operates on byte sequences, not characters.
|
||||
*
|
||||
* Matches as far as possible until we reach a certain set of bytes
|
||||
* and returns the matched substring.
|
||||
*
|
||||
* @param string $bytes Bytes to match.
|
||||
* @param int $max Maximum number of bytes to scan.
|
||||
*
|
||||
* @return mixed Index or false if no match is found. You should use strong
|
||||
* equality when checking the result, since index could be 0.
|
||||
*/
|
||||
private function doCharsUntil($bytes, $max = null)
|
||||
{
|
||||
if ($this->char >= $this->EOF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 === $max || $max) {
|
||||
$len = strcspn($this->data, $bytes, $this->char, $max);
|
||||
} else {
|
||||
$len = strcspn($this->data, $bytes, $this->char);
|
||||
}
|
||||
|
||||
$string = (string) substr($this->data, $this->char, $len);
|
||||
$this->char += $len;
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string so long as $bytes matches.
|
||||
*
|
||||
* Matches as far as possible with a certain set of bytes
|
||||
* and returns the matched substring.
|
||||
*
|
||||
* @param string $bytes A mask of bytes to match. If ANY byte in this mask matches the
|
||||
* current char, the pointer advances and the char is part of the
|
||||
* substring.
|
||||
* @param int $max The max number of chars to read.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function doCharsWhile($bytes, $max = null)
|
||||
{
|
||||
if ($this->char >= $this->EOF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 === $max || $max) {
|
||||
$len = strspn($this->data, $bytes, $this->char, $max);
|
||||
} else {
|
||||
$len = strspn($this->data, $bytes, $this->char);
|
||||
}
|
||||
|
||||
$string = (string) substr($this->data, $this->char, $len);
|
||||
$this->char += $len;
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
<?php
|
||||
/**
|
||||
* Loads a string to be parsed.
|
||||
*/
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
/*
|
||||
*
|
||||
* Based on code from html5lib:
|
||||
|
||||
Copyright 2009 Geoffrey Sneddon <http://gsnedders.com/>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Some conventions:
|
||||
// - /* */ indicates verbatim text from the HTML 5 specification
|
||||
// MPB: Not sure which version of the spec. Moving from HTML5lib to
|
||||
// HTML5-PHP, I have been using this version:
|
||||
// http://www.w3.org/TR/2012/CR-html5-20121217/Overview.html#contents
|
||||
//
|
||||
// - // indicates regular comments
|
||||
|
||||
/**
|
||||
* @deprecated since 2.4, to remove in 3.0. Use a string in the scanner instead.
|
||||
*/
|
||||
class StringInputStream implements InputStream
|
||||
{
|
||||
/**
|
||||
* The string data we're parsing.
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* The current integer byte position we are in $data.
|
||||
*/
|
||||
private $char;
|
||||
|
||||
/**
|
||||
* Length of $data; when $char === $data, we are at the end-of-file.
|
||||
*/
|
||||
private $EOF;
|
||||
|
||||
/**
|
||||
* Parse errors.
|
||||
*/
|
||||
public $errors = array();
|
||||
|
||||
/**
|
||||
* Create a new InputStream wrapper.
|
||||
*
|
||||
* @param string $data Data to parse.
|
||||
* @param string $encoding The encoding to use for the data.
|
||||
* @param string $debug A fprintf format to use to echo the data on stdout.
|
||||
*/
|
||||
public function __construct($data, $encoding = 'UTF-8', $debug = '')
|
||||
{
|
||||
$data = UTF8Utils::convertToUTF8($data, $encoding);
|
||||
if ($debug) {
|
||||
fprintf(STDOUT, $debug, $data, strlen($data));
|
||||
}
|
||||
|
||||
// There is good reason to question whether it makes sense to
|
||||
// do this here, since most of these checks are done during
|
||||
// parsing, and since this check doesn't actually *do* anything.
|
||||
$this->errors = UTF8Utils::checkForIllegalCodepoints($data);
|
||||
|
||||
$data = $this->replaceLinefeeds($data);
|
||||
|
||||
$this->data = $data;
|
||||
$this->char = 0;
|
||||
$this->EOF = strlen($data);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace linefeed characters according to the spec.
|
||||
*/
|
||||
protected function replaceLinefeeds($data)
|
||||
{
|
||||
/*
|
||||
* U+000D CARRIAGE RETURN (CR) characters and U+000A LINE FEED (LF) characters are treated specially.
|
||||
* Any CR characters that are followed by LF characters must be removed, and any CR characters not
|
||||
* followed by LF characters must be converted to LF characters. Thus, newlines in HTML DOMs are
|
||||
* represented by LF characters, and there are never any CR characters in the input to the tokenization
|
||||
* stage.
|
||||
*/
|
||||
$crlfTable = array(
|
||||
"\0" => "\xEF\xBF\xBD",
|
||||
"\r\n" => "\n",
|
||||
"\r" => "\n",
|
||||
);
|
||||
|
||||
return strtr($data, $crlfTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current line that the tokenizer is at.
|
||||
*/
|
||||
public function currentLine()
|
||||
{
|
||||
if (empty($this->EOF) || 0 === $this->char) {
|
||||
return 1;
|
||||
}
|
||||
// Add one to $this->char because we want the number for the next
|
||||
// byte to be processed.
|
||||
return substr_count($this->data, "\n", 0, min($this->char, $this->EOF)) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function getCurrentLine()
|
||||
{
|
||||
return $this->currentLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current column of the current line that the tokenizer is at.
|
||||
* Newlines are column 0. The first char after a newline is column 1.
|
||||
*
|
||||
* @return int The column number.
|
||||
*/
|
||||
public function columnOffset()
|
||||
{
|
||||
// Short circuit for the first char.
|
||||
if (0 === $this->char) {
|
||||
return 0;
|
||||
}
|
||||
// strrpos is weird, and the offset needs to be negative for what we
|
||||
// want (i.e., the last \n before $this->char). This needs to not have
|
||||
// one (to make it point to the next character, the one we want the
|
||||
// position of) added to it because strrpos's behaviour includes the
|
||||
// final offset byte.
|
||||
$backwardFrom = $this->char - 1 - strlen($this->data);
|
||||
$lastLine = strrpos($this->data, "\n", $backwardFrom);
|
||||
|
||||
// However, for here we want the length up until the next byte to be
|
||||
// processed, so add one to the current byte ($this->char).
|
||||
if (false !== $lastLine) {
|
||||
$findLengthOf = substr($this->data, $lastLine + 1, $this->char - 1 - $lastLine);
|
||||
} else {
|
||||
// After a newline.
|
||||
$findLengthOf = substr($this->data, 0, $this->char);
|
||||
}
|
||||
|
||||
return UTF8Utils::countChars($findLengthOf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function getColumnOffset()
|
||||
{
|
||||
return $this->columnOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current character.
|
||||
*
|
||||
* @return string The current character.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->data[$this->char];
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance the pointer.
|
||||
* This is part of the Iterator interface.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
++$this->char;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind to the start of the string.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->char = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the current pointer location valid.
|
||||
*
|
||||
* @return bool Whether the current pointer location is valid.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->char < $this->EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all characters until EOF.
|
||||
*
|
||||
* This reads to the end of the file, and sets the read marker at the
|
||||
* end of the file.
|
||||
*
|
||||
* Note this performs bounds checking.
|
||||
*
|
||||
* @return string Returns the remaining text. If called when the InputStream is
|
||||
* already exhausted, it returns an empty string.
|
||||
*/
|
||||
public function remainingChars()
|
||||
{
|
||||
if ($this->char < $this->EOF) {
|
||||
$data = substr($this->data, $this->char);
|
||||
$this->char = $this->EOF;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return ''; // false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read to a particular match (or until $max bytes are consumed).
|
||||
*
|
||||
* This operates on byte sequences, not characters.
|
||||
*
|
||||
* Matches as far as possible until we reach a certain set of bytes
|
||||
* and returns the matched substring.
|
||||
*
|
||||
* @param string $bytes Bytes to match.
|
||||
* @param int $max Maximum number of bytes to scan.
|
||||
*
|
||||
* @return mixed Index or false if no match is found. You should use strong
|
||||
* equality when checking the result, since index could be 0.
|
||||
*/
|
||||
public function charsUntil($bytes, $max = null)
|
||||
{
|
||||
if ($this->char >= $this->EOF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 === $max || $max) {
|
||||
$len = strcspn($this->data, $bytes, $this->char, $max);
|
||||
} else {
|
||||
$len = strcspn($this->data, $bytes, $this->char);
|
||||
}
|
||||
|
||||
$string = (string) substr($this->data, $this->char, $len);
|
||||
$this->char += $len;
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string so long as $bytes matches.
|
||||
*
|
||||
* Matches as far as possible with a certain set of bytes
|
||||
* and returns the matched substring.
|
||||
*
|
||||
* @param string $bytes A mask of bytes to match. If ANY byte in this mask matches the
|
||||
* current char, the pointer advances and the char is part of the
|
||||
* substring.
|
||||
* @param int $max The max number of chars to read.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function charsWhile($bytes, $max = null)
|
||||
{
|
||||
if ($this->char >= $this->EOF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 === $max || $max) {
|
||||
$len = strspn($this->data, $bytes, $this->char, $max);
|
||||
} else {
|
||||
$len = strspn($this->data, $bytes, $this->char);
|
||||
}
|
||||
$string = (string) substr($this->data, $this->char, $len);
|
||||
$this->char += $len;
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unconsume characters.
|
||||
*
|
||||
* @param int $howMany The number of characters to unconsume.
|
||||
*/
|
||||
public function unconsume($howMany = 1)
|
||||
{
|
||||
if (($this->char - $howMany) >= 0) {
|
||||
$this->char -= $howMany;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look ahead without moving cursor.
|
||||
*/
|
||||
public function peek()
|
||||
{
|
||||
if (($this->char + 1) <= $this->EOF) {
|
||||
return $this->data[$this->char + 1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
/**
|
||||
* Handles special-case rules for the DOM tree builder.
|
||||
*
|
||||
* Many tags have special rules that need to be accomodated on an
|
||||
* individual basis. This class handles those rules.
|
||||
*
|
||||
* See section 8.1.2.4 of the spec.
|
||||
*
|
||||
* @todo - colgroup and col special behaviors
|
||||
* - body and head special behaviors
|
||||
*/
|
||||
class TreeBuildingRules
|
||||
{
|
||||
protected static $tags = array(
|
||||
'li' => 1,
|
||||
'dd' => 1,
|
||||
'dt' => 1,
|
||||
'rt' => 1,
|
||||
'rp' => 1,
|
||||
'tr' => 1,
|
||||
'th' => 1,
|
||||
'td' => 1,
|
||||
'thead' => 1,
|
||||
'tfoot' => 1,
|
||||
'tbody' => 1,
|
||||
'table' => 1,
|
||||
'optgroup' => 1,
|
||||
'option' => 1,
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns true if the given tagname has special processing rules.
|
||||
*/
|
||||
public function hasRules($tagname)
|
||||
{
|
||||
return isset(static::$tags[$tagname]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the rule for the current tag name.
|
||||
*
|
||||
* This may modify the existing DOM.
|
||||
*
|
||||
* @return \DOMElement The new Current DOM element.
|
||||
*/
|
||||
public function evaluate($new, $current)
|
||||
{
|
||||
switch ($new->tagName) {
|
||||
case 'li':
|
||||
return $this->handleLI($new, $current);
|
||||
case 'dt':
|
||||
case 'dd':
|
||||
return $this->handleDT($new, $current);
|
||||
case 'rt':
|
||||
case 'rp':
|
||||
return $this->handleRT($new, $current);
|
||||
case 'optgroup':
|
||||
return $this->closeIfCurrentMatches($new, $current, array(
|
||||
'optgroup',
|
||||
));
|
||||
case 'option':
|
||||
return $this->closeIfCurrentMatches($new, $current, array(
|
||||
'option',
|
||||
));
|
||||
case 'tr':
|
||||
return $this->closeIfCurrentMatches($new, $current, array(
|
||||
'tr',
|
||||
));
|
||||
case 'td':
|
||||
case 'th':
|
||||
return $this->closeIfCurrentMatches($new, $current, array(
|
||||
'th',
|
||||
'td',
|
||||
));
|
||||
case 'tbody':
|
||||
case 'thead':
|
||||
case 'tfoot':
|
||||
case 'table': // Spec isn't explicit about this, but it's necessary.
|
||||
return $this->closeIfCurrentMatches($new, $current, array(
|
||||
'thead',
|
||||
'tfoot',
|
||||
'tbody',
|
||||
));
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
protected function handleLI($ele, $current)
|
||||
{
|
||||
return $this->closeIfCurrentMatches($ele, $current, array(
|
||||
'li',
|
||||
));
|
||||
}
|
||||
|
||||
protected function handleDT($ele, $current)
|
||||
{
|
||||
return $this->closeIfCurrentMatches($ele, $current, array(
|
||||
'dt',
|
||||
'dd',
|
||||
));
|
||||
}
|
||||
|
||||
protected function handleRT($ele, $current)
|
||||
{
|
||||
return $this->closeIfCurrentMatches($ele, $current, array(
|
||||
'rt',
|
||||
'rp',
|
||||
));
|
||||
}
|
||||
|
||||
protected function closeIfCurrentMatches($ele, $current, $match)
|
||||
{
|
||||
if (in_array($current->tagName, $match, true)) {
|
||||
$current->parentNode->appendChild($ele);
|
||||
} else {
|
||||
$current->appendChild($ele);
|
||||
}
|
||||
|
||||
return $ele;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Parser;
|
||||
|
||||
/*
|
||||
Portions based on code from html5lib files with the following copyright:
|
||||
|
||||
Copyright 2009 Geoffrey Sneddon <http://gsnedders.com/>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
use Masterminds\HTML5\Exception;
|
||||
|
||||
class UTF8Utils
|
||||
{
|
||||
/**
|
||||
* The Unicode replacement character.
|
||||
*/
|
||||
const FFFD = "\xEF\xBF\xBD";
|
||||
|
||||
/**
|
||||
* Count the number of characters in a string.
|
||||
* UTF-8 aware. This will try (in order) iconv, MB, and finally a custom counter.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function countChars($string)
|
||||
{
|
||||
// Get the length for the string we need.
|
||||
if (function_exists('mb_strlen')) {
|
||||
return mb_strlen($string, 'utf-8');
|
||||
}
|
||||
|
||||
if (function_exists('iconv_strlen')) {
|
||||
return iconv_strlen($string, 'utf-8');
|
||||
}
|
||||
|
||||
$count = count_chars($string);
|
||||
|
||||
// 0x80 = 0x7F - 0 + 1 (one added to get inclusive range)
|
||||
// 0x33 = 0xF4 - 0x2C + 1 (one added to get inclusive range)
|
||||
return array_sum(array_slice($count, 0, 0x80)) + array_sum(array_slice($count, 0xC2, 0x33));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data from the given encoding to UTF-8.
|
||||
*
|
||||
* This has not yet been tested with charactersets other than UTF-8.
|
||||
* It should work with ISO-8859-1/-13 and standard Latin Win charsets.
|
||||
*
|
||||
* @param string $data The data to convert
|
||||
* @param string $encoding A valid encoding. Examples: http://www.php.net/manual/en/mbstring.supported-encodings.php
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function convertToUTF8($data, $encoding = 'UTF-8')
|
||||
{
|
||||
/*
|
||||
* From the HTML5 spec: Given an encoding, the bytes in the input stream must be converted
|
||||
* to Unicode characters for the tokeniser, as described by the rules for that encoding,
|
||||
* except that the leading U+FEFF BYTE ORDER MARK character, if any, must not be stripped
|
||||
* by the encoding layer (it is stripped by the rule below). Bytes or sequences of bytes
|
||||
* in the original byte stream that could not be converted to Unicode characters must be
|
||||
* converted to U+FFFD REPLACEMENT CHARACTER code points.
|
||||
*/
|
||||
|
||||
// mb_convert_encoding is chosen over iconv because of a bug. The best
|
||||
// details for the bug are on http://us1.php.net/manual/en/function.iconv.php#108643
|
||||
// which contains links to the actual but reports as well as work around
|
||||
// details.
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
// mb library has the following behaviors:
|
||||
// - UTF-16 surrogates result in false.
|
||||
// - Overlongs and outside Plane 16 result in empty strings.
|
||||
|
||||
// Before we run mb_convert_encoding we need to tell it what to do with
|
||||
// characters it does not know. This could be different than the parent
|
||||
// application executing this library so we store the value, change it
|
||||
// to our needs, and then change it back when we are done. This feels
|
||||
// a little excessive and it would be great if there was a better way.
|
||||
$save = mb_substitute_character();
|
||||
mb_substitute_character('none');
|
||||
$data = mb_convert_encoding($data, 'UTF-8', $encoding);
|
||||
mb_substitute_character($save);
|
||||
}
|
||||
// @todo Get iconv running in at least some environments if that is possible.
|
||||
elseif (function_exists('iconv') && 'auto' !== $encoding) {
|
||||
// fprintf(STDOUT, "iconv found\n");
|
||||
// iconv has the following behaviors:
|
||||
// - Overlong representations are ignored.
|
||||
// - Beyond Plane 16 is replaced with a lower char.
|
||||
// - Incomplete sequences generate a warning.
|
||||
$data = @iconv($encoding, 'UTF-8//IGNORE', $data);
|
||||
} else {
|
||||
throw new Exception('Not implemented, please install mbstring or iconv');
|
||||
}
|
||||
|
||||
/*
|
||||
* One leading U+FEFF BYTE ORDER MARK character must be ignored if any are present.
|
||||
*/
|
||||
if ("\xEF\xBB\xBF" === substr($data, 0, 3)) {
|
||||
$data = substr($data, 3);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for Unicode code points that are not valid in a document.
|
||||
*
|
||||
* @param string $data A string to analyze
|
||||
*
|
||||
* @return array An array of (string) error messages produced by the scanning
|
||||
*/
|
||||
public static function checkForIllegalCodepoints($data)
|
||||
{
|
||||
// Vestigal error handling.
|
||||
$errors = array();
|
||||
|
||||
/*
|
||||
* All U+0000 null characters in the input must be replaced by U+FFFD REPLACEMENT CHARACTERs.
|
||||
* Any occurrences of such characters is a parse error.
|
||||
*/
|
||||
for ($i = 0, $count = substr_count($data, "\0"); $i < $count; ++$i) {
|
||||
$errors[] = 'null-character';
|
||||
}
|
||||
|
||||
/*
|
||||
* Any occurrences of any characters in the ranges U+0001 to U+0008, U+000B, U+000E to U+001F, U+007F
|
||||
* to U+009F, U+D800 to U+DFFF , U+FDD0 to U+FDEF, and characters U+FFFE, U+FFFF, U+1FFFE, U+1FFFF,
|
||||
* U+2FFFE, U+2FFFF, U+3FFFE, U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, U+6FFFF, U+7FFFE,
|
||||
* U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, U+AFFFE, U+AFFFF, U+BFFFE, U+BFFFF, U+CFFFE, U+CFFFF,
|
||||
* U+DFFFE, U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, U+FFFFF, U+10FFFE, and U+10FFFF are parse errors.
|
||||
* (These are all control characters or permanently undefined Unicode characters.)
|
||||
*/
|
||||
// Check PCRE is loaded.
|
||||
$count = preg_match_all(
|
||||
'/(?:
|
||||
[\x01-\x08\x0B\x0E-\x1F\x7F] # U+0001 to U+0008, U+000B, U+000E to U+001F and U+007F
|
||||
|
|
||||
\xC2[\x80-\x9F] # U+0080 to U+009F
|
||||
|
|
||||
\xED(?:\xA0[\x80-\xFF]|[\xA1-\xBE][\x00-\xFF]|\xBF[\x00-\xBF]) # U+D800 to U+DFFFF
|
||||
|
|
||||
\xEF\xB7[\x90-\xAF] # U+FDD0 to U+FDEF
|
||||
|
|
||||
\xEF\xBF[\xBE\xBF] # U+FFFE and U+FFFF
|
||||
|
|
||||
[\xF0-\xF4][\x8F-\xBF]\xBF[\xBE\xBF] # U+nFFFE and U+nFFFF (1 <= n <= 10_{16})
|
||||
)/x', $data, $matches);
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$errors[] = 'invalid-codepoint';
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,559 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* The rules for generating output in the serializer.
|
||||
*
|
||||
* These output rules are likely to generate output similar to the document that
|
||||
* was parsed. It is not intended to output exactly the document that was parsed.
|
||||
*/
|
||||
|
||||
namespace Masterminds\HTML5\Serializer;
|
||||
|
||||
use Masterminds\HTML5\Elements;
|
||||
|
||||
/**
|
||||
* Generate the output html5 based on element rules.
|
||||
*/
|
||||
class OutputRules implements RulesInterface
|
||||
{
|
||||
/**
|
||||
* Defined in http://www.w3.org/TR/html51/infrastructure.html#html-namespace-0.
|
||||
*/
|
||||
const NAMESPACE_HTML = 'http://www.w3.org/1999/xhtml';
|
||||
|
||||
const NAMESPACE_MATHML = 'http://www.w3.org/1998/Math/MathML';
|
||||
|
||||
const NAMESPACE_SVG = 'http://www.w3.org/2000/svg';
|
||||
|
||||
const NAMESPACE_XLINK = 'http://www.w3.org/1999/xlink';
|
||||
|
||||
const NAMESPACE_XML = 'http://www.w3.org/XML/1998/namespace';
|
||||
|
||||
const NAMESPACE_XMLNS = 'http://www.w3.org/2000/xmlns/';
|
||||
|
||||
/**
|
||||
* Holds the HTML5 element names that causes a namespace switch.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $implicitNamespaces = array(
|
||||
self::NAMESPACE_HTML,
|
||||
self::NAMESPACE_SVG,
|
||||
self::NAMESPACE_MATHML,
|
||||
self::NAMESPACE_XML,
|
||||
self::NAMESPACE_XMLNS,
|
||||
);
|
||||
|
||||
const IM_IN_HTML = 1;
|
||||
|
||||
const IM_IN_SVG = 2;
|
||||
|
||||
const IM_IN_MATHML = 3;
|
||||
|
||||
/**
|
||||
* Used as cache to detect if is available ENT_HTML5.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $hasHTML5 = false;
|
||||
|
||||
protected $traverser;
|
||||
|
||||
protected $encode = false;
|
||||
|
||||
protected $out;
|
||||
|
||||
protected $outputMode;
|
||||
|
||||
private $xpath;
|
||||
|
||||
protected $nonBooleanAttributes = array(
|
||||
/*
|
||||
array(
|
||||
'nodeNamespace'=>'http://www.w3.org/1999/xhtml',
|
||||
'attrNamespace'=>'http://www.w3.org/1999/xhtml',
|
||||
|
||||
'nodeName'=>'img', 'nodeName'=>array('img', 'a'),
|
||||
'attrName'=>'alt', 'attrName'=>array('title', 'alt'),
|
||||
),
|
||||
*/
|
||||
array(
|
||||
'nodeNamespace' => 'http://www.w3.org/1999/xhtml',
|
||||
'attrName' => array('href',
|
||||
'hreflang',
|
||||
'http-equiv',
|
||||
'icon',
|
||||
'id',
|
||||
'keytype',
|
||||
'kind',
|
||||
'label',
|
||||
'lang',
|
||||
'language',
|
||||
'list',
|
||||
'maxlength',
|
||||
'media',
|
||||
'method',
|
||||
'name',
|
||||
'placeholder',
|
||||
'rel',
|
||||
'rows',
|
||||
'rowspan',
|
||||
'sandbox',
|
||||
'spellcheck',
|
||||
'scope',
|
||||
'seamless',
|
||||
'shape',
|
||||
'size',
|
||||
'sizes',
|
||||
'span',
|
||||
'src',
|
||||
'srcdoc',
|
||||
'srclang',
|
||||
'srcset',
|
||||
'start',
|
||||
'step',
|
||||
'style',
|
||||
'summary',
|
||||
'tabindex',
|
||||
'target',
|
||||
'title',
|
||||
'type',
|
||||
'value',
|
||||
'width',
|
||||
'border',
|
||||
'charset',
|
||||
'cite',
|
||||
'class',
|
||||
'code',
|
||||
'codebase',
|
||||
'color',
|
||||
'cols',
|
||||
'colspan',
|
||||
'content',
|
||||
'coords',
|
||||
'data',
|
||||
'datetime',
|
||||
'default',
|
||||
'dir',
|
||||
'dirname',
|
||||
'enctype',
|
||||
'for',
|
||||
'form',
|
||||
'formaction',
|
||||
'headers',
|
||||
'height',
|
||||
'accept',
|
||||
'accept-charset',
|
||||
'accesskey',
|
||||
'action',
|
||||
'align',
|
||||
'alt',
|
||||
'bgcolor',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'nodeNamespace' => 'http://www.w3.org/1999/xhtml',
|
||||
'xpath' => 'starts-with(local-name(), \'data-\')',
|
||||
),
|
||||
);
|
||||
|
||||
const DOCTYPE = '<!DOCTYPE html>';
|
||||
|
||||
public function __construct($output, $options = array())
|
||||
{
|
||||
if (isset($options['encode_entities'])) {
|
||||
$this->encode = $options['encode_entities'];
|
||||
}
|
||||
|
||||
$this->outputMode = static::IM_IN_HTML;
|
||||
$this->out = $output;
|
||||
$this->hasHTML5 = defined('ENT_HTML5');
|
||||
}
|
||||
|
||||
public function addRule(array $rule)
|
||||
{
|
||||
$this->nonBooleanAttributes[] = $rule;
|
||||
}
|
||||
|
||||
public function setTraverser(Traverser $traverser)
|
||||
{
|
||||
$this->traverser = $traverser;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unsetTraverser()
|
||||
{
|
||||
$this->traverser = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function document($dom)
|
||||
{
|
||||
$this->doctype();
|
||||
if ($dom->documentElement) {
|
||||
foreach ($dom->childNodes as $node) {
|
||||
$this->traverser->node($node);
|
||||
}
|
||||
$this->nl();
|
||||
}
|
||||
}
|
||||
|
||||
protected function doctype()
|
||||
{
|
||||
$this->wr(static::DOCTYPE);
|
||||
$this->nl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $ele
|
||||
*/
|
||||
public function element($ele)
|
||||
{
|
||||
$name = $ele->tagName;
|
||||
|
||||
// Per spec:
|
||||
// If the element has a declared namespace in the HTML, MathML or
|
||||
// SVG namespaces, we use the lname instead of the tagName.
|
||||
if ($this->traverser->isLocalElement($ele)) {
|
||||
$name = $ele->localName;
|
||||
}
|
||||
|
||||
// If we are in SVG or MathML there is special handling.
|
||||
// Using if/elseif instead of switch because it's faster in PHP.
|
||||
if ('svg' == $name) {
|
||||
$this->outputMode = static::IM_IN_SVG;
|
||||
$name = Elements::normalizeSvgElement($name);
|
||||
} elseif ('math' == $name) {
|
||||
$this->outputMode = static::IM_IN_MATHML;
|
||||
}
|
||||
|
||||
$this->openTag($ele);
|
||||
// The tag is already self-closed (`<svg />` or `<math />`) in `openTag` if there are no child nodes.
|
||||
$handledAsVoidTag = $this->outputMode !== static::IM_IN_HTML && !$ele->hasChildNodes();
|
||||
|
||||
if (Elements::isA($name, Elements::TEXT_RAW)) {
|
||||
foreach ($ele->childNodes as $child) {
|
||||
if ($child instanceof \DOMCharacterData) {
|
||||
$this->wr($child->data);
|
||||
} elseif ($child instanceof \DOMElement) {
|
||||
$this->element($child);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handle children.
|
||||
if ($ele->hasChildNodes()) {
|
||||
$this->traverser->children($ele->childNodes);
|
||||
}
|
||||
|
||||
// Close out the SVG or MathML special handling.
|
||||
if ('svg' == $name || 'math' == $name) {
|
||||
$this->outputMode = static::IM_IN_HTML;
|
||||
}
|
||||
}
|
||||
|
||||
// If not unary, add a closing tag.
|
||||
if (!$handledAsVoidTag && !Elements::isA($name, Elements::VOID_TAG)) {
|
||||
$this->closeTag($ele);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a text node.
|
||||
*
|
||||
* @param \DOMText $ele The text node to write.
|
||||
*/
|
||||
public function text($ele)
|
||||
{
|
||||
if (isset($ele->parentNode) && isset($ele->parentNode->tagName) && Elements::isA($ele->parentNode->localName, Elements::TEXT_RAW)) {
|
||||
$this->wr($ele->data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: This probably needs some flags set.
|
||||
$this->wr($this->enc($ele->data));
|
||||
}
|
||||
|
||||
public function cdata($ele)
|
||||
{
|
||||
// This encodes CDATA.
|
||||
$this->wr($ele->ownerDocument->saveXML($ele));
|
||||
}
|
||||
|
||||
public function comment($ele)
|
||||
{
|
||||
// These produce identical output.
|
||||
// $this->wr('<!--')->wr($ele->data)->wr('-->');
|
||||
$this->wr($ele->ownerDocument->saveXML($ele));
|
||||
}
|
||||
|
||||
public function processorInstruction($ele)
|
||||
{
|
||||
$this->wr('<?')
|
||||
->wr($ele->target)
|
||||
->wr(' ')
|
||||
->wr($ele->data)
|
||||
->wr('?>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the namespace attributes.
|
||||
*
|
||||
* @param \DOMNode $ele The element being written.
|
||||
*/
|
||||
protected function namespaceAttrs($ele)
|
||||
{
|
||||
if (!$this->xpath || $this->xpath->document !== $ele->ownerDocument) {
|
||||
$this->xpath = new \DOMXPath($ele->ownerDocument);
|
||||
}
|
||||
|
||||
foreach ($this->xpath->query('namespace::*[not(.=../../namespace::*)]', $ele) as $nsNode) {
|
||||
if (!in_array($nsNode->nodeValue, $this->implicitNamespaces)) {
|
||||
$this->wr(' ')->wr($nsNode->nodeName)->wr('="')->wr($nsNode->nodeValue)->wr('"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the opening tag.
|
||||
*
|
||||
* Tags for HTML, MathML, and SVG are in the local name. Otherwise, use the
|
||||
* qualified name (8.3).
|
||||
*
|
||||
* @param \DOMNode $ele The element being written.
|
||||
*/
|
||||
protected function openTag($ele)
|
||||
{
|
||||
$this->wr('<')->wr($this->traverser->isLocalElement($ele) ? $ele->localName : $ele->tagName);
|
||||
|
||||
$this->attrs($ele);
|
||||
$this->namespaceAttrs($ele);
|
||||
|
||||
if ($this->outputMode == static::IM_IN_HTML) {
|
||||
$this->wr('>');
|
||||
} // If we are not in html mode we are in SVG, MathML, or XML embedded content.
|
||||
else {
|
||||
if ($ele->hasChildNodes()) {
|
||||
$this->wr('>');
|
||||
} // If there are no children this is self closing.
|
||||
else {
|
||||
$this->wr(' />');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function attrs($ele)
|
||||
{
|
||||
// FIXME: Needs support for xml, xmlns, xlink, and namespaced elements.
|
||||
if (!$ele->hasAttributes()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// TODO: Currently, this always writes name="value", and does not do
|
||||
// value-less attributes.
|
||||
$map = $ele->attributes;
|
||||
$len = $map->length;
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$node = $map->item($i);
|
||||
$val = $this->enc($node->value, true);
|
||||
|
||||
// XXX: The spec says that we need to ensure that anything in
|
||||
// the XML, XMLNS, or XLink NS's should use the canonical
|
||||
// prefix. It seems that DOM does this for us already, but there
|
||||
// may be exceptions.
|
||||
$name = $node->nodeName;
|
||||
|
||||
// Special handling for attributes in SVG and MathML.
|
||||
// Using if/elseif instead of switch because it's faster in PHP.
|
||||
if ($this->outputMode == static::IM_IN_SVG) {
|
||||
$name = Elements::normalizeSvgAttribute($name);
|
||||
} elseif ($this->outputMode == static::IM_IN_MATHML) {
|
||||
$name = Elements::normalizeMathMlAttribute($name);
|
||||
}
|
||||
|
||||
$this->wr(' ')->wr($name);
|
||||
|
||||
if ((isset($val) && '' !== $val) || $this->nonBooleanAttribute($node)) {
|
||||
$this->wr('="')->wr($val)->wr('"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function nonBooleanAttribute(\DOMAttr $attr)
|
||||
{
|
||||
$ele = $attr->ownerElement;
|
||||
foreach ($this->nonBooleanAttributes as $rule) {
|
||||
if (isset($rule['nodeNamespace']) && $rule['nodeNamespace'] !== $ele->namespaceURI) {
|
||||
continue;
|
||||
}
|
||||
if (isset($rule['attNamespace']) && $rule['attNamespace'] !== $attr->namespaceURI) {
|
||||
continue;
|
||||
}
|
||||
if (isset($rule['nodeName']) && !is_array($rule['nodeName']) && $rule['nodeName'] !== $ele->localName) {
|
||||
continue;
|
||||
}
|
||||
if (isset($rule['nodeName']) && is_array($rule['nodeName']) && !in_array($ele->localName, $rule['nodeName'], true)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($rule['attrName']) && !is_array($rule['attrName']) && $rule['attrName'] !== $attr->localName) {
|
||||
continue;
|
||||
}
|
||||
if (isset($rule['attrName']) && is_array($rule['attrName']) && !in_array($attr->localName, $rule['attrName'], true)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($rule['xpath'])) {
|
||||
$xp = $this->getXPath($attr);
|
||||
if (isset($rule['prefixes'])) {
|
||||
foreach ($rule['prefixes'] as $nsPrefix => $ns) {
|
||||
$xp->registerNamespace($nsPrefix, $ns);
|
||||
}
|
||||
}
|
||||
if (!$xp->evaluate($rule['xpath'], $attr)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getXPath(\DOMNode $node)
|
||||
{
|
||||
if (!$this->xpath) {
|
||||
$this->xpath = new \DOMXPath($node->ownerDocument);
|
||||
}
|
||||
|
||||
return $this->xpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the closing tag.
|
||||
*
|
||||
* Tags for HTML, MathML, and SVG are in the local name. Otherwise, use the
|
||||
* qualified name (8.3).
|
||||
*
|
||||
* @param \DOMNode $ele The element being written.
|
||||
*/
|
||||
protected function closeTag($ele)
|
||||
{
|
||||
if ($this->outputMode == static::IM_IN_HTML || $ele->hasChildNodes()) {
|
||||
$this->wr('</')->wr($this->traverser->isLocalElement($ele) ? $ele->localName : $ele->tagName)->wr('>');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to the output.
|
||||
*
|
||||
* @param string $text The string to put into the output
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function wr($text)
|
||||
{
|
||||
fwrite($this->out, $text);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a new line character.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function nl()
|
||||
{
|
||||
fwrite($this->out, PHP_EOL);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode text.
|
||||
*
|
||||
* When encode is set to false, the default value, the text passed in is
|
||||
* escaped per section 8.3 of the html5 spec. For details on how text is
|
||||
* escaped see the escape() method.
|
||||
*
|
||||
* When encoding is set to true the text is converted to named character
|
||||
* references where appropriate. Section 8.1.4 Character references of the
|
||||
* html5 spec refers to using named character references. This is useful for
|
||||
* characters that can't otherwise legally be used in the text.
|
||||
*
|
||||
* The named character references are listed in section 8.5.
|
||||
*
|
||||
* @see http://www.w3.org/TR/2013/CR-html5-20130806/syntax.html#named-character-references True encoding will turn all named character references into their entities.
|
||||
* This includes such characters as +.# and many other common ones. By default
|
||||
* encoding here will just escape &'<>".
|
||||
*
|
||||
* Note, PHP 5.4+ has better html5 encoding.
|
||||
*
|
||||
* @todo Use the Entities class in php 5.3 to have html5 entities.
|
||||
*
|
||||
* @param string $text Text to encode.
|
||||
* @param bool $attribute True if we are encoding an attrubute, false otherwise.
|
||||
*
|
||||
* @return string The encoded text.
|
||||
*/
|
||||
protected function enc($text, $attribute = false)
|
||||
{
|
||||
// Escape the text rather than convert to named character references.
|
||||
if (!$this->encode) {
|
||||
return $this->escape($text, $attribute);
|
||||
}
|
||||
|
||||
// If we are in PHP 5.4+ we can use the native html5 entity functionality to
|
||||
// convert the named character references.
|
||||
|
||||
if ($this->hasHTML5) {
|
||||
return htmlentities($text, ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES, 'UTF-8', false);
|
||||
} // If a version earlier than 5.4 html5 entities are not entirely handled.
|
||||
// This manually handles them.
|
||||
else {
|
||||
return strtr($text, HTML5Entities::$map);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape test.
|
||||
*
|
||||
* According to the html5 spec section 8.3 Serializing HTML fragments, text
|
||||
* within tags that are not style, script, xmp, iframe, noembed, and noframes
|
||||
* need to be properly escaped.
|
||||
*
|
||||
* The & should be converted to &, no breaking space unicode characters
|
||||
* converted to , when in attribute mode the " should be converted to
|
||||
* ", and when not in attribute mode the < and > should be converted to
|
||||
* < and >.
|
||||
*
|
||||
* @see http://www.w3.org/TR/2013/CR-html5-20130806/syntax.html#escapingString
|
||||
*
|
||||
* @param string $text Text to escape.
|
||||
* @param bool $attribute True if we are escaping an attrubute, false otherwise.
|
||||
*/
|
||||
protected function escape($text, $attribute = false)
|
||||
{
|
||||
// Not using htmlspecialchars because, while it does escaping, it doesn't
|
||||
// match the requirements of section 8.5. For example, it doesn't handle
|
||||
// non-breaking spaces.
|
||||
if ($attribute) {
|
||||
$replace = array(
|
||||
'"' => '"',
|
||||
'&' => '&',
|
||||
"\xc2\xa0" => ' ',
|
||||
);
|
||||
} else {
|
||||
$replace = array(
|
||||
'<' => '<',
|
||||
'>' => '>',
|
||||
'&' => '&',
|
||||
"\xc2\xa0" => ' ',
|
||||
);
|
||||
}
|
||||
|
||||
return strtr($text, $replace);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# The Serializer (Writer) Model
|
||||
|
||||
The serializer roughly follows sections _8.1 Writing HTML documents_ and section
|
||||
_8.3 Serializing HTML fragments_ by converting DOMDocument, DOMDocumentFragment,
|
||||
and DOMNodeList into HTML5.
|
||||
|
||||
[ HTML5 ] // Interface for saving.
|
||||
||
|
||||
[ Traverser ] // Walk the DOM
|
||||
||
|
||||
[ Rules ] // Convert DOM elements into strings.
|
||||
||
|
||||
[ HTML5 ] // HTML5 document or fragment in text.
|
||||
|
||||
|
||||
## HTML5 Class
|
||||
|
||||
Provides the top level interface for saving.
|
||||
|
||||
## The Traverser
|
||||
|
||||
Walks the DOM finding each element and passing it off to the output rules to
|
||||
convert to HTML5.
|
||||
|
||||
## Output Rules
|
||||
|
||||
The output rules are defined in the RulesInterface which can have multiple
|
||||
implementations. Currently, the OutputRules is the default implementation that
|
||||
converts a DOM as is into HTML5.
|
||||
|
||||
## HTML5 String
|
||||
|
||||
The output of the process it HTML5 as a string or saved to a file.
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* The interface definition for Rules to generate output.
|
||||
*/
|
||||
|
||||
namespace Masterminds\HTML5\Serializer;
|
||||
|
||||
/**
|
||||
* To create a new rule set for writing output the RulesInterface needs to be implemented.
|
||||
* The resulting class can be specified in the options with the key of rules.
|
||||
*
|
||||
* For an example implementation see Serializer\OutputRules.
|
||||
*/
|
||||
interface RulesInterface
|
||||
{
|
||||
/**
|
||||
* The class constructor.
|
||||
*
|
||||
* Note, before the rules can be used a traverser must be registered.
|
||||
*
|
||||
* @param mixed $output The output stream to write output to.
|
||||
* @param array $options An array of options.
|
||||
*/
|
||||
public function __construct($output, $options = array());
|
||||
|
||||
/**
|
||||
* Register the traverser used in but the rules.
|
||||
*
|
||||
* Note, only one traverser can be used by the rules.
|
||||
*
|
||||
* @param Traverser $traverser The traverser used in the rules.
|
||||
*
|
||||
* @return RulesInterface $this for the current object.
|
||||
*/
|
||||
public function setTraverser(Traverser $traverser);
|
||||
|
||||
/**
|
||||
* Write a document element (\DOMDocument).
|
||||
*
|
||||
* Instead of returning the result write it to the output stream ($output)
|
||||
* that was passed into the constructor.
|
||||
*
|
||||
* @param \DOMDocument $dom
|
||||
*/
|
||||
public function document($dom);
|
||||
|
||||
/**
|
||||
* Write an element.
|
||||
*
|
||||
* Instead of returning the result write it to the output stream ($output)
|
||||
* that was passed into the constructor.
|
||||
*
|
||||
* @param mixed $ele
|
||||
*/
|
||||
public function element($ele);
|
||||
|
||||
/**
|
||||
* Write a text node.
|
||||
*
|
||||
* Instead of returning the result write it to the output stream ($output)
|
||||
* that was passed into the constructor.
|
||||
*
|
||||
* @param mixed $ele
|
||||
*/
|
||||
public function text($ele);
|
||||
|
||||
/**
|
||||
* Write a CDATA node.
|
||||
*
|
||||
* Instead of returning the result write it to the output stream ($output)
|
||||
* that was passed into the constructor.
|
||||
*
|
||||
* @param mixed $ele
|
||||
*/
|
||||
public function cdata($ele);
|
||||
|
||||
/**
|
||||
* Write a comment node.
|
||||
*
|
||||
* Instead of returning the result write it to the output stream ($output)
|
||||
* that was passed into the constructor.
|
||||
*
|
||||
* @param mixed $ele
|
||||
*/
|
||||
public function comment($ele);
|
||||
|
||||
/**
|
||||
* Write a processor instruction.
|
||||
*
|
||||
* To learn about processor instructions see InstructionProcessor
|
||||
*
|
||||
* Instead of returning the result write it to the output stream ($output)
|
||||
* that was passed into the constructor.
|
||||
*
|
||||
* @param mixed $ele
|
||||
*/
|
||||
public function processorInstruction($ele);
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
namespace Masterminds\HTML5\Serializer;
|
||||
|
||||
/**
|
||||
* Traverser for walking a DOM tree.
|
||||
*
|
||||
* This is a concrete traverser designed to convert a DOM tree into an
|
||||
* HTML5 document. It is not intended to be a generic DOMTreeWalker
|
||||
* implementation.
|
||||
*
|
||||
* @see http://www.w3.org/TR/2012/CR-html5-20121217/syntax.html#serializing-html-fragments
|
||||
*/
|
||||
class Traverser
|
||||
{
|
||||
/**
|
||||
* Namespaces that should be treated as "local" to HTML5.
|
||||
*/
|
||||
protected static $local_ns = array(
|
||||
'http://www.w3.org/1999/xhtml' => 'html',
|
||||
'http://www.w3.org/1998/Math/MathML' => 'math',
|
||||
'http://www.w3.org/2000/svg' => 'svg',
|
||||
);
|
||||
|
||||
protected $dom;
|
||||
|
||||
protected $options;
|
||||
|
||||
protected $encode = false;
|
||||
|
||||
protected $rules;
|
||||
|
||||
protected $out;
|
||||
|
||||
/**
|
||||
* Create a traverser.
|
||||
*
|
||||
* @param \DOMNode|\DOMNodeList $dom The document or node to traverse.
|
||||
* @param resource $out A stream that allows writing. The traverser will output into this
|
||||
* stream.
|
||||
* @param array $options An array of options for the traverser as key/value pairs. These include:
|
||||
* - encode_entities: A bool to specify if full encding should happen for all named
|
||||
* charachter references. Defaults to false which escapes &'<>".
|
||||
* - output_rules: The path to the class handling the output rules.
|
||||
*/
|
||||
public function __construct($dom, $out, RulesInterface $rules, $options = array())
|
||||
{
|
||||
$this->dom = $dom;
|
||||
$this->out = $out;
|
||||
$this->rules = $rules;
|
||||
$this->options = $options;
|
||||
|
||||
$this->rules->setTraverser($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the traverser to walk the DOM.
|
||||
*
|
||||
* @return resource $out Returns the output stream.
|
||||
*/
|
||||
public function walk()
|
||||
{
|
||||
if ($this->dom instanceof \DOMDocument) {
|
||||
$this->rules->document($this->dom);
|
||||
} elseif ($this->dom instanceof \DOMDocumentFragment) {
|
||||
// Document fragments are a special case. Only the children need to
|
||||
// be serialized.
|
||||
if ($this->dom->hasChildNodes()) {
|
||||
$this->children($this->dom->childNodes);
|
||||
}
|
||||
} // If NodeList, loop
|
||||
elseif ($this->dom instanceof \DOMNodeList) {
|
||||
// If this is a NodeList of DOMDocuments this will not work.
|
||||
$this->children($this->dom);
|
||||
} // Else assume this is a DOMNode-like datastructure.
|
||||
else {
|
||||
$this->node($this->dom);
|
||||
}
|
||||
|
||||
return $this->out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a node in the DOM.
|
||||
*
|
||||
* @param mixed $node A node implementing \DOMNode.
|
||||
*/
|
||||
public function node($node)
|
||||
{
|
||||
// A listing of types is at http://php.net/manual/en/dom.constants.php
|
||||
switch ($node->nodeType) {
|
||||
case XML_ELEMENT_NODE:
|
||||
$this->rules->element($node);
|
||||
break;
|
||||
case XML_TEXT_NODE:
|
||||
$this->rules->text($node);
|
||||
break;
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
$this->rules->cdata($node);
|
||||
break;
|
||||
case XML_PI_NODE:
|
||||
$this->rules->processorInstruction($node);
|
||||
break;
|
||||
case XML_COMMENT_NODE:
|
||||
$this->rules->comment($node);
|
||||
break;
|
||||
// Currently we don't support embedding DTDs.
|
||||
default:
|
||||
//print '<!-- Skipped -->';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk through all the nodes on a node list.
|
||||
*
|
||||
* @param \DOMNodeList $nl A list of child elements to walk through.
|
||||
*/
|
||||
public function children($nl)
|
||||
{
|
||||
foreach ($nl as $node) {
|
||||
$this->node($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is an element local?
|
||||
*
|
||||
* @param mixed $ele An element that implement \DOMNode.
|
||||
*
|
||||
* @return bool true if local and false otherwise.
|
||||
*/
|
||||
public function isLocalElement($ele)
|
||||
{
|
||||
$uri = $ele->namespaceURI;
|
||||
if (empty($uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset(static::$local_ns[$uri]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,456 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
[](https://github.com/dompdf/php-font-lib/actions/workflows/phpunit.yml)
|
||||
|
||||
# PHP Font Lib
|
||||
|
||||
This library can be used to:
|
||||
* Read TrueType, OpenType (with TrueType glyphs), WOFF font files
|
||||
* Extract basic info (name, style, etc)
|
||||
* Extract advanced info (horizontal metrics, glyph names, glyph shapes, etc)
|
||||
* Make an Adobe Font Metrics (AFM) file from a font
|
||||
|
||||
This project was initiated by the need to read font files in the [DOMPDF project](https://github.com/dompdf/dompdf).
|
||||
|
||||
Usage Example
|
||||
-------------
|
||||
|
||||
### Base font information
|
||||
|
||||
```php
|
||||
$font = \FontLib\Font::load('fontfile.ttf');
|
||||
$font->parse(); // for getFontWeight() to work this call must be done first!
|
||||
echo $font->getFontName() .'<br>';
|
||||
echo $font->getFontSubfamily() .'<br>';
|
||||
echo $font->getFontSubfamilyID() .'<br>';
|
||||
echo $font->getFontFullName() .'<br>';
|
||||
echo $font->getFontVersion() .'<br>';
|
||||
echo $font->getFontWeight() .'<br>';
|
||||
echo $font->getFontPostscriptName() .'<br>';
|
||||
$font->close();
|
||||
```
|
||||
|
||||
### Font Metrics Generation
|
||||
|
||||
```php
|
||||
$font = FontLib\Font::load('fontfile.ttf');
|
||||
$font->parse();
|
||||
$font->saveAdobeFontMetrics('fontfile.ufm');
|
||||
```
|
||||
|
||||
### Create a font subset
|
||||
|
||||
```php
|
||||
$font = FontLib\Font::load('fontfile.ttf');
|
||||
$font->parse();
|
||||
$font->setSubset("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ.:,;' (!?)+-*/== 1234567890"); // characters to include
|
||||
$font->reduce();
|
||||
touch('fontfile.subset.ttf');
|
||||
$font->open('fontfile.subset.ttf', FontLib\BinaryStream::modeReadWrite);
|
||||
$font->encode(array("OS/2"));
|
||||
$font->close();
|
||||
```
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "phenx/php-font-lib",
|
||||
"type": "library",
|
||||
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||
"homepage": "https://github.com/PhenX/php-font-lib",
|
||||
"license": "LGPL-2.1-or-later",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Ménager",
|
||||
"email": "fabien.menager@gmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FontLib\\": "src/FontLib"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"FontLib\\Tests\\": "tests/FontLib"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"bin-dir": "bin"
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge" : "^3 || ^4 || ^5 || ^6"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
// Adobe Standard Encoding table for ttf2pt1
|
||||
// Thomas Henlich <Thomas.Henlich@mailbox.tu-dresden.de>
|
||||
|
||||
=20 U+0020 SPACE
|
||||
=21 U+0021 EXCLAMATION MARK
|
||||
=22 U+0022 QUOTATION MARK
|
||||
=23 U+0023 NUMBER SIGN
|
||||
=24 U+0024 DOLLAR SIGN
|
||||
=25 U+0025 PERCENT SIGN
|
||||
=26 U+0026 AMPERSAND
|
||||
=27 U+2019 RIGHT SINGLE QUOTATION MARK
|
||||
=28 U+0028 LEFT PARENTHESIS
|
||||
=29 U+0029 RIGHT PARENTHESIS
|
||||
=2A U+002A ASTERISK
|
||||
=2B U+002B PLUS SIGN
|
||||
=2C U+002C COMMA
|
||||
=2D U+002D HYPHEN-MINUS
|
||||
=2E U+002E FULL STOP
|
||||
=2F U+002F SOLIDUS
|
||||
=30 U+0030 DIGIT ZERO
|
||||
=31 U+0031 DIGIT ONE
|
||||
=32 U+0032 DIGIT TWO
|
||||
=33 U+0033 DIGIT THREE
|
||||
=34 U+0034 DIGIT FOUR
|
||||
=35 U+0035 DIGIT FIVE
|
||||
=36 U+0036 DIGIT SIX
|
||||
=37 U+0037 DIGIT SEVEN
|
||||
=38 U+0038 DIGIT EIGHT
|
||||
=39 U+0039 DIGIT NINE
|
||||
=3A U+003A COLON
|
||||
=3B U+003B SEMICOLON
|
||||
=3C U+003C LESS-THAN SIGN
|
||||
=3D U+003D EQUALS SIGN
|
||||
=3E U+003E GREATER-THAN SIGN
|
||||
=3F U+003F QUESTION MARK
|
||||
=40 U+0040 COMMERCIAL AT
|
||||
=41 U+0041 LATIN CAPITAL LETTER A
|
||||
=42 U+0042 LATIN CAPITAL LETTER B
|
||||
=43 U+0043 LATIN CAPITAL LETTER C
|
||||
=44 U+0044 LATIN CAPITAL LETTER D
|
||||
=45 U+0045 LATIN CAPITAL LETTER E
|
||||
=46 U+0046 LATIN CAPITAL LETTER F
|
||||
=47 U+0047 LATIN CAPITAL LETTER G
|
||||
=48 U+0048 LATIN CAPITAL LETTER H
|
||||
=49 U+0049 LATIN CAPITAL LETTER I
|
||||
=4A U+004A LATIN CAPITAL LETTER J
|
||||
=4B U+004B LATIN CAPITAL LETTER K
|
||||
=4C U+004C LATIN CAPITAL LETTER L
|
||||
=4D U+004D LATIN CAPITAL LETTER M
|
||||
=4E U+004E LATIN CAPITAL LETTER N
|
||||
=4F U+004F LATIN CAPITAL LETTER O
|
||||
=50 U+0050 LATIN CAPITAL LETTER P
|
||||
=51 U+0051 LATIN CAPITAL LETTER Q
|
||||
=52 U+0052 LATIN CAPITAL LETTER R
|
||||
=53 U+0053 LATIN CAPITAL LETTER S
|
||||
=54 U+0054 LATIN CAPITAL LETTER T
|
||||
=55 U+0055 LATIN CAPITAL LETTER U
|
||||
=56 U+0056 LATIN CAPITAL LETTER V
|
||||
=57 U+0057 LATIN CAPITAL LETTER W
|
||||
=58 U+0058 LATIN CAPITAL LETTER X
|
||||
=59 U+0059 LATIN CAPITAL LETTER Y
|
||||
=5A U+005A LATIN CAPITAL LETTER Z
|
||||
=5B U+005B LEFT SQUARE BRACKET
|
||||
=5C U+005C REVERSE SOLIDUS
|
||||
=5D U+005D RIGHT SQUARE BRACKET
|
||||
=5E U+005E CIRCUMFLEX ACCENT
|
||||
=5F U+005F LOW LINE
|
||||
=60 U+2018 LEFT SINGLE QUOTATION MARK
|
||||
=61 U+0061 LATIN SMALL LETTER A
|
||||
=62 U+0062 LATIN SMALL LETTER B
|
||||
=63 U+0063 LATIN SMALL LETTER C
|
||||
=64 U+0064 LATIN SMALL LETTER D
|
||||
=65 U+0065 LATIN SMALL LETTER E
|
||||
=66 U+0066 LATIN SMALL LETTER F
|
||||
=67 U+0067 LATIN SMALL LETTER G
|
||||
=68 U+0068 LATIN SMALL LETTER H
|
||||
=69 U+0069 LATIN SMALL LETTER I
|
||||
=6A U+006A LATIN SMALL LETTER J
|
||||
=6B U+006B LATIN SMALL LETTER K
|
||||
=6C U+006C LATIN SMALL LETTER L
|
||||
=6D U+006D LATIN SMALL LETTER M
|
||||
=6E U+006E LATIN SMALL LETTER N
|
||||
=6F U+006F LATIN SMALL LETTER O
|
||||
=70 U+0070 LATIN SMALL LETTER P
|
||||
=71 U+0071 LATIN SMALL LETTER Q
|
||||
=72 U+0072 LATIN SMALL LETTER R
|
||||
=73 U+0073 LATIN SMALL LETTER S
|
||||
=74 U+0074 LATIN SMALL LETTER T
|
||||
=75 U+0075 LATIN SMALL LETTER U
|
||||
=76 U+0076 LATIN SMALL LETTER V
|
||||
=77 U+0077 LATIN SMALL LETTER W
|
||||
=78 U+0078 LATIN SMALL LETTER X
|
||||
=79 U+0079 LATIN SMALL LETTER Y
|
||||
=7A U+007A LATIN SMALL LETTER Z
|
||||
=7B U+007B LEFT CURLY BRACKET
|
||||
=7C U+007C VERTICAL LINE
|
||||
=7D U+007D RIGHT CURLY BRACKET
|
||||
=7E U+007E TILDE
|
||||
=A1 U+00A1 INVERTED EXCLAMATION MARK
|
||||
=A2 U+00A2 CENT SIGN
|
||||
=A3 U+00A3 POUND SIGN
|
||||
=A4 U+2044 FRACTION SLASH
|
||||
=A5 U+00A5 YEN SIGN
|
||||
=A6 U+0192 LATIN SMALL LETTER F WITH HOOK
|
||||
=A7 U+00A7 SECTION SIGN
|
||||
=A8 U+00A4 CURRENCY SIGN
|
||||
=A9 U+0027 APOSTROPHE
|
||||
=AA U+201C LEFT DOUBLE QUOTATION MARK
|
||||
=AB U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
=AC U+2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
||||
=AD U+203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
=AE U+FB01 LATIN SMALL LIGATURE FI
|
||||
=AF U+FB02 LATIN SMALL LIGATURE FL
|
||||
=B1 U+2013 EN DASH
|
||||
=B2 U+2020 DAGGER
|
||||
=B3 U+2021 DOUBLE DAGGER
|
||||
=B4 U+00B7 MIDDLE DOT
|
||||
=B6 U+00B6 PILCROW SIGN
|
||||
=B7 U+2022 BULLET
|
||||
=B8 U+201A SINGLE LOW-9 QUOTATION MARK
|
||||
=B9 U+201E DOUBLE LOW-9 QUOTATION MARK
|
||||
=BA U+201D RIGHT DOUBLE QUOTATION MARK
|
||||
=BB U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
=BC U+2026 HORIZONTAL ELLIPSIS
|
||||
=BD U+2030 PER MILLE SIGN
|
||||
=BF U+00BF INVERTED QUESTION MARK
|
||||
=C1 U+0060 GRAVE ACCENT
|
||||
=C2 U+00B4 ACUTE ACCENT
|
||||
=C3 U+02C6 MODIFIER LETTER CIRCUMFLEX ACCENT
|
||||
=C4 U+02DC SMALL TILDE
|
||||
=C5 U+00AF MACRON
|
||||
=C6 U+02D8 BREVE
|
||||
=C7 U+02D9 DOT ABOVE
|
||||
=C8 U+00A8 DIAERESIS
|
||||
=CA U+02DA RING ABOVE
|
||||
=CB U+00B8 CEDILLA
|
||||
=CD U+02DD DOUBLE ACUTE ACCENT
|
||||
=CE U+02DB OGONEK
|
||||
=CF U+02C7 CARON
|
||||
=D0 U+2014 EM DASH
|
||||
=E1 U+00C6 LATIN CAPITAL LETTER AE
|
||||
=E3 U+00AA FEMININE ORDINAL INDICATOR
|
||||
=E8 U+0141 LATIN CAPITAL LETTER L WITH STROKE
|
||||
=E9 U+00D8 LATIN CAPITAL LETTER O WITH STROKE
|
||||
=EA U+0152 LATIN CAPITAL LIGATURE OE
|
||||
=EB U+00BA MASCULINE ORDINAL INDICATOR
|
||||
=F1 U+00E6 LATIN SMALL LETTER AE
|
||||
=F5 U+0131 LATIN SMALL LETTER DOTLESS I
|
||||
=F8 U+0142 LATIN SMALL LETTER L WITH STROKE
|
||||
=F9 U+00F8 LATIN SMALL LETTER O WITH STROKE
|
||||
=FA U+0153 LATIN SMALL LIGATURE OE
|
||||
=FB U+00DF LATIN SMALL LETTER SHARP S
|
||||
|
||||
// unencoded characters:
|
||||
=100 U+00E7 LATIN SMALL LETTER C WITH CEDILLA
|
||||
=101 U+00FF LATIN SMALL LETTER Y WITH DIAERESIS
|
||||
=102 U+00E3 LATIN SMALL LETTER A WITH TILDE
|
||||
=103 U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||
=104 U+00B3 SUPERSCRIPT THREE
|
||||
=105 U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX
|
||||
=106 U+00FE LATIN SMALL LETTER THORN
|
||||
=107 U+00E8 LATIN SMALL LETTER E WITH GRAVE
|
||||
=108 U+00B2 SUPERSCRIPT TWO
|
||||
=109 U+00E9 LATIN SMALL LETTER E WITH ACUTE
|
||||
=10A U+00F5 LATIN SMALL LETTER O WITH TILDE
|
||||
=10B U+00C1 LATIN CAPITAL LETTER A WITH ACUTE
|
||||
=10C U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||
=10D U+00FD LATIN SMALL LETTER Y WITH ACUTE
|
||||
=10E U+00FC LATIN SMALL LETTER U WITH DIAERESIS
|
||||
=10F U+00BE VULGAR FRACTION THREE QUARTERS
|
||||
=110 U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||
=111 U+00D0 LATIN CAPITAL LETTER ETH
|
||||
=112 U+00EB LATIN SMALL LETTER E WITH DIAERESIS
|
||||
=113 U+00F9 LATIN SMALL LETTER U WITH GRAVE
|
||||
=114 U+2122 TRADE MARK SIGN
|
||||
=115 U+00F2 LATIN SMALL LETTER O WITH GRAVE
|
||||
=116 U+0161 LATIN SMALL LETTER S WITH CARON
|
||||
=117 U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS
|
||||
=118 U+00FA LATIN SMALL LETTER U WITH ACUTE
|
||||
=119 U+00E0 LATIN SMALL LETTER A WITH GRAVE
|
||||
=11A U+00F1 LATIN SMALL LETTER N WITH TILDE
|
||||
=11B U+00E5 LATIN SMALL LETTER A WITH RING ABOVE
|
||||
=11C U+017E LATIN SMALL LETTER Z WITH CARON
|
||||
=11D U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||
=11E U+00D1 LATIN CAPITAL LETTER N WITH TILDE
|
||||
=11F U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX
|
||||
=120 U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
||||
=121 U+00CD LATIN CAPITAL LETTER I WITH ACUTE
|
||||
=122 U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA
|
||||
=123 U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
=124 U+0160 LATIN CAPITAL LETTER S WITH CARON
|
||||
=125 U+00CC LATIN CAPITAL LETTER I WITH GRAVE
|
||||
=126 U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
|
||||
=127 U+00D2 LATIN CAPITAL LETTER O WITH GRAVE
|
||||
=128 U+00C8 LATIN CAPITAL LETTER E WITH GRAVE
|
||||
=129 U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS
|
||||
=12A U+00AE REGISTERED SIGN
|
||||
=12B U+00D5 LATIN CAPITAL LETTER O WITH TILDE
|
||||
=12C U+00BC VULGAR FRACTION ONE QUARTER
|
||||
=12D U+00D9 LATIN CAPITAL LETTER U WITH GRAVE
|
||||
=12E U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
||||
=12F U+00DE LATIN CAPITAL LETTER THORN
|
||||
=130 U+00F7 DIVISION SIGN
|
||||
=131 U+00C3 LATIN CAPITAL LETTER A WITH TILDE
|
||||
=132 U+00DA LATIN CAPITAL LETTER U WITH ACUTE
|
||||
=133 U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||
=134 U+00AC NOT SIGN
|
||||
=135 U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE
|
||||
=136 U+00EF LATIN SMALL LETTER I WITH DIAERESIS
|
||||
=137 U+00ED LATIN SMALL LETTER I WITH ACUTE
|
||||
=138 U+00E1 LATIN SMALL LETTER A WITH ACUTE
|
||||
=139 U+00B1 PLUS-MINUS SIGN
|
||||
=13A U+00D7 MULTIPLICATION SIGN
|
||||
=13B U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||
=13C U+2212 MINUS SIGN
|
||||
=13D U+00B9 SUPERSCRIPT ONE
|
||||
=13E U+00C9 LATIN CAPITAL LETTER E WITH ACUTE
|
||||
=13F U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||
=140 U+00A9 COPYRIGHT SIGN
|
||||
=141 U+00C0 LATIN CAPITAL LETTER A WITH GRAVE
|
||||
=142 U+00F6 LATIN SMALL LETTER O WITH DIAERESIS
|
||||
=143 U+00F3 LATIN SMALL LETTER O WITH ACUTE
|
||||
=144 U+00B0 DEGREE SIGN
|
||||
=145 U+00EC LATIN SMALL LETTER I WITH GRAVE
|
||||
=146 U+00B5 MICRO SIGN
|
||||
=147 U+00D3 LATIN CAPITAL LETTER O WITH ACUTE
|
||||
=148 U+00F0 LATIN SMALL LETTER ETH
|
||||
=149 U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||
=14A U+00DD LATIN CAPITAL LETTER Y WITH ACUTE
|
||||
=14B U+00A6 BROKEN BAR
|
||||
=14C U+00BD VULGAR FRACTION ONE HALF
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!82 U+201A quotesinglbase
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!89 U+2030 perthousand
|
||||
!8A U+0160 Scaron
|
||||
!8B U+2039 guilsinglleft
|
||||
!8C U+015A Sacute
|
||||
!8D U+0164 Tcaron
|
||||
!8E U+017D Zcaron
|
||||
!8F U+0179 Zacute
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!99 U+2122 trademark
|
||||
!9A U+0161 scaron
|
||||
!9B U+203A guilsinglright
|
||||
!9C U+015B sacute
|
||||
!9D U+0165 tcaron
|
||||
!9E U+017E zcaron
|
||||
!9F U+017A zacute
|
||||
!A0 U+00A0 space
|
||||
!A1 U+02C7 caron
|
||||
!A2 U+02D8 breve
|
||||
!A3 U+0141 Lslash
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+0104 Aogonek
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+015E Scedilla
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+017B Zdotaccent
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+02DB ogonek
|
||||
!B3 U+0142 lslash
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+0105 aogonek
|
||||
!BA U+015F scedilla
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+013D Lcaron
|
||||
!BD U+02DD hungarumlaut
|
||||
!BE U+013E lcaron
|
||||
!BF U+017C zdotaccent
|
||||
!C0 U+0154 Racute
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+0102 Abreve
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+0139 Lacute
|
||||
!C6 U+0106 Cacute
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+010C Ccaron
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+0118 Eogonek
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+011A Ecaron
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+010E Dcaron
|
||||
!D0 U+0110 Dcroat
|
||||
!D1 U+0143 Nacute
|
||||
!D2 U+0147 Ncaron
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+0150 Ohungarumlaut
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+0158 Rcaron
|
||||
!D9 U+016E Uring
|
||||
!DA U+00DA Uacute
|
||||
!DB U+0170 Uhungarumlaut
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+00DD Yacute
|
||||
!DE U+0162 Tcommaaccent
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+0155 racute
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+0103 abreve
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+013A lacute
|
||||
!E6 U+0107 cacute
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+010D ccaron
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+0119 eogonek
|
||||
!EB U+00EB edieresis
|
||||
!EC U+011B ecaron
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+010F dcaron
|
||||
!F0 U+0111 dcroat
|
||||
!F1 U+0144 nacute
|
||||
!F2 U+0148 ncaron
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+0151 ohungarumlaut
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+0159 rcaron
|
||||
!F9 U+016F uring
|
||||
!FA U+00FA uacute
|
||||
!FB U+0171 uhungarumlaut
|
||||
!FC U+00FC udieresis
|
||||
!FD U+00FD yacute
|
||||
!FE U+0163 tcommaaccent
|
||||
!FF U+02D9 dotaccent
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0402 afii10051
|
||||
!81 U+0403 afii10052
|
||||
!82 U+201A quotesinglbase
|
||||
!83 U+0453 afii10100
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!88 U+20AC Euro
|
||||
!89 U+2030 perthousand
|
||||
!8A U+0409 afii10058
|
||||
!8B U+2039 guilsinglleft
|
||||
!8C U+040A afii10059
|
||||
!8D U+040C afii10061
|
||||
!8E U+040B afii10060
|
||||
!8F U+040F afii10145
|
||||
!90 U+0452 afii10099
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!99 U+2122 trademark
|
||||
!9A U+0459 afii10106
|
||||
!9B U+203A guilsinglright
|
||||
!9C U+045A afii10107
|
||||
!9D U+045C afii10109
|
||||
!9E U+045B afii10108
|
||||
!9F U+045F afii10193
|
||||
!A0 U+00A0 space
|
||||
!A1 U+040E afii10062
|
||||
!A2 U+045E afii10110
|
||||
!A3 U+0408 afii10057
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+0490 afii10050
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+0401 afii10023
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+0404 afii10053
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+0407 afii10056
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+0406 afii10055
|
||||
!B3 U+0456 afii10103
|
||||
!B4 U+0491 afii10098
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+0451 afii10071
|
||||
!B9 U+2116 afii61352
|
||||
!BA U+0454 afii10101
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+0458 afii10105
|
||||
!BD U+0405 afii10054
|
||||
!BE U+0455 afii10102
|
||||
!BF U+0457 afii10104
|
||||
!C0 U+0410 afii10017
|
||||
!C1 U+0411 afii10018
|
||||
!C2 U+0412 afii10019
|
||||
!C3 U+0413 afii10020
|
||||
!C4 U+0414 afii10021
|
||||
!C5 U+0415 afii10022
|
||||
!C6 U+0416 afii10024
|
||||
!C7 U+0417 afii10025
|
||||
!C8 U+0418 afii10026
|
||||
!C9 U+0419 afii10027
|
||||
!CA U+041A afii10028
|
||||
!CB U+041B afii10029
|
||||
!CC U+041C afii10030
|
||||
!CD U+041D afii10031
|
||||
!CE U+041E afii10032
|
||||
!CF U+041F afii10033
|
||||
!D0 U+0420 afii10034
|
||||
!D1 U+0421 afii10035
|
||||
!D2 U+0422 afii10036
|
||||
!D3 U+0423 afii10037
|
||||
!D4 U+0424 afii10038
|
||||
!D5 U+0425 afii10039
|
||||
!D6 U+0426 afii10040
|
||||
!D7 U+0427 afii10041
|
||||
!D8 U+0428 afii10042
|
||||
!D9 U+0429 afii10043
|
||||
!DA U+042A afii10044
|
||||
!DB U+042B afii10045
|
||||
!DC U+042C afii10046
|
||||
!DD U+042D afii10047
|
||||
!DE U+042E afii10048
|
||||
!DF U+042F afii10049
|
||||
!E0 U+0430 afii10065
|
||||
!E1 U+0431 afii10066
|
||||
!E2 U+0432 afii10067
|
||||
!E3 U+0433 afii10068
|
||||
!E4 U+0434 afii10069
|
||||
!E5 U+0435 afii10070
|
||||
!E6 U+0436 afii10072
|
||||
!E7 U+0437 afii10073
|
||||
!E8 U+0438 afii10074
|
||||
!E9 U+0439 afii10075
|
||||
!EA U+043A afii10076
|
||||
!EB U+043B afii10077
|
||||
!EC U+043C afii10078
|
||||
!ED U+043D afii10079
|
||||
!EE U+043E afii10080
|
||||
!EF U+043F afii10081
|
||||
!F0 U+0440 afii10082
|
||||
!F1 U+0441 afii10083
|
||||
!F2 U+0442 afii10084
|
||||
!F3 U+0443 afii10085
|
||||
!F4 U+0444 afii10086
|
||||
!F5 U+0445 afii10087
|
||||
!F6 U+0446 afii10088
|
||||
!F7 U+0447 afii10089
|
||||
!F8 U+0448 afii10090
|
||||
!F9 U+0449 afii10091
|
||||
!FA U+044A afii10092
|
||||
!FB U+044B afii10093
|
||||
!FC U+044C afii10094
|
||||
!FD U+044D afii10095
|
||||
!FE U+044E afii10096
|
||||
!FF U+044F afii10097
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!82 U+201A quotesinglbase
|
||||
!83 U+0192 florin
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!88 U+02C6 circumflex
|
||||
!89 U+2030 perthousand
|
||||
!8A U+0160 Scaron
|
||||
!8B U+2039 guilsinglleft
|
||||
!8C U+0152 OE
|
||||
!8E U+017D Zcaron
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!98 U+02DC tilde
|
||||
!99 U+2122 trademark
|
||||
!9A U+0161 scaron
|
||||
!9B U+203A guilsinglright
|
||||
!9C U+0153 oe
|
||||
!9E U+017E zcaron
|
||||
!9F U+0178 Ydieresis
|
||||
!A0 U+00A0 space
|
||||
!A1 U+00A1 exclamdown
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+00AA ordfeminine
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+00BA ordmasculine
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+00BC onequarter
|
||||
!BD U+00BD onehalf
|
||||
!BE U+00BE threequarters
|
||||
!BF U+00BF questiondown
|
||||
!C0 U+00C0 Agrave
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+00C3 Atilde
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+00C8 Egrave
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+00CA Ecircumflex
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+00CC Igrave
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+00CF Idieresis
|
||||
!D0 U+00D0 Eth
|
||||
!D1 U+00D1 Ntilde
|
||||
!D2 U+00D2 Ograve
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+00D5 Otilde
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+00D8 Oslash
|
||||
!D9 U+00D9 Ugrave
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+00DD Yacute
|
||||
!DE U+00DE Thorn
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+00E0 agrave
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+00E3 atilde
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+00E8 egrave
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+00EA ecircumflex
|
||||
!EB U+00EB edieresis
|
||||
!EC U+00EC igrave
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+00EF idieresis
|
||||
!F0 U+00F0 eth
|
||||
!F1 U+00F1 ntilde
|
||||
!F2 U+00F2 ograve
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+00F5 otilde
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+00F8 oslash
|
||||
!F9 U+00F9 ugrave
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+00FD yacute
|
||||
!FE U+00FE thorn
|
||||
!FF U+00FF ydieresis
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!82 U+201A quotesinglbase
|
||||
!83 U+0192 florin
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!89 U+2030 perthousand
|
||||
!8B U+2039 guilsinglleft
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!99 U+2122 trademark
|
||||
!9B U+203A guilsinglright
|
||||
!A0 U+00A0 space
|
||||
!A1 U+0385 dieresistonos
|
||||
!A2 U+0386 Alphatonos
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+2015 afii00208
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+0384 tonos
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+0388 Epsilontonos
|
||||
!B9 U+0389 Etatonos
|
||||
!BA U+038A Iotatonos
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+038C Omicrontonos
|
||||
!BD U+00BD onehalf
|
||||
!BE U+038E Upsilontonos
|
||||
!BF U+038F Omegatonos
|
||||
!C0 U+0390 iotadieresistonos
|
||||
!C1 U+0391 Alpha
|
||||
!C2 U+0392 Beta
|
||||
!C3 U+0393 Gamma
|
||||
!C4 U+0394 Delta
|
||||
!C5 U+0395 Epsilon
|
||||
!C6 U+0396 Zeta
|
||||
!C7 U+0397 Eta
|
||||
!C8 U+0398 Theta
|
||||
!C9 U+0399 Iota
|
||||
!CA U+039A Kappa
|
||||
!CB U+039B Lambda
|
||||
!CC U+039C Mu
|
||||
!CD U+039D Nu
|
||||
!CE U+039E Xi
|
||||
!CF U+039F Omicron
|
||||
!D0 U+03A0 Pi
|
||||
!D1 U+03A1 Rho
|
||||
!D3 U+03A3 Sigma
|
||||
!D4 U+03A4 Tau
|
||||
!D5 U+03A5 Upsilon
|
||||
!D6 U+03A6 Phi
|
||||
!D7 U+03A7 Chi
|
||||
!D8 U+03A8 Psi
|
||||
!D9 U+03A9 Omega
|
||||
!DA U+03AA Iotadieresis
|
||||
!DB U+03AB Upsilondieresis
|
||||
!DC U+03AC alphatonos
|
||||
!DD U+03AD epsilontonos
|
||||
!DE U+03AE etatonos
|
||||
!DF U+03AF iotatonos
|
||||
!E0 U+03B0 upsilondieresistonos
|
||||
!E1 U+03B1 alpha
|
||||
!E2 U+03B2 beta
|
||||
!E3 U+03B3 gamma
|
||||
!E4 U+03B4 delta
|
||||
!E5 U+03B5 epsilon
|
||||
!E6 U+03B6 zeta
|
||||
!E7 U+03B7 eta
|
||||
!E8 U+03B8 theta
|
||||
!E9 U+03B9 iota
|
||||
!EA U+03BA kappa
|
||||
!EB U+03BB lambda
|
||||
!EC U+03BC mu
|
||||
!ED U+03BD nu
|
||||
!EE U+03BE xi
|
||||
!EF U+03BF omicron
|
||||
!F0 U+03C0 pi
|
||||
!F1 U+03C1 rho
|
||||
!F2 U+03C2 sigma1
|
||||
!F3 U+03C3 sigma
|
||||
!F4 U+03C4 tau
|
||||
!F5 U+03C5 upsilon
|
||||
!F6 U+03C6 phi
|
||||
!F7 U+03C7 chi
|
||||
!F8 U+03C8 psi
|
||||
!F9 U+03C9 omega
|
||||
!FA U+03CA iotadieresis
|
||||
!FB U+03CB upsilondieresis
|
||||
!FC U+03CC omicrontonos
|
||||
!FD U+03CD upsilontonos
|
||||
!FE U+03CE omegatonos
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!82 U+201A quotesinglbase
|
||||
!83 U+0192 florin
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!88 U+02C6 circumflex
|
||||
!89 U+2030 perthousand
|
||||
!8A U+0160 Scaron
|
||||
!8B U+2039 guilsinglleft
|
||||
!8C U+0152 OE
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!98 U+02DC tilde
|
||||
!99 U+2122 trademark
|
||||
!9A U+0161 scaron
|
||||
!9B U+203A guilsinglright
|
||||
!9C U+0153 oe
|
||||
!9F U+0178 Ydieresis
|
||||
!A0 U+00A0 space
|
||||
!A1 U+00A1 exclamdown
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+00AA ordfeminine
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+00BA ordmasculine
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+00BC onequarter
|
||||
!BD U+00BD onehalf
|
||||
!BE U+00BE threequarters
|
||||
!BF U+00BF questiondown
|
||||
!C0 U+00C0 Agrave
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+00C3 Atilde
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+00C8 Egrave
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+00CA Ecircumflex
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+00CC Igrave
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+00CF Idieresis
|
||||
!D0 U+011E Gbreve
|
||||
!D1 U+00D1 Ntilde
|
||||
!D2 U+00D2 Ograve
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+00D5 Otilde
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+00D8 Oslash
|
||||
!D9 U+00D9 Ugrave
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+0130 Idotaccent
|
||||
!DE U+015E Scedilla
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+00E0 agrave
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+00E3 atilde
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+00E8 egrave
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+00EA ecircumflex
|
||||
!EB U+00EB edieresis
|
||||
!EC U+00EC igrave
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+00EF idieresis
|
||||
!F0 U+011F gbreve
|
||||
!F1 U+00F1 ntilde
|
||||
!F2 U+00F2 ograve
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+00F5 otilde
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+00F8 oslash
|
||||
!F9 U+00F9 ugrave
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+0131 dotlessi
|
||||
!FE U+015F scedilla
|
||||
!FF U+00FF ydieresis
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!82 U+201A quotesinglbase
|
||||
!83 U+0192 florin
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!88 U+02C6 circumflex
|
||||
!89 U+2030 perthousand
|
||||
!8B U+2039 guilsinglleft
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!98 U+02DC tilde
|
||||
!99 U+2122 trademark
|
||||
!9B U+203A guilsinglright
|
||||
!A0 U+00A0 space
|
||||
!A1 U+00A1 exclamdown
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+20AA afii57636
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+00D7 multiply
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD sfthyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 middot
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+00F7 divide
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+00BC onequarter
|
||||
!BD U+00BD onehalf
|
||||
!BE U+00BE threequarters
|
||||
!BF U+00BF questiondown
|
||||
!C0 U+05B0 afii57799
|
||||
!C1 U+05B1 afii57801
|
||||
!C2 U+05B2 afii57800
|
||||
!C3 U+05B3 afii57802
|
||||
!C4 U+05B4 afii57793
|
||||
!C5 U+05B5 afii57794
|
||||
!C6 U+05B6 afii57795
|
||||
!C7 U+05B7 afii57798
|
||||
!C8 U+05B8 afii57797
|
||||
!C9 U+05B9 afii57806
|
||||
!CB U+05BB afii57796
|
||||
!CC U+05BC afii57807
|
||||
!CD U+05BD afii57839
|
||||
!CE U+05BE afii57645
|
||||
!CF U+05BF afii57841
|
||||
!D0 U+05C0 afii57842
|
||||
!D1 U+05C1 afii57804
|
||||
!D2 U+05C2 afii57803
|
||||
!D3 U+05C3 afii57658
|
||||
!D4 U+05F0 afii57716
|
||||
!D5 U+05F1 afii57717
|
||||
!D6 U+05F2 afii57718
|
||||
!D7 U+05F3 gereshhebrew
|
||||
!D8 U+05F4 gershayimhebrew
|
||||
!E0 U+05D0 afii57664
|
||||
!E1 U+05D1 afii57665
|
||||
!E2 U+05D2 afii57666
|
||||
!E3 U+05D3 afii57667
|
||||
!E4 U+05D4 afii57668
|
||||
!E5 U+05D5 afii57669
|
||||
!E6 U+05D6 afii57670
|
||||
!E7 U+05D7 afii57671
|
||||
!E8 U+05D8 afii57672
|
||||
!E9 U+05D9 afii57673
|
||||
!EA U+05DA afii57674
|
||||
!EB U+05DB afii57675
|
||||
!EC U+05DC afii57676
|
||||
!ED U+05DD afii57677
|
||||
!EE U+05DE afii57678
|
||||
!EF U+05DF afii57679
|
||||
!F0 U+05E0 afii57680
|
||||
!F1 U+05E1 afii57681
|
||||
!F2 U+05E2 afii57682
|
||||
!F3 U+05E3 afii57683
|
||||
!F4 U+05E4 afii57684
|
||||
!F5 U+05E5 afii57685
|
||||
!F6 U+05E6 afii57686
|
||||
!F7 U+05E7 afii57687
|
||||
!F8 U+05E8 afii57688
|
||||
!F9 U+05E9 afii57689
|
||||
!FA U+05EA afii57690
|
||||
!FD U+200E afii299
|
||||
!FE U+200F afii300
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!82 U+201A quotesinglbase
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!89 U+2030 perthousand
|
||||
!8B U+2039 guilsinglleft
|
||||
!8D U+00A8 dieresis
|
||||
!8E U+02C7 caron
|
||||
!8F U+00B8 cedilla
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!99 U+2122 trademark
|
||||
!9B U+203A guilsinglright
|
||||
!9D U+00AF macron
|
||||
!9E U+02DB ogonek
|
||||
!A0 U+00A0 space
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+00A4 currency
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00D8 Oslash
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+0156 Rcommaaccent
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00C6 AE
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+00F8 oslash
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+0157 rcommaaccent
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+00BC onequarter
|
||||
!BD U+00BD onehalf
|
||||
!BE U+00BE threequarters
|
||||
!BF U+00E6 ae
|
||||
!C0 U+0104 Aogonek
|
||||
!C1 U+012E Iogonek
|
||||
!C2 U+0100 Amacron
|
||||
!C3 U+0106 Cacute
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+0118 Eogonek
|
||||
!C7 U+0112 Emacron
|
||||
!C8 U+010C Ccaron
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+0179 Zacute
|
||||
!CB U+0116 Edotaccent
|
||||
!CC U+0122 Gcommaaccent
|
||||
!CD U+0136 Kcommaaccent
|
||||
!CE U+012A Imacron
|
||||
!CF U+013B Lcommaaccent
|
||||
!D0 U+0160 Scaron
|
||||
!D1 U+0143 Nacute
|
||||
!D2 U+0145 Ncommaaccent
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+014C Omacron
|
||||
!D5 U+00D5 Otilde
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+0172 Uogonek
|
||||
!D9 U+0141 Lslash
|
||||
!DA U+015A Sacute
|
||||
!DB U+016A Umacron
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+017B Zdotaccent
|
||||
!DE U+017D Zcaron
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+0105 aogonek
|
||||
!E1 U+012F iogonek
|
||||
!E2 U+0101 amacron
|
||||
!E3 U+0107 cacute
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+0119 eogonek
|
||||
!E7 U+0113 emacron
|
||||
!E8 U+010D ccaron
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+017A zacute
|
||||
!EB U+0117 edotaccent
|
||||
!EC U+0123 gcommaaccent
|
||||
!ED U+0137 kcommaaccent
|
||||
!EE U+012B imacron
|
||||
!EF U+013C lcommaaccent
|
||||
!F0 U+0161 scaron
|
||||
!F1 U+0144 nacute
|
||||
!F2 U+0146 ncommaaccent
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+014D omacron
|
||||
!F5 U+00F5 otilde
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+0173 uogonek
|
||||
!F9 U+0142 lslash
|
||||
!FA U+015B sacute
|
||||
!FB U+016B umacron
|
||||
!FC U+00FC udieresis
|
||||
!FD U+017C zdotaccent
|
||||
!FE U+017E zcaron
|
||||
!FF U+02D9 dotaccent
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!82 U+201A quotesinglbase
|
||||
!83 U+0192 florin
|
||||
!84 U+201E quotedblbase
|
||||
!85 U+2026 ellipsis
|
||||
!86 U+2020 dagger
|
||||
!87 U+2021 daggerdbl
|
||||
!88 U+02C6 circumflex
|
||||
!89 U+2030 perthousand
|
||||
!8B U+2039 guilsinglleft
|
||||
!8C U+0152 OE
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!98 U+02DC tilde
|
||||
!99 U+2122 trademark
|
||||
!9B U+203A guilsinglright
|
||||
!9C U+0153 oe
|
||||
!9F U+0178 Ydieresis
|
||||
!A0 U+00A0 space
|
||||
!A1 U+00A1 exclamdown
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+00AA ordfeminine
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+00BA ordmasculine
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+00BC onequarter
|
||||
!BD U+00BD onehalf
|
||||
!BE U+00BE threequarters
|
||||
!BF U+00BF questiondown
|
||||
!C0 U+00C0 Agrave
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+0102 Abreve
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+00C8 Egrave
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+00CA Ecircumflex
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+0300 gravecomb
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+00CF Idieresis
|
||||
!D0 U+0110 Dcroat
|
||||
!D1 U+00D1 Ntilde
|
||||
!D2 U+0309 hookabovecomb
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+01A0 Ohorn
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+00D8 Oslash
|
||||
!D9 U+00D9 Ugrave
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+01AF Uhorn
|
||||
!DE U+0303 tildecomb
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+00E0 agrave
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+0103 abreve
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+00E8 egrave
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+00EA ecircumflex
|
||||
!EB U+00EB edieresis
|
||||
!EC U+0301 acutecomb
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+00EF idieresis
|
||||
!F0 U+0111 dcroat
|
||||
!F1 U+00F1 ntilde
|
||||
!F2 U+0323 dotbelowcomb
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+01A1 ohorn
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+00F8 oslash
|
||||
!F9 U+00F9 ugrave
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+01B0 uhorn
|
||||
!FE U+20AB dong
|
||||
!FF U+00FF ydieresis
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+20AC Euro
|
||||
!85 U+2026 ellipsis
|
||||
!91 U+2018 quoteleft
|
||||
!92 U+2019 quoteright
|
||||
!93 U+201C quotedblleft
|
||||
!94 U+201D quotedblright
|
||||
!95 U+2022 bullet
|
||||
!96 U+2013 endash
|
||||
!97 U+2014 emdash
|
||||
!A0 U+00A0 space
|
||||
!A1 U+0E01 kokaithai
|
||||
!A2 U+0E02 khokhaithai
|
||||
!A3 U+0E03 khokhuatthai
|
||||
!A4 U+0E04 khokhwaithai
|
||||
!A5 U+0E05 khokhonthai
|
||||
!A6 U+0E06 khorakhangthai
|
||||
!A7 U+0E07 ngonguthai
|
||||
!A8 U+0E08 chochanthai
|
||||
!A9 U+0E09 chochingthai
|
||||
!AA U+0E0A chochangthai
|
||||
!AB U+0E0B sosothai
|
||||
!AC U+0E0C chochoethai
|
||||
!AD U+0E0D yoyingthai
|
||||
!AE U+0E0E dochadathai
|
||||
!AF U+0E0F topatakthai
|
||||
!B0 U+0E10 thothanthai
|
||||
!B1 U+0E11 thonangmonthothai
|
||||
!B2 U+0E12 thophuthaothai
|
||||
!B3 U+0E13 nonenthai
|
||||
!B4 U+0E14 dodekthai
|
||||
!B5 U+0E15 totaothai
|
||||
!B6 U+0E16 thothungthai
|
||||
!B7 U+0E17 thothahanthai
|
||||
!B8 U+0E18 thothongthai
|
||||
!B9 U+0E19 nonuthai
|
||||
!BA U+0E1A bobaimaithai
|
||||
!BB U+0E1B poplathai
|
||||
!BC U+0E1C phophungthai
|
||||
!BD U+0E1D fofathai
|
||||
!BE U+0E1E phophanthai
|
||||
!BF U+0E1F fofanthai
|
||||
!C0 U+0E20 phosamphaothai
|
||||
!C1 U+0E21 momathai
|
||||
!C2 U+0E22 yoyakthai
|
||||
!C3 U+0E23 roruathai
|
||||
!C4 U+0E24 ruthai
|
||||
!C5 U+0E25 lolingthai
|
||||
!C6 U+0E26 luthai
|
||||
!C7 U+0E27 wowaenthai
|
||||
!C8 U+0E28 sosalathai
|
||||
!C9 U+0E29 sorusithai
|
||||
!CA U+0E2A sosuathai
|
||||
!CB U+0E2B hohipthai
|
||||
!CC U+0E2C lochulathai
|
||||
!CD U+0E2D oangthai
|
||||
!CE U+0E2E honokhukthai
|
||||
!CF U+0E2F paiyannoithai
|
||||
!D0 U+0E30 saraathai
|
||||
!D1 U+0E31 maihanakatthai
|
||||
!D2 U+0E32 saraaathai
|
||||
!D3 U+0E33 saraamthai
|
||||
!D4 U+0E34 saraithai
|
||||
!D5 U+0E35 saraiithai
|
||||
!D6 U+0E36 sarauethai
|
||||
!D7 U+0E37 saraueethai
|
||||
!D8 U+0E38 sarauthai
|
||||
!D9 U+0E39 sarauuthai
|
||||
!DA U+0E3A phinthuthai
|
||||
!DF U+0E3F bahtthai
|
||||
!E0 U+0E40 saraethai
|
||||
!E1 U+0E41 saraaethai
|
||||
!E2 U+0E42 saraothai
|
||||
!E3 U+0E43 saraaimaimuanthai
|
||||
!E4 U+0E44 saraaimaimalaithai
|
||||
!E5 U+0E45 lakkhangyaothai
|
||||
!E6 U+0E46 maiyamokthai
|
||||
!E7 U+0E47 maitaikhuthai
|
||||
!E8 U+0E48 maiekthai
|
||||
!E9 U+0E49 maithothai
|
||||
!EA U+0E4A maitrithai
|
||||
!EB U+0E4B maichattawathai
|
||||
!EC U+0E4C thanthakhatthai
|
||||
!ED U+0E4D nikhahitthai
|
||||
!EE U+0E4E yamakkanthai
|
||||
!EF U+0E4F fongmanthai
|
||||
!F0 U+0E50 zerothai
|
||||
!F1 U+0E51 onethai
|
||||
!F2 U+0E52 twothai
|
||||
!F3 U+0E53 threethai
|
||||
!F4 U+0E54 fourthai
|
||||
!F5 U+0E55 fivethai
|
||||
!F6 U+0E56 sixthai
|
||||
!F7 U+0E57 seventhai
|
||||
!F8 U+0E58 eightthai
|
||||
!F9 U+0E59 ninethai
|
||||
!FA U+0E5A angkhankhuthai
|
||||
!FB U+0E5B khomutthai
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+00A1 exclamdown
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+00AA ordfeminine
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+00BA ordmasculine
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+00BC onequarter
|
||||
!BD U+00BD onehalf
|
||||
!BE U+00BE threequarters
|
||||
!BF U+00BF questiondown
|
||||
!C0 U+00C0 Agrave
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+00C3 Atilde
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+00C8 Egrave
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+00CA Ecircumflex
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+00CC Igrave
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+00CF Idieresis
|
||||
!D0 U+00D0 Eth
|
||||
!D1 U+00D1 Ntilde
|
||||
!D2 U+00D2 Ograve
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+00D5 Otilde
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+00D8 Oslash
|
||||
!D9 U+00D9 Ugrave
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+00DD Yacute
|
||||
!DE U+00DE Thorn
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+00E0 agrave
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+00E3 atilde
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+00E8 egrave
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+00EA ecircumflex
|
||||
!EB U+00EB edieresis
|
||||
!EC U+00EC igrave
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+00EF idieresis
|
||||
!F0 U+00F0 eth
|
||||
!F1 U+00F1 ntilde
|
||||
!F2 U+00F2 ograve
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+00F5 otilde
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+00F8 oslash
|
||||
!F9 U+00F9 ugrave
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+00FD yacute
|
||||
!FE U+00FE thorn
|
||||
!FF U+00FF ydieresis
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+0E01 kokaithai
|
||||
!A2 U+0E02 khokhaithai
|
||||
!A3 U+0E03 khokhuatthai
|
||||
!A4 U+0E04 khokhwaithai
|
||||
!A5 U+0E05 khokhonthai
|
||||
!A6 U+0E06 khorakhangthai
|
||||
!A7 U+0E07 ngonguthai
|
||||
!A8 U+0E08 chochanthai
|
||||
!A9 U+0E09 chochingthai
|
||||
!AA U+0E0A chochangthai
|
||||
!AB U+0E0B sosothai
|
||||
!AC U+0E0C chochoethai
|
||||
!AD U+0E0D yoyingthai
|
||||
!AE U+0E0E dochadathai
|
||||
!AF U+0E0F topatakthai
|
||||
!B0 U+0E10 thothanthai
|
||||
!B1 U+0E11 thonangmonthothai
|
||||
!B2 U+0E12 thophuthaothai
|
||||
!B3 U+0E13 nonenthai
|
||||
!B4 U+0E14 dodekthai
|
||||
!B5 U+0E15 totaothai
|
||||
!B6 U+0E16 thothungthai
|
||||
!B7 U+0E17 thothahanthai
|
||||
!B8 U+0E18 thothongthai
|
||||
!B9 U+0E19 nonuthai
|
||||
!BA U+0E1A bobaimaithai
|
||||
!BB U+0E1B poplathai
|
||||
!BC U+0E1C phophungthai
|
||||
!BD U+0E1D fofathai
|
||||
!BE U+0E1E phophanthai
|
||||
!BF U+0E1F fofanthai
|
||||
!C0 U+0E20 phosamphaothai
|
||||
!C1 U+0E21 momathai
|
||||
!C2 U+0E22 yoyakthai
|
||||
!C3 U+0E23 roruathai
|
||||
!C4 U+0E24 ruthai
|
||||
!C5 U+0E25 lolingthai
|
||||
!C6 U+0E26 luthai
|
||||
!C7 U+0E27 wowaenthai
|
||||
!C8 U+0E28 sosalathai
|
||||
!C9 U+0E29 sorusithai
|
||||
!CA U+0E2A sosuathai
|
||||
!CB U+0E2B hohipthai
|
||||
!CC U+0E2C lochulathai
|
||||
!CD U+0E2D oangthai
|
||||
!CE U+0E2E honokhukthai
|
||||
!CF U+0E2F paiyannoithai
|
||||
!D0 U+0E30 saraathai
|
||||
!D1 U+0E31 maihanakatthai
|
||||
!D2 U+0E32 saraaathai
|
||||
!D3 U+0E33 saraamthai
|
||||
!D4 U+0E34 saraithai
|
||||
!D5 U+0E35 saraiithai
|
||||
!D6 U+0E36 sarauethai
|
||||
!D7 U+0E37 saraueethai
|
||||
!D8 U+0E38 sarauthai
|
||||
!D9 U+0E39 sarauuthai
|
||||
!DA U+0E3A phinthuthai
|
||||
!DF U+0E3F bahtthai
|
||||
!E0 U+0E40 saraethai
|
||||
!E1 U+0E41 saraaethai
|
||||
!E2 U+0E42 saraothai
|
||||
!E3 U+0E43 saraaimaimuanthai
|
||||
!E4 U+0E44 saraaimaimalaithai
|
||||
!E5 U+0E45 lakkhangyaothai
|
||||
!E6 U+0E46 maiyamokthai
|
||||
!E7 U+0E47 maitaikhuthai
|
||||
!E8 U+0E48 maiekthai
|
||||
!E9 U+0E49 maithothai
|
||||
!EA U+0E4A maitrithai
|
||||
!EB U+0E4B maichattawathai
|
||||
!EC U+0E4C thanthakhatthai
|
||||
!ED U+0E4D nikhahitthai
|
||||
!EE U+0E4E yamakkanthai
|
||||
!EF U+0E4F fongmanthai
|
||||
!F0 U+0E50 zerothai
|
||||
!F1 U+0E51 onethai
|
||||
!F2 U+0E52 twothai
|
||||
!F3 U+0E53 threethai
|
||||
!F4 U+0E54 fourthai
|
||||
!F5 U+0E55 fivethai
|
||||
!F6 U+0E56 sixthai
|
||||
!F7 U+0E57 seventhai
|
||||
!F8 U+0E58 eightthai
|
||||
!F9 U+0E59 ninethai
|
||||
!FA U+0E5A angkhankhuthai
|
||||
!FB U+0E5B khomutthai
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+00A1 exclamdown
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+20AC Euro
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+0160 Scaron
|
||||
!A7 U+00A7 section
|
||||
!A8 U+0161 scaron
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+00AA ordfeminine
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+017D Zcaron
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+017E zcaron
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+00BA ordmasculine
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+0152 OE
|
||||
!BD U+0153 oe
|
||||
!BE U+0178 Ydieresis
|
||||
!BF U+00BF questiondown
|
||||
!C0 U+00C0 Agrave
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+00C3 Atilde
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+00C8 Egrave
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+00CA Ecircumflex
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+00CC Igrave
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+00CF Idieresis
|
||||
!D0 U+00D0 Eth
|
||||
!D1 U+00D1 Ntilde
|
||||
!D2 U+00D2 Ograve
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+00D5 Otilde
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+00D8 Oslash
|
||||
!D9 U+00D9 Ugrave
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+00DD Yacute
|
||||
!DE U+00DE Thorn
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+00E0 agrave
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+00E3 atilde
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+00E8 egrave
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+00EA ecircumflex
|
||||
!EB U+00EB edieresis
|
||||
!EC U+00EC igrave
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+00EF idieresis
|
||||
!F0 U+00F0 eth
|
||||
!F1 U+00F1 ntilde
|
||||
!F2 U+00F2 ograve
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+00F5 otilde
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+00F8 oslash
|
||||
!F9 U+00F9 ugrave
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+00FD yacute
|
||||
!FE U+00FE thorn
|
||||
!FF U+00FF ydieresis
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+0104 Aogonek
|
||||
!A2 U+0105 aogonek
|
||||
!A3 U+0141 Lslash
|
||||
!A4 U+20AC Euro
|
||||
!A5 U+201E quotedblbase
|
||||
!A6 U+0160 Scaron
|
||||
!A7 U+00A7 section
|
||||
!A8 U+0161 scaron
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+0218 Scommaaccent
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+0179 Zacute
|
||||
!AD U+00AD hyphen
|
||||
!AE U+017A zacute
|
||||
!AF U+017B Zdotaccent
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+010C Ccaron
|
||||
!B3 U+0142 lslash
|
||||
!B4 U+017D Zcaron
|
||||
!B5 U+201D quotedblright
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+017E zcaron
|
||||
!B9 U+010D ccaron
|
||||
!BA U+0219 scommaaccent
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+0152 OE
|
||||
!BD U+0153 oe
|
||||
!BE U+0178 Ydieresis
|
||||
!BF U+017C zdotaccent
|
||||
!C0 U+00C0 Agrave
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+0102 Abreve
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+0106 Cacute
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+00C8 Egrave
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+00CA Ecircumflex
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+00CC Igrave
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+00CF Idieresis
|
||||
!D0 U+0110 Dcroat
|
||||
!D1 U+0143 Nacute
|
||||
!D2 U+00D2 Ograve
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+0150 Ohungarumlaut
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+015A Sacute
|
||||
!D8 U+0170 Uhungarumlaut
|
||||
!D9 U+00D9 Ugrave
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+0118 Eogonek
|
||||
!DE U+021A Tcommaaccent
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+00E0 agrave
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+0103 abreve
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+0107 cacute
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+00E8 egrave
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+00EA ecircumflex
|
||||
!EB U+00EB edieresis
|
||||
!EC U+00EC igrave
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+00EF idieresis
|
||||
!F0 U+0111 dcroat
|
||||
!F1 U+0144 nacute
|
||||
!F2 U+00F2 ograve
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+0151 ohungarumlaut
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+015B sacute
|
||||
!F8 U+0171 uhungarumlaut
|
||||
!F9 U+00F9 ugrave
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+0119 eogonek
|
||||
!FE U+021B tcommaaccent
|
||||
!FF U+00FF ydieresis
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+0104 Aogonek
|
||||
!A2 U+02D8 breve
|
||||
!A3 U+0141 Lslash
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+013D Lcaron
|
||||
!A6 U+015A Sacute
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+0160 Scaron
|
||||
!AA U+015E Scedilla
|
||||
!AB U+0164 Tcaron
|
||||
!AC U+0179 Zacute
|
||||
!AD U+00AD hyphen
|
||||
!AE U+017D Zcaron
|
||||
!AF U+017B Zdotaccent
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+0105 aogonek
|
||||
!B2 U+02DB ogonek
|
||||
!B3 U+0142 lslash
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+013E lcaron
|
||||
!B6 U+015B sacute
|
||||
!B7 U+02C7 caron
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+0161 scaron
|
||||
!BA U+015F scedilla
|
||||
!BB U+0165 tcaron
|
||||
!BC U+017A zacute
|
||||
!BD U+02DD hungarumlaut
|
||||
!BE U+017E zcaron
|
||||
!BF U+017C zdotaccent
|
||||
!C0 U+0154 Racute
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+0102 Abreve
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+0139 Lacute
|
||||
!C6 U+0106 Cacute
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+010C Ccaron
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+0118 Eogonek
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+011A Ecaron
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+010E Dcaron
|
||||
!D0 U+0110 Dcroat
|
||||
!D1 U+0143 Nacute
|
||||
!D2 U+0147 Ncaron
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+0150 Ohungarumlaut
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+0158 Rcaron
|
||||
!D9 U+016E Uring
|
||||
!DA U+00DA Uacute
|
||||
!DB U+0170 Uhungarumlaut
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+00DD Yacute
|
||||
!DE U+0162 Tcommaaccent
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+0155 racute
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+0103 abreve
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+013A lacute
|
||||
!E6 U+0107 cacute
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+010D ccaron
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+0119 eogonek
|
||||
!EB U+00EB edieresis
|
||||
!EC U+011B ecaron
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+010F dcaron
|
||||
!F0 U+0111 dcroat
|
||||
!F1 U+0144 nacute
|
||||
!F2 U+0148 ncaron
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+0151 ohungarumlaut
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+0159 rcaron
|
||||
!F9 U+016F uring
|
||||
!FA U+00FA uacute
|
||||
!FB U+0171 uhungarumlaut
|
||||
!FC U+00FC udieresis
|
||||
!FD U+00FD yacute
|
||||
!FE U+0163 tcommaaccent
|
||||
!FF U+02D9 dotaccent
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+0104 Aogonek
|
||||
!A2 U+0138 kgreenlandic
|
||||
!A3 U+0156 Rcommaaccent
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+0128 Itilde
|
||||
!A6 U+013B Lcommaaccent
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+0160 Scaron
|
||||
!AA U+0112 Emacron
|
||||
!AB U+0122 Gcommaaccent
|
||||
!AC U+0166 Tbar
|
||||
!AD U+00AD hyphen
|
||||
!AE U+017D Zcaron
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+0105 aogonek
|
||||
!B2 U+02DB ogonek
|
||||
!B3 U+0157 rcommaaccent
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+0129 itilde
|
||||
!B6 U+013C lcommaaccent
|
||||
!B7 U+02C7 caron
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+0161 scaron
|
||||
!BA U+0113 emacron
|
||||
!BB U+0123 gcommaaccent
|
||||
!BC U+0167 tbar
|
||||
!BD U+014A Eng
|
||||
!BE U+017E zcaron
|
||||
!BF U+014B eng
|
||||
!C0 U+0100 Amacron
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+00C3 Atilde
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+012E Iogonek
|
||||
!C8 U+010C Ccaron
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+0118 Eogonek
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+0116 Edotaccent
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+012A Imacron
|
||||
!D0 U+0110 Dcroat
|
||||
!D1 U+0145 Ncommaaccent
|
||||
!D2 U+014C Omacron
|
||||
!D3 U+0136 Kcommaaccent
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+00D5 Otilde
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+00D8 Oslash
|
||||
!D9 U+0172 Uogonek
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+0168 Utilde
|
||||
!DE U+016A Umacron
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+0101 amacron
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+00E3 atilde
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+012F iogonek
|
||||
!E8 U+010D ccaron
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+0119 eogonek
|
||||
!EB U+00EB edieresis
|
||||
!EC U+0117 edotaccent
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+012B imacron
|
||||
!F0 U+0111 dcroat
|
||||
!F1 U+0146 ncommaaccent
|
||||
!F2 U+014D omacron
|
||||
!F3 U+0137 kcommaaccent
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+00F5 otilde
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+00F8 oslash
|
||||
!F9 U+0173 uogonek
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+0169 utilde
|
||||
!FE U+016B umacron
|
||||
!FF U+02D9 dotaccent
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+0401 afii10023
|
||||
!A2 U+0402 afii10051
|
||||
!A3 U+0403 afii10052
|
||||
!A4 U+0404 afii10053
|
||||
!A5 U+0405 afii10054
|
||||
!A6 U+0406 afii10055
|
||||
!A7 U+0407 afii10056
|
||||
!A8 U+0408 afii10057
|
||||
!A9 U+0409 afii10058
|
||||
!AA U+040A afii10059
|
||||
!AB U+040B afii10060
|
||||
!AC U+040C afii10061
|
||||
!AD U+00AD hyphen
|
||||
!AE U+040E afii10062
|
||||
!AF U+040F afii10145
|
||||
!B0 U+0410 afii10017
|
||||
!B1 U+0411 afii10018
|
||||
!B2 U+0412 afii10019
|
||||
!B3 U+0413 afii10020
|
||||
!B4 U+0414 afii10021
|
||||
!B5 U+0415 afii10022
|
||||
!B6 U+0416 afii10024
|
||||
!B7 U+0417 afii10025
|
||||
!B8 U+0418 afii10026
|
||||
!B9 U+0419 afii10027
|
||||
!BA U+041A afii10028
|
||||
!BB U+041B afii10029
|
||||
!BC U+041C afii10030
|
||||
!BD U+041D afii10031
|
||||
!BE U+041E afii10032
|
||||
!BF U+041F afii10033
|
||||
!C0 U+0420 afii10034
|
||||
!C1 U+0421 afii10035
|
||||
!C2 U+0422 afii10036
|
||||
!C3 U+0423 afii10037
|
||||
!C4 U+0424 afii10038
|
||||
!C5 U+0425 afii10039
|
||||
!C6 U+0426 afii10040
|
||||
!C7 U+0427 afii10041
|
||||
!C8 U+0428 afii10042
|
||||
!C9 U+0429 afii10043
|
||||
!CA U+042A afii10044
|
||||
!CB U+042B afii10045
|
||||
!CC U+042C afii10046
|
||||
!CD U+042D afii10047
|
||||
!CE U+042E afii10048
|
||||
!CF U+042F afii10049
|
||||
!D0 U+0430 afii10065
|
||||
!D1 U+0431 afii10066
|
||||
!D2 U+0432 afii10067
|
||||
!D3 U+0433 afii10068
|
||||
!D4 U+0434 afii10069
|
||||
!D5 U+0435 afii10070
|
||||
!D6 U+0436 afii10072
|
||||
!D7 U+0437 afii10073
|
||||
!D8 U+0438 afii10074
|
||||
!D9 U+0439 afii10075
|
||||
!DA U+043A afii10076
|
||||
!DB U+043B afii10077
|
||||
!DC U+043C afii10078
|
||||
!DD U+043D afii10079
|
||||
!DE U+043E afii10080
|
||||
!DF U+043F afii10081
|
||||
!E0 U+0440 afii10082
|
||||
!E1 U+0441 afii10083
|
||||
!E2 U+0442 afii10084
|
||||
!E3 U+0443 afii10085
|
||||
!E4 U+0444 afii10086
|
||||
!E5 U+0445 afii10087
|
||||
!E6 U+0446 afii10088
|
||||
!E7 U+0447 afii10089
|
||||
!E8 U+0448 afii10090
|
||||
!E9 U+0449 afii10091
|
||||
!EA U+044A afii10092
|
||||
!EB U+044B afii10093
|
||||
!EC U+044C afii10094
|
||||
!ED U+044D afii10095
|
||||
!EE U+044E afii10096
|
||||
!EF U+044F afii10097
|
||||
!F0 U+2116 afii61352
|
||||
!F1 U+0451 afii10071
|
||||
!F2 U+0452 afii10099
|
||||
!F3 U+0453 afii10100
|
||||
!F4 U+0454 afii10101
|
||||
!F5 U+0455 afii10102
|
||||
!F6 U+0456 afii10103
|
||||
!F7 U+0457 afii10104
|
||||
!F8 U+0458 afii10105
|
||||
!F9 U+0459 afii10106
|
||||
!FA U+045A afii10107
|
||||
!FB U+045B afii10108
|
||||
!FC U+045C afii10109
|
||||
!FD U+00A7 section
|
||||
!FE U+045E afii10110
|
||||
!FF U+045F afii10193
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+2018 quoteleft
|
||||
!A2 U+2019 quoteright
|
||||
!A3 U+00A3 sterling
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AF U+2015 afii00208
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+0384 tonos
|
||||
!B5 U+0385 dieresistonos
|
||||
!B6 U+0386 Alphatonos
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+0388 Epsilontonos
|
||||
!B9 U+0389 Etatonos
|
||||
!BA U+038A Iotatonos
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+038C Omicrontonos
|
||||
!BD U+00BD onehalf
|
||||
!BE U+038E Upsilontonos
|
||||
!BF U+038F Omegatonos
|
||||
!C0 U+0390 iotadieresistonos
|
||||
!C1 U+0391 Alpha
|
||||
!C2 U+0392 Beta
|
||||
!C3 U+0393 Gamma
|
||||
!C4 U+0394 Delta
|
||||
!C5 U+0395 Epsilon
|
||||
!C6 U+0396 Zeta
|
||||
!C7 U+0397 Eta
|
||||
!C8 U+0398 Theta
|
||||
!C9 U+0399 Iota
|
||||
!CA U+039A Kappa
|
||||
!CB U+039B Lambda
|
||||
!CC U+039C Mu
|
||||
!CD U+039D Nu
|
||||
!CE U+039E Xi
|
||||
!CF U+039F Omicron
|
||||
!D0 U+03A0 Pi
|
||||
!D1 U+03A1 Rho
|
||||
!D3 U+03A3 Sigma
|
||||
!D4 U+03A4 Tau
|
||||
!D5 U+03A5 Upsilon
|
||||
!D6 U+03A6 Phi
|
||||
!D7 U+03A7 Chi
|
||||
!D8 U+03A8 Psi
|
||||
!D9 U+03A9 Omega
|
||||
!DA U+03AA Iotadieresis
|
||||
!DB U+03AB Upsilondieresis
|
||||
!DC U+03AC alphatonos
|
||||
!DD U+03AD epsilontonos
|
||||
!DE U+03AE etatonos
|
||||
!DF U+03AF iotatonos
|
||||
!E0 U+03B0 upsilondieresistonos
|
||||
!E1 U+03B1 alpha
|
||||
!E2 U+03B2 beta
|
||||
!E3 U+03B3 gamma
|
||||
!E4 U+03B4 delta
|
||||
!E5 U+03B5 epsilon
|
||||
!E6 U+03B6 zeta
|
||||
!E7 U+03B7 eta
|
||||
!E8 U+03B8 theta
|
||||
!E9 U+03B9 iota
|
||||
!EA U+03BA kappa
|
||||
!EB U+03BB lambda
|
||||
!EC U+03BC mu
|
||||
!ED U+03BD nu
|
||||
!EE U+03BE xi
|
||||
!EF U+03BF omicron
|
||||
!F0 U+03C0 pi
|
||||
!F1 U+03C1 rho
|
||||
!F2 U+03C2 sigma1
|
||||
!F3 U+03C3 sigma
|
||||
!F4 U+03C4 tau
|
||||
!F5 U+03C5 upsilon
|
||||
!F6 U+03C6 phi
|
||||
!F7 U+03C7 chi
|
||||
!F8 U+03C8 psi
|
||||
!F9 U+03C9 omega
|
||||
!FA U+03CA iotadieresis
|
||||
!FB U+03CB upsilondieresis
|
||||
!FC U+03CC omicrontonos
|
||||
!FD U+03CD upsilontonos
|
||||
!FE U+03CE omegatonos
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
!00 U+0000 .notdef
|
||||
!01 U+0001 .notdef
|
||||
!02 U+0002 .notdef
|
||||
!03 U+0003 .notdef
|
||||
!04 U+0004 .notdef
|
||||
!05 U+0005 .notdef
|
||||
!06 U+0006 .notdef
|
||||
!07 U+0007 .notdef
|
||||
!08 U+0008 .notdef
|
||||
!09 U+0009 .notdef
|
||||
!0A U+000A .notdef
|
||||
!0B U+000B .notdef
|
||||
!0C U+000C .notdef
|
||||
!0D U+000D .notdef
|
||||
!0E U+000E .notdef
|
||||
!0F U+000F .notdef
|
||||
!10 U+0010 .notdef
|
||||
!11 U+0011 .notdef
|
||||
!12 U+0012 .notdef
|
||||
!13 U+0013 .notdef
|
||||
!14 U+0014 .notdef
|
||||
!15 U+0015 .notdef
|
||||
!16 U+0016 .notdef
|
||||
!17 U+0017 .notdef
|
||||
!18 U+0018 .notdef
|
||||
!19 U+0019 .notdef
|
||||
!1A U+001A .notdef
|
||||
!1B U+001B .notdef
|
||||
!1C U+001C .notdef
|
||||
!1D U+001D .notdef
|
||||
!1E U+001E .notdef
|
||||
!1F U+001F .notdef
|
||||
!20 U+0020 space
|
||||
!21 U+0021 exclam
|
||||
!22 U+0022 quotedbl
|
||||
!23 U+0023 numbersign
|
||||
!24 U+0024 dollar
|
||||
!25 U+0025 percent
|
||||
!26 U+0026 ampersand
|
||||
!27 U+0027 quotesingle
|
||||
!28 U+0028 parenleft
|
||||
!29 U+0029 parenright
|
||||
!2A U+002A asterisk
|
||||
!2B U+002B plus
|
||||
!2C U+002C comma
|
||||
!2D U+002D hyphen
|
||||
!2E U+002E period
|
||||
!2F U+002F slash
|
||||
!30 U+0030 zero
|
||||
!31 U+0031 one
|
||||
!32 U+0032 two
|
||||
!33 U+0033 three
|
||||
!34 U+0034 four
|
||||
!35 U+0035 five
|
||||
!36 U+0036 six
|
||||
!37 U+0037 seven
|
||||
!38 U+0038 eight
|
||||
!39 U+0039 nine
|
||||
!3A U+003A colon
|
||||
!3B U+003B semicolon
|
||||
!3C U+003C less
|
||||
!3D U+003D equal
|
||||
!3E U+003E greater
|
||||
!3F U+003F question
|
||||
!40 U+0040 at
|
||||
!41 U+0041 A
|
||||
!42 U+0042 B
|
||||
!43 U+0043 C
|
||||
!44 U+0044 D
|
||||
!45 U+0045 E
|
||||
!46 U+0046 F
|
||||
!47 U+0047 G
|
||||
!48 U+0048 H
|
||||
!49 U+0049 I
|
||||
!4A U+004A J
|
||||
!4B U+004B K
|
||||
!4C U+004C L
|
||||
!4D U+004D M
|
||||
!4E U+004E N
|
||||
!4F U+004F O
|
||||
!50 U+0050 P
|
||||
!51 U+0051 Q
|
||||
!52 U+0052 R
|
||||
!53 U+0053 S
|
||||
!54 U+0054 T
|
||||
!55 U+0055 U
|
||||
!56 U+0056 V
|
||||
!57 U+0057 W
|
||||
!58 U+0058 X
|
||||
!59 U+0059 Y
|
||||
!5A U+005A Z
|
||||
!5B U+005B bracketleft
|
||||
!5C U+005C backslash
|
||||
!5D U+005D bracketright
|
||||
!5E U+005E asciicircum
|
||||
!5F U+005F underscore
|
||||
!60 U+0060 grave
|
||||
!61 U+0061 a
|
||||
!62 U+0062 b
|
||||
!63 U+0063 c
|
||||
!64 U+0064 d
|
||||
!65 U+0065 e
|
||||
!66 U+0066 f
|
||||
!67 U+0067 g
|
||||
!68 U+0068 h
|
||||
!69 U+0069 i
|
||||
!6A U+006A j
|
||||
!6B U+006B k
|
||||
!6C U+006C l
|
||||
!6D U+006D m
|
||||
!6E U+006E n
|
||||
!6F U+006F o
|
||||
!70 U+0070 p
|
||||
!71 U+0071 q
|
||||
!72 U+0072 r
|
||||
!73 U+0073 s
|
||||
!74 U+0074 t
|
||||
!75 U+0075 u
|
||||
!76 U+0076 v
|
||||
!77 U+0077 w
|
||||
!78 U+0078 x
|
||||
!79 U+0079 y
|
||||
!7A U+007A z
|
||||
!7B U+007B braceleft
|
||||
!7C U+007C bar
|
||||
!7D U+007D braceright
|
||||
!7E U+007E asciitilde
|
||||
!7F U+007F .notdef
|
||||
!80 U+0080 .notdef
|
||||
!81 U+0081 .notdef
|
||||
!82 U+0082 .notdef
|
||||
!83 U+0083 .notdef
|
||||
!84 U+0084 .notdef
|
||||
!85 U+0085 .notdef
|
||||
!86 U+0086 .notdef
|
||||
!87 U+0087 .notdef
|
||||
!88 U+0088 .notdef
|
||||
!89 U+0089 .notdef
|
||||
!8A U+008A .notdef
|
||||
!8B U+008B .notdef
|
||||
!8C U+008C .notdef
|
||||
!8D U+008D .notdef
|
||||
!8E U+008E .notdef
|
||||
!8F U+008F .notdef
|
||||
!90 U+0090 .notdef
|
||||
!91 U+0091 .notdef
|
||||
!92 U+0092 .notdef
|
||||
!93 U+0093 .notdef
|
||||
!94 U+0094 .notdef
|
||||
!95 U+0095 .notdef
|
||||
!96 U+0096 .notdef
|
||||
!97 U+0097 .notdef
|
||||
!98 U+0098 .notdef
|
||||
!99 U+0099 .notdef
|
||||
!9A U+009A .notdef
|
||||
!9B U+009B .notdef
|
||||
!9C U+009C .notdef
|
||||
!9D U+009D .notdef
|
||||
!9E U+009E .notdef
|
||||
!9F U+009F .notdef
|
||||
!A0 U+00A0 space
|
||||
!A1 U+00A1 exclamdown
|
||||
!A2 U+00A2 cent
|
||||
!A3 U+00A3 sterling
|
||||
!A4 U+00A4 currency
|
||||
!A5 U+00A5 yen
|
||||
!A6 U+00A6 brokenbar
|
||||
!A7 U+00A7 section
|
||||
!A8 U+00A8 dieresis
|
||||
!A9 U+00A9 copyright
|
||||
!AA U+00AA ordfeminine
|
||||
!AB U+00AB guillemotleft
|
||||
!AC U+00AC logicalnot
|
||||
!AD U+00AD hyphen
|
||||
!AE U+00AE registered
|
||||
!AF U+00AF macron
|
||||
!B0 U+00B0 degree
|
||||
!B1 U+00B1 plusminus
|
||||
!B2 U+00B2 twosuperior
|
||||
!B3 U+00B3 threesuperior
|
||||
!B4 U+00B4 acute
|
||||
!B5 U+00B5 mu
|
||||
!B6 U+00B6 paragraph
|
||||
!B7 U+00B7 periodcentered
|
||||
!B8 U+00B8 cedilla
|
||||
!B9 U+00B9 onesuperior
|
||||
!BA U+00BA ordmasculine
|
||||
!BB U+00BB guillemotright
|
||||
!BC U+00BC onequarter
|
||||
!BD U+00BD onehalf
|
||||
!BE U+00BE threequarters
|
||||
!BF U+00BF questiondown
|
||||
!C0 U+00C0 Agrave
|
||||
!C1 U+00C1 Aacute
|
||||
!C2 U+00C2 Acircumflex
|
||||
!C3 U+00C3 Atilde
|
||||
!C4 U+00C4 Adieresis
|
||||
!C5 U+00C5 Aring
|
||||
!C6 U+00C6 AE
|
||||
!C7 U+00C7 Ccedilla
|
||||
!C8 U+00C8 Egrave
|
||||
!C9 U+00C9 Eacute
|
||||
!CA U+00CA Ecircumflex
|
||||
!CB U+00CB Edieresis
|
||||
!CC U+00CC Igrave
|
||||
!CD U+00CD Iacute
|
||||
!CE U+00CE Icircumflex
|
||||
!CF U+00CF Idieresis
|
||||
!D0 U+011E Gbreve
|
||||
!D1 U+00D1 Ntilde
|
||||
!D2 U+00D2 Ograve
|
||||
!D3 U+00D3 Oacute
|
||||
!D4 U+00D4 Ocircumflex
|
||||
!D5 U+00D5 Otilde
|
||||
!D6 U+00D6 Odieresis
|
||||
!D7 U+00D7 multiply
|
||||
!D8 U+00D8 Oslash
|
||||
!D9 U+00D9 Ugrave
|
||||
!DA U+00DA Uacute
|
||||
!DB U+00DB Ucircumflex
|
||||
!DC U+00DC Udieresis
|
||||
!DD U+0130 Idotaccent
|
||||
!DE U+015E Scedilla
|
||||
!DF U+00DF germandbls
|
||||
!E0 U+00E0 agrave
|
||||
!E1 U+00E1 aacute
|
||||
!E2 U+00E2 acircumflex
|
||||
!E3 U+00E3 atilde
|
||||
!E4 U+00E4 adieresis
|
||||
!E5 U+00E5 aring
|
||||
!E6 U+00E6 ae
|
||||
!E7 U+00E7 ccedilla
|
||||
!E8 U+00E8 egrave
|
||||
!E9 U+00E9 eacute
|
||||
!EA U+00EA ecircumflex
|
||||
!EB U+00EB edieresis
|
||||
!EC U+00EC igrave
|
||||
!ED U+00ED iacute
|
||||
!EE U+00EE icircumflex
|
||||
!EF U+00EF idieresis
|
||||
!F0 U+011F gbreve
|
||||
!F1 U+00F1 ntilde
|
||||
!F2 U+00F2 ograve
|
||||
!F3 U+00F3 oacute
|
||||
!F4 U+00F4 ocircumflex
|
||||
!F5 U+00F5 otilde
|
||||
!F6 U+00F6 odieresis
|
||||
!F7 U+00F7 divide
|
||||
!F8 U+00F8 oslash
|
||||
!F9 U+00F9 ugrave
|
||||
!FA U+00FA uacute
|
||||
!FB U+00FB ucircumflex
|
||||
!FC U+00FC udieresis
|
||||
!FD U+0131 dotlessi
|
||||
!FE U+015F scedilla
|
||||
!FF U+00FF ydieresis
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue